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
Try to run the container as root. To do that you can either add to Dockerfile the line:
or run rhe container with the -u parameter:
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.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.Do replace
$USER
with the username you are using, or use some DockerARGS
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 requireSYS_RAWIO
capability, to "Perform I/O port operations (iopl(2)
andioperm(2)
)".Add it with the
--cap-add=SYS_RAWIO
flag in yourrun.sh
.