【问题标题】:'su' command in Docker returns 'must be run from terminal'Docker 中的“su”命令返回“必须从终端运行”
【发布时间】:2016-04-29 17:52:06
【问题描述】:

我正在开发一个用于教学目的的 docker 环境,需要能够在 docker 内切换用户。

我使用密码设置了“用户”用户,但是当我尝试使用 su 切换到它时,我得到“su must be run from terminal”。

如果我尝试 ssh 到 docker 并通过 php shell 发出命令(一个 apache 服务正在 Docker 实例上运行),我会得到这个。

非常感谢任何帮助。

【问题讨论】:

  • 我有兴趣了解有关您的用例/设置的更多信息。在容器中运行 SSH 是一种反模式。您是否需要即时更改用户(当您“在”容器中时?)或作为构建过程的一部分(使用 Dockerfile?)。
  • 如果你谷歌这个错误信息,有几种解决方案。
  • 感谢 warmoverflow 实际帮助将不胜感激。我确实找到了运行 python 的解决方法,但需要一个一致的解决方案。
  • JHarris 我不确定 docker 的原始用途是什么,但我将它用于一个相当具体的特殊场景。我正在其中构建 PoC 漏洞以展示软件(内部)安全性。

标签: linux docker


【解决方案1】:

当你通过 php SSH 进入或进入时,你的会话没有被分配一个 pty。我使用了以下每种解决方案:

回答 1:使用 ssh 登录时使用 ssh -t 或 ssh -tt 来分配 pty:

在运行这样的会话时,由于 ptys,我获得了正确运行命令的乐趣:jenkins shell -> ssh driver -> ssh test -> docker exec。 这里的好答案: https://unix.stackexchange.com/questions/105422/command-must-be-run-from-a-terminal

“尝试 ssh 的 -t 选项。如果不起作用,请尝试 -tt。”

"-t 强制分配伪 tty。这可用于在远程机器上执行任意基于屏幕的程序,这非常有用,例如在实现菜单服务时。多个 -t 选项强制分配 tty,即使ssh 没有本地 tty。”

答案 2:使用 docker run -t ... 和 docker exec -it

使用 -t 和 -it 选项在 docker exec 会话中分配 pty。

同样使用 docker exec,您可以简单地使用 -u 选项以不同用户身份登录到容器并避免使用 su。例如

$ docker exec -u root -it small_hypatia bash

这里有一个很好的问题和答案: https://github.com/docker/docker/issues/8631

答案 3:使用 python 在你的 shell 中生成一个 pty

相当可爱的 hack :)

jenkins@e9fbe94d4c89:~$ su -
su: must be run from a terminal

$ echo "import pty; pty.spawn('/bin/bash')" > /tmp/asdf.py
$ python /tmp/asdf.py

$ su -
Password: 

root@e9fbe94d4c89:~# 

【讨论】:

  • 我正在寻找答案 2(docker 环境)- 有效!
【解决方案2】:

此解决方案通过使用“bsdutiles”包中的“脚本”命令来设置 pty(终端)。 'sleep' 命令用于防止在'su' 命令准备好读取密码之前发送密码。 “tail”命令删除“su”发出的“密码:”输入行。

 sh -c "sleep 1; echo rootpassword" | script -qc 'su -c whoami - root' | tail -n +2

请注意,rootpassword 可以通过多种方式查看(历史记录、ps、/proc/ 等...)。以空格开头的命令至少可以避免历史记录。

【讨论】:

  • 可能需要将脚本部分更改为 script /dev/null -qc [...] 以防止 script 将输出保存到名为 typescript 的文件中。
【解决方案3】:

如果您使用su-exec 而不是su,tty 的问题就完全消失了,因为它直接调用 execvp 而不是像su 那样分叉。

Gosu 是另一个类似的替代方案。

【讨论】:

    【解决方案4】:

    “docker -i”对我不起作用。我在上面两种方式都做了合并,进入容器时,ssh localhost,效果一样。

    docker exec -it -u user img bash -c "ssh localhost";
    

    【讨论】:

      猜你喜欢
      • 2014-01-04
      • 2011-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-22
      • 2016-02-13
      • 1970-01-01
      相关资源
      最近更新 更多