在 bash 脚本中为 ssh 命令提供密码,无需使用公钥和 Expect

Posted

技术标签:

【中文标题】在 bash 脚本中为 ssh 命令提供密码,无需使用公钥和 Expect【英文标题】:Provide password to ssh command inside bash script, Without the usage of public keys and Expect 【发布时间】:2013-05-31 23:40:38 【问题描述】:

我想在脚本中使用SSH,但该脚本不会在我的机器上执行。

在我的实现中有两个限制。

我不能在 shell 的标准之外工作,因此我不能使用expect,因为我不知道它是否可以在这台机器上使用。 我不能指望这台机器会有public keysSSH

有哪些可能的解决方案?

如何在不添加额外依赖项的情况下以自动化且安全的方式向 ssh 提供所请求的密码?

是否可以在脚本中提供密码?

提前谢谢大家:)

【问题讨论】:

perl 或 python 等其他语言可用吗? 通常是的,但在 python 中我知道这是可能的 :) 还是谢谢你 【参考方案1】:

安装 sshpass,然后启动命令:

sshpass -p "yourpassword" ssh -o StrictHostKeyChecking=no yourusername@hostname

【讨论】:

非常感谢,但我不能指望我将运行脚本的计算机安装了 sshpass,这就是我不能使用 expect 的原因。【参考方案2】:

出于安全原因,您必须避免在命令行上提供密码,否则任何运行 ps 命令的人都可以看到您的密码。最好像这样使用sshpass 实用程序:

#!/bin/bash

export SSHPASS="your-password"
sshpass -e ssh -oBatchMode=no sshUser@remoteHost

您可能对How to run the sftp command with a password from Bash script?

感兴趣

【讨论】:

非常感谢,但我不能指望我将运行脚本的计算机安装了 sshpass,这就是我不能使用 expect 的原因。 是的,它可能尚未安装,但您可以从提供的链接下载并自行编译。它不需要任何管理员权限。 我是否必须在每台要运行脚本的计算机上下载它?如果我可以在我的代码中实现它,没关系,但我只想创建一个独立的脚本它将能够在任何地方运行而无需权限,额外的包。这就是我想保持标准的原因。【参考方案3】:

首先:不要将秘密放在明文中 除非您知道为什么这样做是安全的(即您已经评估了可以造成的损害由知道秘密的攻击者)。

如果您可以在脚本中添加秘密,您可以使用它发送一个 ssh 密钥并在 ssh-agent shell 中执行:

#!/usr/bin/env ssh-agent /usr/bin/env bash
KEYFILE=`mktemp`
cat << EOF > $KEYFILE
-----BEGIN RSA PRIVATE KEY-----
[.......]
EOF
ssh-add $KEYFILE

# do your ssh things here...

# Remove the key file.
rm -f $KEYFILE

使用 ssh 密钥的一个好处是您可以轻松地使用forced commands 来限制密钥持有者可以在服务器上执行的操作。

更安全的方法是让脚本运行 ssh-keygen -f ~/.ssh/my-script-key 以创建专用于此目的的私钥,但您还需要一个例程来将公钥添加到服务器。

【讨论】:

我开始得出结论,为脚本的需要生成私钥,删除后将是唯一的解决方案。非常感谢 这是最接近我的问题的答案 :) 谢谢【参考方案4】:

AFAIK 除了使用键或期望您使用命令行版本ssh 之外,没有其他可能性。但是大多数编程语言都有库绑定,比如 C、python、php、...。你可以用这种语言编写程序。这样就可以自动传递密码。但是注意这当然是一个安全问题,因为密码将以纯文本形式存储在该程序中

【讨论】:

谢谢 :) 至少通过向我展示什么是可能的,你很有帮助。我考虑过用 python 开发,但是 python 中 ssh 命令的代码行数是 shell 版本的 100 倍ssh :) 问题只是,ssh 命令需要来自终端的密码。这就是为什么期望它模拟终端的原因。也许人们可以用一种简单的方式做同样的事情。我不知道怎么做。但是,您应该使用 google 找到 100 行;)【参考方案5】:

我完全同意所有说这几乎可以肯定是一个可怕的想法的人。极有可能让其他人攻击您的计算机。

在评估安全隐患后自行承担使用风险

回答

制作一个程序/path/to/saypass输出密码,如

#!/bin/sh
echo 'secret'

使其可执行

chmod +x /path/to/saypass

那么这是主要的命令:

SSH_ASKPASS="/path/to/saypass" DISPLAY=anything setsid ssh username@hostname [farcommand]

这个

设置两个环境变量SSH_ASKPASSDISPLAY 然后运行setsid 然后在没有控制终端的情况下运行ssh 连接到远端hostname ...在本地运行saypass获取密码 ...告诉远端服务器 ...并假设它是正确的 然后运行 ​​farcommand(如果给定)或交互式 shell。

我通常使用datehostname 测试可选的farcommand

这有很多地方出错。

说明

其中的诀窍是标准 Linux 命令行 ssh 有几个环境变量,您可以使用它们来选择一个程序,该程序将被执行以提供密码。

ssh(1) 手册页说:

SSH_ASKPASS 如果ssh 需要密码,如果它是从终端运行的,它将从当前终端读取密码。 如果ssh没有与之关联的终端,但设置了DISPLAYSSH_ASKPASS,它将执行SSH_ASKPASS指定的程序并打开X11窗口读取密码。

所以:您需要一个可以输出密码的程序(shell 脚本或任何其他类型)。那你需要说服ssh使用它:

SSH_ASKPASS 设置为/path/to/saypass DISPLAY 设置为一些愚蠢的东西 没有控制终端(这是setsid 所做的)

您将它们放在以下sh 命令中:

SSH_ASKPASS="/path/to/saypass" DISPLAY=anything setsid ssh username@hostname [command]

ssh 将执行

/path/to/saypass "username@hostname's password:"

指纹检查

如果需要指纹,您通常会在哪里看到消息

The authenticity of host '*hostname* (*ipaddress*)' can't be established.
ECDSA key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
Are you sure you want to continue connecting (yes/no)? 

然后ssh 会像这样运行你的命令:

/path/to/saypass "Please type 'yes' or 'no':"

一体化脚本

以下是用于在主脚本中创建、使用和删除saypass 的单个脚本。每个人都会告诉你不要将明文密码放在文件中,并且永远不要硬编码密码。他们告诉你这是有充分理由的:这会给你带来很多麻烦。使用风险自负。

#!/bin/sh

echo "#!/bin/sh\necho 'secret';rm -f /tmp/saypass.$$" > /tmp/saypass.$$
chmod 775 /tmp/saypass.$$
SSH_ASKPASS="/tmp/saypass.$$" DISPLAY=anything setsid ssh "$@"

SCP

这也适用于scpssh 之上的复制程序:

SSH_ASKPASS=/path/to/saypas DISPLAY=anything setsid scp username@hostname:/path/to/farfile .

警告

真的不要使用这个,除非在可怕、可怕的情况下,例如你有数百台计算机并且无法安装 ssh 密钥之类的东西,sshpass 甚至 expect

如果您确实使用它,请不要告诉任何人我告诉过您如何使用它。实在是太可怕了。

我不知道手册页中关于“打开 X11 窗口”的含义,在我的测试中没有发生这种情况。

经过测试

OpenSSH_6.6.1p1 Ubuntu-2ubuntu2,OpenSSL 1.0.1f 2014 年 1 月 6 日在 Ubuntu 14.04.1 LTS 上, OpenSSH_7.2p2 Ubuntu-4ubuntu2.1,OpenSSL 1.0.2g 2016 年 3 月 1 日在 Ubuntu 16.04.2 LTS 上 OpenSSH_7.6p1 Ubuntu-4ubuntu0.3,OpenSSL 1.0.2n 2017 年 12 月 7 日在 Ubuntu 18.04.5 LTS 上

【讨论】:

以上是关于在 bash 脚本中为 ssh 命令提供密码,无需使用公钥和 Expect的主要内容,如果未能解决你的问题,请参考以下文章

在 Bash 脚本中使用 Expect 为 SSH 命令提供密码

如何从 bash 脚本中 ssh?

在 Bash 脚本中为 Git 提供密码

expect实现自动scp和ssh登录后执行命令,并向bash提供返回值

expect实现自动scp和ssh登录后执行命令,并向bash提供返回值

ssh登录自动输入密码