如何在Alpine Linux中修复"Pseudo-terminal will not be allocated because stdin is not a terminal"?



我正在编写一个运行各种外壳命令的PHP程序。有时,它需要调用su,并且通过设计,我希望这提示提高特权密码。在PHP中使用passthru()为此工作正常。

我选择仅为程序编写功能测试,因为它取决于sshsu和其他Shell命令。因此,我想在phpunit内部运行真实的东西,以查看它是否正如我期望的。

由于这需要SSH服务器和用户帐户配置,因此我设置了在Docker中运行的测试。这种方法看起来很好 - 图像构建,运行时,它调用phpunit,然后退出。我希望有一种方法可以通过Docker返回结果,例如TravisCI。

我选择了Alpine Linux作为我的基本Docker图像,但是我在终端分配方面遇到了问题。我最初以为phpunit正在进入障碍(请参阅此问题的原始版本(,但现在我将其范围缩小到SSH,要么由PHP运行,甚至仅在控制台上。

这很好:

su -c whoami

但是,这不是:

ssh localhost -t 'su -c whoami'

我得到:

su:必须适合正常工作
连接到Local主机关闭。

请注意,ssh是通过无密码访问Localhost(用于测试目的(设置的,因此我期望输入的唯一密码是su ONE。

ssh的手册建议-f有助于要求密码的位置(Switch"请求SSH请在命令执行之前转到后台"(,所以我尝试了以下操作:

ssh localhost -t -f 'su -c whoami'

我得到:

伪末端不会分配,因为stdin不是终端。
4275760BDE94:〜$ su:必须适当工作

啊,另一个错误!好的,所以我尝试了这些想法,尤其是迫使终端:

ssh localhost -tt -f 'su -c whoami'

Double-T仍然向SUID发出投诉,但仍然不起作用。

但是,如果我在我的Ubuntu Dev机器上这样做(也配置了PPK访问自我(,则可以正常工作:

$ ssh localhost -t 'su -c whoami'
Password: 
root
Connection to localhost closed.

使它看起来像Alpine或Busybox的Openssh有错。我该如何进一步研究?

一种解决方案只是将另一个基本发行版交换,ubuntu肯定会正常工作,但这会大大膨胀我的Docker图像尺寸(目前总共有6800万(。因此,如果可以的话,我想和Alpine坚持一会儿。

不太可能成为Docker

我确实想知道docker是否可能阻止终端被创建或附加,但很快就打折了,因为我可以使用docker exec -it container_name sh获得交互式外壳。此外,我可以在Docker Shell内的两个单独命令中进行ssh,然后在两个单独的命令中进行su

bash无济于事

我注意到bash在高山中可用,但这也没有帮助,这让我感到惊讶:

/ $ 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.

尝试外壳插值

我发现这几乎有效:

/ $ ssh -t localhost "$( su -c whoami )"
sh: Password:: not found
sh: root: not found
Connection to localhost closed.

这使用标准高山sh壳,并使用上述链接上的"$()"构造,并且我不完全理解。它输出Password:,这是su中的提示,然后等待密码。输入密码后,运行whoami,该密码打印root

所以看起来它正在运行命令,但是我不确定它是否立即运行whoami,然后将其传递给ssh(不是我想要的(,或者是否正在将远程壳接收到Localhost,然后进行操作它(这是我打算的(。

无论如何,它正在尝试 run stdout行,就好像它们本身是命令一样。我该如何仅通过SSH打印输出?

我猜想这将在Ubuntu容器中起作用,事实证明这是正确的。有趣的是,我仍然会在此命令中获得"必须从终端运行"错误:

su -c whoami

但不是在这里,在ssh无密码命令中明确分配终端的self:

ssh -t localhost 'su -c whoami'

不幸的是,新操作系统将我的68m图像撞到了430m,urgh!因此,我应该非常乐意收到可以在高山上使用的新答案。

相关内容

最新更新