243

我需要创建一个脚本来自动向 OpenSSHssh客户端输入密码。

假设我需要myname@somehost使用密码SSH 进入a1234b

我已经试过了...

#~/bin/myssh.sh
ssh myname@somehost
a1234b

...但这不起作用。

我怎样才能将此功能放入脚本中?

4

23 回答 23

325

首先你需要安装sshpass

  • Ubuntu/Debian:apt-get install sshpass
  • Fedora/CentOS:yum install sshpass
  • 拱:pacman -S sshpass

例子:

sshpass -p "YOUR_PASSWORD" ssh -o StrictHostKeyChecking=no YOUR_USERNAME@SOME_SITE.COM

自定义端口示例:

sshpass -p "YOUR_PASSWORD" ssh -o StrictHostKeyChecking=no YOUR_USERNAME@SOME_SITE.COM:2400

笔记:

  • sshpass-f也可以在传递标志 时从文件中读取密码。
    • 如果执行命令,使用-f可防止密码可见。ps
    • 存储密码的文件应具有安全权限。
于 2013-05-24T12:21:23.553 回答
145

在寻找这个问题的答案几个月后,我终于找到了一个更好的解决方案:编写一个简单的脚本。

#!/usr/bin/expect

set timeout 20

set cmd [lrange $argv 1 end]
set password [lindex $argv 0]

eval spawn $cmd
expect "password:"
send "$password\r";
interact

把它放到/usr/bin/exp,所以你可以使用:

  • exp <password> ssh <anything>
  • exp <password> scp <anysrc> <anydst>

完毕!

于 2015-02-03T06:59:49.997 回答
83

使用公钥认证:https ://help.ubuntu.com/community/SSH/OpenSSH/Keys

在源主机中只运行一次:

ssh-keygen -t rsa # ENTER to every field
ssh-copy-id myname@somehost

就是这样,之后你就可以在没有密码的情况下进行 ssh 了。

于 2012-08-30T17:51:10.590 回答
31

您可以使用期望脚本。我已经很久没有写过一篇了,但它应该如下所示。您将需要使用#!/usr/bin/expect

#!/usr/bin/expect -f
spawn ssh HOSTNAME
expect "login:" 
send "username\r"
expect "Password:"
send "password\r"
interact
于 2012-08-30T17:53:31.990 回答
25

变体 I

sshpass -p PASSWORD ssh USER@SERVER

变体 II

#!/usr/bin/expect -f
spawn ssh USERNAME@SERVER "touch /home/user/ssh_example"
expect "assword:"
send "PASSWORD\r"
interact
于 2015-01-17T00:10:59.930 回答
17

sshpass + autossh

已经提到的一个很好的好处sshpass是您可以将它与 一起使用autossh,从而消除更多的交互效率低下。

sshpass -p mypassword autossh -M0 -t myusername@myserver.mydomain.com

如果您的 wifi 因关闭笔记本电脑而中断,这将允许自动重新连接。

于 2018-01-16T21:47:33.340 回答
15

sshpass具有更好的安全性

我在寻找一种通过 ssh 进入陷入困境的服务器的方法时偶然发现了这个线程——处理 SSH 连接尝试花了一分钟多的时间,并且在我输入密码之前就超时了。在这种情况下,我希望能够在提示可用时立即提供我的密码。

(如果不是很清楚:如果服务器处于这种状态,那么设置公钥登录为时已晚。)

sshpass救援。但是,有比sshpass -p.

我的实现直接跳到交互式密码提示(不会浪费时间查看是否可以进行公钥交换),并且永远不会将密码显示为纯文本。

#!/bin/sh
# preempt-ssh.sh
# usage: same arguments that you'd pass to ssh normally
echo "You're going to run (with our additions) ssh $@"

# Read password interactively and save it to the environment
read -s -p "Password to use: " SSHPASS 
export SSHPASS

# have sshpass load the password from the environment, and skip public key auth
# all other args come directly from the input
sshpass -e ssh -o PreferredAuthentications=keyboard-interactive -o PubkeyAuthentication=no "$@"

# clear the exported variable containing the password
unset SSHPASS
于 2017-11-20T17:07:16.143 回答
9

我认为我没有看到任何人建议这样做,而 OP 只是说“脚本”所以......

我需要解决同样的问题,而我最熟悉的语言是 Python。

我使用了 paramiko 库。此外,我还需要使用sudo. 事实证明 sudo 可以通过“-S”标志通过标准输入接受其密码!见下文:

import paramiko

ssh_client = paramiko.SSHClient()

# To avoid an "unknown hosts" error. Solve this differently if you must...
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

# This mechanism uses a private key.
pkey = paramiko.RSAKey.from_private_key_file(PKEY_PATH)

# This mechanism uses a password.
# Get it from cli args or a file or hard code it, whatever works best for you
password = "password"

ssh_client.connect(hostname="my.host.name.com",
                       username="username",
                       # Uncomment one of the following...
                       # password=password
                       # pkey=pkey
                       )

# do something restricted
# If you don't need escalated permissions, omit everything before "mkdir"
command = "echo {} | sudo -S mkdir /var/log/test_dir 2>/dev/null".format(password)

# In order to inspect the exit code
# you need go under paramiko's hood a bit
# rather than just using "ssh_client.exec_command()"
chan = ssh_client.get_transport().open_session()
chan.exec_command(command)

exit_status = chan.recv_exit_status()

if exit_status != 0:
    stderr = chan.recv_stderr(5000)

# Note that sudo's "-S" flag will send the password prompt to stderr
# so you will see that string here too, as well as the actual error.
# It was because of this behavior that we needed access to the exit code
# to assert success.

    logger.error("Uh oh")
    logger.error(stderr)
else:
    logger.info("Successful!")

希望这可以帮助某人。我的用例是一次在大约 300 台服务器上创建目录、发送和解压缩文件以及启动程序。因此,自动化至关重要。我试过了sshpassexpect然后想出了这个。

于 2018-12-04T17:04:47.873 回答
8
# create a file that echo's out your password .. you may need to get crazy with escape chars or for extra credit put ASCII in your password...
echo "echo YerPasswordhere" > /tmp/1
chmod 777 /tmp/1

# sets some vars for ssh to play nice with something to do with GUI but here we are using it to pass creds.
export SSH_ASKPASS="/tmp/1"
export DISPLAY=YOURDOINGITWRONG
setsid ssh root@owned.com -p 22

参考:https ://www.linkedin.com/pulse/youre-doing-wrong-ssh-plain-text-credentials-robert-mccurdy?trk=mp-reader-card

于 2016-08-03T13:57:17.403 回答
8

这是我登录服务器的方式:

ssp <server_ip>
  • alias ssp='/home/myuser/Documents/ssh_script.sh'
  • cat /home/myuser/Documents/ssh_script.sh

ssp

#!/bin/bash

sshpass -p mypassword ssh root@$1

因此:

ssp server_ip
于 2019-05-28T12:48:16.437 回答
3

我正在使用以下解决方案,但为此您必须安装sshpass如果尚未安装,请使用sudo apt install sshpass

现在你可以这样做了,

sshpass -p *YourPassword* shh root@IP

您也可以创建一个 bash 别名,这样您就不必一次又一次地运行整个命令。请按照以下步骤操作

cd ~

sudo nano .bash_profile

在文件末尾添加以下代码

mymachine() { sshpass -p *YourPassword* shh root@IP }

source .bash_profile

现在只需mymachine从终端运行命令,您将在没有密码提示的情况下进入您的机器。

笔记:

  1. mymachine可以是您选择的任何命令。
  2. 如果在此任务中安全性对您而言并不重要,并且您只想自动化工作,则可以使用此方法。
于 2020-09-29T19:03:11.840 回答
3

这基本上是 abbotto's answer 的扩展,有一些额外的步骤(针对初学者)可以让你从你的 linux 主机启动你的服务器,非常容易:

  1. 编写一个简单的 bash 脚本,例如:
#!/bin/bash

sshpass -p "YOUR_PASSWORD" ssh -o StrictHostKeyChecking=no YOUR_USERNAME@SOME_SITE.COM
  1. 保存文件,例如“startMyServer”,然后通过在终端中运行来使文件可执行:
sudo chmod +x startMyServer
  1. 将文件移动到“PATH”变量中的文件夹(在终端中运行“echo $PATH”以查看这些文件夹)。因此,例如将其移动到“/usr/bin/”。

瞧,现在您可以通过在终端中输入“startMyServer”来进入您的服务器。

PS (1) 这不是很安全,请查看 ssh 密钥以获得更好的安全性。

PS (2) SMshrimant 的答案非常相似,对某些人来说可能更优雅。但我个人更喜欢使用 bash 脚本。

于 2020-10-21T12:58:43.127 回答
3

如果您在 Windows 系统上执行此操作,则可以使用 Plink(PuTTY 的一部分)。

plink your_username@yourhost -pw your_password
于 2019-08-13T14:26:03.157 回答
1

我得到这个工作如下

.ssh/config 被修改以消除是/否提示 - 我在防火墙后面,所以我不担心被欺骗的 ssh 密钥

host *
     StrictHostKeyChecking no

为期望创建一个响应文件,即 answer.expect

set timeout 20
set node [lindex $argv 0]
spawn ssh root@node service hadoop-hdfs-datanode restart

expect  "*?assword {
      send "password\r"   <- your password here.

interact

创建您的 bash 脚本并在文件中调用 expect

#!/bin/bash
i=1
while [$i -lt 129]    # a few nodes here

  expect answer.expect hadoopslave$i

  i=[$i + 1]
  sleep 5

done

使用新配置刷新 128 个 hadoop 数据节点 - 假设您为 hadoop/conf 文件使用 NFS 挂载

希望这对某人有所帮助-我是 Windows numpy,这花了我大约 5 个小时才弄清楚!

于 2014-03-27T02:57:24.813 回答
1

我设法让它与它一起工作:

SSH_ASKPASS="echo \"my-pass-here\""
ssh -tt remotehost -l myusername
于 2019-04-16T17:23:59.480 回答
1

我有一个更好的解决方案,包括使用您的帐户登录,而不是更改为 root 用户。这是一个 bash 脚本

http://felipeferreira.net/index.php/2011/09/ssh-automatic-login/

于 2016-05-24T13:25:38.493 回答
1

@abbotto 的答案对我不起作用,不得不做一些不同的事情:

  1. yum install sshpass 改为 -rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/sshpass-1.05-1.el6.x86_64.rpm
  2. 使用 sshpass 的命令更改为 - sshpass -p "pass" ssh user@mysite -p 2122
于 2016-11-15T14:40:38.170 回答
0

这有效:

#!/usr/bin/expect -f
spawn ssh USERNAME@SERVER "touch /home/user/ssh_example"
expect "assword:"
send "PASSWORD\r"
interact

但是!如果您遇到如下错误,只需使用 expect 开始您的脚本,而不是 bash,如下所示:expect myssh.sh 而不是bash myssh.sh

/bin/myssh.sh: 2: spawn: not found /bin/myssh.sh: 3: expect: not found /bin/myssh.sh: 4: send: not found /bin/myssh.sh: 5: expect: not found /bin/myssh.sh: 6: send: not found
于 2022-02-14T10:09:41.283 回答
0

在下面的示例中,我将编写我使用的解决方案:

场景:我想使用 sh 脚本从服务器复制文件:

#!/usr/bin/expect
$PASSWORD=password
my_script=$(expect -c "spawn scp userName@server-name:path/file.txt /home/Amine/Bureau/trash/test/
expect \"password:\"
send \"$PASSWORD\r\"
expect \"#\"
send \"exit \r\"
")

echo "$my_script"
于 2019-10-03T13:03:44.510 回答
-2

在脚本中使用此脚本 tossh,第一个参数是主机名,第二个参数是密码。

#!/usr/bin/expect
set pass [lindex $argv 1]
set host [lindex $argv 0]
spawn ssh -t root@$host echo Hello
expect "*assword: " 
send "$pass\n";
interact"
于 2019-02-18T10:19:29.050 回答
-3

要通过 shell 脚本连接远程机器,请使用以下命令:

sshpass -p PASSWORD ssh -o StrictHostKeyChecking=no USERNAME@IPADDRESS

其中IPADDRESS,USERNAMEPASSWORD是需要在脚本中提供的输入值,或者如果我们想在运行时提供,请使用“读取”命令。

于 2017-08-07T15:46:24.923 回答
-3

这在大多数情况下应该会有所帮助(您需要先安装 sshpass!):

#!/usr/bin/bash
read -p 'Enter Your Username: ' UserName;
read -p 'Enter Your Password: ' Password;
read -p 'Enter Your Domain Name: ' Domain;

sshpass -p "$Password" ssh -o StrictHostKeyChecking=no $UserName@$Domain
于 2021-01-09T15:55:33.713 回答
-16

在 linux/ubuntu 中

ssh username@server_ip_address -p port_number

按回车,然后输入您的服务器密码

如果您不是 root 用户,请在命令开头添加sudo

于 2019-09-30T10:33:13.170 回答