我已经配置sudo
为在没有密码的情况下运行,但是当我尝试运行时ssh 'sudo Foo'
,仍然收到错误消息sudo: sorry, you must have a tty to run sudo
。
为什么会发生这种情况,我该如何解决?
我已经配置sudo
为在没有密码的情况下运行,但是当我尝试运行时ssh 'sudo Foo'
,仍然收到错误消息sudo: sorry, you must have a tty to run sudo
。
为什么会发生这种情况,我该如何解决?
Answers:
那可能是因为您的/etc/sudoers
文件(或其包含的任何文件)具有:
Defaults requiretty
...这sudo
需要TTY。已知Red Hat系统(RHEL,Fedora ...)在默认sudoers
文件中需要TTY 。这并没有提供真正的安全优势,可以安全删除。
红帽已确认该问题,它将在以后的版本中删除。
如果不能更改服务器的配置,则可以使用-t
或-tt
选项ssh
在远程端生成伪终端,以解决该错误配置的变通方法,但是请注意,它具有许多方面效果。
-tt
用于交互使用。它将本地终端置于raw
模式,以便您与远程终端进行交互。这意味着,如果ssh
I / O不是从终端到终端,则会有副作用。例如,所有的输入将被回送,特殊终端字符(^?
,^C
,^U
)将导致特殊的处理; 在输出时,LF
s将转换为CRLF
s ...(有关更多详细信息,请参见“ 为什么要更改此二进制文件?”的此答案。
为了最大程度地减少影响,可以按以下方式调用它:
ssh -tt host 'stty raw -echo; sudo ...' < <(cat)
在< <(cat)
将避免在本地终端的(如果有的话)的设定raw
模式。而且我们正在使用stty raw -echo
将远程终端的线路规则设置为直通(有效地使其行为类似于将使用的管道代替不带的伪终端-tt
,尽管仅在运行该命令后才适用),因此您需要以延迟发送某些东西作为输入,直到发生这种情况为止)。
请注意,由于远程命令的输出将到达终端,因此自打开以来,这仍将影响其缓冲(对于许多应用程序将基于行)和带宽效率TCP_NODELAY
。另外-tt
,ssh
将IPQoS设置lowdelay
为throughput
。您可以使用以下两种方法来解决:
ssh -o IPQoS=throughput -tt host 'stty raw -echo; sudo cmd | cat' < <(cat)
另外,请注意,这意味着远程命令无法在其stdin上检测到文件结尾,并且远程命令的stdout和stderr合并为单个流。
因此,毕竟不是很好的解决方法。
如果你一个有一个的方式来产卵远程主机上的伪终端(像expect
,zsh
,socat
,perl
的IO::Pty
...),那么这将是更好地使用它来创建伪终端连接sudo
(但不适用于I / O),并且ssh
不带-t
。
例如,使用expect
:
ssh host 'expect -c "spawn -noecho sh -c {
exec sudo cmd >&4 2>&5 <&6 4>&- 5>&- 6<&-}
exit [lindex [wait] 3]" 4>&1 5>&2 6<&0'
或与script
(此处假设从实现util-linux
):
ssh host 'SHELL=/bin/sh script -qec "
sudo cmd <&3 >&4 2>&5 3<&- 4>&- 5>&-
" /dev/null 3<&0 4>&1 5>&2'
(假设(对于这两者而言)远程用户的登录Shell类似于Bourne)。
默认情况下,SUDO配置为要求TTY。也就是说,SUDO有望从登录外壳运行。您可以通过将-t
开关添加到SSH调用中来满足此要求:
ssh -t someserver sudo somecommand
-t
伪tty 的力量分配。
如果要全局执行此操作,请修改/etc/sudoers
以指定!requiretty
。可以按每个用户,每个组或所有级别进行。
使用该-t
标志来ssh
强制tty分配。
$ ssh luci tty
not a tty
$ ssh luci -t tty
/dev/ttys003
$
-t
在Pseudo-terminal will not be allocated because stdin is not a terminal.
我使用Docker和Centos 7遇到了这个问题。我最终做了以下工作:
yum install -y sudo
sed -i -e 's/Defaults requiretty.*/ #Defaults requiretty/g' /etc/sudoers
我在https://hub.docker.com/r/liubin/fluentd-agent/~/dockerfile中发现了此黑客
requiretty
默认sudoer中只有sudo的redhat发行版。这将是固定在新版本