4

Hi i am new to docker and linux. I am trying to ping a particular ip address from a python file in a container built on ubuntu 18.04 base.

I get the following error when the kubernetes pod container is ran on CentOS OS but it runs fine on Ubuntu OS

sudo: effective uid is not 0, is /usr/bin/sudo on a file system with the 'nosuid' option set or an NFS file system without root privileges?

I am trying to run the container as a normal user. I have a security context in the container deployment yaml as below:

fsGroup: 2000 
runAsNonRoot: true
runAsUser: 1000

In the docker file i am trying to create a normal user and add it to sudoers grp as below

RUN adduser --disabled-password --gecos '' <normal user>
RUN adduser <normal user> sudo
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
USER <normal user>

python file which calls the ping command as follows

subprocess.check_call(f"sudo ping -c 3 {address}")

1 Answer 1

4

Rationale

The error message you face with Kubernetes on CentOS already gives a hint about how sudo is working: It makes use of the setuid bit to have it effectively executed as owner of the executable, intended to be root, regardless which user executes it. Two conditions need to be met for this to work:

  1. The underlying filesystem needs to be mounted without the nosuid option, which prevents setuid functionality. You can list all mounts with with this flag e.g. via:
    mount | grep nosuid
    
  2. The owner of the file needs to be root, which you can check via:
    ls -l "$(which sudo)"
    
    The owner's mode should show rws, where the s is the setuid bit, which needs to be present as well, of course.

Needless to say that both conditions need to be met on host system level when using a host system kernel feature. I'm no expert with the different container platforms, whether and how they mount the container images and do UNIX user namespace sandboxing, so that sudo within the container may naturally be ineffective for granting host system capabilities.

Solutions

Granting a user full passwordless sudo permissions only to run ping in my personal opinion is no good idea anyway for security reasons, in case it is even possible within Docker. There are safer options to achieve this, I'll start with the one which should definitely work for your use case and is IMHO the safest from security point of view and continue with two other general solutions, while not recommending them.

  1. It is possible to define UNIX groups which shall have ICMP listen permissions without requiring root privileges. Some Linux distributions even do this by default, the common init system systemd as well does this via their upstream default configuration:
    echo 'net.ipv4.ping_group_range = 0 2147483647' > /etc/sysctl.d/99-ping.conf
    sysctl -p /etc/sysctl.d/99-ping.conf
    
    This allows all possible UNIX users ICMP permissions, the group range can be narrowed down to a single UNIX group only, of course. It needs to be applied on the container's host system.
  2. Raw network socket capabilities can be granted via the ping executable directly to all users which execute it:
    setcap 'cap_net_raw+ep' "$(which ping)"
    
    This is how many ping implementations/packages ship by default, but it theoretically grants much more permissions than ICMP listening only.
  3. The ping executable itself can have the setuid bit so that it is effectively executed as root user in every case:
    chmod +s "$(which ping)"
    
    Some ping implementations/packages ship like this by default, but needless to say that this is the worst options from security point of view.

In your case, solutions 2 and 3 would need to be applied within the container to the container's ping executable and do only work when there is no sandboxing for executable capabilities respectively UNIX users, i.e. the root user within the container is the same root user on the host for solution 3. That sudo does not work indicates that the the last condition may not be met. Already these limitations in combination with containers and the security benefits IMHO clearly underlines the benefit of solution 1.

3
  • I have tried applying the ip group range to the containers host OS system, rebooted the host OS, reapplied the deployment also restarted the container, Yet the ping fails for CentOS but works for Ubuntu OS
    – karthik
    Commented Jan 31, 2022 at 10:02
  • Clarification: Yet the ping fails when container is running on CentOS but works when container runs on Ubuntu OS I am running ping -c 3 <IP> and not sudo ping. I still get socket: Operation not permitted error
    – karthik
    Commented Jan 31, 2022 at 10:17
  • Did you verify on CentOS via sysctl 'net.ipv4.ping_group_range' that the setting was applied correctly? Probably with that host or K8s there is another sandboxing done. Just to rule it out, try to apply the sysctl change within the container as well.
    – MichaIng
    Commented Oct 9, 2022 at 8:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .