如何修复 Alpine Linux 中的 "Pseudo-terminal will not be allocated because stdin is not a terminal"?
How to fix "Pseudo-terminal will not be allocated because stdin is not a terminal" in Alpine Linux?
我正在编写一个 PHP 程序,其中包含 运行 各种 shell 命令。有时它需要调用 su
,根据设计,我希望它提示输入提升权限的密码。在 PHP 中使用 passthru()
对此效果很好。
我选择只为我的程序编写功能测试,因为它依赖于 ssh
、su
和其他 shell 命令。因此,我想 运行 PHP 单元中的真实内容,看看它是否按我预期的那样工作。
由于这需要 SSH 服务器和用户帐户配置,因此我在 Docker 中将测试设置为 运行。这种方法看起来会很好 - 图像构建,当它 运行s 它调用 PHPUnit,然后退出。我希望有一种方法可以通过 Docker 将结果 return 发送到调用系统,例如 Travis CI.
我选择了 Alpine Linux 作为我的基础 Docker 图像,但是我在终端分配方面遇到了问题。我最初认为 PHPUnit 妨碍了(请参阅此问题的原始版本)但我现在将其范围缩小到 SSH,运行 by PHP 或者甚至只是在控制台。
这很好用:
su -c whoami
然而,这不是:
ssh localhost -t 'su -c whoami'
我得到:
su: must be suid to work properly
Connection to localhost closed.
请注意,ssh
设置为无密码访问本地主机(用于测试目的),因此我希望输入的唯一密码是 su
。
ssh
的手册建议 -f
有助于要求输入密码的地方(开关 "requests ssh to go to background just before command execution")所以我试试这个:
ssh localhost -t -f 'su -c whoami'
然后我得到:
Pseudo-terminal will not be allocated because stdin is not a terminal.
4275760bde94:~$ su: must be suid to work properly
啊,又是一个错误!好的,所以 I've tried these ideas,特别是强制终端:
ssh localhost -tt -f 'su -c whoami'
double-t 仍然发出有关 SUID 的投诉,并且仍然不起作用。
但是,如果我在我的 Ubuntu 开发机器上执行此操作(也配置了 PPK 自我访问权限)它工作正常:
$ ssh localhost -t 'su -c whoami'
Password:
root
Connection to localhost closed.
这看起来像是 Alpine 或 BusyBox 的 OpenSSH 有问题。我该如何进一步深入研究?
一个解决方案就是切换到另一个基本发行版,Ubuntu 肯定可以正常工作,但这会大大增加我的 Docker 图像大小(目前总共有 68M 非常好)。所以,如果可以的话,我想坚持使用 Alpine。
不太可能 Docker
我确实想知道 Docker 是否会阻止创建或附加终端,但很快就忽略了这一点,因为我可以通过 docker exec -it container_name sh
获得交互式 shell。此外,我可以在 Docker shell 中的两个单独命令中执行 ssh
然后 su
就好了。
Bash 没用
我注意到 Bash 在 Alpine 中可用,但这也没有帮助,这让我感到惊讶:
/ $ apk add bash
bash-4.3$ bash
bash-4.3$ su nonpriv
bash-4.3$ ssh localhost whoami
nonpriv
bash-4.3$ ssh localhost 'su -c whoami'
su: must be suid to work properly
bash-4.3$ ssh localhost 'su -s /bin/bash -c whoami'
su: must be suid to work properly
bash-4.3$ ssh -t localhost 'su -s /bin/bash -c whoami'
su: must be suid to work properly
Connection to localhost closed.
bash-4.3$ ssh -tt localhost 'su -s /bin/bash -c whoami'
su: must be suid to work properly
Connection to localhost closed.
bash-4.3$ ssh -tf localhost 'su -s /bin/bash -c whoami'
Pseudo-terminal will not be allocated because stdin is not a terminal.
bash-4.3$ su: must be suid to work properly
bash-4.3$ ssh -ttf localhost 'su -s /bin/bash -c whoami'
bash-4.3$ su: must be suid to work properly
Connection to localhost closed.
尝试shell插值
我发现这几乎有效:
/ $ ssh -t localhost "$( su -c whoami )"
sh: Password:: not found
sh: root: not found
Connection to localhost closed.
这使用标准的 Alpine sh
shell,并使用 "$()"
构造,在上述 link 上找到,我不完全理解。输出Password:
,也就是su
中的提示,然后等待输入密码。输入密码后 whoami
为 运行,打印出 root
.
所以它看起来像是 运行ning 命令,但我不确定它是否立即 运行ning whoami
然后传递给 ssh
(不是我想要的)或者它是否正在获取远程 shell 到本地主机然后再执行它(这就是我想要的)。
在任何情况下,它都试图 运行 stdout 行,就好像它们本身就是命令一样。我怎样才能通过 SSH 打印输出 运行?
我在我的问题中猜测这将在 Ubuntu 容器中工作,事实证明这是正确的。有趣的是,我仍然收到此命令的 "must be run from a terminal" 错误:
su -c whoami
但这里不是,终端在 SSH 无密码命令中明确分配给自己:
ssh -t localhost 'su -c whoami'
不幸的是,新的 OS 将我的 68M 图片增加到了 430M,呃!因此,我应该很高兴收到使它在 Alpine 上运行的新答案。
我正在编写一个 PHP 程序,其中包含 运行 各种 shell 命令。有时它需要调用 su
,根据设计,我希望它提示输入提升权限的密码。在 PHP 中使用 passthru()
对此效果很好。
我选择只为我的程序编写功能测试,因为它依赖于 ssh
、su
和其他 shell 命令。因此,我想 运行 PHP 单元中的真实内容,看看它是否按我预期的那样工作。
由于这需要 SSH 服务器和用户帐户配置,因此我在 Docker 中将测试设置为 运行。这种方法看起来会很好 - 图像构建,当它 运行s 它调用 PHPUnit,然后退出。我希望有一种方法可以通过 Docker 将结果 return 发送到调用系统,例如 Travis CI.
我选择了 Alpine Linux 作为我的基础 Docker 图像,但是我在终端分配方面遇到了问题。我最初认为 PHPUnit 妨碍了(请参阅此问题的原始版本)但我现在将其范围缩小到 SSH,运行 by PHP 或者甚至只是在控制台。
这很好用:
su -c whoami
然而,这不是:
ssh localhost -t 'su -c whoami'
我得到:
su: must be suid to work properly
Connection to localhost closed.
请注意,ssh
设置为无密码访问本地主机(用于测试目的),因此我希望输入的唯一密码是 su
。
ssh
的手册建议 -f
有助于要求输入密码的地方(开关 "requests ssh to go to background just before command execution")所以我试试这个:
ssh localhost -t -f 'su -c whoami'
然后我得到:
Pseudo-terminal will not be allocated because stdin is not a terminal.
4275760bde94:~$ su: must be suid to work properly
啊,又是一个错误!好的,所以 I've tried these ideas,特别是强制终端:
ssh localhost -tt -f 'su -c whoami'
double-t 仍然发出有关 SUID 的投诉,并且仍然不起作用。
但是,如果我在我的 Ubuntu 开发机器上执行此操作(也配置了 PPK 自我访问权限)它工作正常:
$ ssh localhost -t 'su -c whoami'
Password:
root
Connection to localhost closed.
这看起来像是 Alpine 或 BusyBox 的 OpenSSH 有问题。我该如何进一步深入研究?
一个解决方案就是切换到另一个基本发行版,Ubuntu 肯定可以正常工作,但这会大大增加我的 Docker 图像大小(目前总共有 68M 非常好)。所以,如果可以的话,我想坚持使用 Alpine。
不太可能 Docker
我确实想知道 Docker 是否会阻止创建或附加终端,但很快就忽略了这一点,因为我可以通过 docker exec -it container_name sh
获得交互式 shell。此外,我可以在 Docker shell 中的两个单独命令中执行 ssh
然后 su
就好了。
Bash 没用
我注意到 Bash 在 Alpine 中可用,但这也没有帮助,这让我感到惊讶:
/ $ apk add bash
bash-4.3$ bash
bash-4.3$ su nonpriv
bash-4.3$ ssh localhost whoami
nonpriv
bash-4.3$ ssh localhost 'su -c whoami'
su: must be suid to work properly
bash-4.3$ ssh localhost 'su -s /bin/bash -c whoami'
su: must be suid to work properly
bash-4.3$ ssh -t localhost 'su -s /bin/bash -c whoami'
su: must be suid to work properly
Connection to localhost closed.
bash-4.3$ ssh -tt localhost 'su -s /bin/bash -c whoami'
su: must be suid to work properly
Connection to localhost closed.
bash-4.3$ ssh -tf localhost 'su -s /bin/bash -c whoami'
Pseudo-terminal will not be allocated because stdin is not a terminal.
bash-4.3$ su: must be suid to work properly
bash-4.3$ ssh -ttf localhost 'su -s /bin/bash -c whoami'
bash-4.3$ su: must be suid to work properly
Connection to localhost closed.
尝试shell插值
我发现这几乎有效:
/ $ ssh -t localhost "$( su -c whoami )"
sh: Password:: not found
sh: root: not found
Connection to localhost closed.
这使用标准的 Alpine sh
shell,并使用 "$()"
构造,在上述 link 上找到,我不完全理解。输出Password:
,也就是su
中的提示,然后等待输入密码。输入密码后 whoami
为 运行,打印出 root
.
所以它看起来像是 运行ning 命令,但我不确定它是否立即 运行ning whoami
然后传递给 ssh
(不是我想要的)或者它是否正在获取远程 shell 到本地主机然后再执行它(这就是我想要的)。
在任何情况下,它都试图 运行 stdout 行,就好像它们本身就是命令一样。我怎样才能通过 SSH 打印输出 运行?
我在我的问题中猜测这将在 Ubuntu 容器中工作,事实证明这是正确的。有趣的是,我仍然收到此命令的 "must be run from a terminal" 错误:
su -c whoami
但这里不是,终端在 SSH 无密码命令中明确分配给自己:
ssh -t localhost 'su -c whoami'
不幸的是,新的 OS 将我的 68M 图片增加到了 430M,呃!因此,我应该很高兴收到使它在 Alpine 上运行的新答案。