skip to Main Content

I have an application I am trying to move into a docker container. I have most things working, but the part of the application that requires elevated privileges (to use socket and configure network parameters) does not seem to be working.

What I’ve tried:

  • Giving the --privileged flag
  • Giving the --cap-add=NET_ADMIN flag
  • Removing security options with --security-opt apparmor=unconfined --security-opt seccomp=unconfined
  • Adding user groups and sudo in the Dockerfile
  • Using the --net=host option.
  • Adding my user to the docker group

This is the error I’m getting:

Process Process-2:
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/multiprocessing/process.py", line 315, in _bootstrap
    self.run()
  File "/usr/local/lib/python3.9/multiprocessing/process.py", line 108, in run
    self._target(*self._args, **self._kwargs)
  File "/app/support_files/wizard_configuration_routines.py", line 781, in find_device
    device_list = scan_subnet('192.168.30.0/24',g_interface)
  File "/app/support_files/wizard_configuration_routines.py", line 757, in scan_subnet
    answered, unanswered = scapy.arping(subnet,verbose=False,iface=g_interface)
  File "/usr/local/lib/python3.9/site-packages/scapy/layers/l2.py", line 890, in arping
    ans, unans = srp(
  File "/usr/local/lib/python3.9/site-packages/scapy/sendrecv.py", line 687, in srp
    s = iface.l2socket()(promisc=promisc, iface=iface,
  File "/usr/local/lib/python3.9/site-packages/scapy/arch/linux.py", line 484, in __init__
    self.ins = socket.socket(
  File "/usr/local/lib/python3.9/socket.py", line 232, in __init__
    _socket.socket.__init__(self, family, type, proto, fileno)
PermissionError: [Errno 1] Operation not permitted

Below are the relevant files

Dockerfile

# Slim version of Python
FROM python:3.9-slim

# Download Package Information
RUN apt update -y

# Install Tkinter
RUN apt install tk -y

# Install fontconfig
RUN apt install fontconfig -y

# Install Pillow
RUN python3 -m pip install Pillow
RUN python3 -m pip install ouster-sdk
RUN python3 -m pip install scapy
RUN python3 -m pip install customtkinter
RUN apt install net-tools -y
RUN fc-cache -f -v

# Commands to run Tkinter application
CMD ["/app/SCOT_wizard.py"]
ENTRYPOINT ["python3"]

build.sh

sudo docker build -t tkinter_in_docker .

run.sh

sudo docker run -u=$(id -u $USER):$(id -g $USER) 
 -e DISPLAY=$DISPLAY 
 -v /tmp/.X11-unix:/tmp/.X11-unix:rw 
 -v $(pwd)/app:/app 
 -v $(pwd)/logs:/logs 
 -v $(pwd)/records:/records 
 -v $(pwd)/fonts:/.fonts
 -w /app 
 --privileged 
 --net=host 
 --rm 
  tkinter_in_docker

In an attempt to understand the problem, I made a simple docker container that has the line that is failing, and it works. I can’t figure out why it won’t work in the larger application. Here is the minimum example:

Dockerfile

# Slim version of Python
FROM python:3.9-slim

# Download Package Information
RUN apt update -y
RUN apt install net-tools -y
RUN apt install -y libpcap0.8 

RUN python3 -m pip install scapy
# Commands to run Tkinter application
CMD ["SCOT_wizard.py"]
ENTRYPOINT ["python3"]

run.sh

sudo docker run 
 -v $(pwd)/app:/app 
 -w /app 
 --net=host 
 --rm 
  tkinter_in_docker

/app/SCOT_wizard.py

import scapy.all as scapy
answered, unanswered = scapy.arping('192.168.11.0/24',verbose=False,iface='eno2')
print(answered)

2

Answers


  1. Try to run the container as root. To do that you can either add to Dockerfile the line:

    USER root
    

    or run rhe container with the -u parameter:

    docker run -u root <image-name>
    
    Login or Signup to reply.
  2. Your minimal example seems to work because you are not trying to run it as a specific user using the -u option. In your main application, you are setting the user of the container to the same user as your host system with -u=$(id -u $USER):$(id -g $USER). That could be why your main application does not have enough privileges, but your minimal example does.

    USER root still has the same error, and docker run -u root messes up the X server forwarding that I’m using to see the application.
    Is there another way to get the process to run with the needed permissions?

    Since running your container with a user root does not work, make sure that user has the necessary permissions inside the container. That might involve adding the user to specific groups that have access to raw sockets.
    For example, you can add the user to the netdev group (mentioned here) inside the container, but remember, this group might not exist in a slim container.

    RUN groupadd -r netdev && usermod -a -G netdev $USER
    

    Do replace $USER with the username you are using, or use some Docker ARGS to make it dynamic.
    See also "Running Docker Containers as a Non-root User with a Custom UID / GID" by Nick Janetakis.

    Along with NET_ADMIN, the raw socket operation might require SYS_RAWIO capability, to "Perform I/O port operations (iopl(2) and ioperm(2))".
    Add it with the --cap-add=SYS_RAWIO flag in your run.sh.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search