通过 ssh 执行 sudo 的正确方法是什么?

问题描述 投票:0回答:8

我有一个脚本,它使用

sudo
通过 SSH 在远程服务器上运行另一个脚本。但是,当我输入密码时,它会显示在终端上。 (否则效果很好)

ssh user@server "sudo script"

执行此操作的正确方法是什么,以便我可以通过 SSH 输入

sudo
的密码,而不会在输入时出现密码?

ssh sudo
8个回答
307
投票

另一种方法是使用

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

47
投票

我能够使用以下命令完全自动化它:

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

优点:

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

关于安全性:正如Kurt所说,运行此命令将在本地bash历史记录中显示您的密码,最好将密码保存在不同的文件中或将所有命令保存在.sh文件中并执行它。注意:该文件需要具有正确的权限,以便只有允许的用户才能访问它。


13
投票

通过 SSH 进行 Sudo 传递密码,无需 tty:

您可以在 ssh 上使用 sudo,而无需强制 ssh 拥有伪 tty(不使用 ssh“-t”开关),方法是告诉 sudo 不需要交互式密码,而只需从 stdin 获取密码。您可以通过使用 sudo 上的“-S”开关来执行此操作。这使得 sudo 监听 stdin 上的密码,并在看到换行符时停止监听。

示例 1 - 简单的远程命令

在此示例中,我们发送一个简单的

whoami
命令:

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

我们告诉 sudo 不要发出提示,并从标准输入获取输入。这使得 sudo 密码传递完全无声,因此您得到的唯一响应是

whoami
的输出。

此技术的优点是允许您通过 sudo 通过 ssh 运行程序,而这些程序本身需要 stdin 输入。这是因为 sudo 在 stdin 的第一行上消耗密码,然后让它运行的任何程序继续获取 stdin。

示例 2 - 需要自己的标准输入的远程命令

在下面的示例中,远程命令“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
构造将导致输入的所有内容(包括密码)记录在 local 机器的 .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

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


7
投票

假设您不想要密码提示

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

示例

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

4
投票

最好的方法是

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

希望它能帮助您消除疑虑。


1
投票
目标机器上配置中的

NOPASS
就是解决方案。继续阅读 http://maestric.com/doc/unix/ubuntu_sudo_without_password


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

0
投票

确认@ofirule 的答案非常有效。 我什至尝试使用

sshpass
并且它有效。这是如何将其与 sshpass 一起使用:

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

你会发现自己直接进入了 root shell

© www.soinside.com 2019 - 2024. All rights reserved.