【发布时间】:2021-09-03 21:06:37
【问题描述】:
我预计以下命令会因权限异常而失败,因为它是以非特权用户身份运行的。但相反,它似乎成功了。
% 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
知道我应该怎么做才能删除该功能并触发我试图重现的错误吗?
【问题讨论】:
-
我试图理解这里的问题,443端口只在容器内部运行,并没有暴露在外部机器中。每个容器内会有多个用户吗?
-
假设您试图让 Docker 接管您的 public 端口 443,如果不获取这些特权,就无法真正获得对特权资源的访问。您可以通过配置
sudo来限制您的权限,以尽可能地限制它们;但在这种情况下,能够运行sudo docker run可能已经足以接管系统,因此不清楚如何有效地限制此命令的权限。我的建议是简单地运行它并承担后果。 (但你不是这样做的。) -
我应该得到绑定异常,而不是绑定端口。那应该是小于1024的行为端口号不应该被非root用户打开