3
docker run --rm --cap-drop=net_bind_service --publish 8080:80 --name nginx nginx

ps --forest -fC nginx
UID          PID    PPID  C STIME TTY          TIME CMD
root      449870  449847  0 12:38 ?        00:00:00 nginx: master process nginx -g daemon off;
101       449929  449870  0 12:38 ?        00:00:00  \_ nginx: worker process
101       449930  449870  0 12:38 ?        00:00:00  \_ nginx: worker process
101       449931  449870  0 12:38 ?        00:00:00  \_ nginx: worker process
101       449932  449870  0 12:38 ?        00:00:00  \_ nginx: worker process
101       449933  449870  0 12:38 ?        00:00:00  \_ nginx: worker process
101       449934  449870  0 12:38 ?        00:00:00  \_ nginx: worker process
101       449935  449870  0 12:38 ?        00:00:00  \_ nginx: worker process
101       449936  449870  0 12:38 ?        00:00:00  \_ nginx: worker process
101       449937  449870  0 12:38 ?        00:00:00  \_ nginx: worker process
101       449938  449870  0 12:38 ?        00:00:00  \_ nginx: worker process
101       449939  449870  0 12:38 ?        00:00:00  \_ nginx: worker process
101       449940  449870  0 12:38 ?        00:00:00  \_ nginx: worker process

so the process doesn't have net_bind_service, yet it was able to start and bind to port 80.

getpcaps 449870                      
449870: cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap=ep

see this:

docker run --rm --privileged --pid container:nginx --network container:nginx -it --volumes-from nginx --name debug nixery.dev/shell/gnugrep/ps/libcap/htop/lsof/iproute2 bash

bash-5.2# ps aufx
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
0            112  0.0  0.0   4936  4184 pts/0    Ss   19:55   0:00 bash
0            123  0.0  0.0   7240  2324 pts/0    R+   19:56   0:00  \_ ps aufx
0              1  0.0  0.0   8940  6052 ?        Ss   19:38   0:00 nginx: master process nginx -g daemon off;
101           29  0.0  0.0   9328  2564 ?        S    19:38   0:00 nginx: worker process
101           30  0.0  0.0   9328  2564 ?        S    19:38   0:00 nginx: worker process
101           31  0.0  0.0   9328  2564 ?        S    19:38   0:00 nginx: worker process
101           32  0.0  0.0   9328  2564 ?        S    19:38   0:00 nginx: worker process
101           33  0.0  0.0   9328  2564 ?        S    19:38   0:00 nginx: worker process
101           34  0.0  0.0   9328  2564 ?        S    19:38   0:00 nginx: worker process
101           35  0.0  0.0   9328  2564 ?        S    19:38   0:00 nginx: worker process
101           36  0.0  0.0   9328  2564 ?        S    19:38   0:00 nginx: worker process
101           37  0.0  0.0   9328  2564 ?        S    19:38   0:00 nginx: worker process
101           38  0.0  0.0   9328  2564 ?        S    19:38   0:00 nginx: worker process
101           39  0.0  0.0   9328  2564 ?        S    19:38   0:00 nginx: worker process
101           40  0.0  0.0   9328  2568 ?        S    19:38   0:00 nginx: worker process

bash-5.2# ss -ltnp

State                Recv-Q               Send-Q                              Local Address:Port                               Peer Address:Port               Process                                                                                                                                                        
LISTEN               0                    511                                       0.0.0.0:80                                      0.0.0.0:*                   users:(("nginx",pid=40,fd=6),("nginx",pid=39,fd=6),("nginx",pid=38,fd=6),("nginx",pid=37,fd=6),("nginx",pid=36,fd=6),("nginx",pid=35,fd=6),("nginx",pid=34,fd=6),("nginx",pid=33,fd=6),("nginx",pid=32,fd=6),("nginx",pid=31,fd=6),("nginx",pid=30,fd=6),("nginx",pid=29,fd=6),("nginx",pid=1,fd=6))
LISTEN               0                    511                                          [::]:80                                         [::]:*                   users:(("nginx",pid=40,fd=7),("nginx",pid=39,fd=7),("nginx",pid=38,fd=7),("nginx",pid=37,fd=7),("nginx",pid=36,fd=7),("nginx",pid=35,fd=7),("nginx",pid=34,fd=7),("nginx",pid=33,fd=7),("nginx",pid=32,fd=7),("nginx",pid=31,fd=7),("nginx",pid=30,fd=7),("nginx",pid=29,fd=7),("nginx",pid=1,fd=7))

so why container was able to start and bind to port 80 yet the net_bind_service is not listed for the process caps?

1 Answer 1

6

Instead of enabling the privilege to bind to low ports (and other features), Docker lowers the value of the low port below which privilege is needed to 0, thus removing the barrier and allowing any unprivileged process to bind to any port:

daemon/oci_linux.go:

      // allow opening any port less than 1024 without CAP_NET_BIND_SERVICE
      if sysctlExists("net.ipv4.ip_unprivileged_port_start") {
          s.Linux.Sysctl["net.ipv4.ip_unprivileged_port_start"] = "0"
      }

unless it's the host's network or the configuration tells otherwise. Likewise a few lines above, ping (which used to require privilege) gets allowed on non-rootless containers.

You must log in to answer this question.

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