简体   繁体   English

用脚本自动输入SSH密码

[英]Automatically enter SSH password with script

I need to create a script that automatically inputs a password to OpenSSH ssh client.我需要创建一个脚本,自动将密码输入到 OpenSSH ssh客户端。

Let's say I need to SSH into myname@somehost with the password a1234b .假设我需要使用密码a1234b将 SSH 放入myname@somehost

I've already tried...我已经试过了...

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

...but this does not work. ...但这不起作用。

How can I get this functionality into a script?我怎样才能将此功能放入脚本中?

First you need to install sshpass .首先你需要安装sshpass

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

Example:例子:

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

Custom port example:自定义端口示例:

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

Notes:笔记:

  • sshpass can also read a password from a file when the -f flag is passed.-f标志被传递时, sshpass还可以从文件中读取密码。
    • Using -f prevents the password from being visible if the ps command is executed.如果执行ps命令,则使用-f可防止密码可见。
    • The file that the password is stored in should have secure permissions.存储密码的文件应该具有安全权限。

After looking for an answer to the question for months, I finally found a better solution: writing a simple script.在找了几个月的问题答案后,我终于找到了一个更好的解决方案:编写一个简单的脚本。

#!/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

Put it to /usr/bin/exp , So you can use:把它放到/usr/bin/exp ,所以你可以使用:

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

Done!完毕!

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

In the source host run this only once:在源主机中只运行一次:

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

That's all, after that you'll be able to do ssh without password.就是这样,之后您就可以在没有密码的情况下执行 ssh。

You could use an expects script.您可以使用期望脚本。 I have not written one in quite some time but it should look like below.我已经有一段时间没有写过一篇了,但它应该如下所示。 You will need to head the script with #!/usr/bin/expect您需要使用#!/usr/bin/expect来引导脚本

#!/usr/bin/expect -f
spawn ssh HOSTNAME
expect "login:" 
send "username\r"
expect "Password:"
send "password\r"
interact

Variant I变体 I

sshpass -p PASSWORD ssh USER@SERVER

Variant II变体二

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

sshpass with better security sshpass具有更好的安全性

I stumbled on this thread while looking for a way to ssh into a bogged-down server -- it took over a minute to process the SSH connection attempt, and timed out before I could enter a password.我在寻找一种通过 ssh 进入陷入困境的服务器的方法时偶然发现了这个线程 - 处理 SSH 连接尝试花了一分钟多的时间,并且在我输入密码之前超时。 In this case, I wanted to be able to supply my password immediately when the prompt was available.在这种情况下,我希望能够在提示可用时立即提供我的密码。

(And if it's not painfully clear: with a server in this state, it's far too late to set up a public key login.) (如果不是很清楚:服务器处于这种状态,设置公钥登录为时已晚。)

sshpass to the rescue. sshpass来救援。 However, there are better ways to go about this than sshpass -p .但是,有比sshpass -p更好的方法来解决这个sshpass -p

My implementation skips directly to the interactive password prompt (no time wasted seeing if public key exchange can happen), and never reveals the password as plain text.我的实现直接跳到交互式密码提示(没有浪费时间查看是否可以进行公钥交换),并且从不以纯文本形式显示密码。

#!/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

sshpass + autossh sshpass + autossh

One nice bonus of the already-mentioned sshpass is that you can use it with autossh , eliminating even more of the interactive inefficiency.已经提到的一个不错的奖金sshpass是,你可以用它autossh ,消除更加的互动效率低下。

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

This will allow autoreconnect if, eg your wifi is interrupted by closing your laptop.这将允许自动重新连接,例如,您的 wifi 因关闭笔记本电脑而中断。

I don't think I saw anyone suggest this and the OP just said "script" so...我想我没有看到有人提出这个建议,OP 只是说“脚本”所以......

I needed to solve the same problem and my most comfortable language is Python.我需要解决同样的问题,而我最熟悉的语言是 Python。

I used the paramiko library.我使用了 paramiko 库。 Furthermore, I also needed to issue commands for which I would need escalated permissions using sudo .此外,我还需要使用sudo发出需要升级权限的sudo It turns out sudo can accept its password via stdin via the "-S" flag!事实证明 sudo 可以通过标准输入通过“-S”标志接受它的密码! See below:见下文:

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!")

Hope this helps someone.希望这可以帮助某人。 My use case was creating directories, sending and untarring files and starting programs on ~300 servers as a time.我的用例是在大约 300 台服务器上创建目录、发送和解压缩文件以及启动程序。 As such, automation was paramount.因此,自动化至关重要。 I tried sshpass , expect , and then came up with this.我尝试了sshpassexpect ,然后想出了这个。

This is how I login to my servers.这就是我登录服务器的方式。

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

#!/bin/bash #!/bin/bash

sshpass -p mypassword ssh root@$1 sshpass -p mypassword ssh root@$1

And therefore...因此...

ssp server_ip
# 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

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

I am using below solution but for that you have to install sshpass If its not already installed, install it using sudo apt install sshpass我正在使用以下解决方案,但为此您必须安装sshpass如果尚未安装,请使用sudo apt install sshpass

Now you can do this,现在你可以这样做,

sshpass -p *YourPassword* shh root@IP

You can create a bash alias as well so that you don't have to run the whole command again and again.您也可以创建一个 bash 别名,这样您就不必一次又一次地运行整个命令。 Follow below steps按照以下步骤操作

cd ~

sudo nano .bash_profile

at the end of the file add below code在文件末尾添加以下代码

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

source .bash_profile

Now just run mymachine command from terminal and you'll enter your machine without password prompt.现在只需从终端运行mymachine命令,您将在没有密码提示的情况下进入您的机器。

Note:笔记:

  1. mymachine can be any command of your choice. mymachine可以是您选择的任何命令。
  2. If security doesn't matter for you here in this task and you just want to automate the work you can use this method.如果在此任务中安全性对您来说并不重要,而您只想自动化工作,则可以使用此方法。

This is basically an extension of abbotto's answer, with some additional steps (aimed at beginners) to make starting up your server, from your linux host, very easy:这基本上是 abbotto 答案的扩展,还有一些额外的步骤(针对初学者)使从您的 linux 主机启动服务器非常容易:

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

sshpass -p "YOUR_PASSWORD" ssh -o StrictHostKeyChecking=no YOUR_USERNAME@SOME_SITE.COM
  1. Save the file, eg 'startMyServer', then make the file executable by running this in your terminal:保存文件,例如“startMyServer”,然后通过在终端中运行以下命令使文件可执行:
sudo chmod +x startMyServer
  1. Move the file to a folder which is in your 'PATH' variable (run 'echo $PATH' in your terminal to see those folders).将文件移动到“PATH”变量中的文件夹(在终端中运行“echo $PATH”以查看这些文件夹)。 So for example move it to '/usr/bin/'.因此,例如将其移动到“/usr/bin/”。

And voila, now you are able to get into your server by typing 'startMyServer' into your terminal.瞧,现在您可以通过在终端中输入“startMyServer”来进入您的服务器。

PS (1) this is not very secure, look into ssh keys for better security. PS (1) 这不是很安全,查看 ssh 密钥以获得更好的安全性。

PS (2) SMshrimant answer is quite similar and might be more elegant to some. PS (2) SMshrimant 的答案非常相似,对某些人来说可能更优雅。 But I personally prefer to work in bash scripts.但我个人更喜欢在 bash 脚本中工作。

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

plink your_username@yourhost -pw your_password

I got this working as follows我按如下方式工作

.ssh/config was modified to eliminate the yes/no prompt - I'm behind a firewall so I'm not worried about spoofed ssh keys .ssh/config 被修改以消除是/否提示 - 我在防火墙后面,所以我不担心欺骗的 ssh 密钥

host *
     StrictHostKeyChecking no

Create a response file for expect ie answer.expect为expect ie 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

Create your bash script and just call expect in the file创建你的 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

Gets 128 hadoop datanodes refreshed with new config - assuming you are using a NFS mount for the hadoop/conf files使用新配置刷新 128 个 hadoop 数据节点 - 假设您对 hadoop/conf 文件使用 NFS 挂载

Hope this helps someone - I'm a Windows numpty and this took me about 5 hours to figure out!希望这对某人有所帮助 - 我是一个 Windows numpty,这花了我大约 5 个小时才弄清楚!

I have a better solution that inclueds login with your account than changing to root user.我有一个更好的解决方案,包括使用您的帐户登录,而不是更改为 root 用户。 It is a bash script这是一个bash脚本

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

The answer of @abbotto did not work for me, had to do some things differently: @abbotto 的答案对我不起作用,必须做一些不同的事情:

  1. yum install sshpass changed to - rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/sshpass-1.05-1.el6.x86_64.rpm yum install sshpass 改为 - rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/sshpass-1.05-1.el6.x86_64.rpm
  2. the command to use sshpass changed to - sshpass -p "pass" ssh user@mysite -p 2122使用 sshpass 的命令更改为 - sshpass -p "pass" ssh user@mysite -p 2122

I managed to get it working with that:我设法让它与它一起工作:

SSH_ASKPASS="echo \"my-pass-here\""
ssh -tt remotehost -l myusername

In the example bellow I'll write the solution that I used:在下面的示例中,我将编写我使用的解决方案:

The scenario: I want to copy file from a server using sh script:场景:我想使用 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"

This works:这有效:

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

BUT ,,, If you have an error like below: just start your script with expect, but not bash, as shown here: expect myssh.sh instead of bash myssh.sh但是,,, 如果您遇到如下错误:只需使用 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

Use this script tossh within script, First argument is the hostname and second will be the password.在脚本中使用此脚本 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"

To connect remote machine through shell scripts , use below command:要通过 shell 脚本连接远程机器,请使用以下命令:

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

where IPADDRESS , USERNAME and PASSWORD are input values which need to provide in script, or if we want to provide in runtime use "read" command.其中IPADDRESSUSERNAMEPASSWORD是需要在脚本中提供的输入值,或者如果我们想在运行时提供使用“读取”命令。

This should help in most of the cases (you need to install sshpass first!):这在大多数情况下应该会有所帮助(您需要先安装 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

In linux/ubuntu在 linux/ubuntu 中

ssh username@server_ip_address -p port_number

Press enter and then enter your server password按回车键,然后输入您的服务器密码

if you are not a root user then add sudo in starting of command如果您不是 root 用户,则在命令开头添加sudo

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM