我预计下面的命令会因为权限异常而失败,因为它是作为非特权用户运行的。但相反,它似乎成功了。
% docker run --rm -u nobody alpine nc -l 0.0.0.0 443
% docker exec -it b2b471d05398 sh
~ $ id
uid=65534(nobody) gid=65534(nobody)
~ $ ps
PID USER TIME COMMAND
1 nobody 0:00 nc -l 0.0.0.0 443
8 nobody 0:00 sh
15 nobody 0:00 ps
~ $ %
我已经尝试禁用各种功能,但是,这些都不能阻止nc
成功运行并绑定到端口。
docker run --rm -u nobody --cap-drop=SETUID --cap-drop=NET_BIND_SERVICE --cap-drop=SETFCAP --cap-drop=NET_RAW alpine nc -l 0.0.0.0 443
对于David Maze的回答,我用Debian GNU/Linux
构建了一个映像。
Dockerfile
:
FROM python:slim-buster
EXPOSE 80
USER nobody
CMD python -m http.server 80
docker build命令
docker build -t test .
仍然可以通过非root绑定特权端口用户
docker run --rm test
我也试过这样做:
docker run --rm --cap-drop=SETUID --cap-drop=NET_BIND_SERVICE --cap-drop=SETFCAP --cap-drop=NET_RAW test
是否知道我应该做些什么来删除功能并触发我试图重现的错误?
TL;在命令中包含--sysctl "net.ipv4.ip_unprivileged_port_start=1024"
选项
长答:
介绍在docker文档中,
警告
docker组授予同等权限给root用户
这不是指您打算在容器内使用的用户,而是指您的${user}。很重要因为这将授予所有码头工人能做的事!
然而,当没有人不是可以登录的适当用户时,uid存在并且docker将使用该uid运行程序。看到
测试所述问题
我尝试了netcat问题,但我没有在alpine nc上找到任何合适的资源。测试它似乎没有正确打开端口。🤷python服务器在测试时提供了更多的洞察力。
如果您尝试以下操作,您将看到安全性主机网络是否正常工作
正确权限被拒绝:
docker run -u nobody --cap-drop=all --network host --rm python:slim-buster python -m http.server 80
docker run --cap-drop=all --network host --rm python:slim-buster python -m http.server 80
docker run -u nobody --network host --rm python:slim-buster python -m http.server 80
授予root权限(从介绍中可以看到,是根的等效)):
docker run --network host --rm python:slim-buster python -m http.server 80
但是确实存在问题对于桥梁来说:
docker run -u nobody --cap-drop=all --rm python:slim-buster python -m http.server 80
解释环顾四周,你可以找到docker桥接接口不包括在端口开放限制中。请参见问题合并。
和往常一样,看看他们的测试,你会发现"答案">
3种口味带桥权限被拒绝
docker run -u nobody --cap-drop=all --sysctl "net.ipv4.ip_unprivileged_port_start=1024" --rm python:slim-buster python -m http.server 80
docker run -u nobody --sysctl "net.ipv4.ip_unprivileged_port_start=1024" --rm python:slim-buster python -m http.server 80
docker run --cap-drop=all --sysctl "net.ipv4.ip_unprivileged_port_start=1024" --rm python:slim-buster python -m http.server 80
这里正确地授予root(特权用户,同时要求特权用户访问)
docker run --sysctl "net.ipv4.ip_unprivileged_port_start=1024" --rm python:slim-buster python -m http.server 80
Alpine基于一个名为BusyBox的最小工具集,该工具集包含许多标准命令行实用程序的自己的实现。BusyBox支持的nc
语法是
nc -l -p 443 0.0.0.0
where-l
设置了"listen"mode,-p 443
为监听端口。(实际上,如果没有-p
选项,我希望BusyBoxnc
立即退出-l
选项和两个位置参数,然后您将无法将docker exec
放入容器中。)
如果没有-p
选项,BusyBoxnc
将选择任意端口并将其打印到stderr。这不是一个特权端口,这就是为什么你不会得到错误。docker logs
应该显示端口号,容器内的netstat
应该显示备用端口上的侦听器。