【问题标题】:Any difference between su -www-data vs sudo -u www-data in docker?docker 中的 su -www-data 与 sudo -u www-data 有什么区别?
【发布时间】:2021-11-28 06:18:45
【问题描述】:

我的 php 脚本在 docker 中运行,我需要使用 www-data 用户运行它,所以在我的 dockerfile 的 ENTRYPOINT 中我可以

su www-data -s /bin/sh -c "/usr/local/bin/php xxx"

或者

sudo -u www-data "/usr/local/bin/php xxx"

我知道sudo和su之间的一般区别,但是切换到非root用户有什么区别?

到目前为止,对我来说唯一的区别是没有为基于 alpine 的 docker 安装 sudo,所以我需要先安装它。

【问题讨论】:

  • 这两件事都不做。切换到USER www-data,然后设置CMD php xxx。在 Docker 中通常不需要 sudo,正确设置它可能会很棘手。
  • 但在我的 ENTRYPOINT 中还有其他命令需要以 root 身份运行。

标签: docker sudo alpine su


【解决方案1】:

首先,您可能想看看this

避免安装或使用 sudo,因为它具有不可预测的 TTY 和可能导致问题的信号转发行为。如果您绝对需要类似于 sudo 的功能,例如将守护进程初始化为 root 但以非 root 身份运行,请考虑使用“gosu”。

因此,对于您的场景,您可以使用默认的USER root 运行Dockerfile,并在docker-entrypoint.sh 中仍然使用root 运行您的命令,最后使用exec gosu xxx xxx 分叉并替换旧的过程。一个最小的例子:

Dockerfile:

FROM debian

RUN set -eux; \
    apt-get update; \
    apt-get install -y gosu; \
    rm -rf /var/lib/apt/lists/*;

COPY docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh

ENTRYPOINT ["docker-entrypoint.sh"]

docker-entrypoint.sh:

#!/bin/bash
echo "show user before gosu:"
id
echo "show user after gosu:"
exec gosu www-data id

执行:

$ docker build -t abc:1 .
$ docker run --rm abc:1
show user before gosu:
uid=0(root) gid=0(root) groups=0(root)
show user after gosu:
uid=33(www-data) gid=33(www-data) groups=33(www-data)

您也可以参考一些开源图片以供参考:redis & its entrypoint

【讨论】:

  • 感谢您回答我的问题,尤其是我不知道 gosu 存在。现在我还有一个问题,如果不是关于docker,su和sudo切换到非root用户有什么区别吗?我觉得没有太大区别。
  • 我想这两个概念已经有很多比较了,比如this,因为它不是一个新概念。供您使用,因为您是root时调用它,所以我看不出有什么区别,但是如果作为普通用户,我们可能会看到区别。
  • 另外,sudo 需要更改 sudoers,而 su 不需要。
  • 我在周围看到的许多 Dockerfile 为他们的非 root 用户提供了无限制的 sudoers 访问权限,并将他们的密码设置为一个容易猜到的东西,以纯文本形式记录在 Dockerfile 和 docker history 中。如果您可以通过先说sudo 来做任何事情,那么这充其量只是对安全性的微不足道的改进。 (也:xkcd.com/149
  • @DavidMaze 但是 su www-data 有什么问题?