0

How can I run a script in a docker container with additional capabilities, such as NET_ADMIN?

I'm testing out some commands that I'd like to run in a docker image that require the NET_ADMIN permissions. For example, this works:

docker run --rm -it --cap-add 'NET_ADMIN' debian:stable-slim "iptables -L"

But if I want to execute a script (via docker exec), then suddenly the --cap-add option is not available.

root@disp8686:~# cat << EOF > docker_script.sh
> apt-get update
> apt-get -y install iptables
> iptables -L
> EOF
root@disp8686:~# docker exec -it --cap-add 'NET_ADMIN' debian:stable-slim docker_script.sh
unknown flag: --cap-add
See 'docker exec --help'.
root@disp8686:~# 

Why does --cap-add exist for docker run but not docker exec and how can I run a script in a docker container using --cap-add?

Michael Altfield
  • 2,083
  • 23
  • 39
  • `docker exec` is a debugging tool, and can't change the capability set of the container. As a design goal, containers can't generally modify the host's networking configuration; whatever you're trying to run, it's probably better done without Docker. Is there relevant application code that actually needs this setup that you can add to the question? – David Maze Sep 18 '20 at 19:03
  • The purpose isn't to modify the host's network config. The purpose is to modify the container's network config. This is for my app's build script, and I need `NET_ADMIN` to configure `iptables` so I can be sure that some of the build commands that might otherwise download unverified code (namely `pip`) can't access the internet while safe package managers (eg `apt-get`) can. I'm using docker so it's portable and users can easily verify that my builds are reproducible. – Michael Altfield Sep 18 '20 at 19:25

1 Answers1

0

docker exec does not support the --cap-add option, but you can use the --volume option of docker run to make a script on the docker host available to a container and execute it inside the container as follows:

tmpDir=`mktemp -d`
pushd "${tmpDir}"

cat << EOF > docker_script.sh
apt-get update
apt-get -y install iptables
iptables -L
EOF
chmod +x docker_script.sh

sudo docker run --rm -it --cap-add 'NET_ADMIN' --volume "${tmpDir}:/root" debian:stable-slim /bin/bash -c "cd /root && ./docker_script.sh"

Here is an example execution in Debian 10:

user@disp7086:~$ tmpDir=`mktemp -d`
user@disp7086:~$ pushd "${tmpDir}"
/tmp/tmp.PXmB9uJ8oM ~
user@disp7086:/tmp/tmp.PXmB9uJ8oM$ 
user@disp7086:/tmp/tmp.PXmB9uJ8oM$ cat << EOF > docker_script.sh
> apt-get update
> apt-get -y install iptables
> iptables -L
> EOF
user@disp7086:/tmp/tmp.PXmB9uJ8oM$ chmod +x docker_script.sh
user@disp7086:/tmp/tmp.PXmB9uJ8oM$ 

user@disp7086:/tmp/tmp.PXmB9uJ8oM$ sudo docker run --rm -it --cap-add 'NET_ADMIN' --volume "${tmpDir}:/root" debian:stable-slim /bin/bash -c "cd /root && ./docker_script.sh"
Get:1 http://deb.debian.org/debian stable InRelease [122 kB]
...
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
user@disp7086:/tmp/tmp.PXmB9uJ8oM$

Michael Altfield
  • 2,083
  • 23
  • 39