非root用户在特权端口上运行的程度



我预计下面的命令会因为权限异常而失败,因为它是作为非特权用户运行的。但相反,它似乎成功了。

% 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应该显示备用端口上的侦听器。

相关内容

  • 没有找到相关文章

最新更新