source: http://ubuntuforums.org/showthread.php?t=128206
I noticed many people wanted to set up a secure way (non cleartext and authentication required) to transfer files but wanted to limit their users from accessing a shell or browsing the entire file system. For the past week, I have been searching for a way to do this myself.
However, most of the solutions posted to these requests didn't suit me:
chrootssh, which I found difficult to set up since it involved compiling from source instead of installing from a package; set up another ftp server (like vsftpd), since I already had sshd running, I didn't want to manage another server and I was having difficulty getting this to work securely; setting the user's shell to the sftp-server, which still allowed to user to get out of their directories (but limited the user to sftp).
I also tried rssh unsuccessfully once before finding a HOWTO from the gentoo-wiki website
HOWTO_SFTP_Server_(chrooted%2C_without_shell). (Many thanks to them). I adapted their HOWTO slightly to work for Ubuntu.
It took me a week to finally set it up and get it working since I started trying. I hope this HOWTO will help anyone else who wants to do this, but since I am writing this HOWTO after I set it up, I may accidentally forget a step. In addition, my system may differ from your's (FYI, Ubuntu Breezy with i686 kernel; but even if you have the same, your configs may differ). I make no
guarantees that this will work on your system. I am just writing this in hopes that it will help. Feel free to post any suggestions/comments/questions/corrections. NOTE: I only tested my setup for SFTP.
First, you need the "openssh-server" package. (I assume you already have that installed, updated, and configured. If not, it is pretty easy to do so & there are other tutorials available. You can get it through Synaptic Package Manager.)
Then get the "rssh" package through Synaptic or through apt-get.
Once that is ready, you can configure rssh by editing the file "/etc/rssh.conf". (You probably want to make a backup copy of that file by typing the command:
sudo cp /etc/rssh.conf /etc/rssh.orig.conf
The command I used to edit /etc/rssh.conf was :
sudo nano /etc/rssh.conf
Note: you need the nano text editor to do this. replace "nano" with "gedit" or another text editor if you want.
The file should already be mostly filled out. Just uncomment (by removing the '#') the lines "#allowsftp" to allow sftp and if you want, uncomment the line "#allowscp". I left "#allowscp" commented since I only wanted sftp.
There should be a line in "/etc/rssh.conf" that currently reads:
#chrootpath = "/usr/local/chroot dir"
change it to:
chrootpath = "/home/chroot"
(uncomment the line and change the path to "/home/chroot". The path is personal preference, but I decided "/home/chroot".) Doing this tells rssh to chroot jail everyone using rssh to the directory "/home/chroot".
At this point, your rssh.conf file should have the following uncommented lines:
logfacility = LOG_USER
allowsftp
umask = 022
chrootpath = "/home/chroot"
Now to make sure OpenSSH does not weaken rssh (gunzip and read "/usr/share/doc/rssh/SECURITY" for more information), make sure you have the latest package for openssh-server and run the following command:
cat /etc/ssh/sshd_config | grep "PermitUserEnvironment"
If you see the line beginning with "PermitUserEnvironment", use your text editor to either remove the line from "/etc/ssh/sshd_config" or to change the line to
PermitUserEnvironment=no
Now to build the chrooted directory. There should be a zipped script at "/usr/share/doc/rssh/examples/mkchroot.sh.gz". Unzip the file, make a copy and edit the copy. You can do so using the following series of commands
sudo gunzip /usr/share/doc/rssh/examples/mkchroot.sh.gz
sudo cp /usr/share/doc/rssh/examples/mkchroot.sh ~/mkchroot.sh
sudo nano ~/mkchroot
If you scroll through the file, you will find the lines:
scp_path=/usr/bin/scp"
sftp_server_path=/usr/lib/sftp-server"
rssh_path=/usr/bin/rssh"
chroot_helper_path=/usr/lib/rssh/rssh_chroot_helper"
Make sure these paths match the ones given when you type the following command:
rssh -v
If they do not match, change your script so the paths match.
If your setup is like mine, your sftp server will actually be located in "/usr/lib/openssh/sftp-server" instead of "/usr/lib/sftp-server", which is where rssh thinks the sftp-server is. If this is your case, change
sftp_server_path=/usr/lib/sftp-server"
to
sftp_server_path=/usr/lib/openssh/sftp-server"
Save the script and exit the editor.
Then make the script executable with the following command:
sudo chmod u+x ~/mkchroot.sh
Now remember how you made
chrootpath = "/home/chroot"
in "/etc/rssh"? Well, now you actually make the chroot directory by running the following commands:
cd ~
sudo ./mkchroot.sh /home/chroot
While running that command, don't worry if you get the error saying that it cannot copy "linux-gate.so.1". It isn't a real file. However, you will probably need to copy the file "ld-linux.so.2" if it appears when you type the command:
ldd /usr/bin/scp | grep "ld-linux.so.2"
but is not in the path "/home/chroot/lib/ld-linux.so.2". You can copy the file with the following commands:
cd /home/chroot
sudo cp /lib/ld-linux.so.2 lib/
Just to play it safe, make sure you have "libnss_compact.so.2" in the directory "/home/chroot/lib". If not, put it there with the following command:
sudo cp /lib/libnss_compact.so.2 /home/chroot/lib/
Now make rssh a valid shell by running the command:
add-shell /usr/bin/rssh
Now create a new user (I called mine "sft" for secure file transfer). Make the shell for the new user "/usr/bin/rssh". Make sure the home directory path is inside the chroot jail. For me, I made the home directory "/home/chroot/home/sft". If you don't know how to add a user, there is a GUI under System -> Administration -> Users and Groups.
Now to apply the finishing touches and tie up loose ends:
For logging to work properly, you need to tell sysklogd to listen to "/home/chroot/dev/log". You can do this by editing "/etc/init.d/sysklogd".
Warning
You can seriously mess up your system logging if you mess up here. BE CAREFUL!
(you can replace nano with your text editor of choice). Run the following to edit "/etc/init.d/sysklogd":
sudo nano /etc/init.d/sysklogd
You should find a line that starts with:
SYSLOGD=
Simply add the following in the appropriate space on the line:
-a /home/chroot/dev/log
If your config is like mine, the original line will read:
SYSLOGD=-u syslog"
The new line will read:
SYSLOGD=-a /home/chroot/dev/log -u syslog"
You will need to tell sysklogd to restart to get the new config; use the following command:
sudo /etc/init.d/sysklogd restart
From what I read online, some programs may need /etc/passwd in order to run properly (I think scp). To play it safe, place a copy of /etc/passwd in the chroot directory using the following command:
sudo cp /etc/passwd /home/chroot/etc/
For security reasons, you will probably want to remove all irrelevant lines from the passwd file in "/home/chroot/etc/". So for my passwd file, since the name of the account that will use this chrooted directory, I only have the line:
sft:x:1001:1001:Secure File Transfer Account,,,:/home/sft:/usr/bin/rssh
Warning
Please edit only the chroot copy of the passwd file, not the real one in /etc/passwd
You can use nano or another text editor to remove the other lines. (I also changed the home directory in the chroot passwd file from "/home/chroot/home/sft" to "/home/sft". I'm not sure if this is necessary, but I did this because I felt this will be better.)
In order for the chrooting process to work, "/usr/lib/rssh/rssh_chroot_helper" has to be setuid root. (Note: this path is relative to real root, not chroot root.) To setuid root, run the command:
sudo chmod u+s /usr/lib/rssh/rssh_chroot_helper
Now remember how rssh thinks that the sftp subsystem is located at "/usr/lib/sftp-server" but it is actually located in "/usr/lib/openssh/sftp-server"? If not, you can run the command:
rssh -v
to figure it out. (Note: if this is not the case on your system, since our configs may differ, you should not follow this step and you should not follow one of the previous steps where you changed sftp_server_path=/usr/lib/sftp-server" to sftp_server_path=/usr/lib/openssh/sftp-server".)
If however, your sftp-server is located in "/usr/lib/openssh/" and rssh thinks that it is located in "/usr/lib/" and your sshd (ssh server) thinks that the sftp subsystem is located at "/usr/lib/openssh/", make the following changes. (Note: you can check where sshd thinks the sftp subsystem is by the following command:
cat /etc/ssh/sshd_config | grep "Subsystem sftp "
First, create a link to "/usr/lib/openssh/sftp-server" at "/usr/lib/". (Note: I already found a symbolic link to sftp-server in my "/usr/lib", so I kept it as a symbolic link. However, a hard link seems more reasonable to me. I'll let you decide which one you want. If you don't know the difference between a symbolic link and a hard link, feel free to look it up; if you know how to explain the difference properly, please post an explanation.)
To create the symbolic link, use the command:
sudo ln -s /usr/lib/openssh/sftp-server /usr/lib/
To create the hard link, use the command:
sudo ln /usr/lib/openssh/sftp-server /usr/lib/
Now that the sftp-server exists in "/usr/lib", you can change the config file for your sshd. Use your text editor to edit "/etc/ssh/sshd_config". For me, the command was:
sudo nano /etc/ssh/sshd_config
Then find the line:
Subsystem sftp /usr/lib/openssh/sftp-server
and replace it with:
Subsystem sftp /usr/lib/sftp-server
Save and exit the text editor when done. In order for the new config to take effect, you need to tell sshd to reload the config using the following command:
sudo /etc/init.d/ssh reload
Now you have to fix your chroot directory setup (you need to be able to run "/usr/lib/sftp-server" even when chrooted). To do this, create a hard link between for "/home/chroot/usr/lib/openssh/sftp-server" at "/home/chroot/usr/lib/" using the following command:
sudo ln /home/chroot/usr/lib/openssh/sftp-server /home/chroot/usr/lib/
Finally, there may be some files in the rsshed account's home directory like ".bashrc". If these are not needed, you can just delete them using the command "rm".
At this point, your setup should be done (unless you or I missed a step).
Fire up your favorite SFTP client and test the new setup. Hopefully it will work. Now try to ssh in using the rsshed account. A message should appear, and then rssh should exit, closing the connection.
If you get a "connection closed" error and you have followed all the steps, adding null to your chrooted dev directory may help. You can do this with the command
mknod -m 666 /home/chroot/dir/dev/null c 1 3
where /home/chroot is the chroot directory.
Side note: If the user with the chrooted rsshed account manages to get to the server & get to the graphical login, they can login like a normal user (without chroot restrictions & without protection provided by rssh since the rssh shell is not the login shell).
Warning
I have discovered that this setup will still allow people to use the port forwarding feature of SSH if it is enabled on the server. See the info section below for the fix
Tip
Update on AllowTcpForwarding:
You can use "Match" in your sshd_config to allow/disallow certain groups/users the ability to forward TCP connections.
# Example of overriding settings on a per-user basis
#Match User anoncvs
# X11Forwarding no
# AllowTcpForwarding no
# ForceCommand cvs server
Match Group chroot
AllowTcpForwarding no
(You need to place the rssh users into a group called "chroot" in this example.)