As many people might know, I am a bit security paranoid when it comes to my servers and sending stuff over the Internet in plain text. Therefore have I been using SFTP and SSH when I needed something sent over the Internet to my servers.
SFTP does however have a downside, in order to get the security of data encryption using sftp you will have to create an user account on the server with a valid shell, and therefore would every user have access to the whole system in read mode, which is a security risk.
One of the solutions would be to make a chroot for each user on the server, but this is both time consuming and a complete waste of space.
I finally found a good solution, there is a patched version of OpenSSH which gives a chroot feature of making sftp only connections, this however does not allowed the user to use a shell also, it’s either sftp or ssh, not both, if you need this, you will have to create a chroot for every user.
There is however a problem with the new patch, the author only give guiding for a source installation or using OpenBSD, but my servers are running Debian Etch and Ubuntu (7.04 and 7.10), so there is some new steps in order to get it working the debian-way.
1. Get the debian-way tool
First of you need to get the tools from Debian in order to be able to compile your own sources, Debian makes this easy for us, the only thing you should need is the build-essential package, which easily can be installed by running apt-get install build-essential.
2. Get the source of your current openssh-server
Now you’ll need the source for the current version of openssh-server for your Debian version. Most default installs of Debian does not include a deb-src source, so you will need to add a deb-src to your apt sources.list file, look it up in the documentation.
It’s a good idea to be in a temporary dir while unpacking, editing and installing a source package, so first I will jump into /tmp and install the source. Next I will unpack the source of openssh-server and finally install all packages which depends on openssh-server in order to make it compile.
root@dudi:~# cd /tmp
root@dudi:/tmp# apt-get source openssh-server
root@dudi:/tmp# apt-get build-dep openssh-server
3. Patching the source
It’s now time to patch the openssh-server source with some minor changes to the sftp-server.c file, I have uploaded 3 different versions with the new code added, this will not conclude that it will work with your source, the most secure thing would be to open the source in your browser, search for zephid or Minstrel, and paste the code into your sftp-server.c file.
- http://www.zephid.dk/wp-content/uploads/sftp-chroot/debian_etch/sftp-server.c (Debian etch / openssh-server_4.3p2-9)
- http://www.zephid.dk/wp-content/uploads/sftp-chroot/ubuntu_fesity/sftp-server.c (Ubuntu fesity / openssh-server_4.3p2-8)
- http://www.zephid.dk/wp-content/uploads/sftp-chroot/ubuntu_gutsy/sftp-server.c (Ubuntu gutsy / openssh-server_4.6p1-5)
The fast method:
root@dudi:/tmp# cd openssh-*
root@dudi:/tmp/openssh-4.3p2# rm sftp-server.c
root@dudi:/tmp/openssh-4.3p2# wget an_url_from_above
Manual method (Find and paste code):
root@dudi:/tmp# cd openssh-*
root@dudi:/tmp/openssh-4.3p2# nano -w sftp-server.c
4. Compiling and installing the patched openssh-server
It is now time to compile and install the new patched openssh-server, this is easy, we will first create a Debian package (deb) and use dpkg to install it.
root@dudi:/tmp/openssh-4.3p2# dpkg-buildpackage -uc -b
root@dudi:/tmp/openssh-4.3p2# cd ..
root@dudi:/tmp# dpkg -i openssh-server_4.3p2-9_i386.deb
By now you should have a running patched openssh-server, its a good idea to check it by trying to shh to localhost and see if it responses correctly, a common error if something is wrong is a “Connection reset” error, if that happens you will have to remove, purge and install the openssh-server package and try again.
5. Getting a new sftp-only shell
Download sftpsh.c to /tmp
Locate the path to sftp-server (/usr/lib/openssh/sftp-server on most Debian installations)
Open sftpsh.c in an edtior and locate SFTP_BINARY and change the path to your sftp location.
Compile and install the shell:
root@dudi:/tmp# gcc sftpsh.c -o sftpsh
root@dudi:/tmp# cp sftpsh /bin/
root@dudi:/tmp# echo /bin/sftpsh >> /etc/shells
root@dudi:/tmp# chmod +s /usr/lib/openssh/sftp-server
This will install the sftp-only shell to /bin/sftpsh and make it a valid shell by adding it to /etc/shells.
Since the patch uses suid to chroot and lock an user, we will need to give chmod +s to the sftp-server program.
6. Using the sftp chroot
Using the sftp-chroot is easy, first you will have to change the default shell for the user you want locked to sftp and his/hers home dir. The new shell would be /bin/sftpsh.
Secondly you will have to add a ‘full stop’ to the users home dir, eg. /home/zephid/./
There are different methods to add these options, I personally make the changes manually by editing the /etc/passwd file by hand, this is however far from safe, one typo and you might have a complete locked down system with no user/root access.
A more safe method would be to use the usermod tool provided by Debian, eg:
root@dudi:/tmp# usermod -s /bin/sftpsh \
-d /home/zephid/./ zephid
You should now be able to login by using sftp user@host but not by using ssh user@host, if you can do both, you did something wrong somewhere in this guide.
7. Preventing upgrade
While I was working, I realised that apt-get would upgrade openssh-server with the package from it own repository, this is however easy to fix by running:
root@dudi:~# echo “openssh-server hold” | dpkg –set-selections
This will put the openssh-server on hold, this could be a security issue since you want be noticed if there is a new version available, therefore would it be a good idea to add yourself to some kind of maillinglist which will notice you when there is a new packages available.
This code is not supported by anyone, therefore use it with care and have a backup ready if something goes wrong, my first attempt with this was a broken openssh-server which made it impossible to login, I therefore recommend trying this out in a Virtualbox with no sensitive data.
Thanks to Jason A. Dour for the sftpsh.c program and Minstrel for making this possible.