This section discusses several advanced uses of SSH, including agent forwarding, X Window System forwarding, port forwarding, escape sequences, perpetual tunneling with autossh, and storing your SSH private key on a USB drive.
In SSH Authentication, we presented a way to configure SSH such that you would only have to enter your private key's passphrase once per user session. This works great until you need to connect to a third host from the second one. At first glance, the fix for this issue would be to copy your private key to all machines you would ever want to ssh from. This is not only suboptimal, it is also a huge security risk, especially if you do not necessarily trust the intermediary hosts. Hopefully, this is something that is already being addressed by most current SSH implementations. In fact, what you need is a mechanism that retains in memory a decrypted copy of the private key on all hosts you SSH to, such as shown in Figure 15-6.
Keep in mind that your private key is held and decrypted in memory on the remote host. In other words, there is a nonnegligible risk that a local administrator or malicious software running with administrative privileges could read your decrypted private key from memory.
In order to configure agent forwarding, you should enable it in the ssh_config file by adding the following:
[root@simca-1000 ˜]#cat >> /etc/ssh/ssh_config
ForwardAgent yes
^D
SSH is the de facto standard remote shell application as flexible as it is secure. But, what if you want to remotely open a graphical session? You would need some sort of VPN. Fortunately SSH provides this feature. On the client side, you can designate a local TCP port that is connected to a remote port and vice versa; e.g., a remote port could be connected to your local machine, as shown in Figure 15-7.
Configuring port forwarding can be somewhat confusing; here is a quick overview that corresponds to the example shown in Figure 15-7:
[emoret@simca-1000 ˜]$ ssh renault-4l -L 5900:127.0.0.1:5901
Last login: Thu Sep 14 18:12:27 2006 from simca-1000.sabre.juniper.net
[emoret@renault-4l ˜]$
The -L
option stands for Local to remote forwarding as opposed to -R
, which stands for Remote to local forwarding.
The first port number, 5900, is the TCP port opened locally—in this case, on simca-1000.
The last port number, 5901, is the TCP port that opens a TCP session on the remote machine.
The IP address between those two port numbers identifies the host to which the remote SSH server connects; in our example, it is 127.0.0.1 (the loopback interface) because this is where the remote VNC server runs.
Once our SSH session has started, we should use a VNC client on simca-1000 and open a session to the local loopback interface on port 5900, as shown in Figure 15-8.
In another scenario, you can use the SSH server as a gateway for other services, such as Windows Remote Desktop running on a third machine. Assuming your Windows host is at 192.168.1.5 behind renault-4l, the command line would look like the following:
[emoret@simca-1000 ˜]$ ssh renault-4l -L 3389:192.168.1.5:3389
Last login: Thu Sep 14 18:12:27 2006 from simca-1000.sabre.juniper.net
[emoret@renault-4l ˜]$
In this configuration, Windows Remote Desktop Protocol (RDP) is encapsulated within an SSH tunnel between simca-1000 and renault-4l and would go directly on the wire unencrypted by SSH between renault-4l and the Windows host.
SSH does not natively forward UDP traffic. If this is something you want to achieve, you should investigate running PPP over SSH.
One notable exception to SSH not forwarding UDP is the built-in X11 forwarding capability.
SSH implements the following specific features for X11 forwarding:
Traffic forwarding, by creating a dummy X display number on the remote host that is redirected to your local X11 display.
Xauth magic cookie management, by adding a magic cookie specific to your SSH session to your remote Xauthority file, such as to allow the remote machine to use your local display.
To enable X11 forwarding, just type the following on the client side:
[root@simca-1000 ˜]#cat >> /etc/ssh/ssh_config
ForwardX11 yes
^D
Test it by opening a remote session to your server and launching any graphical application from the remote shell.
If you wish to terminate the interactive shell opened by SSH, notice that any application using X11 or port forwarding blocks the closing of SSH until it is terminated. There is a nice trick that allows for closing the CLI while keeping the remote application opened through the SSH tunnel. When you quit the remote shell, just enter ˜?
to see a list of escape sequences. You get the following list:
# ˜?
Supported escape sequences:
˜. - terminate connection
˜B - send a BREAK to the remote system
˜C - open a command line
˜R - Request rekey (SSH protocol 2 only)
˜^Z - suspend ssh
˜# - list forwarded connections
˜& - background ssh (when waiting for connections to terminate)
˜? - this message
˜˜ - send the escape character by typing it twice
(Note that escapes are only recognized immediately after newline.)
Make sure the sequence is typed on a new line or it will not work. Notice ˜&
, which allows you to close the shell while leaving the SSH tunnel up for any opened applications.
To keep your SSH tunnel up after closing the remote shell, enter ˜&
.
Note that you could have achieved the same using the -f
option, which allows SSH to go into background just before executing a remote command, as shown in the following example:
[emoret@simca-1000 ˜]$ ssh -f renault-4l xterm
[emoret@simca-1000 ˜]$
Another feature is the ability to issue SSH port-forwarding commands in the middle of an SSH session. For example, say you opened a session to renault-4l, and then realized you forgot to issue the port-forwarding command option. You could close the current session and reopen a new one with the right parameter, but a smarter way would be to simply enter the escape sequence ˜C
and issue the port-forwarding directive:
[emoret@simca-1000 ˜]$ssh renault-4l
Last login: Fri Sep 15 15:37:17 2006 from simca-1000.sabre.juniper.net [emoret@renault-4l ˜]$<type ˜C>
ssh>?
Commands: -Lport:host:hostport Request local forward -Rport:host:hostport Request remote forward -KRhostport Cancel remote forward [emoret@renault-4l ˜]$<type ˜C>
ssh>-L5900:localhost:5901
Forwarding port. [emoret@renault-4l ˜]$
If you make extensive use of SSH tunneling capabilities, you may sometimes have to restart the session in case you lose connectivity. This can become annoying at times. A simple approach is to make use of the autossh package. This program establishes an SSH session and monitors its state. If it goes down for any reason, it will cleanly terminate the current session and open a new one. All this is completely transparent to the end user. Here is a quick example:
[emoret@simca-1000 ˜]$ autossh -M 2000 renault-4l
Last login: Fri Sep 15 17:50:33 2006 from simca-1000.sabre.juniper.net
[emoret@renault-4l ˜]$
With these options, autossh will send test data on port 2000 and listen for the same data back on port 2001. If traffic monitoring fails, it will reinitiate an SSH session.
Test it just for fun. Disconnect your network interface and type a command. You should not see anything on the console. Now connect your network cable back and wait a few seconds for autossh to do its job. After a little while, you should see your command executed and the result displayed.
autossh, of course, works only with seamless authentication such as public/private keys and ssh-agent (see SSH Authentication).
If you followed each and every step described in this chapter, you should be fairly secure with your SSH configuration. The one last bit that might leave you uncomfortable is to permanently store your private key on at least one machine. What if that host gets compromised? One way of mitigating the risk is to store your SSH private key on a removable device such as a USB drive. It is in fact really simple to implement.
All you have to do is to point your SSH client to the private key file located on the USB device. You can do so with the following command on Fedora Core 5:
[root@simca-1000 ˜]#cat >> /etc/ssh/ssh_config
IdentifyFile /media/disk/id_dsa
^D