SSH

So if we can't use telnet to remotely connect between one machine and another, what can we use?

Well, it's an application called Secure Shell and secure shell is certainly the recommended way of connecting Linux machines and it can do more than a telnet session. A telnet session is just a login but secure shell is a, as the name implies, a shell - so it can do a login for us.

The original version was Secure Shell 1 but we are going to be talking about Secure Shell 2. It is provided by a package called OpenSSH.

There is another tool called "scp", which is secure copy, the same as the copy command except you copy securely across the network.

You've also got SFTP, which is Secure Ftp Session, and what that does is it secures ftp transfers from one machine's data file, from one machine to another.

So secure shell is more than just a login program, it's a copy program, an ftp program and it can do some other things as well.

Public and Private Key Infrastructure

Let us review the public and private key infrastructure, which we did look at earlier when we were talking about GPG.

Do not become confused between GPG and SSH:

GPG uses public and private key to encrypt and sign email's. SSH uses public and private keys to verify who you are.

Essentially the purpose is similar but these two are not the same.

Connecting to a remote machine and signing an email is very different processes. Secure Shell needs a public and private key pair just as GPG does.

Now in terms of secure shell and public and private key infrastructure, similar as GPG, you have things like RSA and DSA encryption algorithms. And RSA seems to be the favored option for creating key pairs. You also need a length of a key. So for example the length of the key could be 1024 bits. What this creates for us is a public key, which we can exchange with any other systems. And a private key that would remain private on our machine under all circumstances, you should not share it.

And in order to create the key pair we needed to supply a pass phrase.

So understanding the facts that we have a public key that we can share and a private key that we keep private at all costs and use as needed. And really what is happening at the OS level is that on our machine we have our private key and on the remote machine we have our public and we encrypt with our private key, which can only be decrypted with our public key. Now you will recall with GPG we could encrypt and sign, here there is no real signing involved, here it is more focused on encrypting the data we send and receive over the network.

Sample Session for Generating a key

The first thing we need to do is to create our public private key pairs using an application called ssh-keygen.

"ssh-keygen" takes a number of parameters so you need to, at this stage, log-in as an user.

Once logged in, issue the ssh-keygen command as expressed below:

1.Using the"-t" option generate a RSA key.

2.How big is my key going to be? 1024 bits it asks if we generate the key (thus the command is ssh-keygen -t rsa -b 1024).

3.Now it needs to save this key somewhere and by default it's going to save the key in "/home/riaan/.ssh/" called id_rsa.pub . (In fact it will save your public key as that and your private key will just be saved as id_rsa.)

4.So once we've run the ssh-keygen command, we then enter a pass phrase note that the same philosophy is applied to entering pass phrases as with gpg.

riaan@debian:~> ssh-keygen -t rsa -b 1024
Generating public/private rsa key pair.
Enter file in which to save the key (/home/riaan/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/riaan/.ssh/id_rsa.
Your public key has been saved in /home/riaan/.ssh/id_rsa.pub.
The key fingerprint is:
15:9e:85:1d:fc:23:2c:ed:81:8c:d3:5a:94:21:93:19 riaan@linux
riaan@debian:~>
                

Once the pass phrase is generated or entered, ssh-keygen returns a "fingerprint" of this particular key.

As an example to demonstrate the usefulness of the key just generated, let us take a scenario with two machines - machine A and machine B.

We want to be able to log-in from machine A to machine B. On machine A we've created a public private key pair and we're going to put our public key on machine B (remote) so that machine B can authenticate who we are.

As part of this authentication, machine B would need to be able to encrypt data flowing between one and the other machine. If it was just a matter of connecting and we weren't worried about encrypting passwords or encrypting usernames or whatever, we would just use telnet to connect between one and the other.

Sample Session for Accepting a fingerprint

Assuming that you want to connect on a regular basis to machine B and assuming that you are the system administrator on machine A, you send your public key via email to the administrator of workstation B.

Now workstation B is going to get that key and it's going to add the key to their authorized_keys.

Administrator B will create a user on their machine for you to use, and will add your public key to the authorized key of that user.

For our purposes we create a user for Riaan on workstation B called "riaanbre", Riaan generates his public private key pair on workstation A. He then sends me his public key.

Sample Session for Verifying a fingerprint

Once Riaan's key is in his home directory, the System administrator for workstation B would run the command:

ssh-keygen -l -f
                

-l would display the fingerprint of the encrypted key

-f would give it a file

Riaan puts his key in the /home/ directory for the user called "riaanbre" on workstation B we could then could test it against Riaan.key.pub (in this case this is the name of the file that Riaan sent to the administrator of machine B).

Once the administrator at workstation B has verified Riaan's fingerprint, he adds Riaan's fingerprint (key) to a file called /home/riaan/.ssh/authorized_keys.

Once Riaan's key is an authorized key he should be able to secure shell into machine B by using:

ssh -l riaanbre 192.168.1.144 
                

or he could have said

ssh riaanbre@192.168.1.144 
                

That would then prompt him for a password. Before he gets that password, it would send him a fingerprint of the host he's connecting to.

Now, why would the host send a fingerprint?

Primarily because if workstation B was masquerading or if there was another work station, call it workstation 5, masquerading as workstation B, then when Riaan tries to connect to workstation B, he's actually connecting to the private machine.

In this case the fingerprint of the host is used to check that Riaan is not connecting to the masquerading workstation(s) but actually to the correct workstation.

How do you check that this is the workstation that you are expecting to connect to?

Well, in the directory /etc/ssh/ssh_host_rsa or dsa (as the case may be) key.pub is the public key for that host. The way we test our public key is by using the command "ssh-keygen -l -f":

riaan@linux:/etc/ssh> ssh-keygen -l -f ssh_host_rsa_key.pub
1024 d7:aa:e9:09:1c:eb:f6:04:f7:15:ef:fa:8d:b8:f9:70 ssh_host_rsa_key.pub
riaan@linux:/etc/ssh>
                

The system administrator of workstation B has verified with Riaan that the fingerprint that he's receiving when he's trying to connect to workstation B is actually the fingerprint of workstation B. Riaan can then accept it with a yes at that point.

riaan@debian:~> ssh 192.168.10.144
The authenticity of host '192.168.10.144 (192.168.10.144)' can't be established.
RSA key fingerprint is f6:11:d9:54:32:37:18:e1:f4:5b:4a:06:37:1e:98:68.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.10.144' (RSA) to the list of known hosts.
riaan@192.168.10.144's pass phrase
                

Riaan accepted the fingerprint for the host, workstation B, it's now added to his main known hosts lists so it won't ask him again whether this is in fact the fingerprint for his host because it will have it recorded.

It now asks him to enter a pass phrase and this pass phrase is not the login password, this is his pass phrase that he entered when he created the key with the initial "ssh-keygen -t rsa -b 1024".

So Riaan is now able to log in, using his pass phrase, to the remote machine workstation B. Even though he's got a password on workstation B, he's not using that password, and this is quite important, because an encrypted password of his pass phrase is the thing that's passed across the network, not the unencrypted password on workstation B.

When Riaan accepted workstation B's fingerprint it was added to a file in Riaan's home directory, so that would be home/riaan/.ssh/ to a file called known_hosts and Riaan could quite easily go and delete that host out of there so that the next time he connected to workstation B, it will again ask him, "Is this the correct fingerprint"?

Why would you want to do that? Well, perhaps the machine has changed, perhaps there's a new administrator, who knows why, perhaps the administrator of workstation B re-created his host key.

The known_host is just a public file because all it obtains are a whole bunch of public keys for the host that you are connected to.

As part of this process, you will have seen that Riaan's public key travels from workstation A to workstation B and it got assigned to his .ssh in his home directory.

The question is, why would you want to exchange keys? Because ultimately you still have to type in a password. Well, the reason that you're exchanging keys is that you know, from workstation A, Riaan can type his pass phrase rather than his password on workstation B, and that ensures that all transactions are encrypted including the username and the password.

And how does he pass his public key around to the various machines? Well, he can ftp it or he can secure key copy it or he can send it via email.

You can copy it in a number of ways, remember it's a public key so it's not that critical if other people get hold of his public key as there's not much they can do with it.

Let's assume that Riaan's having to open a number of sessions over and over again. Well, he's going to get pretty hacked-off at having to continually type his pass phrase every time he opens a new session between workstation A and workstation B.

So he decides to use a tool called ssh agent and ssh agent's job is to keep track of the public keys that are being used in connecting to hosts.

Essentially, what happens is when Riaan, on workstation A, needs to connect to workstation B, the ssh agent will verify that this key does come from Riaan. In other words, the ssh agent's responsibility is to handle the key. The first time Riaan connects between workstation A and workstation B, he gets prompted for his pass phrase.

Once he's given his pass phrase he can then add the fact that he has been granted access and the ssh agent's job for that session is to remember the key.

He then starts off a second ssh and what happens? Well the ssh agent responds with the verification on the key and so he can connect to workstation B as many time as he wants without being asked to enter his pass phrase.

There is a catch - the catch is, is that any session, any secure shell session has to be started off of the sibling of the ssh agent. So if you started a terminal and we ssh'ed into workstation B, you then did a sshadd to add the public key to the agent, then you started a new terminal session and you ssh'd into workstation B, it would again ask you for a pass phrase.

Sample Session Using ssh agent

The first thing Riaan has to run is "exec ssh-agent /bin/bash" and what that does is replace the current shell with "ssh-agent" which starts a new shell. At this point Riaan needs to use "ssh-add" to add his public key to the agent.( read the man page for ssh-add to learn how this is done)

Once Riaan has done an ssh-add, he's asked for his pass phrase and the pass phrase that it's asking for there is the pass phrase that Riaan supplied when the private and public key pair was created.

Riaan added his public key to the agent and when he tries to secure shell into workstation B, it didn't ask him for his pass phrase. Why? Because when he added the user to the ssh-agent, at that point it's asking for his pass phrase. (If he tried to open a different terminal it would again ask him for his pass phrase because that new terminalouldn't be a sibling of the ssh-agent that we started earlier.)

If you administrate a good number of machines you would not want to type a password every time you connected to one of these machines. To get around this create an account and a public private key pair but instead of entering a pass-phrase, enter no pass phrase at all. Not entering a pass-phrase is the equivalent of secure shelling without a password.

The downside of this is that if control is lost of the administrators' workstation, whoever gets hold of this workstation has then got access to the other workstations on the network.

Sample Session to destroy your public/private key pair

This time you're going to destroy your public private key pair using the "ssh-keygen -t rsa -b 1024" command. When asked for a pass phrase hit enter.

It will probably say something like I'm going to over write the current RSA public private key pair and you say Yes - you do want to over write them.

When it asks for a pass phrase hit enter, in other works you don't give it any pass phrase at all and it will create a public private key pair - id_rsa and id_rsa.pub.

It will also produce a fingerprint.

riaan@linux:~/.ssh> ssh-keygen -t rsa -b 1024
Generating public/private rsa key pair.
Enter file in which to save the key (/home/riaan/.ssh/id_rsa):
/home/riaan/.ssh/id_rsa already exists.
Overwrite (y/n)? y
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/riaan/.ssh/id_rsa.
Your public key has been saved in /home/riaan/.ssh/id_rsa.pub.
The key fingerprint is:
4d:86:ee:58:66:71:c1:65:01:98:14:46:92:82:7d:d8 riaan@linux
                

At this point you need to copy this to workstation B and over write your authorized key, or you append it to your authorized key file. Log out of workstation B.

At that point you should be able to secure shell from workstation A to workstation B, as a user without a password.

Now you can run remote commands such as:

ssh riaan@192.168.1.114 (or whatever your second machine's IP address is) uptime

and this runs the "uptime" command on the remote machine and returns the output to the local screen, without having to log in to the remote machine. This pretty much gives you full control on the remote machine.

So we've been able to verify the fingerprint of the host we are connecting to, we've been able to generate public private key pairs in order to authenticate who we are and where we're coming from, and we've been able to generate entry pass phrase public private keys which allowed us to log in automatically without entering a password from one host to another.

The secure set of utilities, Secure Shell, Secure FTP will now use the public private key sets in order to encrypt and decrypt traffic flowing between the two.

Of course, we've gone through a whole wad of effort there to exchange key pairs but in fact if you were to log in as root from workstation A to workstation B, it would still encrypt the whole conversation. You would be encrypting using the password from workstation B rather than the pass phrase from workstation A.