SSH basics
Using ssh and its functionality should be a second nature to all Linux sysadmins, for some users some aspects of ssh are still a mystery, so let's shed some light on it. Here you will not learn basics shell commands and usage, I will simply try to explain usage of ssh protocol itself, and it benefits. How to use ssh, how to setup keys, how to use ssh agent that will enable some extra functionality for programs like scp, rsync, etc.
First of all what is ssh?
SSH is client-server secure shell network protocol usually used for remote host or network device administration. Other than that it allows secure tunneling, TCP port and X11 forwarding, file transfers.
For now, let's stick to remote host administration. I'll be focusing on ssh client rather than configuring ssh server, suffice to say ssh server is a daemon, by default running on remote host and listening on tcp port 22.
SSH client is a program used to connect to sshd on remote host.
Simple usage would be:
bash# ssh username@hostname
If you're contacting remote hostname for the first time it will ask you to review and save remote host's fingerprint. It will be used in future connections to determine host's authenticity. If for some reason remote host changes its IP, hardware, location, key... you will be warned and denied access to remote host because it might be fraud, or some kind of man in the middle attack.
If you are sure that fingerprint change is valid you will have to remove previously learned fingerprint and save a new one.
If for some reason remote sshd is not listening on TCP port 22 you should give additional -p option to ssh client like this:
bash# ssh -p 2210 username@hostname
this way you will instruct your ssh client to connect to remote TCP port 2210.
By default sshd has the password authentication enabled so using examples above will prompt you for remote user's password. Sometimes you will find remote hosts have the password authentication disabled for security reasons. To "circumvent" this restriction ssh has an ability to authenticate with pre-generated keys.
How to generate ssh keys?
Note: if you are using some old Debian or Ubuntu distribution, before generating keypair verify that you have patched your libssl as noted here: http://www.ubuntu.com/usn/usn-612-1
To enable key authentication we must generate a new key pair. By default command:
bash# ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. The key fingerprint is: 28:ce:58:0a:61:7b:b4:d6:7b:b2:e0:11:9e:d9:b2:77 root@branko.toic.org
will generate new default 2048bit rsa key, it will prompt you to enter a path where key will be saved and enter a passphrase. I strongly recommend that you use strong password on your key. I
If you saved your key in default location (~/.ssh/id_rsa or ~/.ssh/id_dsa) when contacting remote host ssh agent will try to use your key file as first method of authentication even if password auth is enabled on remote server. If you have saved your key file on some other location you will have to supply your ssh client with additional -i parameter followed by your private key location (later on you will learn how to overcome this parameter so don't panic just yet):
How this thing works anyway?
For now all we have is two keys generated. I will asume you have used default rsa key in default location ~/.ssh/id_rsa if you have made it somewhat different you will have to edit your commands accordingly.
You should by now have your keypair located at ~/.ssh/id_rsa and ~/.ssh/id_rsa.pub first key (id_rsa) is your private key that you shouldn't distribute around, second key (id_rsa.pub) is public key which you will set up on remote hosts as authorized key for certain user(s).
When connecting to remote host it will try to locate ~/.ssh/authorized_keys and ~/.ssh/authorized_keys2 files for that user to which you are connecting. If one of those file have your public key (content of your id_rsa.pub) that is matching your private key you will be authenticated and will be allowed to login, if not ssh will try other means of authentication such as password based if enabled by the server.
Distributing your public key
You now have to distribute content of id_rsa.pub to authorized_keys file on remote servers for each user name that we will use. To do so you must upload your id_rsa.pub file to remote server (upload it to your home directory for now) and issue command:
bash# cat ~/id_rsa.pub >> ~/.ssh/authorized_keys
This way we will append our key to authorized keys for that user.
If you yet have no means to connect via ssh to remote host because password auth is disabled when uploading make sure remote filename will be called authorized_keys. This way we will have content of our public key in authorized keys and will enable us to connect to remote host.
Caution: If authorized_keys file already exists on remote server, uploading our id_rsa.pub file over it will disable all other authorized keys, try other means of adding content of your id_rsa.pub to authorized_keys
Connecting to remote hosts
Now we can connect to remote host with same commands as before:
bash# ssh root@branko.toic.org Enter passphrase for key '/home/branko/.ssh/id_rsa':
Here you will enter passphrase defined when we were creating keyfile.
Note: to change passphrase for current private key use command:
bash# ssh-keygen -f [private key location] -p
Now you maybe wondering how is this any different from password authentication? For one you can now distribute your public key file to any number of hosts and use single private key file to contact all off those hosts. You can even use same private key on more than one workstation so it's not needed to recreate steps above for each workstation. Other than that, it will reduce possibility of remote password brute force attacks on your servers, enables you to use applications that use your key files for contacting remote hosts like scp, rsync, etc.
Besides that, using ssh keys enables you some more functionality by using ssh-agent
Ssh-agent? What is that?
Ssh agent is simple shell tool that comes bundled with ssh client. It enables you to "put your keyfile and your passphrase in its hands".
Sounds awfully! Now why would I do that?
Consider this situation, you are working on dedicated workstation and you have 8h work time. In that period you will be contacting multiple remote hosts on multiple occasions. Entering passphrase one time after another may be acceptable at first, but later it becomes waste of time.
Ssh-agent allows you to unlock you private key so you won't be prompted for your passphrase each time you try to connect to remote host.
Also it allows you to add multiple private keys so you can us them all when connecting to remote hosts, if you have created keyfile that isn't in its default location, adding it to ssh-agent will not require you enter additional -i parameter to ssh client.
After finishing with your work you can simply remove your key from agent, and it will again prompt you for your passphrase when trying to connect to remote host.
Note: for Gnome or KDE users (or any DE for that matter) ssh-agent is integrated within DE keyring for the duration of your session
How do I use this ssh-agent?
First of all we need to start the ssh agent. One would say easy way of doing it is typing ssh-agent to terminal, that may be true but it will require you to set extra environment variables afterwards. Trying to run ssh-agent will start the process and output those variables, so even easiest way of doing it is to invoke ssh agent command with eval:
bash# eval 'ssh-agent'
that way we will have ssh agent and variables set at once.
Note: ssh-agent supports key lifetime, you can limit the time key can be in ssh agent by adding -t parameter followed by number of seconds or in other time format specified in sshd_config.
Now when the agent is running all we need to do is add our keyfile to agent with:
bash# ssh-add
It will then add your default private key located in ~/.ssh/id_rsa or id_dsa to agent. It will ask you for it's passphrase only this time. If you wish to add another private key from different location you should use:
bash# ssh-add [location to private key] **Note:** adding **-t** parameter followed by lifetime in seconds will overwrite ssh-agents **-t** parameter.
To remove private key from ssh agent simply type:
bash# ssh-add -d
again this will only remove default key if you have additional key inserted you should use:
bash# ssh-add -d [location to private key]
to remove all private keys from ssh-agent simply type:
bash# ssh-add -D
Practical use of all above?
Using ssh keys in combination with ssh agent will save you a lot of time. Consider example above when you frequently use ssh client to connect to multiple hosts, this will save you troubles, with password managers, time consuming password finding and retyping etc.