如何让ssh从标准输入接收密码

38

如何让SSH读取标准输入中的密码,因为它默认情况下不会这样做?


相关:将密码传递给su/sudo/ssh - Piotr Dobrogost
8个回答

28

根据这个post,你可以做以下操作:

创建一个命令,使用SSH_ASKPASS打开SSH会话(在man ssh中查找SSH_ASKPASS)

$ cat > ssh_session <<EOF
export SSH_ASKPASS="/path/to/script_returning_pass"
setsid ssh "your_user"@"your_host"
EOF

注意: 为了避免ssh尝试在tty上询问,我们使用setsid

创建一个脚本,返回你的密码(注意echo "echo

$ echo "echo your_ssh_password" > /path/to/script_returning_pass

使它们可执行
$ chmod +x ssh_session
$ chmod +x /path/to/script_returning_pass

试一试

$ ./ssh_session

请记住,ssh代表安全外壳协议,如果您将用户、主机和密码存储在纯文本文件中,那么您会误导该工具并创建可能的安全漏洞。


2
另一个要求是必须设置DISPLAY。如果您正在运行X,您不会注意到。如果您没有运行X,您将会注意到。为了使上面的ssh_script更具可移植性,请添加以下内容:export DISPLAY; DISPLAY=dummy - Blaine
此外(如果您没有setsid命令),除了设置DISPLAY和SSH_ASKPASS之外,您还需要将STDIN从/dev/null重定向,以使ssh-add相信它不在终端上:ssh-add /path/to/key < /dev/null - mike
我使用了这个想法从pass获取口令,以一种通用的方式提供给ssh-add,根据需要生成askpass脚本。https://milosophical.me/blog/2018/ssh-pass.html - mike
有人可以更新解决方案,以考虑评论中的建议吗? - M. Barbieri
在MacOS Ventura上,您还可以将SSH_ASKPASS_REQUIRE设置为force,这样无论是否设置了DISPLAY,都会始终调用$SSH_ASKPASS - wto

17

您可以使用sshpass,例如在官方Debian存储库中。示例:

$ apt-get install sshpass
$ sshpass -p 'password' ssh username@server

遗憾的是,这是我使用的唯一解决方案,对于ssh跳板主机来说并不是很好。另一个选择是使用“expect”,但我猜想它会带来更多麻烦而不是帮助。 - Sridhar Sarnobat
3
Homebrew(macOS)已禁止安装sshpass:我们不会添加sshpass,因为它会让新手SSH用户太容易破坏SSH的安全性。 - mike
@mike 你难道不觉得Homebrew维护者通过拯救我们自己来增强全球安全感到高兴吗? - iconoclast
哈哈,是的!我最终写了自己的hack:https://milosophical.me/blog/2018/ssh-pass.html。你的情况可能会有所不同。 - mike

10

大多数SSH客户端无法做到这一点。您可以通过使用SSH API,例如Python的Paramiko来解决此问题。但请注意,不要重写所有安全策略。


有什么想法为什么它不起作用吗?直觉上应该可以。 - Sridhar Sarnobat
4
这不应该起作用,因为这会鼓励初级系统管理员编写脚本时把SSH密码与脚本逻辑混在一起。在网络和系统管理环境中,需要明确区分安全敏感信息和完成任务两方面。密码认证并不足够安全。由于ssh在sysadmin环境中被广泛使用,尝试让用户远离仅限于密码的安全性是一个好主意。 - pvoosten

6

这个答案的要点是一个简单通用的脚本:

#!/bin/bash
[[ $1 =~ password: ]] && cat || SSH_ASKPASS="$0" DISPLAY=nothing:0 exec setsid "$@"

将其保存为pass,执行chmod +x pass,然后按以下方式使用:

$ echo mypass | pass ssh user@host ...

如果它的第一个参数包含password:,则将其输入传递给其输出(cat),否则它会启动在设置自身为SSH_ASKPASS程序后呈现的任何内容。当ssh遇到设置了SSH_ASKPASSDISPLAY的情况时,它将启动SSH_ASKPASS引用的程序,并将提示user@host 's password:传递给它。

如果您之前没有通过SSH连接到此主机,则可能需要在ssh命令中添加-oStrictHostKeyChecking=no参数,否则它会提示用户是否信任未知的主机密钥。显然,只有在您确信信任未知的主机密钥时才这样做。 - villapx

5
一个老帖子被挖出来了...
我在寻找解决同样问题的方法时发现了这个,希望有一天它能对某人有用:
1. 安装ssh-askpass程序(apt-get、yum...)。 2. 设置SSH_ASKPASS变量(export SSH_ASKPASS=/usr/bin/ssh-askpass)。 3. 从终端打开一个没有未定义TERMINAL变量的新ssh连接(setsid ssh user@host)。
看起来很简单,但还没有检查过是否安全(只在本地安全环境中使用)。
就是这样。

4

FreeBSD邮件列表推荐使用expect库。

如果您需要程序化ssh登录,您真的应该使用公钥登录,然而——显然,这种方式比使用外部库通过stdin传递密码要安全得多,因为存在更少的安全漏洞。


3
一个更好的 sshpass 替代品是:https://github.com/clarkwang/passh
我使用 sshpass 时遇到问题,如果 ssh 服务器没有添加到我的 known_hosts 中,sshpass 将不会显示任何消息,而 passh 没有这个问题。

2
我不确定您需要这个功能的原因,但似乎您可以使用ssh-keygen来实现此行为。它允许您在计算机上拥有一个私钥和服务器上的公钥,从而无需使用密码即可登录服务器。http://www.linuxproblem.org/art_9.html

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接