14.10. OpenSSH

Contributed by Chern Lee.

OpenSSH is a set of network connectivity tools used to access remote machines securely. Additionally, TCP/IP connections can be tunneled/forwarded securely through SSH connections. OpenSSH encrypts all traffic to effectively eliminate eavesdropping, connection hijacking, and other network-level attacks.

OpenSSH is maintained by the OpenBSD project and is installed by default in FreeBSD. It is compatible with both SSH version 1 and 2 protocols.

14.10.1. Advantages of Using OpenSSH

When data is sent over the network in an unencrypted form, network sniffers anywhere in between the client and server can steal user/password information or data transferred during the session. OpenSSH offers a variety of authentication and encryption methods to prevent this from happening.

14.10.2. Enabling the SSH Server

To see if sshd(8) is enabled, check /etc/rc.conf for this line:

sshd_enable="YES"

This will start sshd(8), the daemon program for OpenSSH, the next time the system initializes. Alternatively, it is possible to use service(8) to start OpenSSH now:

# service sshd start

14.10.3. The SSH Client

To use ssh(1) to connect to a system running sshd(8), specify the username and host to log into:

# ssh user@example.com
Host key not found from the list of known hosts.
Are you sure you want to continue connecting (yes/no)? yes
Host 'example.com' added to the list of known hosts.
user@example.com's password: *******

SSH utilizes a key fingerprint system to verify the authenticity of the server when the client connects. The user is prompted to type yes when connecting for the first time. Future attempts to login are verified against the saved fingerprint key and the ssh(1) client will display an alert if the saved fingerprint differs from the received fingerprint on future login attempts. The fingerprints are saved in ~/.ssh/known_hosts.

By default, recent versions of sshd(8) only accept SSH v2 connections. The client will use version 2 if possible and will fall back to version 1. The client can also be forced to use one or the other by passing it the -1 or -2 for version 1 or version 2, respectively. The version 1 compatibility is maintained in the client for backwards compatibility with older versions.

14.10.4. Secure Copy

Use scp(1) to copy a file to or from a remote machine in a secure fashion.

#  scp user@example.com:/COPYRIGHT COPYRIGHT
user@example.com's password: *******
COPYRIGHT            100% |*****************************|  4735
00:00
#

Since the fingerprint was already saved for this host in the previous example, it is verified when using scp(1) here.

The arguments passed to scp(1) are similar to cp(1), with the file or files to copy in the first argument, and the destination in the second. Since the file is fetched over the network, through an SSH, connection, one or more of the file arguments takes the form user@host:<path_to_remote_file>.

14.10.5. Configuration

The system-wide configuration files for both the OpenSSH daemon and client reside in /etc/ssh.

ssh_config configures the client settings, while sshd_config configures the daemon. Each file has its own manual page which describes the available configuration options.

14.10.6. ssh-keygen(1)

Instead of using passwords, ssh-keygen(1) can be used to generate DSA or RSA keys to authenticate a user:

% ssh-keygen -t dsa
Generating public/private dsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_dsa):
Created directory '/home/user/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user/.ssh/id_dsa.
Your public key has been saved in /home/user/.ssh/id_dsa.pub.
The key fingerprint is:
bb:48:db:f2:93:57:80:b6:aa:bc:f5:d5:ba:8f:79:17 user@host.example.com

ssh-keygen(1) will create a public and private key pair for use in authentication. The private key is stored in ~/.ssh/id_dsa or ~/.ssh/id_rsa, whereas the public key is stored in ~/.ssh/id_dsa.pub or ~/.ssh/id_rsa.pub, respectively for the DSA and RSA key types. The public key must be placed in ~/.ssh/authorized_keys on the remote machine for both RSA or DSA keys in order for the setup to work.

This setup allows connections to the remote machine based upon SSH keys instead of passwords.

Warning:

Many users believe that keys are secure by design and will use a key without a passphrase. This is dangerous behavior and the method an administrator may use to verify keys have a passphrase is to view the key manually. If the private key file contains the word ENCRYPTED the key owner is using a passphrase. While it may still be a weak passphrase, at least if the system is compromised, access to other sites will still require some level of password guessing. In addition, to better secure end users, the from may be placed in the public key file. For example, adding from="192.168.10.5 in the front of ssh-rsa or rsa-dsa prefix will only allow that specific user to login from that host IP.

If a passphrase is used in ssh-keygen(1), the user will be prompted for the passphrase each time in order to use the private key. ssh-agent(1) can alleviate the strain of repeatedly entering long passphrases, and is explored in Section 14.10.7, “Using SSH Agent to Cache Keys”.

Warning:

The various options and files can be different according to the OpenSSH version. To avoid problems, consult ssh-keygen(1).

14.10.7. Using SSH Agent to Cache Keys

To load SSH keys into memory for use, without needing to type the passphrase each time, use ssh-agent(1) and ssh-add(1).

Authentication is handled by ssh-agent(1), using the private key(s) that are loaded into it. Then, ssh-agent(1) should be used to launch another application. At the most basic level, it could spawn a shell or a window manager.

To use ssh-agent(1) in a shell, start it with a shell as an argument. Next, add the identity by running ssh-add(1) and providing it the passphrase for the private key. Once these steps have been completed, the user will be able to ssh(1) to any host that has the corresponding public key installed. For example:

% ssh-agent csh
% ssh-add
Enter passphrase for /home/user/.ssh/id_dsa:
Identity added: /home/user/.ssh/id_dsa (/home/user/.ssh/id_dsa)
%

To use ssh-agent(1) in Xorg, a call to ssh-agent(1) needs to be placed in ~/.xinitrc. This provides the ssh-agent(1) services to all programs launched in Xorg. An example ~/.xinitrc might look like this:

exec ssh-agent startxfce4

This launches ssh-agent(1), which in turn launches XFCE, every time Xorg starts. Once Xorg has been restarted so that the changes can take effect, run ssh-add(1) to load all of the SSH keys.

14.10.8. SSH Tunneling

OpenSSH has the ability to create a tunnel to encapsulate another protocol in an encrypted session.

The following command tells ssh(1) to create a tunnel for telnet(1):

% ssh -2 -N -f -L 5023:localhost:23 user@foo.example.com
%

This example uses the following options:

-2

Forces ssh(1) to use version 2 to connect to the server.

-N

Indicates no command, or tunnel only. If omitted, ssh(1) initiates a normal session.

-f

Forces ssh(1) to run in the background.

-L

Indicates a local tunnel in localport:remotehost:remoteport format.

user@foo.example.com

The login name to use on the specified remote SSH server.

An SSH tunnel works by creating a listen socket on localhost on the specified port. It then forwards any connections received on the local host/port via the SSH connection to the specified remote host and port.

In the example, port 5023 on localhost is forwarded to port 23 on localhost of the remote machine. Since 23 is used by telnet(1), this creates an encrypted telnet(1) session through an SSH tunnel.

This can be used to wrap any number of insecure TCP protocols such as SMTP, POP3, and FTP.

Example 14.1. Using ssh(1) to Create a Secure Tunnel for SMTP
% ssh -2 -N -f -L 5025:localhost:25 user@mailserver.example.com
user@mailserver.example.com's password: *****
% telnet localhost 5025
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 mailserver.example.com ESMTP

This can be used in conjunction with ssh-keygen(1) and additional user accounts to create a more seamless SSH tunneling environment. Keys can be used in place of typing a password, and the tunnels can be run as a separate user.


14.10.8.1. Practical SSH Tunneling Examples

14.10.8.1.1. Secure Access of a POP3 Server

In this example, there is an SSH server that accepts connections from the outside. On the same network resides a mail server running a POP3 server. To check email in a secure manner, create an SSH connection to the SSH server, and tunnel through to the mail server.

% ssh -2 -N -f -L 2110:mail.example.com:110 user@ssh-server.example.com
user@ssh-server.example.com's password: ******

Once the tunnel is up and running, point the email client to send POP3 requests to localhost on port 2110. This connection will be forwarded securely across the tunnel to mail.example.com.

14.10.8.1.2. Bypassing a Draconian Firewall

Some network administrators impose firewall rules which filter both incoming and outgoing connections. For example, it might limit access from remote machines to ports 22 and 80 to only allow ssh(1) and web surfing. This prevents access to any other service which uses a port other than 22 or 80.

The solution is to create an SSH connection to a machine outside of the network's firewall and use it to tunnel to the desired service.

% ssh -2 -N -f -L 8888:music.example.com:8000 user@unfirewalled-system.example.org
user@unfirewalled-system.example.org's password: *******

In this example, a streaming Ogg Vorbis client can now be pointed to localhost port 8888, which will be forwarded over to music.example.com on port 8000, successfully bypassing the firewall.

14.10.9. The AllowUsers Option

It is often a good idea to limit which users can log in and from where using AllowUsers. For example, to only allow root to log in from 192.168.1.32, add this line to /etc/ssh/sshd_config:

AllowUsers root@192.168.1.32

To allow admin to log in from anywhere, list that username by itself:

AllowUsers admin

Multiple users should be listed on the same line, like so:

AllowUsers root@192.168.1.32 admin

Note:

It is important to list each user that needs to log into this machine; otherwise, they will be locked out.

After making changes to /etc/ssh/sshd_config, tell sshd(8) to reload its configuration file by running:

# service sshd reload

14.10.10. Further Reading

The OpenSSH website.

ssh(1), scp(1), ssh-keygen(1), ssh-agent(1), ssh-add(1), and ssh_config(5) for client options.

sshd(8), sftp-server(8), and sshd_config(5) for server options.

All FreeBSD documents are available for download at http://ftp.FreeBSD.org/pub/FreeBSD/doc/

Questions that are not answered by the documentation may be sent to <freebsd-questions@FreeBSD.org>.
Send questions about this document to <freebsd-doc@FreeBSD.org>.