Automatically enter SSH password with script

2019-01-02 19:25发布

问题:

I need to create a script that automatically inputs a password to OpenSSH ssh client.

Let's say I need to SSH into myname@somehost with the password a1234b.

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?

回答1:

First you need to install sshpass.

  • Ubuntu/Debian: apt-get install sshpass
  • Fedora/CentOS: yum install sshpass
  • Arch: 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.
    • Using -f prevents the password from being visible if the ps command is executed.
    • The file that the password is stored in should have secure permissions.


回答2:

After looking for an answer for 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 "assword:"
send "$password\r";
interact

Put it to /usr/bin/exp, then you can use:

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

Done!



回答3:

Use public key authentication: 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.



回答4:

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 -f
spawn ssh HOSTNAME
expect "login:" 
send "username\r"
expect "Password:"
send "password\r"
interact


回答5:

Variant 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


回答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

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



回答7:

sshpass with better security

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. 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. However, there are better ways to go about this than 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


回答8:

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 -p mypassword autossh -M0 -t myusername@myserver.mydomain.com

This will allow autoreconnect if, e.g. your wifi is interrupted by closing your laptop.



回答9:

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

host *
     StrictHostKeyChecking no

Create a response file for expect i.e. 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

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

Hope this helps someone - I'm a Windows numpty and this took me about 5 hours to figure out!



回答10:

I have a better solution that inclueds login with your account than changing to root user. It is a bash script

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



回答11:

The answer of @abbotto did not work for me, had to do some things differently:

  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
  2. the command to use sshpass changed to - sshpass -p "pass" ssh user@mysite -p 2122


回答12:

I don't think I saw anyone suggest this and the OP just said "script" so...

I needed to solve the same problem and my most comfortable language is Python.

I used the paramiko library. Furthermore, I also needed to issue commands for which I would need escalated permissions using sudo. It turns out sudo can accept its password via stdin via the "-S" flag! 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. As such, automation was paramount. I tried sshpass, and expect and then came up with this.

I hope it helps someone as much as it did me!



回答13:

To get key-exchange to work from a thumbdrive, you have to copy your private key to your drive, and specify it in your ssh command (to avoid using the local accounts private key), e.g.:

ssh -i id_rsa host

Alternatively, you could use expect (which is a separate script from shell). Here's a previous question regarding SSH and expect.

Note that anyone will be able to open the expect script and see the login credentials in plain text.



回答14:

To connect remote machine through shell scripts , use below command:

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.



回答15:

Do this:

echo mypassword | ssh USERNAME@IPADDRESS

This simply pipes the password to ssh and it is used as the immediate required input.



标签: