On occasion you may want to exchange data with someone else. You’d like to grant that person access to your system (or network) but in such a way that the person has limited access to other areas of the system (or general resources on your network). This article will show you how to setup a chrooted jail that restricts the user to only SFTP on Mac OS X Leopard. It further limits the user so that they cannot traverse the filesystem outside the bounds you specify.
If you the exchange is one way (for example you want someone to be able to download a file), you can sometimes post it to a website and send them the URL. But sometimes you want to be able to exchange files back and forth. Of course for small files, email is the most obvious way to do this these days.
Another way that is increasingly used is to restrict the user to a specific portion of the computer that serves as the exchange intermediate (sometimes called a chrooted jail). FTP servers often offer such a facility, but more often people are moving away from FTP to other mechanisms. There are third party applications such as RSSH that can be used to create chrooted environments using secure transfer methods like SSH. They work, but sometimes they can be difficult to set up (or are not supported on the platform of choice).
Mac OS X Leopard 10.5.5 or higher
Server or Client version
Remote login enabled (SSH/SFTP)
A user account that is allowed to remotely access the system (in this example the user account name is bubbrubb)
All commands are performed as root (or via sudo). If root is disabled on your system, you can use sudo or ‘sudo su’ to root.
An important restriction for this to work, is that where ever your files exist on the computer the path to those files must be owned and only be writable by root. A simple example:
The root directory (/) needs to be owned by root, and only writable by root. Similarly the directory foo must also be owned by root and only writable by root. The group and everyone permissions can be readable or executable, just not writable.
Another example. Say you want your files to be stored on a drive separate from your main OS drive:
Again, /, /Volumes and the volume Storage must all be owned by root and only writable by root.
If you are wondering how a user would write to the disk if only root owns it, I’ll explain that in a bit.
Storage Location Setup
For this example we’ll use /Volumes/Storage. (Note, you can do this via symlinks too, but for now, we’ll just use the disk structure that Mac OS X sets up on disk insertion).
sudo su to root: chmod g-w / chmod g-w /Volumes chmod g-w /Volumes/Storage chown root /Volumes/Storage
Make a directory for your user:
mkdir /Volumes/Storage/bubbrubb chown bubbrubb /Volumes/Storage/bubbrubb chmod 700 /Volumes/Storage/bubbrubb
The above does the following:
1) Create a path to the general storage location that only root can modify. (this will not work, if this isn’t true, the connection will outright fail).
2) Create a directory that bubbrubb owns and can write to. We restrict the other permissions so that only user bubbrubb can read and write there (you could log into the server using bubbrubbs account OR modify the group permissions so that others accounts in that group can read and write there too). The important part is that all folders leading up to that one are writable only by root.
SSH Remote Access
First test that the user account you want to restrict can ssh into your system. If that works, then continue. If not, figure out why, then:
cp /etc/sshd_config /etc/sshd_config.bkup
Then edit sshd_config commenting out the line:
Subsystem sftp /usr/libexec/sftp-server
and adding the line:
Subsystem sftp internal-sftp
Then add a block similar to the follow (substituting the User name for the appropriate name on your system):
Match User bubbrubb X11Forwarding no AllowTcpForwarding no ChrootDirectory /Volumes/Storage
On Leopard Server the match criteria take effect immediately (that is you do not need to restart the service), you may need to on Leopard Client.
Note that in the above Match statement we place the user into the directory one level up from where they can write. Remember, that the path that the user logs into by default can only be writable by root. Once the user logs in, they cd to their directory and can then write files there.
User connections and uploading files
First try connecting via ssh:
mymac:~ bubbrubb$ ssh [email protected] Password:
The connection will hang after you type in your password. Press control-C to cancel the connection. If it goes through some setting didn’t take effect.
Then try with sftp:
mymac:~ bubbrubb$ ssh [email protected] Password: sftp> cd bubbrubb sftp> put testfile Uploading file to /bubbrubb/testfile testfile 100% 0 0.0KB/s 00:00 sftp> get testfile Fetching /bubbrubb/testfile to testfile sftp>
If you made it this far, then you have successfully set up your chrooted jail.
This does not appear to work on systems running Leopard earlier than 10.5.5. I tried this using a system running 10.5.4 and it failed. I didn’t do an exhaustive test. YMMV.
I can’t stress this enough. The path permissions up to and including the entry point for the jail MUST be owned by root and writable only by root. If not, the connection will fail.
You can increase the verbosity of the sftp connection using the -v, -vv, or -vvv flags with SFTP.