Secure Shell (SSH) is a protocol for building encrypted tunnels between hosts. SSH is most commonly used for remote command-line access to a system, but you can use it as a generic wrapper around other protocols or even to build virtual private networks. One common use for SSH is to support secure file transfer protocol service, or SFTP, which doesn’t give you a shell prompt but does encrypt files and authentication information as they cross the network.
The OpenBSD project supports OpenSSH, a freely licensed client and server. OpenSSH is the most widely deployed SSH server in the world, with roughly 97 percent market share, and is generally considered the standard SSH server. Entire books have been written about OpenSSH, including mine (SSH Mastery, Tilted Windmill Press, 2012).
OpenBSD includes the OpenSSH server sshd(8)
, the OpenSSH command-line client ssh(1)
, and the SFTP client sftp(1)
. We’ll focus on sshd
here, since you can use any number of SSH clients. The ones I use most commonly are ssh
(for Unix-like systems) and PuTTY (for Windows). For SFTP, I commonly use sftp
(for Unix-like systems) and WinSCP (for Windows).
Unless you specified otherwise during installation, OpenBSD starts sshd
by default. If you don’t want sshd
to run, disable it in /etc/rc.conf.local.
sshd_flags=NO
The first time you start sshd
, OpenBSD creates host keys in /etc/ssh. These are sets of public and private keys that uniquely identify an SSH server. Each key file includes the word key in its name. When your client first connects to the SSH server, it presents a fingerprint summary of the server’s host key. If you tell the client to accept the key, the client will cache the server’s host key. If this key ever changes, the client warns the user that the server’s unique identity has changed, and that the user might be offering his login credentials to a different server. (Anyone who gets copies of the host keys can have another server masquerade as yours.) Be sure to back up your host keys, and protect them from theft.
You could change sshd
’s behavior by adding command-line flags, but the most common way to reconfigure sshd
is to edit the files in /etc/ssh.
OpenSSH has many configuration options. The ones that are most commonly changed involve the network settings. You can control the port, IP address, and version of IP sshd
listens to by editing the configuration file /etc/ssh/sshd_config. Here’s an example:
Port 22 AddressFamily any ListenAddress 0.0.0.0 ListenAddress ::
The Port
keyword specifies the TCP/IP port that sshd
attaches to. The default is TCP port 22.
Some people recommend using a port other than 22 to avoid password-guessing worms. Far better ways to protect your SSH server are to allow only public-key authentication or use a packet filter to allow logins from only selected hosts or networks.
The AddressFamily
keyword specifies the version of IP that sshd
uses. The default is to use both IPv4 and IPv6, but you can restrict it to a specific protocol with the inet
(IPv4) or inet6
(IPv6) keyword.
Lastly, you can attach sshd
to a specific IP address with the ListenAddress
option.
Organizations commonly need to confine users to a particular directory or subset of directories. For example, many websites allow users command-line access over SSH so that they can edit their files and debug problems more easily, or even just SFTP access to their files. Those users should have access to their own directories, but not to other users’ files, or any other part of the system. One solution is to chroot
the user in his home directory. If you have several users who need to access a shared directory, you can chroot
all of them in that directory.
Locking users in a directory involves three steps: choosing the directory to lock users into, populating that directory, and configuring sshd
to chroot
those users. To demonstrate, we’ll walk through an example of chroot
ing the user lasnyder
in his home directory, and give him command-line access, so he will be able to access only the programs in his chroot
.
First, specify the chroot
directory with the ChrootDirectory
option.
ChrootDirectory /home/lasnyder
This works well if all of your users need to be locked into the same directory, but if you want users to have their own private directory, or if you want to specify a directory elsewhere on the filesystem, things get more complex.
OpenSSH supports the %%
, %h
, and %u
macros to represent home directories. If your chroot
directory includes a literal %
, use the %%
macro to represent it. The server in this example has home directories on /disk%3/home, so the %%
macro is needed to escape the percent sign.
ChrootDirectory /disk%%3/home/lasnyder
The %u
macro expands to the user’s username. You could use this to give users a chroot
some place other than their home directory (though I don’t know why you wouldn’t just give them a home directory in the desired location). Here, each user has a directory under /var/www:
ChrootDirectory /var/www/%u
Finally, you could lock each user in his home directory with the %h
macro.
ChrootDirectory %h
Wherever you lock a user, you must give that directory everything the user needs to function, since the user won’t be able to leave that directory to get a tool that he might need.
Most programs, such as a shell, require at least a few device nodes, and the user must have a shell program to be able to run one. If a user has only SFTP access, you don’t need to do any special preparation of the chroot
. OpenSSH’s SFTP server includes everything it needs. But if users have shell access, they need basic device nodes and a shell program.
For our example, to give lasnyder
what he needs, go to the chroot
directory, create a dev directory, and then make the standard device nodes using /dev/MAKEDEV
. You can remove the console
, klog
, kmem
, ksyms
, mem
, and xf86
devices.
# cd /home/lasnyder # /dev/MAKEDEV std # rm console klog kmem ksyms mem xf86
Now we need to get the user a shell. Since programs running inside the shell cannot access any files outside the chroot
, including shared libraries, any shell copied into a chroot
must be statically linked. The included system shells are statically linked, and most shells in the ports tree can be built in static flavors.
Verify that a shell is statically linked with file(1)
, and then create a bin directory inside the chroot
and copy the shell there.
# file /bin/ksh /bin/ksh: ELF 32-bit LSB executable, Intel 80386, version 1, for OpenBSD, statically linked, stripped # cd /home/lasnyder # mkdir bin # cd bin # cp /bin/ksh .
Lastly, although a chroot
ed user should not have write access to his own root directory, he needs a real home directory. The user’s home directory in /etc/passwd is relative to the chroot
; in other words, if a user’s home directory in /etc/passwd is /home/lasnyder, and the user is chroot
ed to /home/lasnyder, his personal files and dotfiles actually go in /home/lasnyder/home/lasnyder.
# chown root:wheel /home/lasnyder # mkdir -p /home/lasnyder/home/lasnyder # chown lasnyder:lasnyder /home/lasnyder/home/lasnyder
The user now has a command-line friendly jail cell on the system. Now we need to tell sshd
to lock the user in it.
Applying this chroot
strategy to all of your users probably isn’t advisable—if nothing else, your sysadmins need unfettered system access to perform maintenance.
To tell sshd
to chroot
specific users, either by name or by group, use the Match
keyword at the end of sshd_config. Match lets you change sshd
’s default behavior based on factors such as user and client IP address. (Match
has many more functions; see sshd_config(5)
for examples.)
For example, if you wanted to chroot
only the user lasnyder
, you could use Match
to specify his username. Early in the configuration, you would have a ChrootDirectory
statement that turns off chroot
for most users. Then, at the end of the configuration, you would change the setting based on matching that username.
… ChrootDirectory none … Match User lasnyder ChrootDirectory %h
You could also chroot
all users in a group.
… ChrootDirectory none … Match Group webcustomers ChrootDirectory %h
If you have multiple Match
terms, separate them with commas.
… ChrootDirectory none … Match User lasnyder, jgballard, pkdick ChrootDirectory %h
Or, if most of your users are chroot
ed, reverse the default and specifically dechroot
your sysadmins.
… ChrootDirectory %h … Match Group wheel ChrootDirectory none
With careful configuration, you can restrict access to only the desired users.
SSH can do a whole lot more, such as securely eliminate passwords from your network. It’s worth your time to fully master this protocol.
OpenBSD’s built-in services can help you hold your network together, and they provide all kinds of useful support infrastructure. Now that you know how to configure some of these built-in programs, let’s see how to use OpenBSD as a desktop.