Sudo over SSH 传递密码,不需要 tty:
您可以在 ssh 上使用 sudo,而无需强制 ssh 具有伪 tty(不使用 ssh“-t”开关),方法是告诉 sudo 不需要交互式密码并从标准输入中获取密码。您可以使用 sudo 上的“-S”开关来执行此操作。这使得 sudo 在标准输入上侦听密码,并在看到换行时停止侦听。
示例 1 - 简单的远程命令
在这个例子中,我们发送一个简单的whoami 命令:
$ ssh user@server cat \| sudo --prompt="" -S -- whoami << EOF
> <remote_sudo_password>
root
我们告诉 sudo 不要发出提示,并从标准输入中获取输入。这使得 sudo 密码完全静默传递,因此您得到的唯一响应是来自 whoami 的输出。
这种技术的好处是允许您通过 sudo 通过 ssh 运行程序,这些程序本身需要标准输入。这是因为 sudo 在 stdin 的第一行使用密码,然后让它运行的任何程序继续获取 stdin。
示例 2 - 需要自己的标准输入的远程命令
在以下示例中,远程命令“cat”是通过 sudo 执行的,我们通过标准输入提供了一些额外的行供远程 cat 显示。
$ ssh user@server cat \| sudo --prompt="" -S -- "cat" << EOF
> <remote_sudo_password>
> Extra line1
> Extra line2
> EOF
Extra line1
Extra line2
输出表明 <remote_sudo_password> 行正在被 sudo 使用,并且远程执行的 cat 正在显示额外的行。
如果您想使用 ssh 在不使用命令行的情况下将密码传递给特权命令,这将是有益的一个示例。比如说,如果你想通过 ssh 挂载一个远程加密容器。
示例 3 - 安装远程 VeraCrypt 容器
在这个示例脚本中,我们通过 sudo 远程挂载 VeraCrypt 容器,没有任何额外的提示文本:
#!/bin/sh
ssh user@server cat \| sudo --prompt="" -S -- "veracrypt --non-interactive --stdin --keyfiles=/path/to/test.key /path/to/test.img /mnt/mountpoint" << EOF
SudoPassword
VeraCryptContainerPassword
EOF
需要注意的是,在上述所有命令行示例(除脚本之外的所有内容)中,命令行上的<< EOF 构造将导致键入的所有内容(包括密码)记录在本地 机器的 .bash_history。因此,强烈建议您在实际使用时完全通过脚本来完成,如上面的 veracrypt 示例,或者,如果在命令行上,则将密码放入文件并通过 ssh 重定向该文件。
示例 1a - 没有本地命令行密码的示例 1
第一个例子因此变成:
$ cat text_file_with_sudo_password | ssh user@server cat \| sudo --prompt="" -S -- whoami
root
示例 2a - 没有本地命令行密码的示例 2
第二个例子会变成:
$ cat text_file_with_sudo_password - << EOF | ssh va1der.net cat \| sudo --prompt="" -S -- cat
> Extra line1
> Extra line2
> EOF
Extra line1
Extra line2
如果您将整个内容放在脚本中,则无需将密码放在单独的文件中,因为脚本的内容不会最终出现在您的历史记录中。不过,如果您想允许不应该看到密码的用户执行脚本,它仍然很有用。