Secure Shell
Secure Shell is a program for logging into and executing commands on a remote machine. It is intended to replace less secure programs such as rlogin, rsh, rcp, and telnet. Its goal is to provide secure encrypted communications between two hosts over an insecure network. X11 connections and arbitrary TCP ports can also be forwarded over the secure channel. Another useful feature is session compression.
Secure Shell protects against:
IP spoofing, where a remote host sends out packets that pretend to come from another trusted host. ssh even protects against a spoofing host on the local network pretending it is your router to the outside.
IP source routing, where a host can pretend that an IP packet comes from another trusted host
DNS spoofing, where an attacker forges name server records
Interception of cleartext passwords and other data by intermediate hosts
Manipulation of data by people in control of intermediate hosts
Attacks based on listening to X authentication data and spoofed connection to the X11 server
The ssh program performs host and user identification using public/private key cryptography. Someone hostile who has taken over the network can force ssh to disconnect, but cannot decrypt or play back the traffic, nor hijack the connection. Additionally, as of the release of the Solaris 9 operating environment, ssh is now an integrated tool.
Given all the above, why aren't more sites using Secure Shell? Perhaps it is just a matter of education. The next few sections should help to rectify the situation. However, due to the large number of things you can do with ssh, this article is not able to explain them all in detail. Examples provided in a later section will demonstrate a few more popular uses.
Secure Shell Configuration Files
Since ssh uses many different configuration files, this can make it seem overly complex. This article does not list all the different files; refer to the man pages for ssh(1) and sshd(1M). Some specific files will be discussed as they are encountered during usage examples in the next section. One file you are sure to encounter on first use of ssh is:
$HOME/.ssh/known_hosts or /etc/ssh_known_hosts
The ssh program automatically maintains a list of all known hosts it has ever been used with. The system administrator can predefine hosts for you in the /etc/ssh_known_hosts file or new hosts will be added to the user's $HOME/.ssh/known_hosts file automatically during use. After using a given host, future invocations check these files for the host. If the host has changed, a warning is provided and password authentication is disabled. This prevents certain types of attacks from being successful.
Secure Shell Examples
The following sections illustrate some popular uses for Secure Shell.
Simple ssh From One Host to Another
This example demonstrates use of ssh for telnet replacement.
$ ssh home1 user1@home1's password: xxxxx Last login: Thu Mar 27 20:57:29 2003 from home2 Sun Microsystems Inc. SunOS 5.9 Generic May 2002 $
Using ssh to Forward the X11 Protocol
This example demonstrates use of ssh to run an X11 based application on a remote host and display the application on the local host's display. This example assumes you are sitting at a system running an X11 server.
$ ssh -f home1 /usr/openwin/bin/xterm user1@home1's password: xxxxx $
The xterm appears. The -f option tells ssh to background itself after prompting for any required authentication information. Note that you might need the -X option if X11 forwarding has not been enabled in the ssh client configuration file. Further, note that X11 forwarding must be enabled in the sshd server configuration file as well. The ssh program takes care of setting up your DISPLAY environment variable appropriately along with configuring appropriate X11 server authorizations on the local hosts.
Identity Key Generation
One of the features of ssh is its ability to utilize public/private key cryptography for both server and user identification. If you have been curious while reading this paper and tried ssh on a system, you have already seen an example of server identification. When an ssh client connects to a server, the server presents its public host key and the client compares it to its own copy stored in the known_hosts file as discussed in the configuration file section. If there is a difference, the user must decide the appropriate action to take. Like hosts, users can have public/private key cryptographic identities. This section discusses the user identification facet of Secure Shell.
$ ssh-keygen -t rsa Enter file in which to save the key(/home/user1/.ssh/id_rsa): Generating public/private rsa key pair. Enter passphrase(empty for no passphrase): xxxxx Enter same passphrase again: xxxxx Your identification has been saved in /home/user1/.ssh/id_rsa. Your public key has been saved in /home/user1/.ssh/id_rsa.pub. The key fingerprint is: md5 1024 d5:87:b0:23:33:ce:71:b3:f0:55:b6:b0:0d:00:77:74 user1@home1
This generates an RSA identity stored in user1's .ssh directory. To use the identity, add the contents of the id_rsa.pub file to the remote host's ~/.ssh/authorized_keys file.
A subsequent ssh to this host will look somewhat different since it will attempt to use the RSA identity rather than the normal user password. You are then prompted for the passphrase as follows:
$ ssh home2 Enter passphrase for key '/home/user1/.ssh/id_rsa': xxxxx Last login: Thu Apr 10 16:01:06 2003 from home1 Sun Microsystems Inc. SunOS 5.9 Generic May 2002 $
Authentication Agents
The above example was fine, but you still need to provide your passphrase rather than your password each time to initiate a connection. Using an ssh authentication agent, you can implement a form of single sign-on and you will not have to provide the passphrase every time you run ssh.
Assuming you have set up RSA identities as shown above, do the following on the client host:
$ eval 'ssh-agent' Agent pid 5737 $
When the ssh agent runs outside the eval, it outputs shell variables for use by future invocations of ssh. Running inside the eval allows the shell variables to take effect on the current shell and future subshells. These shell variables tell the future ssh invocations to utilize this agent. The next step is to add keys for use by this agent.
$ ssh-add Enter passphrase for /home/user1/.ssh/id_rsa: xxxxx Identity added: /home/user1/.ssh/id_rsa(/home/user1/.ssh/id_rsa) $
Now retry an ssh like before:
$ ssh home1 Last login: Thu Apr 10 16:04:27 2003 from home1 Sun Microsystems Inc. SunOS 5.9 Generic May 2002 $
Note that no password or passphrase was required, which provides our single sign-on capability. It is possible to run the agent on a different host than the client host if a more secure system is available, but this is left as an exercise for the reader.
TCP Port Forwarding
Consider the following scenario. You are currently logged into host home1 which does not have internet access. It can, however, access a remote host home2 which, in turn, can access the internet via an http proxy on yet another host http_proxy_host on port 8080. The following ssh command will set up a tunnel to home2, and tell it to port forward a local port from home1 over the tunnel and to the http proxy.
From host home1:
$ ssh -L 8080:http_proxy_host:8080 home2 user1@home2's password: xxxxx $
Now from your browser on host home1, set your proxy to localhost:8080 and you'll really use the proxy server accessible from home2.