Restricting Users to SFTP Only and to Home Directories Using a Chroot

A chroot jail is a miniature environment which provides only just enough resources for one or another program to run. In this case, the sftp program is the one that is chroot’ed. The process can be made easier with tools like rssh or scponly – both of whcih are available in Red Hat Enterprise Linux 5.

However, the problem comes up when you want to use multiple users in this environment and you want to restrict each user so that they cannot see the rest of the environment, including other users. Neither rssh nor scponly will handle this sort of thing.

There is the program MySecureShell but it is not included with either RHEL or Ubuntu Server. One would have to compile it from source or use their packages for these environments.

However, as of OpenSSH 4.9 this problem was resolved: with the addition of the Match and ChrootDirectory options to OpenSSH 4.9 – as well as an internal SFTP server (in contrast to the external helper program otherwise used) – this allows the kind of restrictions wanted here.

Ubuntu Server Lucid Lynx (10.04) and Red Hat Enterprise Server 6 both come with OpenSSH 5.3p1 which includes both of these options. However, Red Hat Enterprise 5 only comes with OpenSSH 4.3p2. To see which version you have, use a command like this:

$ ssh -V
OpenSSH_4.3p2, OpenSSL 0.9.8e-fips-rhel5 01 Jul 2008
$

Red Hat did backport the ChrootDirectory option into OpenSSH in RHEL 5 back in 2009, but not the Match option. Thus the ChrootDirectory option is good for everyone or no one. It is possible to use the option on the command line or in a specially crafted configuration file, but this requires a special server for SFTP instead of using the normal one – meaning two instances of SSH running if you want standard SSH logins.

It doesn’t seem to be possible to pass such options into rssh; rssh doesn’t allow you to pass options to ssh.

If you are using RHEL 5, it appears that the best option is to compile the most recent OpenSSH from source. To build the source, unpack the archive and copy the file contrib/redhat/openssh.spec from the unpacked openssh directory to the /usr/src/redhat/SPECS directory. Edit the file to your desire (such as disabling all of the X11 capabilities) and then perform this command:

rpmbuild -ba openssh.spec

In my case, the SPEC file contained a error in 5.9p1: there is a line that says:

%doc CREDITS ChangeLog INSTALL LICENCE OVERVIEW README* PROTOCOL* TODO WARNING*

Since there are no files named WARNING* this fails. Remove that entry from the end of the line:

%doc CREDITS ChangeLog INSTALL LICENCE OVERVIEW README* PROTOCOL* TODO

Then it compiles without problem.

If you want to use a recent version of OpenSSH on RHEL 5, you’ll have to make some configuration changes – and watch out for some changes. Changes include:

  • ServerKeyBits increased from 768 to 1024 (knock back down with specific entry if this worries you)
  • Protocol only supports version 2 by default
  • ShowPatchLevel not supported by standard OpenSSH (requires patch)
  • New ECSDA keys not supported fully or properly; `ssh-keygen -A` generates errors (can be ignored)
  • MaxSessions added to configuration file
  • AuthorizedKeysFile changes meaning slightly
  • UseDNS is included in the configuration file (instead of being hidden – set it to “no” for speed)
  • Banner is set to “none” by default

Change the Subsystem configuration entry for sftp to look like this:

Subsystem sftp internal-sftp

Add this to the end of the configuration:

Match group sftp-only
 ChrootDirectory %h
 AllowTCPForwarding no
 X11Forwarding no
 ForceCommand internal-sftp

Don’t forget to restart the ssh server:

service sshd restart

When you do this, make sure to have a root shell already open on the system so that you don’t get locked out. The user should exist in the password file like so:

test:x:521:521::/home/test:/bin/nologin

The home directory must be owned by user root and group root – including all directories in the path. The shell does not matter, as SSH will take over before the shell is activated; however, if there are other ways to log in with this user aside from SSH, then a proper shell like /bin/nologin or /bin/false is necessary.

For the specified configuration the user must be a member of the sftp-only group – either primary or secondary, it doesn’t matter. The Match option can also be used against a single user instead.

If you want the user – or anyone else – to be able to write files in this tree, create a subdirectory in the home directory with the appropriate permissions. The user – and others – will not be able to write to the home directory, but will be able to write to the subdirectory.

Don’t forget to test the login first – and don’t forget to have a root shell open before you start changing OpenSSH configuration or you may be unable to SSH into the system!

Logging transfers via SFTP

When you install OpenSSH, you also get SFTP for free: a replacement for FTP. (Note that SFTP is related to FTP by name only.)

SFTP is very useful, but as is normally configured, it does not provide any logging of user’s file transfers. For monitoring usage, this can be a problem.

The original setting in sshd_config might look like this:

Subsystem sftp /usr/libexec/openssh/sftp-server

This lack of logging is easily remedied; the details can be found in the man page for sftp-server:

Subsystem sftp /usr/libexec/openssh/sftp-server -l INFO

For best results, check your system’s man pages for the available options.

Are SSH Passwords Safer than Keys?

It almost goes without saying that servers should never run telnet or rlogin but rather should have SSH instead. Today’s UNIX and Linux server operating systems, whether commercial or open source, come with SSH (usually OpenSSH) installed.

The question is: is password authentication more secure than public key authentication? This question has been asked before; consider these two questions from serverfault.com, one from November 2010 and one from June 2010. The instinctive response from many will be “Of course not!” – but the question remains. What are the actual downfalls to password authentication – or are there any?

There are multiple problems that can exist with public key authentication that password adherents will point out.

Firstly, there is the possibility that a system can be compromised and the keys taken. This risk is not so high as it might sound; if you are running Linux or UNIX on the system and have it properly secured, the risk of system compromise is lower than you might think. It is also possible (and recommended) to encrypt the keys with a passphrase.

Secondly, those who recommend passwords will note that passwords exist only in your mind (as long as you don’t write it down). However, is an easily memorable password truly secure?

There are numerous advantages to using a key, including many not directly related to security: you can have different keys for different systems, and keys can be restricted in various ways by the server administrator. It is also possible to revoke access to a user without affecting any other user – no more having to tell everyone the new password after a password change.

Keys are also not susceptible to brute force attacks. A hacker can attempt to break into an SSH server by brute force by trying a variety of passwords and usernames; this is not possible with keys. This sort of attack can come from anywhere, which makes it easier for hackers to do and more likely to occur. If there are a lot of users using SSH, then the likelihood of someone using a weak password is much higher – making the risk of server compromise that much higher as well.

Passwords can also be stolen remotely. If a server is compromised, the next time you log in you may be connecting to a hacked SSH server which copies all of your passwords. If you used public key authentication, then your private key would never be seen (or compromised) by the remote server.

So how do you properly secure your private key? Here are a number of things you can do:

  • Password protect your private key.
  • Put the key on a removable device and remove after using.
  • Put the key on an encrypted volume.
  • Use ssh-agent to store the key instead of using it over and over.

If you have already created a key without a password, you can add a password by using ssh-keygen:

$ ssh-keygen -p -f id_mykey
Key has comment 'id_mykey'
Enter new passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved with the new passphrase.
$

There are a number of good sources of information on SSH – and OpenSSH in particular. Try some of these:

SSH Key Conversions: ssh-keygen (OpenSSH)

I’ve discussed this before, but this time I’m focusing on another angle. When interacting with commercial SSH implementations (such as exists on OpenVMS and Tru64 implementations) it becomes useful to know how to convert your OpenSSH public keys to SSH2 format and vice versa.

These examples will assume that you are using OpenSSH and are on a UNIX system. Note that these are public keys, not private keys. All key types (DSA, RSA) should convert fine, but DSA is the stronger cryptographic algorithm.

One you have a public key in the appropriate format, you can add it to the authorized keys file (whatever that may be called). This is normally found in ~/.ssh or ~/.ssh2 depending on the SSH version.

The OpenSSH utility ssh-keygen is what makes this happen. This utility can do a lot more than just generate keys. It can be used to change passphrases of encrypted keys; convert keys; generate public keys from private OpenSSH keys; and read and write keys to smartcards.

Converting an SSH2 key to OpenSSH

To use an SSH2 public key in OpenSSH, it needs to be converted. Use the ssh-keygen utility in this manner:

ssh-keygen -e -f ~/.ssh/id_dsa_ssh2.pub > ~.ssh/id_dsa.pub

Converting an OpenSSH key to SSH2

Using an OpenSSH public key in SSH2 requires a conversion; ssh-keygen can do this:

ssh-keygen -i -f ~/.ssh/id_dsa.pub > ~/.ssh/id_dsa_ssh2.pub

Using OpenSSH public keys with OpenVMS (and SSH2)

Every Linux box comes with OpenSSH, as does every BSD (at least, I don’t know of any that don’t). UNIX almost invariably comes with OpenSSH as well (although Tru64 is a dying hold-out).

However, OpenVMS 8 comes with an implementation of SSH that appears to be very similar to the commercial SSH produced by F-Secure and distributed by Attachmate.

To use your OpenSSH keys with VMS, a conversion is required – and the configuration files are different as well.

The versions of SSH used are:

VMS $ ssh "-V"
$1$dga010:[sys1.syscommon.][sysexe]tcpip$ssh_ssh2.exe: SSH Secure Shell OpenVMS
(V5.5) 3.2.0 on HP rx2660 (1.40GHz/6.0MB) - VMS V8.3

UNIX $ ssh -V
OpenSSH_5.1p1, OpenSSL 0.9.8g 19 Oct 2007

First, the key must be converted. Using OpenSSH this is easy (assume that the OpenSSH key my_key.pub already exists):

$ ssh-keygen -e -f my_key.pub > my_vmskey.pub
$

Then copy this file to your VMS login directory, putting it into the directory [.ssh2] (relative to your VMS login directory). Let's assume that the UNIX host is named openssh:

VMS $ scp openssh:~/my_vmskey.pub .
VMS $

Then edit the file AUTHORIZATIONS to include this line:

key my_vmskey.pub

Then be sure to test it out from your OpenSSH host:

openssh $ slogin vms
The authenticity of host 'vms (10.6.4.4)' can't be established.
DSA key fingerprint is 46:43:2f:df:0a:4b:37:e2:4f:f9:63:05:21:84:c9:44.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'vms' (DSA) to the list of known hosts.
Welcome to HP OpenVMS Industry Standard 64 Operating System, Version V8.3

$

Note that since you've not logged into the VMS machine previously, it must have its fingerprint added to the file known_hosts.

There is a good article about key conversions that seems to cover all the bases.

The Geek Stuff blog also has an excellent article on connecting to a SSH2 server using OpenSSH, as well as excellent articles on setting up SSH2 for logins and setting OpenSSH for logins.

Of course, the definitive book is SSH: The Definitive Guide by by Daniel Barrett, Richard Silverman, and Robert Byrnes. This book is also now online.

Tips for SSH

There are a couple of very interesting things about SSH that I never knew before – and I think you’ll find them interesting as well. Over at nixshell, there was a pointer to an article (by Nico Golde) about creating port forwarding allocations on the fly over an existing connection.

To do this (from an existing networked SSH session), use the ~ escape character like so:

~C

The results can look like this:

$ 
ssh> -h
Commands:
      -L[bind_address:]port:host:hostport    Request local forward
      -R[bind_address:]port:host:hostport    Request remote forward
      -KR[bind_address:]port                 Cancel remote forward

$

In this case, I entered ~C then the “command” -h for help. To enter a command at this prompt, it is necessary to press ~C each time; after the help screen came out I pressed the enter key and you see the UNIX prompt returned.

However, there is a lot more. Going further in nion’s blog (the source), there is also a post about using the ControlMaster and ControlPath options to reuse an existing SSH connection for much faster connections. This sounds exciting and is something I’ll have to investigate myself. Expect to see more on this later.

Securing your network traffic

If you want to start some exciting discussion in a security forum, just say you use telnet: you’ll find that every admin knows that telnet is insecure, that one should use OpenSSH or similar to encrypt the traffic, and that telnet should be banned from the server environment entirely.

However, telnet is not the only server that transmits its passwords in the clear. There are a lot of others. Here’s a list I came up with:

  • FTP
  • HTTP
  • IMAP
  • IPP
  • LDAP
  • LPD
  • NFS
  • POP3
  • rsync
  • SMTP
  • SNMP
  • syslog
  • VNC
  • X11
  • XDMCP

I won’t cover all of these here (more about these items can be found in my book) but I do want to cover just a few.

Consider, for example, the mail protocols: SMTP, POP3, and IMAP. SSL encryption is available with all three – but do you use it? And what about your logins to your mailbox at your ISP? Every time you login, your password to your mailbox goes across the wire in the clear.

What about NFS – particularly NFS home directories? If you have unencrypted secrets in your home directory, then these items will be transmitted across the network in the clear as well. What about private SSH keys? Unfortunately, there is no way to encrypt NFS traffic.

VNC is another one to watch for: if you type passwords for your root logins over VNC – even if you are using SSH in your VNC session – the passwords are in the clear. The only way to secure VNC entirely is to use an SSH tunnel to encrypt it.

X11 is insecure in the same way, but presents special problems. However, OpenSSH handles X transparently through the use of special tunnels just for X.

syslog is another unencrypted service; do you have passwords put into the system logs? What about secret doings of your servers? How much information leakage can you handle? Unfortunately, syslog is another service that cannot be secured unless you use something such as syslog-ng which permits you to use TCP (and thus, an OpenSSH tunnel).