If you are doing administrative tasks on a regular basis and you have access to more than one host you might know that it doesn’t always work easily.
Ssh is the de facto way of accessing remote hosts securely. You can set up ssh for the usage of passwords but this isn’t the preferrable way. Using passwords has its weaknesses but much more important it is less comfortable to work with. There are a lot of documents on the net describing how to use ssh keys to communicate with your hosts. Basically it is invoking ssh-keygen on the commandline and copying the .pub file to the remote host.
On the remote host you put the .pub file in a file called authorized_keysin a directory .ssh below the users home directory. If the permsisions are set up correctly you are done.
Usually you protect you ssh keys with passphrase (you are asked by ssh-keygen). Until now there is no benefit you just exchanged using a password with the usage of a passphrase. There is a little programm called ssh-agent that you can run on your machine. It inquires the passphrase for a key once and then it stores the unlocked key in memory for further use. Just invoke
and after entering the passphrase it is there. You can check this by invoking ssh-add -l which lists the stored keys. Now you can connect to the remote host and you are not asked for the passphrase a second time. This works even from different terminal windows.
Using ssh-agent can do more for you. Imagine you have two hosts which both have your public key installed. If you are connected to host1 you can connect from there to host2 and if everything is set up well than you are just logged in. How? There is a thing called agent forwarding. If you log in to another host via ssh your remote environment is prepared with some variables that ssh can use. One of these is the SSH_AUTH_SOCK. Let’s say it is some kind of access handle to the existing ssh connection. If you are invoking ssh host2 than the command tries to do key negotiation. As soon as the ssh command sees the SSH_AUTH_SOCKit asks there about a valid key, too. We could say that host2 asks at login time for a valid key. As we are connected from host1 this host gets the request. Host1 detects the SSH_AUTH_SOCK and routes the request long this route. So the request for the key reaches our machine from where we connected host1.
There is no real limit on the chain length. If you would try to connect from host2 to host3 than it would also work. The only thing that is needed is that all of the participating ssh daemons do not forbid agent forwarding. If it doesn’t work at first then try to add the commandline option -A to your ssh calls. This tries to enable agent forwarding but in most of the standard configuration it is allowed.
If you want to copy files from host1 to host2 instead of just logging in the utility rsync comes to the rescue. Rsync utilizes ssh to enable to connection. It then has the ability to copy a complete directory in a 1:1 fashion. If the agent forwarding is set up using rsync ist not more than logging into host1 and do something like:
user@host1> rsync -av /my/special/directory/ host2:/some/directory/
It just works because rsync is using ssh by default and ssh will use agent forwarding if applicable.
copying protected things
But what do you do if you like to copy stuff that only root is allowed to access? The SSH_AUTH_SOCK only works in the environment of the user being logged in. It is likely that you will use sudo in order to access the files with root permission. But then you get a new environment and your SSH_AUTH_SOCKis gone. Well, then we need to copy this information to the root account you would say? Right! The only thing we need to do is
sudo env SSH_AUTH_SOCK=$SSH_AUTH_SOCK rsync -av /protected/directory/ host2:/some/directory/
This commandline switches the user to root. Then it invokes the env command which alters the environement of the root shell. The information SSH_AUTH_SOCK is evaluated before the sudo is started so the information is already exchanged with the real value. After this the rsync command is invoked in the shell (now with root permission). Rsync will use the ssh command to connect to the other host. Ssh will look if an SSH_AUTH_SOCK exists. It will then use the users ssh connection to request the valid ssh key. On the client side your cached ssh-agent key will be treated and the login will succeed and the files are copied. You can enable this behaviour to work automatically for every sudo user. You just need to configure sudo via the visudo command and add a
lineDefaults env_keep += "SSH_AUTH_SOCK"
anywhere. If there is a
than you should put the new line after this.This whole scenario you can build up much more complex by using tunnels and paket forwarding. But for now it is enough to digest I think.