我今天一直在阅读uid 1001背后的理论,特别是在Docker中,最好不要让容器作为根用户运行。
到目前为止,我能告诉unix系统的是…
- root用户的UID为0大多数unix发行版都保留第一个
- 100个新用户被分配的UID从500或1000开始
- 当你创建一个新帐户,通常会给下一个最高的未使用帐户数字1001(不确定这与上一个点的关系意味着什么。如果有人能澄清,请(
我见过很多Dockerfile的例子,它们只会尝试使用1001。
USER 1001
两个问题
理论1001是否可以安全使用,因为它高于主机上新用户的uid分配范围,即点2?
将用户指定为1001是最佳做法,还是最好添加一个新用户?
RUN useradd -ms /bin/bash newuser
USER newuser
WORKDIR /home/newuser
谢谢
如果您的容器不需要在命名卷或从主机装载的目录绑定中写入数据,那么容器运行的用户ID通常根本不重要。仍然有一些限制(如果您试图侦听小于1024的端口号,则用户ID必须为0,或者必须在启动时手动添加功能(。
我会使用你的第二个表单,只是在Dockerfile的结束之前我不会切换用户。
FROM python:3.8 # arbitrary choice
# ... install OS packages ...
# Create the user. This doesn't need to be repeated if the
# application code changes. It is a "system" user without
# a home directory and a default shell. We don't care what
# its numeric user ID is.
RUN useradd -r newuser
# WORKDIR creates the directory. It does not need to be
# under /home. It should be owned by root.
WORKDIR /app
# Copy the application in and do its installation, still as root.
COPY requirements.txt .
RUN pip3 install -r requirements.txt
COPY . .
# Switch USER only at the end of the file.
USER newuser
CMD ["./app.py"]
"主目录"在Docker中通常不是一个定义明确的概念;我在这里创建了没有特定主目录的用户,并且应用程序目录不在正常的Linux/home
目录下。类似地,我还没有特意为这个用户指定shell,或者专门使用GNUbash。
此设置的一个重要安全点是root
拥有应用程序文件,但newuser
正在运行代码。如果存在某种折衷,这将为您提供额外的保护层:折衷的应用程序代码不能覆盖应用程序代码或其固定静态数据。
我在开始这项工作时提出了一个警告,即如果您不需要在文件系统中持久保存数据,那么这项工作很好。如果它这样做了,它将需要有一定的适应性,这可能意味着以root身份启动,但随后放弃特权。我支持两种运行模式:
容器最初启动时有一个完全空的目录,可能由root拥有(一个命名为Docker的卷;一个名为Kubernetes的卷(。在这种情况下,创建所需的数据目录,并在Dockerfile中使其归用户所有。
docker run -v somevolume:/data myimage
容器启动时有一个绑定安装的主机目录,还有一个命名要使用的主机用户ID的
-u
选项。docker run -u $(id -u) "$PWD/data:data" myimage
您需要使用入口点包装脚本来检测您所处的情况,创建初始存储结构,设置其权限,并在需要时切换到非root用户。有一些重量较轻的工具,如gosu或su exec,专门支持这种情况。DockerHubconsul
镜像的入口点脚本有一个在启动时执行此操作的示例。