Mini Howto: sftp chroot

The goal:

Create an SFTP server with encryption.


Do not allow the SFTP users to reach/see the OS binaries on sftp sessions. Create unique environment for their logon session.

Do not allow the SFTP users to login to the server using ssh.

If possible, use the same service for legitimate admin tasks, etc…


Patch the openssh sftp-server.c file, and create a restricted shell for logons.


The following document is offered in good faith as comprising only safe programming and procedures. No responsibility is accepted by the author for any loss or damage caused in any way to any person or equipment, as a direct or indirect consequence of following these instructions. (and this disclaimer is shamelessly stolen from Setting up Samba over SSH Tunnel mini-HOWTO: Disclaimer)

The environment:

I used an old RH 8.0 box already loaded with openssh. How to disable the installed version and how to reenable the new version will not be covered in this document. I also used openssh-3.8p1.


1) First start by downloading the latest source of openssh.

untar it:

# tar xzvf openssh-3.8p1.tar.gz

Go to the openssh directory

# cd openssh-3.8p1/

2) Get the patch from here. The filename is sftp-chroot.diff. (There is also a howto in this directory. This is the howto i was inspired from. Very nice write-up. read it too!)

Save this patch in the openssh source directory (/path/of/openssh-3.8p1/)

3) Patch the sftp-server.c file by issuing this command:

# patch < ./sftp-chroot.diff
It will give you some results full of Hunks (well i guess at least three) This is good as long as it says succeeded in each one of them (Go check the diff file and admire the /./ trick for some time, drool…)

4) Now it`s time to configure your openssh compilation. It is totally up to you to choose where all of your files will reside. What I did is this

# ./configure –prefix=/opt/sshd –libexecdir=/opt/sshd/openssh –sysconfdir=/opt/sshd/conf –mandir=/opt/sshd/man –with-pid-dir=/opt/sshd/pid –with-pam

(I did this way because i wanted everything related to sshd to reside in a different partition that I mounted as /opt )

Most of Linux users can replace their distributions` openssh by configuring like this:

# ./configure –prefix=/usr –libexecdir=/usr/libexec/openssh –sysconfdir=/etc/ssh –mandir=/usr/share/man

For more info do a ./configure –help .

5) After the config comes a make:

# make

6) Here you have two options:

a) Completely install your compiled beautiful shiny new openssh binaries. (I chose shiny new ones)

# make install

b) Use your old but distro supported sshd.

locate where your sftp-server binary is and overwrite it with the one you just compiled. The fresh one should be in the source directory. (The old one in RedHat is in /usr/libexec/openssh/)

7) Create a restrictive shell for your sftp users:

Download the shell code from here. Compile it.

# gcc -o sftpsh sftpsh.c

Copy it to /bin

# cp sftpsh /bin

Add it to your shells file in /etc/shells

# echo “/bin/sftpsh” >> /etc/shells

(Read the code and understand what`s going on!)

8) Create a directory where you will chroot. (Again the directory is your choice.)

# mkdir /opt/sftproot

9) Create a test user:

# mkdir /opt/sftproot/sshdtest

# useradd sshdtest -d /opt/sftproot/sshdtest

# passwd sshdtest

# chown sshdtest.sshdtest /opt/sftproot/sshdtest

A lot of distros will create tiny little files like .bash_profile etc…, wipe them out if you don`t need them.

# rm ~sshdtest/.* ~sshdtest/*

10) Edit this user`s settings:

Edit /etc/passwd file and find your user`s line. Edit its home directory from /opt/sftproot/sshdtest to /opt/sftproot/./sshdtest (Yes there is a /./ there!)

Also edit its shell to /bin/sftpsh

The user entry in /etc/passwd should look like this:


(The bolds are important 666s can be different)

11) You should be good to go!

Test your new settings. First try to ssh to your machine. enter the password of sshdtest user. You shouldn`t be allowed for a login.

Then try to sftp to this box. you should only see your home directory and when you type cd / you should only go to / of your chrooted environment.

Enjoy! 🙂


Original howto

A little bit more detailed howto

Leave a Reply