CISE Help & Resources
Secure Shell Technical Details
This page describes the use of SSH to increase the security at CISE.
Contents
Intro to client/server relationships and TCP/IP networking
The client/server principle simply states that some entities (the servers) have something (information, disk space, pizza) while other entities do not, and those other entities must go to a server to get the "something" they need. Within the context of a network, this means that network services (printing, home directory disk space) can exist on one machine to be accessed when needed by others. This obviates the need for every service needed to be on every network machine. Instead of needing to buy printers and disks for every single machine, one or a few machines can hold them and others can access them from other, cheaper client machines.
Most of the programs that are used on the internet operate under the client/server principle. This means that if a user on a local machine wants to use a service on a remote machine, the user must connect to a process on the remote machine that will "serve" the services to the user. For example, if user A wishes to login and use a shell on a remote machine, user A uses a client program (say rsh) to connect to a process on the remote machine (rshd) that will serve a shell to the user.
TCP/IP connections on unix systems make use of network ports. A port is used to allow network programs to find each other. In the typical case, a server (or daemon) process (like ftpd, which accepts incomming ftp client requests) will start up, bind to a port, then sleep until an incoming connection arrives. Once the incoming rerquest has connected, the server process usually forks off a child server process to talk to the given client and continues to listen for new connections. Communication now happens between the initiating client program and the forked server process. For many services, the server port is well known (like port 21 for ftpd) so that client programs will know where to connect in order to obtain the service. SSHD uses port 22 to listen for incoming SSH client requests. Here's a simple diagram of a typical connection:

SSHD forks off a child, and communication continues between the client on port 3467 and the server on port 22.
SSH and port forwarding
Normally, when a user logs in to a remote system using SSH, that connection is encrypted. However, SSH can be used to encrypt other connections as well. By default, SSH encrypts X11 connections from the remote machines. SSH can also be used to encrypt other connections. The details are as follows.
Diagram of an SSH secure X11 session
To show how SSH encrypts it's X11 connection, first let's look at how a normal X11 connection behaves. Normally, the X server runs on port 6000 of the machine whose console a user is using. If I am on waterspout.cise.ufl.edu, then my X server is running waterspout.cise.ufl.edu, port 6000. Normally, the default DISPLAY environment variable on the machine whose console you are logged into is either ":0" or "host:0", and this is shorthand for "on this host, my X server is running on port 6000" . If a user had an X server running on port 6001, the corresponding DISPLAY variable would be either ":1" or "host:1". Here's a diagram of how this connections looks ({}'s indicated that this port number is required, []'s indicate that the port number can vary):

This diagram shows an xterm on machine "Remote" whose DISPLAY variable is set to "Local:0", and the xterm is communicating with the X server on "Local" that is running on port 6000.
An SSH encrypted connection is illustrated here:

This diagram is somewhat more complicated. Let's assume the user is using the command "ssh -n Remote xterm &" (see the man page for more details on the SSH command line switches).
There are six steps to consider:
- The user initiates an SSH connection. SSH attempts to connect to port 22 on the remote host.
- If successful, SSHD on the machine Remote forks off a child SSHD process. This process will handle the SSH connection between the two machines. If X11 forwarding is enabled, the process listens on port ( 6000 + <# of first unused port from 6001-600n> ).
- The child SSHD now forks off the command received from the original SSH client. In this case it is an xterm. SSHD sets the DISPLAY environment variable for the xterm to "Remote: <SSHD fake X server port - 6000> ", e.g., "Remote:1" .
- The xterm sends all X information to the fake server on it's own host.
- The fake SSHD-X server encrypts the X information, then sends it to the SSH client on the Local machine.
- The SSH client decrypts the information and sends it to the real X server, which displays it. Note: the real X server on Local is communicating to the SSH client on Local and *not* the xterm on Remote, in much the same way as the xterm on Remote is communicating with the fake SSHD-X server on Remote.
Caveats
SSH automatically sets the DISPLAY environment variable to a secure proxy X server. This ensures that X11 connections are encrypted. However, for some X clients users may wish to use the normal DISPLAY variable to provide an increase in speed if security is not as much of an issue (encryption slows down the connections somewhat). Here are some examples:
% echo $DISPLAY waterspout.cise.ufl.edu:0 % ssh bass % echo $DISPLAY bass:2.0
Notice that the DISPLAY variable points to an X server on the remote machine. This is the fake server that talks to the real X server at waterspout. Any x clients that use this DISPLAY variable will have their X connection encrypted. However, if the user is going to be, say, using xv to look at a group of images, then he/she may want to run the command:
% setenv DISPLAY waterspout.cise.ufl.edu:0
for the faster response.
SSH and Proxy Servers in General
SSH handles all the port forwarding concerns automatically for X. For other protocols, SSH has the ability to "forward" ports on one machine across an encrypted channel to a port on another machine, but it requires some setup on the part of the user. The forwarded port can be considered a "proxy server" for the service on the other machine.
SSH has two ways of forwarding ports (aside from the automatic X-server port forwarding). The first is uses the -L option to SSH, and the second uses the -R option (see the man page for more details).
ssh -L
Use the ssh -L command to have a local port act as a proxy for a port on a remote host.
ssh -L local-port:remote-machine:remote-port \ remote-machine
The -L option forwards a port (local-port) on the local machine across an encrypted channel to a server port (remote-port) on the remote machine (remote-machine), thereby setting up a proxy server on the local machine for the actual remote server.
Here's an example encrypted ftp session. First, start the SSH session that sets up the ports:
waterspout% ssh -L 1234:sand:21 sand
This forwards 1234 on the local machine (waterspout) to port 21 (the FTPD port) on sand. In other words, port 1234 on waterspout becomes a proxy ftp server for sand.
In another window, run the ftp command:
waterspout% ftp waterspout 1234 Connected to waterspout.cise.ufl.edu. 220 sand FTP server (wu-2.4(2) May 30 15:13 EDT 1994) ready. Name (waterspout:jfh): 331 Password required for jfh. Password: XXXXX 230 User jfh logged in. ...
Note that although the prompt says "Name (waterspout:jfh)", the "220" line clarifies that you are actually connecting to sand.
So, the user jfh has actually ftp'd to sand via an encrypted channel. Please note, however, due to the implementation of the ftp protocol, the data returning will not be encrypted (ftp uses two TCP/IP channels, one for the inital connection and one for data returned). The password sent over however is encrypted. Also note that using "localhost" (an alias for a local machine) instead of the local hostname will fail, as the ftpd daemon on the remote side will try to send to "localhost", which in this case is the remote machine, so you must explicitely use the name of the local machine in all cases.
Here's a diagram to show the actual and the conceptual view of the connection.

ssh -R
Use the ssh -R command to have a port on a remote host act as a proxy for a local port.
ssh -R remote-port:remote-machine:local-port \ remote-machine
