通过 SSH 使用 Sudo 传递密码,不需要 tty:
您可以在 ssh 上使用 sudo,而无需强制 ssh 具有伪终端(无需使用 ssh \'-t\' 开关),方法是告诉 sudo 不需要交互式密码,只需从 stdin 获取密码即可。您可以使用 sudo 上的 \'-S\' 开关来执行此操作。这会使 sudo 在 stdin 上监听密码,并在看到换行符时停止监听。
示例 1 - 简单的远程命令
在此示例中,我们发送一个简单的 whoami
命令:
$ ssh user@server cat \| sudo --prompt="" -S -- whoami << EOF
> <remote_sudo_password>
> EOF
root
我们告诉 sudo 不要发出提示,而是从 stdin 获取输入。这使得 sudo 密码传递完全无声,因此您得到的唯一响应是来自 whoami
.
此技术的优点是允许您通过 ssh 使用 sudo 运行需要 stdin 输入的程序。这是因为 sudo 会在第一行 stdin 上消耗密码,然后让它运行的任何程序继续获取 stdin。
示例 2 - 需要自己的 stdin 的远程命令
在下面的例子中,远程命令 'cat' 通过 sudo 执行,并且我们通过 stdin 提供一些额外的行以供远程 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
如果您将整个密码放入脚本中,则无需将密码放在单独的文件中,因为脚本的内容不会出现在您的历史记录中。不过,如果您想允许不应看到密码的用户执行脚本,这仍然很有用。