Throwing Away Your Password to Enable Secure Logins on Remote Hosts.
We thought we would clarify the process by which someone creates a SSH key pair in order to securely connect to one or more remote hosts.
This method alleviates and obviates the need for you to login using your password in combination with your username on a remote host, but more importantly, it secures that connection because afterward, you should disable the ability to login with a password for the given account...
We also advocate the use of non-standard ports when using ssh, and disabling root logons in SSH as well. Once you have logged in, you can simply 'su -' to root. Yes, root should not be able to login remotely either to ensure the most secure scenario, but as with anything, the policy is determined and you work within those parameters.
FOR THE IMPATIENT: If you're in a hurry, and just want to do this real quick, we've got you covered. Simply scroll down to the end of the article where it says: ### FOR THE IMPATIENT ###
Another firm recommendation we advocate is that you always create your key/pairs with a passphrase. ssh-agent will take care of the rest, since you will only have to enter your passphrase once during each login.
That way, if someone else manages to obtain possession of your private key, it is useless to them (Repeat this sentence again until it sinks in). Remember, ssh-agent will ensure that you don't have to enter your passphrase each time you ssh into another box.
Our hypothetical user's name is joeuser. His local workstation's hostname is localbox. the remote machine we will install the public RSA key on is remotebox.sld.tld.
First, joeuser logs on to localbox, and then he creates the RSA key/pair:
|joeuser@localbox:~$ ssh-keygen -b 2048 -t rsa|
Here's the breakdown of the command:
-b sets the length of the keys to 2048 bits.
-t indicates to use the RSA hashing algorithm.
Remember to create your passphrase. If you insist on having an empty passphrase, then you can use something similar to the following when creating your keys or just hit enter when asked to provide one using the command above:
|$ ssh-keygen -b 1024 -t dsa -f id_dsa -P ''|
Note that in the second example, we chose to create DSA keys, while in the first example, we created RSA keys for SSH protocol version 2.
In this second example, the -b option sets the length of the keys to 1024 bits.
-t indicates to use the DSA hashing algorithm.
-f sets the file name as id_dsa.
-P '' sets the private key password to be null.
The null private key password allows for automated SSH connections. Use this in scripts so that hosts may affect connections to other hosts. We've already recommended that you don't have a blank passphrase, but if you want to know more about why, we'll just get all Socratic on you and ask, "Do you know who root is (or how many of them there are?) on your box?"
And now you want to ask the question, "Should I use RSA keys or DSA keys?"
And the answer is, that the question itself is beyond the scope of this tutorial. They're both good, and they both work. We recommend you google for more information so you can arrive at your own informed decision, since there are so many different opinions on the subject.
Moving on now, we're going to put the public key on the remote box. Things are about to get fun....
|joeuser@localbox:~$ ssh-copy-id remotebox.sld.tld|
You'll be asked for your password, logged in, then logged out. All in about one second, and you're done.
|joeuser@localbox:~$ ssh remotebox.sld.tld|
This time you'll be asked for your passphrase. And you're in!
A word about passphrases. they're kind of like passwords, but they can be an arbitrary length string consisting of white space. Without going into detail, the following might be a example of a good passphrase, although you could be stupid and use the name of your pet.
f0r It w4s 3n0uGh n0t tw0 34t whUt u DiD n0t lYk3, bu77 h33 wh00 r3fl3cts 0n 4n0th3R m4N$ w4n7 0f bR33ding sh3ws h33 w4nt$ i7 4s muCh, hIm$3lF..!!..#@&
You might consider that like hunting squirrels with a twelve gauge - or not. We'll leave it up to you to determine what's best in your hostile environment, but consider the following:
Wait!!! Remember when we said we recommend using non-standard ports when connecting via SSH? Yes you do. The previous command will not work in this case, so we need to either do it that way, then configure SSHD on the remote host to listen on a different port afterwards, or more likely, just perform the following instead (Where the non-standard port number in this example is 2222):
joeuser@localbox:~$ ssh remotebox.sld.tld -p2222
joeuser@remotebox:~$ mkdir -p .ssh
joeuser@localbox:~$ cd .ssh
joeuser@localbox:~/.ssh$ scp -P2222 id_rsa.pub email@example.com:.ssh/authorized_keys
You'll be asked for your password this one time, the id_rsa.pub will be copied over to ~/.ssh/authorized_keys on the host, and it will exit. Then you simply:
|joeuser@localbox:~$ ssh remotebox.sld.tld -p2222|
You'll be asked to enter your passphrase if you have one (One time if you're running stock Slackware, since ssh-agent will remember it). After that, you won't be asked anything - you'll just be logged in!
At the very beginning of the article, we provided you with the command line to create your RSA keys with a length of 2048 bits using the -b option. had you not done this, it would have defaulted to creating a key of 768 bits. If you opted to use a DSA key it must be 1024bits long.
If you forget your passphrase, you are screwed, unless you have a supercomputer and you won't be needing to use your key again until your grandchildren are ready to retire. So if you followed the example above and made yourself a totally wacky passphrase, and realize you really didn't want to do that, it's a simple matter to change your passphrase at any time by running ssh-keygen again with the -p option. ;)
We now turn our attention to SSHD itself. Bear in mind that you can affect some, all, or none of the changes we're about to show you. The most important factor is to determine what level of security you are going to require.
We are going to configure SSHD to act in the following manner:
1.) No remote root logons
2.) No remote logins will be permitted via simple password authentication.
3.) Allow remote logins only from "specific" users.
4.) Listen on TCP port number 61329 for incoming connections instead of the default (TCP port 22).
This will require that you have already installed your RSA or DSA public key onto the machine, since you won't be able to login to the machine using a password anymore. It will also require you to 'su -' to root, since root will not be allowed to logon remotely via SSH anymore. Here we go.
Fire up pico, vim, or vi and edit your sshd_config file
joeuser@remotebox:~$ su -
root@remotebox:~# vim /etc/ssh/sshd_config
find the line below, uncomment it (That means remove the octothorpe, more commonly referred to as the "#" sign), and change "yes" to "no".
Now locate and do the same for the following line (uncomment and change "yes" to "no")
You may also want to only allow certain users to login too. Say, Joe Montana and Mary Contrary and Herman Munster. If so, Add the following line to the end of sshd_config (with the usernames that correspond to the users you want to allow access to):
AllowUsers joeuser mary hmunster
The last item we're going to address in your sshd_config file is the port number that SSHD listens on for incoming connections. In the example below, as stated above, we're going to configure SSHD to listen on TCP port number 61329.
With consideration to any rules you may need to adjust on firewalls between your workstation and the remote host, you can generally choose any number between 1024 and 65535 (and we recommend that you do).
Locate the following line, uncomment it (the octothorpe, remember?) and change "22" to "61329".
X11 and TCP forwarding are disabled by default in Slackware Linux - that's a good thing, unless you need it. So we wont' address it in this article. Not running Slackware? Well then it sucks to be you.
There are a myriad of other options for you to consider as well. For example, by default, SSHD is configured to listen on all of your IPv4 and IPv6 addresses, while you may want to specify just one specific IP Address. The man pages and /usr/doc/openssh*/ (/usr/doc/openssh-5.5p1 at the time of this writing) have a wealth of information in this regard - we'll leave that for you to investigate on your own.
Are you ready? Did you create your RSA key, copy it over to the remote host, disable remote root access, password authentication in ssh, and add your username to the list of those permitted to gain access via ssh?
Good. Let's restart sshd:
|root@remotebox:~# vim /etc/rc.d/rc.sshd restart|
At this point, you're all done. Let's wrap things up with a discussion about security, and how to add and/or remove the keys you keep in your home directory for remote machines you've logged into at least once.
Here are some things you're invariably going to run across later. We want you to be prepared...
If you log onto a host, and the remote server's key has changed, you're going to get a scary notification. If you [wisely] chose Slackware as your Linux distro, then you won't even be able to complete the login - that's a good thing too!
Now, it may be because the machine was rooted by some "evil-doer". Or if the remote machine isn't pwn3d by a h4x0rb0i, then perhaps the administrators created a new box, restored everyone's home directories, and you need to replace the key you have for that machine. There are many reasons why this may occur - the important thing is that you are prevented from logging into the remote host until you ascertain exactly why.
You will be presented with the offending line number to delete if you want to go ahead and just let the new server key get installed on your system, and you can simply open Vim and remove that line from your ~/.ssh/known_hosts file - but it looks a little scary to most people, and we have a simple one-liner for you to make things easy.
First, it needs to be determined how you refer to the remote host when you ssh into that box. Do you refer to it by its IP address, by a simple hostname, or by it's FQDN?
The way you refer to the host is the way you need to refer to it when you delete its key from your ~/.ssh/known_hosts file.
Next, merely invoke the following command. We'll provide you with a few examples so you get the idea:
If DNS or /etc/hosts isn't being used, then this first example using only IP addresses might be best for you:
|joeuser@localbox:~$ ssh-keygen -R ip-address|
If you have an entry in your /etc/hosts for the remote machine (This method is commonly used on a LAN):
|joeuser@localbox:~$ ssh-keygen -R hostname|
|joeuser@localbox:~$ ssh-keygen -R remotebox.sld.tld|
This third example is probably the most common.
If you want to remove the key manually using vim or vi, then simply:
|joeuser@localbox:~$ vim .ssh/known_hosts|
nnG" (where "nn" is the offending line number you were informed of regarding the offending key) and then "
dd" followed by "
If pico is your editor of choice, then:
|joeuser@localbox:~$ pico +nn .ssh/known_hosts|
y", and then hit enter/return. Simple. Done. The nano editor is a clone of pico, and works in an identical manner, BTW. In the example above, "
nn" refers once again to the line number you want to be at in your editor.
Last but not least. One question we constantly get from users is, "But my username on my own workstation is different from most of the remote hosts that I need to log into. So do I need to create different keys, local users that match those names, or what?"
We have an answer for you, and it's much easier than you might have imagined.
Let's say that, once again, you are joeuser on your local machine. You've just created your RSA or DSA key/pair and installed it on a couple of remote machines, some with SSH on port 22, and some running SSHD running on bizarre port numbers.
Let's say the username on the remote machine is "mary". All you do is:
|joeuser@localbox:~$ ssh-copy-id firstname.lastname@example.org|
Same for root - if you haven't disabled remote logins from root.
|joeuser@localbox:~$ ssh-copy-id email@example.com|
Although like we said above, we recommend you disable remote root logins.
And that's it. There's no need to read any further, you've done everything and now it's time to enjoy the fruits of your labor. We hope this has helped you out.
### FOR THE IMPATIENT ###
um... yeah... Let's recap the whole process for the impatient - as we promised we would do, at the beginning of this article:
1.) create the 768 bit RSA key for SSH protocol version 2:
|joeuser@localbox:~$ ssh-keygen -t rsa|
Just hit enter when prompted to create your passphrase. A blank passphrase is easier.
2.) copy your id_rsa.pub public key to the remote host:
|joeuser@localbox:~$ ssh-copy-id remotebox.sld.tld|
You'll be asked for your password, logged on, then off, all in the blink of an eye.
3.) now login to the remote host:
|joeuser@localbox:~$ ssh remotebox.sld.tld|
You're in. And, congrats, you're a bonehead too - now go and read the whole article and find out why.