Published on (
 See this if you're having trouble printing code examples

FreeBSD Basics Cryptosystems: Configuring SSH

by Dru Lavigne

I received a lot of feedback regarding the last article on SSH. I'd like to thank those users who sent URLs for configuring SSH and their favorite SSH utilities. There is definitely a plethora of information regarding SSH, and I can only barely scratch its surface in the space of two articles. Accordingly, I'll be including pointers to additional reading and utilities to try yourself.

In this week's article, I want to spend a bit of time in the SSH configuration files, then mention briefly other utilities that allow the integration of SSH between your FreeBSD system and other operating systems.

We saw in the last article that it is possible both to make and accept SSH connections using the default FreeBSD configurations. We also saw that we could increase authentication security by generating a user key pair and copying over the public key to the SSH server. OpenSSH includes a utility known as ssh-agent, or the SSH authentication agent. IBM DeveloperWorks has an excellent article series which explains how to use ssh-agent. The author also goes into greater detail about how the public and private keys work and gives many useful links to other resources.

Also in FreeBSD Basics:

Fun with Xorg

Sharing Internet Connections

Building a Desktop Firewall

Using DesktopBSD

Using PC-BSD

Since SSH is composed of a client and a server, there are two configuration files. Not surprisingly, one is called ssh_config and the other sshd_config. That extra "d", for daemon, or the SSH server, is significant. The very first time I changed an SSH configuration file, I mistakenly added a server line to the client configuration file and scratched my head in puzzlement when it had no effect on my system. Remember to keep in mind that the SSH client is where you are sitting, and the SSH server is the machine you want to access remotely.

Both of these files have manpages which explain all of the possible configuration options. Both are well worth a read as you might possibly be intrigued by an option that I didn't cover here. Let's start by taking a look at the default SSH client configuration file. Some lines have been broken to fit on the page:

$ cat /etc/ssh/ssh_config

#   $OpenBSD: ssh_config,v 1.15 2002/06/20 20:03:34 stevesk Exp $
#   $FreeBSD: src/crypto/openssh/ssh_config,v 2002/07/25 16:03:44 \
	fanf Exp $

# This is the ssh client system-wide configuration file.  See
# ssh_config(5) for more information.  This file provides defaults for
# users, and the values can be changed in per-user configuration files
# or on the command line.

# Configuration data is parsed as follows:
#  1. command line options
#  2. user-specific file
#  3. system-wide file
# Any configuration value is only changed the first time it is set.
# Thus, host-specific definitions should be at the beginning of the
# configuration file, and defaults at the end.

# Site-wide defaults for various options

# Host *
#   ForwardAgent no
#   ForwardX11 no
#   RhostsAuthentication no
#   RhostsRSAAuthentication no
#   RSAAuthentication yes
#   PasswordAuthentication yes
#   BatchMode no
#   CheckHostIP no
#   StrictHostKeyChecking ask
#   IdentityFile ~/.ssh/identity
#   IdentityFile ~/.ssh/id_rsa
#   IdentityFile ~/.ssh/id_dsa
#   Port 22
#   Protocol 2,1
#   Cipher 3des
#   Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour, \
#   EscapeChar ~
#   VersionAddendum FreeBSD-20020629

You probably noticed that every line in this file starts with a # character (or is a remark). This doesn't mean that the SSH client has no configurations. Instead, the defaults are listed here as a reference. If you want to change a default, you first remove the # on the appropriate line, then insert the new value. All of the possible values are listed in the ssh_config manpage.

As you go through the manpage, you'll notice that some configuration options only apply to certain versions. Whenever possible, you should use SSH version 2. If you always use a FreeBSD client to connect to a FreeBSD server, the default configurations on both the client and the server will ensure you always use version 2. However, if you are using your FreeBSD system to access a non-FreeBSD system, you may be forced to use version 1 as that is all many systems support.

What are the differences between versions 1 and 2? If you do a search on the Internet, the most common answer you'll receive is that version 2 is a complete re-write that addressed many of the security issues that appeared in version 1. The two versions also differ in the algorithms that they support which I've summarized here:

VersionEncryption Algorithms
version 1DES, 3DES, blowfish
version 2AES-128, AES-192, AES-256, blowfish, CAST-128, ArcFour

VersionCryptographic Checksums
version 1none

You'll note that version 2 has support for stronger algorithms, and it provides protection against tampering. Remember, HMAC is a good acronym to find in a cryptosystem.

Note this line in the client configuration file:

#  Protocol 2,1

This means that the client will try to use version 2; if the server only supports version 1, the client will use that instead. If you change the line to:

Protocol 2

the client will fail to connect to any servers that only support version 1. Remember that if you do make any changes, remove the # or your change will be ignored as it will still be commented.

Two lines deal with ciphers or encryption algorithms:

#   Cipher 3des
#   Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour, \

The first line is used during a version 1 session. The manpage indicates that you should not use DES unless you absolutely have to. Note that the default is 3DES instead of the stronger, more efficient blowfish. This is because many non-FreeBSD systems don't support blowfish. Unfortunately, there are systems who only support version 1 and also only support DES. If this is the case, the default client configuration will fail, meaning you will have to change the line to:

Cipher DES

Avoid this if possible. While this is still much, much better than using telnet to connect to the system and sending everything in clear text, it decreases the security provided by SSH.

The second line that deals with ciphers is used during a version 2 session. If you're curious about what the cbc indicates, this definition may or may not clear it up for you. This line gives an ordered list of encryption algorithms. The first algorithm that matches the server will be used to encrypt the data.

Note that /etc/ssh/ssh_config is the global client configuration file. This means that the values in this file can be overridden by using switches when you use the ssh command. Also, if you are a lazy typist and always end up using the same switches, you can create a customized configuration file in your home directory. For example, instead of using the l switch in order to login as the user biko, I could create a file called ~/.ssh/config and place this line in it:

User biko

All SSH parameters are case sensitive, so make sure to capitalize the U in User.

Now whenever I ssh to, I don't have to remember to include the l switch. I'll still be prompted for biko's password.

If you are using a hostname or FQDN instead of an IP when you use the ssh command, you may find that your client will hang for a moment or so while the name is resolved. You might find a speed difference if you add an entry for the SSH server in /etc/hosts on the SSH client.

Let's switch gears a bit and move on to the SSH server configuration file /etc/ssh/sshd_config. This file is similar to the SSH client file in that all lines begin with a # and all possible values are listed in its manpage.

Treat the SSH daemon with more care. After all, in order to run the daemon, you need to open port 22 on that system. If that system has Internet access, anyone in the world can attempt to connect to that computer on that port. If you are using password authentication and an unauthorized user is able to guess a username and password, they will be able to login to that system with all of the rights of that user. See why root SSH logins aren't allowed and why using a public key with a passphrase protected private key is a good thing?

It is important to verify that you are using a recent version of the SSH daemon. To check the SSH server version, telnet to port 22 of the machine running the SSH daemon. If you're sitting at the server, the following command works; otherwise, telnet to the IP of the server.

telnet localhost 22
Trying ::1...
Connected to localhost.
Escape character is '^]'.
SSH-1.99OpenSSH_3.4p1 FreeBSD-20020702
quit            ^^^^^
Connection closed by foreign host.

Related Reading

SSH, The Secure Shell: The Definitive Guide
By Daniel J. Barrett, Richard E. Silverman

Make sure you are running a version greater than 3.3. All software, including software designed to provide security, has the potential of being compromised, and it is important to run software that has been patched against all known exploits. This becomes doubly important for an application such as OpenSSH, which is used to allow remote users access to a system.

If you regularly run cvsup and portupgrade, your FreeBSD system will be kept up-to-date. It is also a good idea to subscribe to, so you can be notified of new exploits that affect your FreeBSD system as they are discovered. The FreeBSD homepage includes directions on how to subscribe, as well as a record of past security advisories.

You can also consider installing the most recent version of OpenSSH, which is found in /usr/ports/security/openssh. This article demonstrates a FreeBSD 4.7-RELEASE system using the OpenSSH included in the base install.

There are several ways to control which hosts and users are allowed to access your SSH daemon. One is with a firewall. If you don't want anyone to access your SSH server over an Internet connection, place the SSH server behind a firewall with rules that deny access to port 22. If you do have users that will be accessing the SSH server over the Internet, you will need to add a rule that allows port 22. If your SSH clients have static IPs, you can allow just those addresses in your firewall rule.

Next, you can modify /etc/ssh/sshd_config. First, make a banner. While a banner itself offers no security, it does serve as a warning to unauthorized users and may make a bit of difference if you ever need to approach an ISP or legal authorities regarding unauthorized access. Here, I've made a simple banner:

$ cat /etc/ssh/banner

This is a private system!!! All connection attempts are logged and 
monitored. All unauthorized connection attempts will be investigated and 
handed over to the proper authorities.


Then, to tell the daemon to display the banner, I'll change this line in /etc/ssh/sshd_config:

#Banner /some/path


Banner /etc/ssh/banner

The banner itself will be displayed before the password or passphrase prompt. Note that banners will only be displayed to clients using SSH version 2 as they are unsupported by version 1.

If your SSH clients don't have static IPs or don't always use the same computers to access the SSH server, it is difficult to specify source IPs in your firewall rule. Fortunately, you can specify which users are allowed to authenticate to the SSH server by adding the AllowUsers parameter to the SSH daemon configuration file. Here, I'll restrict access to the users genisis and biko:

AllowUsers genisis biko

Any user that is not in that list will still receive a password prompt when they attempt to connect to the SSH daemon. However, even if they give a correct username and password, they will receive a permission denied message and their connection attempt will fail. A message regarding the failed attempt will be printed to the console of the SSH daemon, copied to /var/log/messages and emailed to root as part of the daily security run output. As you can see, this is a very good line to add to the SSH daemon configuration file. To be even pickier, if your users always login from the same system, you can do this:

AllowUsers genisis@ biko@

However, don't be that picky if your users don't always sit at the same system or if those systems don't have static IPs. For example, if genisis tries to connect from, she will receive a connection denied message.

Depending upon your requirements, you might also want to add these lines:

ClientAliveInterval 120
ClientAliveCountMax 2

The first value indicates that if the client hasn't sent any data for more than 2 minutes (120 seconds), the server will send a message to the client asking for a response. The second line indicates that if the client doesn't respond after 4 minutes (120 times 2), the server will disconnect the client.

You can also consider changing the value in this line:

#Port 22

to another port number. If you do so, make sure your clients are aware of the port they must use to connect to the server so they can specify it either on the command line or in the ssh_config file. While this adds a bit of security by defeating random or scripted attempts to port 22 and preventing port 22 from showing up in a scan, a knowledgable unauthorized user can simply telnet to your alternate port and discover that the SSH daemon is listening.

If you don't want the world in general to know that your SSH server is running FreeBSD, you can also change this parameter:

#  VersionAddendum FreeBSD-20020629

You may remember seeing that line in the output when I telnetted to port 22. If I change that to something like this:

VersionAddendum   For Authorized Users Only!!!!

it will change that line in the telnet output to:

SSH-2.-OpenSSH_3.4p1 For Authorized Users Only!!!!

Note that it will still indicate the version of OpenSSH in use. This is another reason why you always want to be running a recent, fully patched version as any user who knows how to use telnet can easily find out if your SSH server is patched against known exploits.

If your SSH server has multiple IPs, all of them will listen for port 22 connection attempts by default. If you only want one of the addresses to listen, change this line:


replacing with the desired IP address.

Remember, if you make any changes to the daemon's configuration file, you'll need to send a "signal one" to sshd to notify it of the changes:

killall -1 sshd

After informing sshd of the changes, always use a ssh client to test your changes. For example, if I add this line:

Allowusers genisis biko

yet find that user dlavigne is still able to connect, it is time to check that line for a typo. It is very easy to forget that parameters are case sensitive. In this case, AllowUsers would have worked but Allowusers was silently ignored and failed miserably. You don't want to find out six months later that anyone was allowed to connect when you thought you had restricted connections to two users.


I'd like to leave you with some helpful URLs.

In the next article, I'd like to continue the cryptosystems series by covering the basics of VPNs and IPsec.

Dru Lavigne is a network and systems administrator, IT instructor, author and international speaker. She has over a decade of experience administering and teaching Netware, Microsoft, Cisco, Checkpoint, SCO, Solaris, Linux, and BSD systems. A prolific author, she pens the popular FreeBSD Basics column for O'Reilly and is author of BSD Hacks and The Best of FreeBSD Basics.

Read more FreeBSD Basics columns.

Return to the BSD DevCenter.

Copyright © 2009 O'Reilly Media, Inc.