正确的方法

我有一个脚本,它使用 sudo 通过 SSH 在远程服务器上运行另一个脚本。但是,当我输入密码时,它会出现在终端上。(否则就没问题了)

ssh user@server "sudo script"

这样做的正确方法是什么,以便我可以在 SSH 上键入 sudo 的密码,而不会在键入时出现密码?

238467 次浏览

目标机器上的配置中的 NOPASS是解决方案。请继续读取 http://maestric.com/doc/unix/ubuntu_sudo_without_password

另一种方法是使用 -t开关到 ssh:

ssh -t user@server "sudo script"

man ssh:

 -t      Force pseudo-tty allocation.  This can be used to execute arbi-
trary screen-based programs on a remote machine, which can be
very useful, e.g., when implementing menu services.  Multiple -t
options force tty allocation, even if ssh has no local tty.

最好的方法是 ssh -t user@server "sudo <scriptname>",例如 ssh -t user@server "sudo reboot"。 它将首先提示输入用户密码,然后输入 root 用户密码(因为我们使用 root 权限运行脚本或命令)。

我希望这能帮你消除疑虑。

假设您不需要密码提示 :

ssh $HOST 'echo $PASSWORD | sudo -S $COMMMAND'

例子

ssh me@localhost 'echo secret | sudo -S echo hi' # outputs 'hi'

我可以用下面的命令完全自动化它:

echo pass | ssh -tt user@server "sudo script"

优点:

  • 没有密码提示
  • 不会在远程机器 bash 历史记录中显示密码

关于安全性: 正如 科特所说,运行此命令将在本地 bash 历史记录中显示您的密码,最好将密码保存在另一个文件中,或者将 all 命令保存在。并执行它。注意: 该文件需要有正确的权限,以便只有允许的用户可以访问它。

Sudo over SSH 传递密码,不需要 tty:

通过告诉 sudo 不需要交互式密码,只需从 stdin 获取密码,就可以使用 sudo over ssh,而不必强制 ssh 使用伪 tty (不需要使用 ssh“-t”开关)。您可以通过在 sudo 上使用“-S”开关来实现这一点。这使得 sudo 在 stdin 上侦听密码,并在看到换行符时停止侦听。

示例1-简单远程命令

在这个例子中,我们发送一个简单的 whoami命令:

$ ssh user@server cat \| sudo --prompt="" -S -- whoami << EOF
> <remote_sudo_password>
root

我们告诉 sudo 不要发出提示,并从 stdin 获取它的输入。这使得 sudo 密码传递完全静默,因此您得到的唯一响应是来自 whoami的输出。

这种技术的好处是允许您通过 sudo over ssh 运行程序,而这些程序本身需要 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

输出显示了 sudo 正在使用 <remote_sudo_password>行,然后远程执行的 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.因此,强烈建议在实际使用中,要么完全通过脚本来完成,如上面的 veraccrypt 示例,要么在命令行上将密码放入文件并通过 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

如果要将整个内容放在一个脚本中,那么将密码放在一个单独的文件中是不必要的,因为脚本的内容不会最终出现在您的历史记录中。但是,如果您希望允许不应该看到密码的用户执行脚本,那么它仍然可能是有用的。

echo $VAR_REMOTEROOTPASS | ssh -tt -i $PATH_TO_KEY/id_mykey $VAR_REMOTEUSER@$varRemoteHost
echo \"$varCommand\" | sudo bash

确认@ofirule 的答案非常有效。 我甚至尝试使用 sshpass和它工作。这是如何使用它与 sshpass:

echo $pass | sshpass -p $pass ssh -tt cloud_user@$ip "sudo su -"

您将发现自己直接位于根 shell 中