使用脚本自动输入SSH密码

use*_*855 173 linux ssh shell openssh

我需要创建一个自动输入密码给OpenSSH ssh客户端的脚本.

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

我已经尝试过......

#~/bin/myssh.sh
ssh myname@somehost
a1234b
Run Code Online (Sandbox Code Playgroud)

......但这不起作用.

如何将此功能添加到脚本中?

abb*_*tto 252

首先,您需要安装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
Run Code Online (Sandbox Code Playgroud)

自定义端口示例:

sshpass -p "YOUR_PASSWORD" ssh -o StrictHostKeyChecking=no YOUR_USERNAME@SOME_SITE.COM:2400
Run Code Online (Sandbox Code Playgroud)

笔记:

  • sshpass也可以在-f传递标志时从文件中读取密码.
    • -f如果ps执行命令,则使用防止密码可见.
    • 存储密码的文件应具有安全权限.

  • 这比使用Expect要好得多. (11认同)
  • 请注意,虽然sshpass会阻止你的密码来自`ps -aux`这样的命令,你通常不应该输入密码来运行命令,因为同一台计算机上的其他用户可以通过运行`ps -aux`来查看密码. .如果可行,您还希望使用公钥身份验证,如其他答案中所述.这允许您将身份验证信息与脚本分开,以便您可以无忧无虑地与其他人共享脚本,然后决定在〜/ .ssh文件夹上启用加密,而无需加密脚本. (5认同)
  • 不幸的是,在带有自定义ssh端口的服务器上,这对我不起作用...为什么ssh只能给我们在命令行中插入密码的选项? (2认同)
  • @mauvm该链接目前正常运行. (2认同)
  • 要使自定义端口工作,请在命令末尾添加"-p port-number" (2认同)

dam*_*n_c 82

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

#!/usr/bin/expect

set timeout 20

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

eval spawn $cmd
expect "assword:"
send "$password\r";
interact
Run Code Online (Sandbox Code Playgroud)

把它/usr/bin/exp,然后你可以使用:

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

完成!

  • "assword"很棒:-) (13认同)
  • 也许它没有得到更多的支持是因为人们没有预料到它? (11认同)
  • 任何在机器上运行ps的人都可以看到密码. (8认同)
  • 这是IMO不是一个很好的答案的原因是因为密码写在脚本中,这是迄今为止最不安全的方法...... (5认同)
  • 这个答案应该得到更多的选票,这是一个伟大的包装.刚试了几个常见的操作,比如使用各种标志和远程命令执行进行rsyncing,每次都有效.添加到我的工具箱中的有用脚本,谢谢@damn_c! (2认同)

Die*_*sen 65

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

在源主机中只运行一次:

ssh-keygen -t rsa # ENTER to every field
ssh-copy-id myname@somehost
Run Code Online (Sandbox Code Playgroud)

这就是全部,之后你就可以在没有密码的情况下做ssh了.

  • Downvoted,因为这甚至没有尝试回答实际问题. (17认同)
  • 我知道了.但我需要密码ssh.这是因为,"我"可能在拇指驱动器上有脚本,需要从任何计算机运行它; 而不是禁用密码的需要. (15认同)
  • 不幸的是,我处于OP状态,因为系统管理员不允许通过rsa/dsa密钥进行身份验证并需要密码.你要去做什么. (3认同)
  • @ user1467855,我认为你需要更好地解释你的要求.没有人建议你有一个不安全的网络.在公钥方法中,用户仍然可以使用密码登录.但是你可以将私钥复制到你的拇指驱动器上,这意味着拇指驱动器是唯一可以在没有密码的情况下登录的东西. (2认同)
  • 这个还是提示首次登录,不能在脚本中使用! (2认同)

Lip*_*ngo 28

您可以使用expect脚本.我在相当长的一段时间内没有写过,但它应该如下所示.您将需要使用脚本#!/usr/bin/expect

#!/usr/bin/expect -f
spawn ssh HOSTNAME
expect "login:" 
send "username\r"
expect "Password:"
send "password\r"
interact
Run Code Online (Sandbox Code Playgroud)

  • 我按照你的建议做了,但出现以下错误: `/bin/myssh.sh: 2: spawn: not found /bin/myssh.sh: 3: Expect: not found /bin/myssh.sh: 4: send: not找到 /bin/myssh.sh: 5: 期望: 未找到 /bin/myssh.sh: 6: 发送: 未找到` (3认同)

Rem*_*lex 21

变种我

sshpass -p PASSWORD ssh USER@SERVER
Run Code Online (Sandbox Code Playgroud)

变体II

#!/usr/bin/expect -f
spawn ssh USERNAME@SERVER "touch /home/user/ssh_example"
expect "assword:"
send "PASSWORD\r"
interact
Run Code Online (Sandbox Code Playgroud)

  • 不,sshpass不是ssh.`大纲sshpass [-ffilename | -dnum | -ppassword | -e] [options]命令参数 (4认同)

Sri*_*bat 9

sshpass + autossh

已经提到的一个很好的奖励sshpass是你可以使用它autossh,消除更多的交互式低效率.

sshpass -p mypassword autossh -M0 -t myusername@myserver.mydomain.com
Run Code Online (Sandbox Code Playgroud)

这将允许自动重新连接,例如,关闭笔记本电脑会中断您的wifi.

  • 请注意,您不能在此组合中将选项`-f`添加到autossh中,因为`与autossh一起使用时,ssh将*不能*要求输入密码或口令。`http://www.harding.motd.ca /autossh/README.txt也https://superuser.com/questions/1278583/autossh-not-working-in-background (2认同)

Ian*_*Ian 8

sshpass 更好的安全性

我偶然发现了这个线程,同时寻找一种方法来进入陷入困境的服务器 - 它花了一分多钟来处理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
Run Code Online (Sandbox Code Playgroud)

  • 我发现 `PreferredAuthentications=keyboard-interactive` 不起作用,但是用 `PreferredAuthentications=password` 替换它起作用了。 (3认同)
  • 自我注意:更新脚本以使用 `trap` 以防止 ctrl-C 泄漏 `SSHPASS` 变量 (2认同)

Dim*_*Dak 8

这就是我登录服务器的方式。

ssp <server_ip>
Run Code Online (Sandbox Code Playgroud)
  • 别名 ssp='/home/myuser/Documents/ssh_script.sh'
  • cat /home/myuser/Documents/ssh_script.sh

#!/bin/bash

sshpass -p mypassword ssh root@$1

因此...

ssp server_ip
Run Code Online (Sandbox Code Playgroud)


小智 6

# 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
Run Code Online (Sandbox Code Playgroud)

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

  • 我觉得这篇文章只是讽刺! (3认同)

Joh*_*ell 5

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

我需要解决相同的问题,而我最舒适的语言是Python。

我使用了paramiko库。此外,我还需要使用发出需要升级权限的命令sudo。事实证明,sudo可以通过“ -S”标志通过stdin接受其密码!见下文:

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!")
Run Code Online (Sandbox Code Playgroud)

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


SMs*_*ant 5

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

现在你可以这样做,

sshpass -p *YourPassword* ssh root@IP

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

cd ~

sudo nano .bash_profile

在文件末尾添加以下代码

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

source .bash_profile

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

笔记:

  1. mymachine可以是您选择的任何命令。
  2. 如果在此任务中安全性对您来说并不重要,而您只想自动化工作,则可以使用此方法。


Tom*_*m O 5

这基本上是 abbotto 答案的扩展,带有一些额外的步骤(针对初学者),使从 Linux 主机启动服务器变得非常容易:

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

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

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

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

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