39

I need to use sshpass to launch a remote command through SSH from a Java code.

If I manually type in a console:

ssh -p 22 user@ipaddress mplayer '/media/data/myFavouriteSong.mp3'

works perfectly, but asks for password. So I tried running sshpass:

sshpass -p mypass ssh -p 22 user@ipaddress mplayer '/media/data/myFavouriteSong.mp3'
sshpass -p mypass ssh -l user@ipaddress mplayer '/media/data/myFavouriteSong.mp3'
sshpass -p mypass ssh -t user@ipaddress mplayer '/media/data/myFavouriteSong.mp3'
sshpass -p mypass ssh user@ipaddress echo 'OK'

and none of them work.

muru
  • 197,895
  • 55
  • 485
  • 740

10 Answers10

43

This may be caused by the host-key checks done by ssh. It looks like sshpass keeps silent on invalid host keys (no output on neither stderr nor stdout) and exists with status-code 6. At the time of this writing, this was revision 50, and the matching constant in the code is RETURN_HOST_KEY_UNKNOWN, which hints to that error.

Your error-code may differ and looking at the code linked above may give you some insight.

If your issue is an invalid host-key you should think twice about overriding the error with a CLI option. Your machine could be compromised or you may be subject to a MITM attack! If you are 100% certain that this is not the case and if you have no means to keep the verified host-keys up-to date, you can use a command like this:

sshpass -pfoobar ssh -o StrictHostKeyChecking=no user@host command_to_run
exhuma
  • 722
  • 2
    With the brew install, a space is needed after -p. https://github.com/hudochenkov/homebrew-sshpass – AnneTheAgile Dec 21 '16 at 00:43
  • 2
    NOTICE: Everyone should remember that it is more secure to use passwordless SSH Host Keys whenever possible! By definition, using SSHPass is less secure. – Questionmark Jun 07 '18 at 13:45
  • @Questionmark while that is true, there are edge-cases where the remote endpoint does not support authentication via key. Which is where sshpass comes in handy – exhuma Jun 08 '18 at 11:42
  • Yes, I know. That is why I said "whenever possible"... – Questionmark Jun 08 '18 at 14:11
  • "In my case StrictHostKeyChecking=no is necessary ..." - This completely bypasses the check if you are talking to the right server. You could be talking to a malicious host, and anything you send over SSH (including the password) becomes compromised. And you wouldn't even notice it. There may be situations where this is necessary, but you should not provide that option in an answer that does not require it. – marcelm Oct 01 '18 at 16:00
  • @marcelm You are absolutely right. I completely reworded the answer to properly warn about the potential issue. – exhuma Oct 02 '18 at 14:17
  • Awesome, have a +1 :) – marcelm Oct 02 '18 at 18:13
  • 1
    With new enough SSH, there's StrictHostKeyChecking=accept-new. – muru Oct 03 '18 at 04:25
  • @exhuma: there are no such edge cases (otherwise post link) where SSH host keys cannot be used. It might be a obsolete very old version of SSH that should never be used, as it is full of unfixed security holes. sshpass is only used by people that are clueless about how you can use crypto keys to safely log into a Linux system, that are used to this dumb Windows system where you will store a password in a file somewhere. Please please read this: https://www.tecmint.com/ssh-passwordless-login-using-ssh-keygen-in-5-easy-steps/ and become a more professional admin! Both more secure and better. – Markus Bawidamann Oct 29 '20 at 02:33
  • @MarkusBawidamann yes there are edge-cases. I work with older hardware network devices which support SSH for remote management. They are located in an isolated network and SSH is only used for mgmt. Their main function is too critical to warrant a replacement/upgrade and they don't support key-based logins. Providing a link would quite likely be in violation of an NDA. In my 20+ years of sysadmin work this is the first time I came across this issue (hence why I mentioned them as edge cases). So instead of attacking my experience you should do some research first yourself. – exhuma Oct 30 '20 at 11:44
  • @exhuma: I have done the research, I have a lot of experience and have never come across this and am most shocked that hardly an article mentions that this is really horrible for security: ssh should never used that way, as it defeats the whole secure aspect of it. But of course it is a free country, you can use whatever you want. – Markus Bawidamann Oct 31 '20 at 03:04
11

sshpass command works only if the password prompt ends in assword:.

If your password prompt is different you may have to adjust the source code of sshpass to recognize the prompt you have.

I have seen password prompts like Password for user@host: on some systems, maybe this is your problem.

αғsнιη
  • 35,660
rjs
  • 111
  • 1
  • 3
  • 3
    sorry? -P prompt Which string should sshpass search for to detect a password prompt – m3nda Oct 29 '17 at 06:34
  • 4
    This new option (needs at least V1.0.6 of sshpass) solves that problem. – rjs Nov 02 '17 at 10:48
  • Oh, sorry. This kind of issue (solution?) happen so often, old questions that are already fixed at new versions. Thanks. – m3nda Nov 02 '17 at 21:05
6

I think you want something like:

sshpass -p yourpassword ssh user@ipaddress somecommand

For instance, this works for me:

sshpass -p mypassword ssh username@10.0.0.9 touch foo
αғsнιη
  • 35,660
2
  1. make a key

    ssh-keygen -t rsa

  2. make a .ssh folder on the remote server it will ask for a password

    ssh $USER@SEVERNAME mkdir -p .ssh

  3. copy the key to the remote server

    cat .ssh/id_rsa.pub | ssh $USER@SERVER 'cat >> .ssh/authorized_keys'


Check if it asks for a password, if not it should work.

ssh $USER@SEVERNAME 'command'
Michele
  • 904
  • 7
  • 23
1

sshpass syntax is

sshpass [-ffilename|-dnum|-ppassword|-e] [options] command arguments

Note that there is no space between the -p and the password.

Also I've noticed that you have to connect with ssh at least once manually to obtain the RSA key of the machine you are connecting to, to go into the ~/.ssh/known_hosts file before sshpass will allow you to connect.

so after obtaining the entry in the known_hosts file I can run a command such as

sshpass -ffilename_with_password_in_it ssh user@server uname -a

and it will execute the command uname -a on the remote server and output the results to the standard out on the local machine.

BeowulfNode42
  • 580
  • 2
  • 6
  • 15
1

There is lots of way to do that, here is my suggested solution:

First of all, storing your password in a variable is give you more flexible commands. sshpass has an option for that:

-e: this option allows to read password from $SSHPASS environment variable

You have two way to set this variable:

  1. Set directly in your code:

    export SSHPASS='your_pass'
    
  2. Or ask for it:

    readPassword () {
      echo Ssh Password: 
      read -s SSHPASS
      eval "export SSHPASS='""$SSHPASS""'"
    }
    
    # read password
    
    readPassword
    

Than execute your command;

  1. If your command is static, run it directly:

    sshpass -e ssh user@host << EOF
    mplayer '/media/data/myFavouriteSong.mp3'
    command2 parameter1 parameter2 parameter3 ...
    command3 parameter1 parameter2 parameter3 ...
    ...
    EOF
    
  2. If your command will be dynamic use like this:

    DYN_FILE_LOC='/media/data/myFavouriteSong.mp3'
    
    eval 'sshpass -e ssh user@host << EOF
    mplayer "$DYN_FILE_LOC"
    command2 parameter1 parameter2 parameter3 ...
    command3 parameter1 parameter2 parameter3 ...
    ...
    EOF'
    

hope this helps someone.

  • In your readPassword function, can't you just do export SSHPASS? – kutschkem Apr 20 '15 at 11:13
  • @kutschkem, I trust but my idea that i think here; i dont want to write my pass in a static file but instead of writing password again and again for lots of servers(7+), i write once :) You don't have to use readPassword function, you can just write your password, it should work :) Only i want to share my code which is shows an example using sshpass for dynamic commands :D – veysiertekin Apr 20 '15 at 12:07
  • No, I just mean that the eval is not necessary after the read, export does not need an assignment. http://ss64.com/bash/export.html – kutschkem Apr 20 '15 at 12:35
  • the problem with -e is that the export will be listed in your history – ejaenv Mar 05 '18 at 21:29
1

@exhuma had an example that lead to it working for me.

The password needs to be in form of -pPassword (without the space)

also quotes may be necessary: sshpass -p'Password&0' user@hostname

0

The simplest usage is to set the SSHPASS variable:

read -p "SSH password:" SSHPASS
export SSHPASS

Then you can run e.g.:

sshpass -e ssh $user@$host echo Test

If something is going wrong, the -v flag will give you more information.

mwfearnley
  • 3,317
  • 2
  • 22
  • 28
0

sshpass uses pseudo terminals and the man page includes apologies for breaking occasionally. You can also try fd0ssh. It works if you do not need to send stdin to a process on the remote machine. That works if you just issue a command and capture the result.

papukaija
  • 2,425
Bruce
  • 629
  • 1
  • 5
  • 8
0

What you need is -f -t -t -t

sshpass -p$PASS ssh -f -t -t -t $USER@$HOST $COMMAND

Additionally you might have to remove "requiretty" from sudo config (/etc/sudoers) on the remote machine.

Ehsan
  • 226