Password-less logins with OpenSSH
Posted by Steve on Fri 3 Jun 2005 at 09:45
Because OpenSSH allows you to run commands on remote systems, showing you the results directly, as well as just logging in to systems it's ideal for automating common tasks with shellscripts and cronjobs. One thing that you probably won't want is to do though is store the remote system's password in the script. Instead you'll want to setup SSH so that you can login securely without having to give a password.
Thankfully this is very straightforward, with the use of public keys.
To enable the remote login you create a pair of keys, one of which you simply append to a file upon the remote system. When this is done you'll then be able to login without being prompted for a password - and this also includes any cronjobs you have setup to run.
If you don't already have a keypair generated you'll first of all need to create one.
If you do have a keypair handy already you can keep using that, by default the keys will be stored in one of the following pair of files:
- ~/.ssh/identity and ~/.ssh/identity.pub
- (This is an older DSA key).
- ~/.ssh/id_rsa and ~/.ssh/id_rsa.pub
- (This is a newer RSA key).
If you have neither of the two files then you should generate one. The DSA-style keys are older ones, and should probably be ignored in favour of the newer RSA keytypes (unless you're looking at connecting to an outdated installation of OpenSSH). We'll use the RSA keytype in the following example.
To generate a new keypair you run the following command:
skx@lappy:~$ ssh-keygen -t rsa
This will prompt you for a location to save the keys, and a pass-phrase:
Generating public/private rsa key pair. Enter file in which to save the key (/home/skx/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/skx/.ssh/id_rsa. Your public key has been saved in /home/skx/.ssh/id_rsa.pub.
If you accept the defaults you'll have a pair of files created, as shown above, with no passphrase. This means that the key files can be used as they are, without being "unlocked" with a password first. If you're wishing to automate things this is what you want.
Now that you have a pair of keyfiles generated, or pre-existing, you need to append the contents of the .pub file to the correct location on the remote server.
Assuming that you wish to login to the machine called mystery from your current host with the id_rsa and id_rsa.pub files you've just generated you should run the following command:
ssh-copy-id -i ~/.ssh/id_rsa.pub username@mystery
This will prompt you for the login password for the host, then copy the keyfile for you, creating the correct directory and fixing the permissions as necessary.
The contents of the keyfile will be appended to the file ~/.ssh/authorized_keys2 for RSA keys, and ~/.ssh/authorised_keys for the older DSA key types.
Once this has been done you should be able to login remotely, and run commands, without being prompted for a password:
skx@lappy:~$ ssh mystery uptime 09:52:50 up 96 days, 13:45, 0 users, load average: 0.00, 0.00, 0.00What if it doesn't work?
There are three common problems when setting up passwordless logins:
- The remote SSH server hasn't been setup to allow public key authentication.
- File permissions cause problems.
- Your keytype isn't supported.
Each of these problems is easily fixable, although the first will require you have root privileges upon the remote host.
If the remote server doesn't allow public key based logins you will need to updated the SSH configuration. To do this edit the file /etc/sshd/sshd_config with your favourite text editor.
You will need to uncomment, or add, the following two lines:
RSAAuthentication yes PubkeyAuthentication yesOnce that's been done you can restart the SSH server - don't worry this won't kill existing sessions:
/etc/init.d/ssh restartFile permission problems should be simple to fix. Upon the remote machine your .ssh file must not be writable to any other user - for obvious reasons. (If it's writable to another user they could add their own keys to it, and login to your account without your password!).
If this is your problem you will see a message similar to the following upon the remote machine, in the file /var/log/auth:
Jun 3 10:23:57 localhost sshd[18461]: Authentication refused: bad ownership or modes for directory /home/skx/.sshTo fix this error you need to login to the machine (with your password!) and run the following command:
cd chmod 700 .sshFinally if you're logging into an older system which has an older version of OpenSSH installed upon it which you cannot immediately upgrade you might discover that RSA files are not supported.
In this case use a DSA key instead - by generating one:
ssh-keygenThen appending it to the file ~/.ssh/authorized_keys on the remote machine - or using the ssh-copy-id command we showed earlier.
Note if you've got a system running an older version of OpenSSH you should upgrade it unless you have a very good reason not to. There are known security issues in several older releases. Even if the machine isn't connected to the public internet, and it's only available "internally" you should fix it.
Instead of using authorized_keys/authorized_keys2 you could also achieve a very similar effect with the use of the ssh-agent command, although this isn't so friendly for scripting commands.
This program allows you to type in the passphrase for any of your private keys when you login, then keep all the keys in memory, so you don't have password-less keys upon your disk and still gain the benefits of reduced password usage.
If you're interested read the documentation by running:man ssh-agent
The information to enable this (for GDM at least) is available in the README in the libpam-ssh package.
[ Parent | Reply to this comment ]
[ Send Message | View Steve's Scratchpad | View Weblogs ]
An interesting package which I'd not heard of before. Thanks for the tip!
Steve
-- Steve.org.uk
[ Parent | Reply to this comment ]
Well, I use ssh-key with password at work, to access some of my private hosts. My work box could be "compromised" (I have to give access to it to my cooperators), and I do not want then to access my own hosts. But from other side, I'd like not to type my password for key again and again. There comes `ssh-add' command, which use ssh-agent to store unecrypted key for my session (in my case it's Gnome on Ubuntu, but it's suitable for debian).
Very nice article :)
Lukasz Nowak
[ Parent | Reply to this comment ]
Thanks, Steve!
[ Parent | Reply to this comment ]
[ Send Message | View Steve's Scratchpad | View Weblogs ]
You're most welcome.
The only reason I chose to put this up right now is so that I can cover mosshe shortly - that really does require that you use password-less logins....
Steve
-- Steve.org.uk
[ Parent | Reply to this comment ]
To backup remote servers, I use rsync over ssh with the key valid only for the rsync-listener (and a shell script to double-check the given parameters). It is the most secure way I can think of to backup servers directly. And it's pretty fast too...
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
In the past I have written a bit about how you can still gain some convenience without compromising security with SSH keys here:
http://chris.quietlife.net/2003/10/13/key-management/
http://chris.quietlife.net/2003/10/14/security-part-ii/
http://chris.quietlife.net/2003/10/23/security-part-iii/
[ Parent | Reply to this comment ]
[ Send Message | View Steve's Scratchpad | View Weblogs ]
Good links, and a good point.
In general I'd agree that having passphrase-less keys is a bad idea, for purely internal LAN access it's not such a terrible idea, but for cross-network links its best to limit the commands that can be run.
I think enough people have commented to make that obvious now, so I'll not make a new article 'Password-less logins with OpenSSH - Securely' ;)
Steve
-- Steve.org.uk
[ Parent | Reply to this comment ]
Unless you have a very specific command that can be embedded in an authorized_keys file, you should always use a passphrase on your keys.
I worked on solving just this problem for an article I'm writing (which will be posted here in the not-too-distant future). Here is a section, with some minor modifications:
In order to script our backups while using a ssh key with a passphrase, we need an application which will retain use of the key over a long term. We'll use keychain, a tool which itself uses ssh-agent, which does the actual caching.
Install keychain:
~# apt-get install keychainTo set up local root's bash profile to run keychain on login, add these lines to ~/.bash_profile:keychain --clear id_dsa . ~/.keychain/$HOSTNAME-shThis will have keychain first clear the existing keys (in the case of a normal root compromise, the attacker can't access the remote systems), then attempt to load the id_dsa key and finally source the appropriate output from ssh-agent.
The next time root logs in, she will be prompted to enter the passphrase for the ssh key, and any subsequent process running as root will not need to use a password to log into the remote system.
[ Parent | Reply to this comment ]
[ Send Message | View Steve's Scratchpad | View Weblogs ]
I had planned on mentioning keychain at some point, but I'll look forward to your piece instead of covering it myself.
This piece was mostly setup for covering things such as remote backups via rsync over ssh - and simple server monitoring with mosshe.
Still I guess I should have made more comments about limitting the commands executed, or security in general.
Steve
-- Steve.org.uk
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
Upon login, either keychain or ssh-agent (not sure which, but leaning towards ssh-agent) clears the keys from memory. So if your account is breached by a brute-force password attack, for example, the attacker still won't have access to remote systems without breaking your passphrase on your ssh key.
You are correct in noting that an advanced attacker could still potentially get the key from memory (I don't have any specific info on this, but it is a concern).
The main point here is that if a system is broken into, and you're using passhprase-free keys, all the systems on which these keys are used are also breached. Using keychain with passphrase-enabled keys requires a higher level of sophistication on the part of the attacker in order to either break the passphrase or know how to exploit the key from memory.
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
[ Send Message | View Steve's Scratchpad | View Weblogs ]
You'd probably be able to start looking at the opie-client package, then started to look more depending on what software you're authenticating against.
Still if you're worried about keyloggers on a machine passwords would be the least of your problem.
You'd want to make sure all the software were legit and not just logging all network traffic.
Steve
-- Steve.org.uk
[ Parent | Reply to this comment ]
having said that, if you have to use this method there are ways of making it less vulnerable. one thing every noob should know is that you can restrict which user accounts on the server are allowed to be accessed in a 'password-less' way via its /etc/ssh/sshd_config file.
the line
AuthorizedKeysFile %h/.ssh/SOME_ORIGINAL_NAMEcan be made to point to a filename which is non-default (as above), and which you will only use in the home directories of users with severely restricted privileges.
while we're at it, sshd_config also contains the line PermitRootLogin that should likely be set to No unless you have a damn good reason.
finally, you can restrict which accounts can be accessed via SSH at all by explicitly listing them with
AllowUsers username
[ Parent | Reply to this comment ]
[ Send Message | View Steve's Scratchpad | View Weblogs ]
AllowUser and PermitRootLogin have already been covered in Keeping SSH Access Secure.
But the idea of limitting key access to a restricted set of accounts is a good one.
Steve
-- Steve.org.uk
[ Parent | Reply to this comment ]
i am humbled by the depth and breadth of this site.
[ Parent | Reply to this comment ]
My understanding is that RSA was in SSH1, DSA was introduced in SSH2, then RSA was added back into SSH2.
Here is an excerpt from Bruce Schneier's Crypto-Gram for November 15, 1999:
The security of most other public-key algorithms -- ElGamal, DSA, etc. -- is based on the discrete logarithm problem. The two problems are very similar, and all of the modern factoring algorithms can be used to calculate discrete logarithms in the multiplicative group of a finite field. To a rough approximation, factoring a number of a certain size and calculating the discrete logarithm of numbers the same size takes the same amount of work. This means that for a given key size, RSA, ElGamal, DSA, etc. are approximately equally secure. (This isn't strictly true, but it's a good enough approximation for this essay.)
[ Parent | Reply to this comment ]
UsePAM no
Am I crazy?
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
[ Send Message | View redbeard's Scratchpad | View Weblogs ]
UsePAM yes ChallengeResponseAuthentication noI can prevent using PAM passwords (requiring public/private key authentication) but still use the PAM framework for implementing other things? If that's the case, I'd be absolutely thrilled. Unfortuntaely, the man page is a little vague on ChallengeResponseAuthentication:
Specifies whether challenge-response authentication is allowed. All authentication styles from login.conf5 are supported. The default is "yes".I'll repost this elsewhere if no one notices ;)
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
Slightly off topic but something I would like to know. I have a script that uses scp, ssh, and rsync multiple times. Currently I have to type in the one password about 5 times each time I run the script. I run the script manually so I have no problem typing in the password, but I would like to do it only once.
Is there a way to keep one secure connection open and just use that connection for each of the various commands? Or some way to cache the password for just the duration of that script?
[ Parent | Reply to this comment ]
#!/usr/bin/expect spawn ssh user@host expect "Password: " { sleep 1 send "secret\r" } timeout { send_user "Error connecting" } # I have no idea why this needs to be here, except if it isn't the # password does not get sent and the login doesn't happen # So this should just timeout expect "alksjd" { send_user "Whoa" } timeout { } interact
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
You can probably find a way to cache the password by reading it in with the 'read' shell command (put echo off).
A more correct way is to write a script and run that on the remote host. Or you could also pass more complex commands (including shell programming) with ssh, you are not limited to one command. I don't know why you wouldn't use a key for that, though. I backup remote machines from cron on a secure machine with a DSA key -- rsync over ssh. I don't have to type any passwords because the key doesn't have one (which is perfectly fine in this case because it's a secure host that's not directly connected to the internet and has no services running). I can not run keychain on it because I'm rarely present in that office and it is rebooted occasionally due to bad power lines, but I'm thinking up a way to feed keychain PGP-signed and -encrypted input by means of a secure bot script hidden somewhere on the web.
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
I ran into one problem while I was working. You suggest editing /etc/sshd/sshd_config. On my systems this file is /etc/ssh/sshd_config (note the extra 'd').
It might be a typo on your part or a change in naming -- this tutorial is eighteen months old now, and I'm running bleeding edge sid! Thanks for the work.
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
just a question, is there any way to do such a thing in Windows too ?
in windows i use putty , and everytime I have to enter my password...
[ Parent | Reply to this comment ]
[ Send Message | View Steve's Scratchpad | View Weblogs ]
Yes, you want to read the putty documentation - it can store public keys too, and allow passwordless logins.
[ Parent | Reply to this comment ]
I followed the guidelines and came across a couple of issues that I would like to share with you.
1. The ssh-copy-id command stored the public key in the authorized_keys rather than authorized_keys2 although the new keys were of type RSA.
2. I ended up using the identity file switch to make the password-less feature work
ssh -i ~/.ssh/id_rsa REMOTE_HOST
I was using a FC6 machine as the local and a Debian3.1 one for the remote.
Regards
[ Parent | Reply to this comment ]
chmod 644 ~/.ssh/authorized_keys
... for some reason (not sure why the permissions were set differently), in order to get password-less SSH logins to work. So that's perhaps another thing to check if it's not working for you.
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
I had to manually copy the public key over using scp, then ssh in (using a password) and manually append the key to authorized_keys2 (cat source >> authorized_keys2).
[ Parent | Reply to this comment ]
I tried it, and the attitude is strange! It always asks me for a password when I try to connect to a machine on certain NIS domain that I'm not on it, and it doesn't prompt for password in the reverse path (From the NIS machine to mine)!
How can I solve??
Thanks,
Ahmad
[ Parent | Reply to this comment ]
You can also run ssh with some -v to get verbose trace of what happens when you connect to the other machine.
[ Parent | Reply to this comment ]
I had been having problems with getting sftp to work in batch mode. And I was getting this error:
Permission denied (publickey,password).
Couldn't read packet: Connection reset by peer
I followed the instructions the article to use ' ssh-copy-id -i ~/.ssh/id_rsa.pub "my_remote_host"'. And afterwards, by golly, I could ssh to my_remote_host without having to type in a password. But I still could not use sftp. Then I read that perhaps the client and server are using a newer version of the protocol, and that when using the newer version sftpd looks for ~/.ssh/authorized_keys2.
So I copied ~/.ssh/authorized_keys to ~/.ssh/authorized_keys2, and now sftp works fine.
[ Parent | Reply to this comment ]
as of today (July '09), the following two commands suffice on an updated Debian "stable" version:
$ ssh-keygen
$ ssh-copy-id login@host
regards, 'Titan'
[ Parent | Reply to this comment ]
The command is:
scp -p [file] [remote_host]@[IP]:/home/[dir]
I'm working with our lab machines now, and it seems that we have DSA, not RSA. The output of ssh -V shows:
OpenSSH_3.8.1p1 Debian-8.sarge.4, OpenSSL 0.9.7e 25 Oct 2004
I'm aware that OpenSSH goes up to at least 5.2 by now. I don't think our company is really interested in version updates, so at this point I'm just wondering if there's any options.
The result of the scp command is a password prompt, so the process isn't working. I've tried using the above RSA procedure, only starting with "ssh-keygen -t dsa" instead of "rsa" and also tried the suggestions from other users, above. chmod 644, etc.
I'm a lower-intermediate user, and keys are pretty new to me, but this doc was a huge step in at least the right direction. Any help or suggestions?
[ Parent | Reply to this comment ]
Thanks mostly to:
http://ubuntuforums.org/showthread.php?t=1047156
The issue, for me at least, was mostly the $home permissions. Needed to be 715, and I think the default that the company uses is 777. OpenSSH obviously doesn't want full permissions.
So long as ~/.ssh/authorized_keys is chmod to 600 (maybe id_rsa.pub as well), and ~ is 715, it works for me. This also works on Fedora test systems (we have standard OS installs of both Debian and Fedora, no unique packages).
Thanks!
[ Parent | Reply to this comment ]
for example:
#!/bin/bash
ssh 123.12.3.45 {sample ip address}
echo "hai vamsi"
output:
just connecting to remote system and stopping over there.
I need your help in this regards to proceed further.
Thanks in advance
Vamsi
vamsi.kunasani@gmail.com
[ Parent | Reply to this comment ]
You probably figured this out by now, but...
You need to test your command for executing in bash before you put it in the script--because it works the same way in the script or on the command line. Then you will see you can just write in the script: ssh user@ip-address command --it looks like you are trying to issue commands over SSH but by using echo? That's not right. I hope this helps.
[ Parent | Reply to this comment ]