Bash:检查是否可以使用 sshpass 在远程主机上执行 sudo;密码有多“暴露”?

Bash:检查是否可以使用 sshpass 在远程主机上执行 sudo;密码有多“暴露”?

我正在使用下面的 bash 脚本来测试sudo远程主机上是否可用。

我从用户输入中获取密码。我理解(在一定程度上)在脚本中使用密码会涉及安全性权衡,所以我对此的某个方面有疑问。

请参阅下面的脚本,该脚本使用sshpass并测试用户是否能够sudo --stdin --validate成功运行。

为了尽量避免泄露密码(据我所知?),我选择使用sshpasswith-e而不是-p,但只是想知道第二部分---该echo \"${SSHPASS}\" | sudo --stdin --validate行。

运行此脚本并在远程主机上查看后history,我无法在用户帐户或 root 帐户的命令行上看到“回显”的密码。

所以我的问题是:在远程端进行这样的回显是否会在任何地方暴露密码(如果是,在哪里?),或者下面这种方法是否“相当安全”?

两端的用户环境都是Ubuntu 18或者20。

#!/bin/bash

# obtain username and host from user input
read -p "Enter username@host: " remote

# obtain password from user input
read -r -s -p "Enter password: " SSHPASS

# set password as environment variable for `sshpass` below, it requires this for `-e`
export SSHPASS

echo
echo -n "Testing if can sudo on ${remote}... "

if result=$( sshpass -e ssh -o PasswordAuthentication=yes "${remote}" "echo \"${SSHPASS}\" | sudo --stdin --validate" 2>&1 ); then
    echo "YES!"
else
    echo "FAILED"
    echo "${result}"
fi

unset SSHPASS

答案1

虽然看起来不像,但密码实际上已经暴露在本地和远程服务器上。

两种情况下的原因是它是进程的命令行的一部分,sshpass或者更隐含的bash -c,如下所述。

当您通过 运行命令时ssh <host> <command>命令部分通过 传递给登录 shell -c。这意味着任何能够列出进程的用户都可以看到bash -c "echo "<password>" | sudo --stdin --validate"

如果您想测试一下,while ! ps aux | grep '[s]udo'; do :; done只需像远程系统中的任何其他用户一样简单操作即可。请注意,这是一个主动等待循环,会导致 CPU 使用率激增。

为了解决这个问题,您应该回显密码并将其传送到您的 SSH,而不是远程回显:echo "${SSHPASS}" | sshpass -e ssh -o PasswordAuthentication=yes "${remote}" "sudo --stdin --validate" 2>&1

答案2

使用 GPG 加密和 PIPE 直接限制暴露,而不是将其输出到纯文本文件/字符串:

gpg -d -q .sshpasswd.gpg | sshpass -P 通过 ssh -i ~/.ssh/key.pem -ttR xxx.xxx.xxx.xxx

-P 传递

选项搜索例如“密码......”或“密码短语”提示来填写。

答案3

尝试在本地运行 sshpass(用于远程 sudo),但失败了

1. 测试

没有 ssh 的 sudo //ok

$ SSHPASS=your_passwd sshpass -e sudo id
uid=0(root) gid=0(root) groups=0(root)

sudo 和 ssh //失败

SSHPASS=your_passwd sshpass -v -e  ssh localhost -t 'sudo id' 
[sudo] password for xxx:

2. 原因

$ ssh root@localhost  >/dev/null
root@localhost's password:

$ sudo id >/dev/null
[sudo] password for xxx:
$ ssh -t localhost sudo id 
[sudo] password for xxx:

$ ssh -t localhost sudo id >/dev/null
//nothing

'sshpass' 无法通过 ssh + sudo 工作的原因是:正常sudossh发送提示符到 tty,但ssh+sudo 发送提示符到 stdout,但 sshpass 在 tty 等待提示符。


我猜测拓扑结构如下:

[local pty]  <---> ssh <--(stdio)--> [remote pty] <---> sudo


解决方法

所以sudo --stdin是简单的方法://在本地回显以确保安全

echo your_pass | ssh localhost 'sudo --stdin id'

或 //在远程运行 sshpass

$ ssh localhost 'SSHPASS=your_pass sshpass -e sudo id'


我记得bash只记录交互模式下执行的命令历史记录,
而以空格开头的cmd也不会记录:(ls 1记录)vs ls 2(不记录)

相关内容