A couple of weeks ago I started with the first tutorial in a series of security-related ones. This is the second tutorial in this series. Last time I spoke about SSH and sudo. As Raymii pointed out in the comments, I never mentioned how to actually generate your own SSH key. In this tutorial, I would like to show you how to do that.
Why would you want to use an SSH key? Well, normally when you log into a server you get asked for a password. But not only you: anybody who tries to log in to the server gets asked for the password. This means that an attacker can actually try and keep guessing passwords for a long, long time. To tackle this problem, you shouldn’t be using password authentication but rather an SSH keypair. With your public key on the server and your private key on your PC, SSH can match those two and give you access. A password is no longer needed. But why is it more secure?
Because an SSH key is extremely hard to guess, virtually impossible. Not only because the private key is usually 2048 bits (or more), but also because the private and public key need to match. So you would need to actually guess the private key that matches the public key. Good luck with that ;-)
So, let’s generate an SSH-key!
Generating an SSH key
Generating an SSH key is done with the ‘ssh-keygen’ command. This should be available by default on most Linux distributions and Mac OS X. ssh-keygen generates a keypair for your with a private and public key. The public key is uploaded to the server you want to authenticate with. The private key is used to match with a public key on the server to see if you are allowed to access it over SSH. Only if the public and private key match, you get access to the server.
Your SSH private key is protected with a password. You have to make sure this is a strong password, as your SSH key could very well be the key to all your servers. ‘hunter2’ is not a good password, for example. Your password shouldn’t contain any dictionary words, dates (that are important to you), your address or any (family) names. It should basically be random letters, numbers and symbols where the letters differ in case as well. I usually use KeePass2 to check a password’s strength. It’s not a guarantee, but an indication. I make sure my passwords are at least 100bits on the strength meter.
So what is a good password? Well, I would consider this a good/decent password: KIanf832hWN()@jnfs*@. Of course, this one is quite hard to remember, so you may have to cook up one that’s a bit easier to remember but has the same strength. If you find it too hard to remember the password in general, you could always store it in a KeePass2 database. You would need to guard that with a password again, though… Anyway, you probably got the point: pick a very strong password. In case your private key ever gets in the wrong hands, it’ll be hard for whoever has it to crack your password if you have a good password.
Editorial note: if anybody has good (additional) advice for coming up with string passwords that are easy to remember, please add them in the comments.
Now, let’s generate the SSH key with the following command:
ssh-keygen -b 4096 -C “Maarten Kossen”
We invoke the ssh-keygen command with to parameters: -b and -C. The -C is user for a comment for the SSH key. This could be ‘This is the key for my office servers’ or your name, like I used in the example. This comment will be in your public key and will be listed in all the authorized_keys files your public key is in. It’s basically a label for your key.
The -b parameter is used to indicate the number of bits the key will be. Basically it’s like this: the more bits, the stronger a key is and the harder it is to crack. ssh-keygen’s default length is 2048 bits, which is fine, but I’m going for better. So, with -b 4096 I’m making the key 4096 bits, which should be better ;-)!
This is the output of the command:
mpkossen@ny:~$ ssh-keygen -b 4096 -C “Maarten Kossen”
Generating public/private rsa key pair.
Enter file in which to save the key (/home/mpkossen/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/mpkossen/.ssh/id_rsa.
Your public key has been saved in /home/mpkossen/.ssh/id_rsa.pub.
The key fingerprint is:
0a:14:c2:08:bc:95:20:1c:d1:bc:06:3e:95:c7:e3:03 Maarten Kossen
The key’s randomart image is:
+–[ RSA 4096]—-+
|**B = |
|o+.E = |
|. = * . |
| + + o |
| o . . S |
| . . |
| . |
| |
| |
+—————–+
mpkossen@ny:~$
First, it asks you where you want to save the private key. The default is usually good, unless you want to change the name of the keyfile. If you want to put it somewhere custom, make sure you enter a full path and a filename (so no trailing slash). Then it asks you for your password, twice. Enter your strong password twice and you should be good. Finally, it generates the key and shows you some key information.
You just generated your own SSH key! Let’s now set up ssh-agent so you don’t have to type your password every time you log into a server.
Setting up ssh-agent
ssh-agent is a small program that holds private keys for as long as it runs. It helps you authenticate with servers which you are logging in to using public key authentication. On Ubuntu, ssh-agent runs by default and is nicely integrated into GNOME. This is not the case on many other systems, however.
So let’s start ssh-agent by running the following command (this has to be done as the user owning the SSH key):
eval $(ssh-agent)
This will start ssh-agent as a background process and store the environment variables it outputs in your environment, by using eval. If we would not have used eval and just ran ‘ssh-agent’, the agent wouldn’t have been available but would have just output the commands you would have to run for the agent to work.
This is what it will output using eval (the pid number varies, of course):
mpkossen@ny:~$ eval $(ssh-agent)
Agent pid 579
mpkossen@ny:~$
So, now the agent is up and running, let’s add an SSH-key to it. For the default key, run:
ssh-add
Which will ask for your password and output:
mpkossen@ny:~$ ssh-add
Enter passphrase for /home/mpkossen/.ssh/id_rsa:
Identity added: /home/mpkossen/.ssh/id_rsa (/home/mpkossen/.ssh/id_rsa)
mpkossen@ny:~$
ssh-add searched for default keynames, of which id_rsa is one, and adds them to the ssh-agent. Once you’ve typed your password, the “unlocked” key is stored with ssh-agent and can be used to authenticate against other servers. Now try to log in to a server where you’ve added the public key to. It shouldn’t ask you for your password!
Now, doing this every time you open a terminal just to SSH into a server is a bit overkill. Therefore, you could consider starting ssh-agent with your bash session:
echo ‘eval $(ssh-agent)’ >> ~/.bash_profile
This will start ssh-agent every time you open a new bash terminal session. You would still have to run ssh-add manually, but that could also be done automatically after starting ssh-agent:
echo ‘ssh-add’ >> ~/.bash_profile
Which would add SSH key(s) once you log in (and ask for their password).
The above solutions are temporary, however. If you close the terminal, ssh-agent will still run but won’t be available in a new terminal session. There are various solutions to handle this, but one I’ve found to work quite well is one from Joseph M. Reagle: http://www.cygwin.com/ml/cygwin/2001-06/msg00537.html. His script will detect a running agent and start one if no running one is found.
Another solution is using Keychain (http://www.funtoo.org/wiki/Keychain) which is a frontend for ssh-agent and ssh-add. I personally have no experience yet with Keychain, as Ubuntu has made me a little spoiled and lazy in this area. However, I’ve read a lot of good things about Keychain and I know several people that use it.
Final notes
The recipe is there, for an easier and more secure SSH-life. Which solution suits your needs, however, is up to you. Do you always leave your terminal open? Then I wouldn’t bother too much with adding a script to your bash login, but just run the commands once when you start the terminal. Closing and openings tabs, new terminals, etc.? Then I would definitely recommend either one of the two linked solutions.
Happy SSH-ing!
Related Posts:
- How to Rapidly Install Java, OpenJDK & Oracle JDK on your VPS - December 14, 2015
- It’s been a great ride - December 14, 2015
- Cheap Windows VPS – $21/quarter 1GB KVM-based Windows VPS in 11 worldwide locations - November 30, 2015
All good in the client side.
But how about the server.
“Now try to log in to a server where you’ve added the public key to” <– How?
Thanks for the first part tho, very good explanation.
And by how i mean how do we add our public key to the server.
It is quite easy for me to generate strong but easy to remember password:
1) pick two or three UNRELATED words, they can be your favorite childhood comic character, a brand of your shoe/watch/laptop, plus one word which is not english or your native language. Two or three words should be more than eight to ten characters easy.
2) change all vowels into numbers, like kiddie text
3) If you must use number like birthdate or such, look at the characters on top of your number key, starting from the tilde (~) to =… use them instead of number, so if I mean to type 12345, I type them as !@#$% instead..
Example: sp1d3rm4nT0y0t484j4j!!@@## (spiderman, toyota, bajaj, 112233) now try to crack that lol
This is a very good article on SSH login without password. Here is another one that worked for me when I first started doing this. It’s very simple, concise and easy to understand. http://tinyurl.com/m9ztegw