27

How would I connect to another computer through SSH in one line? If I were to do ssh host@IP, it would require me to enter the password in the second line. I was thinking that I could do something like this: ssh host@IP | echo password, but that puts the password in before asking for the password.

  • 2
    This sort of thinking comes from the days of telnet and expect, back when the internet was a safer place. Allen's answer is correct, Jakuje's answer is techncally true but not the tool for the job in most places. – Criggie Jun 4 '17 at 21:16
  • 3
    This is a good question for setting up passwordless login. I'd ask that you revisit your accepted answer. Which Jakuje's answer -is- correct, and will work, the proper way to do this is with SSH keys, described in Allan's answer. – Scot Jun 5 '17 at 0:34
  • If ssh would read the password from stdin, then echo password | ssh host@IP would work, but usually SSH tries to read directly from the terminal. – Paŭlo Ebermann Jun 5 '17 at 17:59
80

You should be using SSH keys to authenticate with rather than putting your password on the command line as it's extremely insecure.

The way this works is once you have your SSH keys set up, all you have to do is issue the command:

ssh user@host

and without typing another thing, you will be automatically logged in.


Copy SSH Public Key to Mac/FreeBSD/Linux from macOS

This assumes you have access to the remote server via password based authentication (typing in a password), and that you have already generated your private/public keypair (if not, see below). In the following example, we are using RSA. To start with let's copy the key over (be aware that the "home" directory differs between macOS, Linux, BSD, etc.):

Using SCP:

scp ~/.ssh/id_rsa.pub username@hostname:/Users/username/.ssh/

Or simply cat-ing the file to authorized_keys (I prefer this method):

cat id_rsa.pub | ssh username@hostname ' cat >>.ssh/authorized_keys'

(Your key name may differ)  If the .ssh directory does not exist on the remote server you will need to login and create it.

Now the key has been copied from the mac to the remote server. Set correct permissions for the SSH Public Key on the remote server:

chmod 600  ~/.ssh/id_rsa.pub

Next add the key to the SSH authorized_keys file, if the file does not exist create it.

If the file authorized_keys already exists in ~/.ssh the use the following command:

cat id_rsa.pub >> authorized_keys

If the file does not exist enter the following commands:

cat id_rsa.pub > authorized_keys

chmod 600 authorized_keys
chown user:group authorized_keys


Generate SSH Public/Private key on macOS

Open up the Terminal by going to Applications -> Utilities -> Terminal

In the terminal, use the following command to start the key generation

ssh-keygen -t rsa

Next you will be prompted to provide the location where you want to create the private key file:

Enter file in which to save the key (/Users/username/.ssh/id_rsa):

Leave this empty to create the key in the default location, which is /Users/username/.ssh/id_rsa. The public key file will be created in the very same location, and with the same name, but with the .PUB extension.

After you will be prompted to choose a passphrase. This is the password optional to use the private key.

Enter passphrase (empty for no passphrase):

Your SSH key is generated.

Now, keep in mind, if you put in a passphrase you will be required to enter it each time you connect. The utility ssh-agent will keep the passphrase in memory alleviating the need to manually enter it every time you connect while you are in the same session. For more details see man ssh-agent

  • 6
    Absolutely this - keys can and should completely replace passwords for any ssh access over the internet. I'd suggest you expand on the need for security of the private key, that its not something to have laying about on all your computers. – Criggie Jun 4 '17 at 21:12
  • +1 This is a really good answer, not only because of what it says, but also because of how you've explained it. Anything that's easier for users to follow and helps them to be more secure is a plus in my books! – Monomeeth Jun 5 '17 at 0:20
  • 7
    Great answer. Just wanted to add that ssh-copy-id is a nice tool for automating some of the above. – Scot Jun 5 '17 at 0:32
  • A mention of ssh-agent might also help. Most (all?) versions of OS X / macOS come with it, and it allows password-less login even when the key is password protected. – Qsigma Jun 5 '17 at 10:27
  • 1
    @Scot - it's not part of macOS by default and must be installed via Homebrew or MacPorts. I'm not a fan of installing software for things can can be accomplished in 1 line or a short, self written script and for those reasons I thought it was outside the scope of the answer. However, it's a good little utility and worth mentioning. – Allan Jun 5 '17 at 11:04
13

There are several possibilities. Your example will obviously not work, but you can achieve something similar using sshpass utility:

sshpass -p password ssh host@IP

Note, this is not recommended because the password will be visible for other processes or in the shell history.

A much better way to do the same is to set up the passwordless authentication using SSH keys. In short:

ssh-keygen -t rsa -f ~/.ssh/id_rsa
ssh-copy-id IP
  • I tried the sshpass as you recommended, but it said command not found. – Ben A. Jun 4 '17 at 20:30
  • 8
    Well ... You will probably have to install it. And no, I don't recommend it. Set up passwordless authentication using ssh keys. – Jakuje Jun 4 '17 at 20:34
  • 4
    @BenA. set up passwordless authentication by defining a public/private keypad and setting it up on both machines involved. That's much easier (and actually safer) than any password – nohillside Jun 4 '17 at 20:37
  • 8
    A thousand times no. sshpass is a dirty hack used for connecting to devices that speak ssh but don't do keys properly, and its main use is setup scripts. You would not use sshpass on a multiuser machine ps auxw | grep sshpass will tell other users the ssh password. – Criggie Jun 4 '17 at 21:14
  • 1
    @Criggie, not entirely. While I'm 100% behind the key-based solution, I have sshpass on a couple of internal-only Raspberry Pis (for random tasks, and accessed by random clients; passing keys around just for internal use is a hassle). Running your command gives the following output: pi@sshbox:~ $ ps auxw | grep sshpass pi 4891 0.0 0.3 2256 1560 pts/0 S+ 06:29 0:00 sshpass -p zzzzzzzz ssh pi@192.168.0.208. The zzzzzzzz is literal; sshpass masks the content of the password. Perhaps earlier iterations were less privacy-aware. – flith Jun 5 '17 at 6:31
3

I have spent a long time looking for the answer to this too. Despite it being insecure and all these people telling you to use RSA keys (which IS a more secure and reliable idea), it is quite possible.

Use a program called expect for this. Expect will watch stdout (and I think stderr if configured correctly) for you, waiting for certain messages and responding to them with output. Expect itself is actually a scripting language, and when I was doing this same thing, I had a very hard time getting my own script to work properly because of timing. However, expect also includes a handy utility called autoexpect.

With autoexpect, it will watch you and generate an expect script for you. Simply run autoexpect and the command you want:

autoexpect ssh host@ip 

and do what you'd normally do. When you exit the program (by typing exit in the ssh'd shell), it will generate the script. In case that you don't want the whole script you're writing to be in an expect script, you can edit the script from autoexpect (called script.exp) to exit before typing the exit command into the shell. The line you want to move to change the script ending is:

expect eof

which means expect end of file. Hope this helps!

  • 1
    In case no one else has said it yet: Welcome to Ask Different! – Synoli Jun 5 '17 at 13:50
2

Using expect is just plain wrong to log into an ssh connection for anything other than in a test suite.

What @ben-a is looking for is already implemented in ssh. The trick is to how to use it. So here goes:

  1. Generate a public/private keypair using ssh-keygen. Use either ECDSA or RSA as the -t (or type) and for RSA use 2048 or 4096 as the -b (or BITS length). This should suffice at the moment of writing. ALWAYS use a PASSWORD!
  2. Utilize the ssh-copy-id or the above mentioned methodology to create on the machine you're logging on to (a.k.a. the server) the ~/.ssh/authorized_keys file. Within there is a copy of the public key you just generated.
  3. Now on the machine you use to log into the 'server' (or client) you open the file ~/.ssh/config. If it does not exist you can create it.
  4. In this file, you add the following for your needs

    host <name you want to use for this connection>
        Hostname <DNS or IP of the server>
        user <user name you want to use>
        identitiesonly yes
        identityfile <path to the private key>
    
  5. You can now use just ssh <name> to setup the connection, but it will still need the password for your key. To solve this, use the for-this-purpose developed and included ssh-agent. To add your key to the agent just use ssh-add <path to keyfile>. You will be asked for the password, and it will store the key for you securely for this session. If it yields the error "can't find the ssh-agent" (or similar), that means that probably the agent hasn't been started. You can start it for this session using ssh-agent bash. This will start a new shell with the agent active in it.

When using these steps, you not only make it harder for someone to impersonate you by hijacking your credentials, but also keep the usability in order (its easier to use than plain passwords).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .