SFTP_Server
Contents
|
Installing and Configuring rssh
You'll need to emerge the restricted rssh shell, and then add it to the list of accepted shells:
emerge rssh echo /usr/bin/rssh >> /etc/shells
and you'll want to modify the rssh config and make some minor changes to enable chrooting, scp, and sftp.
| File: /etc/rssh.conf |
logfacility = LOG_USER allowscp allowsftp umask = 022 chrootpath="/home" |
If you wish to disable scp, or sftp independently, just remove the line or comment it out with a #.
What is SCP/SFTP?
FTP transmits data in "cleartext," meaning anyone between your computer and the host server you're connected to can potentially intercept critical information such as passwords. Fortunately, there are several file transfer standards (Scp and Sftp, for example) that are similar in function to FTP but utilize Secure Shell encryption to protect your information in transit. If you use a Unix-based server, you should be able to invoke either sftp or scp from the command line. GL cluster servers have scp installed on them.
Building the Chrooted Environment
- Next, we need to build a chroot environment for rssh to work.
This involves copying a few files to our chrooted folder (/home).
| Code: copying essential files into chroot |
cd /home/ mkdir -p usr/bin cp /usr/bin/scp usr/bin cp /usr/bin/rssh usr/bin mkdir -p usr/libexec mkdir -p usr/lib/misc cp /usr/lib/misc/rssh_chroot_helper usr/lib/misccp /usr/lib/misc/sftp-server usr/lib/misc |
Though we're not quite done copying files yet. Now we need to copy the dependencies of those files. ldd will tell us what files are needed
| Code: Finding dependent libraries |
# ldd /usr/bin/scp
libutil.so.1 => /lib/libutil.so.1 (0x4001c000)
libz.so.1 => /usr/lib/libz.so.1 (0x4001f000)
libnsl.so.1 => /lib/libnsl.so.1 (0x4002d000)
libcrypto.so.0.9.6 => /usr/lib/libcrypto.so.0.9.6 (0x40042000)
libc.so.6 => /lib/libc.so.6 (0x40106000)
libdl.so.2 => /lib/libdl.so.2 (0x40235000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000) |
So now we need to make the necessary folders, and copy the libs needed for scp.
| Code: copying libraries |
# cd /home # mkdir lib # cp /lib/libutil.so.1 lib # cp /lib/libnsl.so.1 lib # cp /lib/libc.so.6 lib # cp /lib/libdl.so.2 lib # cp /lib/ld-linux.so.2 lib # mkdir -p usr/lib # cp /usr/lib/libz.so.1 usr/lib # cp /usr/lib/libcrypto.so.0.9.6 usr/lib |
Now run ldd on the other files we copied into our chroot environment.
| Code: Finding other essential libraries |
# ldd /usr/bin/rssh # ldd /usr/lib/misc/rssh_chroot_helper # ldd /usr/lib/misc/sftp-server |
Copy the libraries associated with those files if there are any we didn't already get from scp. Note: for me, there were no other dependencies. copying all the dependencies for scp was enough for me. This should be the case for you as well unless your configuration is very different.
Or you can run the following copy these dependency files to your chroot for you
| Code: Script to finding and install other essential libraries |
# chroot=`sed -ne's/^chrootpath[^=]*=[^"/]*\(\|"\)\([^"]*\).*/\2/p' /etc/rssh.conf`
# for f in `ldd /usr/bin/rssh /usr/lib/misc/rssh_chroot_helper /usr/lib/misc/sftp-server /usr/bin/scp | sed -ne's/.*=> \([^ ]*\).*/\1/p' | sort -u | grep -v "^$"`; do echo "Copying $f to ${chroot}${f}"; cp $f ${chroot}${f}; done |
Note: You must have the destination directories setup before hand
Finally add the also required ld-linux.so.2 and libcrypt.so.1 libraries to the jail (otherwise sftp/scp won't work).
| Code: copying ld-linux.so.2 |
# cp /lib/ld-linux.so.2 lib # cp /lib/libcrypt.so.1 lib |
Note:If you are using /dev/log don`t forget to mkdir dev in your chroot and edit /etc/syslog-ng/syslog-ng.conf accordingly.
rssh_chroot_helper & suid
You have to check the rssh_chroot_helper to ensure it has SUID perm:
| Code: Setting Suid in rssh_chroot_helper |
# chmod u+s rssh_chroot_helper # ls -alh rssh_chroot_helper -rwsr-xr-x 1 root root 19K 2007-02-16 05:39 rssh_chroot_helper |
If SUID is not set, the chroot() call will not work and you will see this in /var/log/messages :
| Code: chroot() call fails if not suid |
Sep 27 09:17:14 server2 rssh_chroot_helper[26106]: chroot() failed, 2: Operation not permitted |
Note for AMD64 Users
AMD64 users need to have libraries in /lib64 and /usr/lib64. I made this work by:
| Code: Adding AMD64 links |
# ln -s lib lib64 # cd usr; ln -s lib lib64; cd .. |
Defining Users
- The only thing left to do now is create a user and change their shell to /usr/bin/rssh. there are a couple of ways to do this. you could run superadduser
| Code: |
# emerge superadduser
...
# superadduser
Login name for new user []: testuser
User ID ('UID') [ defaults to next available ]:
Initial group [ users ]:
Additional groups (comma separated) []:
Home directory [ /home/testuser ]
- Warning: '/home/testuser' already exists !
Do you wish to change the home directory path? (Y/n) n
Shell [ /bin/bash ] /usr/bin/rssh
Expiry date (YYYY-MM-DD) []: |
or simply modify an existing user account
# usermod -s /usr/bin/rssh testuser
Starting the Daemon and Testing
- Finally make sure sshd is running
| Code: checking sshd |
# /etc/init.d/sshd status : * status: started |
if not, run #/etc/init.d/sshd start and try connecting:
| Code: testing your connection |
# sftp testuser@yourip.com Connecting to yourip.com... testuser@yourip.com's password: sftp> ls . .. .bash_profile .bashrc .qmail sftp> pwd Remote working directory: /testuser sftp> exit ssh testuser@yourip.com testuser@yourip.com's password: This account is restricted to scp or sftp. If you believe this is in error, please contact your system administrator. Connection to yourip.com closed. |
Voilà! sftp with chrooting, and no shell allowed!
Possible problems: a user can create .ssh unless it already exists and add some LD_PRELOAD stuff to .ssh/environment resulting in arbitrary code execution (within the chroot). Also tools like courier-maildrop might induce problems, because .mailfilter may contain shell commands.
See Also
Getting scp to work
To get scp working I have learned you must copy these files too:
cd /home cp /lib/libnss_compat.so.2 lib
mkdir etc cp /etc/passwd etc ### Be sure to edit the password after copying! ### Leave only the user needed to login with.
Easier passwd example
cd /home/(user) mkdir etc cd etc getent passwd (user) > passwd
Solution to "connection closed"
If you get "connection closed" when trying to log on via sftp, try:
mkdir /your/chroot/dir/dev mknod -m 666 /your/chroot/dir/dev/null c 1 3
Sometimes one of /lib/libnss_* files may be required. In my case it was /lib/libnss_compat.so.2
cp /lib/libnss_compat.so.2 /your/chroot/dir/lib/
If you are using one chroot per user wrong permissions in rssh.conf can also cause "connection closed":
user=adam:077:00010:/home/rssh_chroot/adam
in my case mis-typing 077 as 0077 or 00010 as 0010 or 000010
Any idea how to have one chroot per user?
This is done by creating separate chroot directories for each user. Let's take our user Adam as an example.
First, make a parent chroot dir. Nothing will actually chroot to this, it's just a tidy way to do this. You can use regular home dirs if you want, it really doesn't matter. I do it this way so I know at a glance that these users are rssh chroot'ed users.
- mkdir /home/rssh_chroot
Now create Adam's dir:
- mkdir -p /home/rssh_chroot/adam
- chown adam:adam /home/rssh_chroot/adam
- chmod 770 /home/rssh_chroot/adam
Now, follow the above instructions for creating a chroot WITHIN the adam directory, replacing "/home" with "/home/rssh_chroot/adam" in the procedures. Add the following line, edited as you want, to /etc/rssh.conf:
user=adam:077:00010:/home/rssh_chroot/adam
Once the files necessary for a chroot are in place:
- cd /home/rssh_chroot
- chown -R root:root adam/lib
- chmod –R 755 adam/lib
- chown -R root:root adam/usr
- chmod –R 755 adam/usr
- chown adam:adam /home/rssh_chroot/adam
- chmod 770 /home/rssh_chroot/adam
You can now repeat this for any other user. Each will have a separate copy of the necessary libraries, but this is the only way to accomplish this. I would start by copying the entire adam dir to a new name, and simply chown-ing the dir to the new user:
- cp –Rp adam betty
- chown betty:betty betty
Then add the right line to /etc/rssh.conf:
user=betty:077:00010:/home/rssh_chroot/betty
Rinse. Repeat.
Additional tips and tricks
There were a few other things I had to do to get this working. I was having a problem that appears to be common: you get a "connection closed" with no other hint of what's going wrong and you are positive that your shared libs are set up correctly. Well, I figured it out!
First, you definitely want to set things up so that you can see the log messages that rssh_chroot_helper will log while executing in the jail. This was the key to solving the problem. For syslog-ng, this is easy; look for the source src code> section in the /etc/syslog-ng/syslog-ng.conf file and add unix-string("/chroot/jail/dev/log"); code> just after the unix-string("/dev/log"); code> line. Be sure to restart syslog-ng.
Once I did this, I started seeing log messages from rssh_chroot_helper in /var/log/messages, and in fact saw this nasty one: sftp-server[4589]: fatal: No user found for uid xxxx code>. This indicated that I was missing an /etc/passwd file in the chroot jail. I copied a minimal version of my system /etc/passwd to /chroot/jail/etc/passwd, and also a minimal /etc/group to /chroot/jail/etc/group and wonder of wonders, it all worked perfectly.
A few additional things I noticed after getting the basic configuration working:
- Your jailed /etc/passwd can be mostly fake; apparently the only thing that sftp-server really cares about are the usernames, uids, and gids. I used /dev/null as the homedir and /bin/false as the shell even though I didn't have /bin/false in the jail. Didn't seem to matter.
- Your jailed /etc/group is mostly fake too. Again, it only cares about group names and gids. Specifically group membership is taken from the system's /etc/group not /chroot/jail/etc/group
- You only need a very minimal set of executables in your jail. I narrowed it down to /chroot/jail/usr/bin/sftp and /chroot/jail/usr/lib/misc/sftp-server. Specifically you don't need rssh or rssh_chroot_helper in the jail. Note that I'm only allowing sftp so if you allow other rssh programs (e.g. scp) you'll have to put them up there too.
- You do need a /chroot/jail/dev/null as described above. You don't need to create /chroot/jail/dev/log as syslog-ng will create it correctly.
- The minimal set of shared libs I needed to copy were:
- lib/ld-linux.so.2
- lib/libc.so.6
- lib/libcrypt.so.1
- lib/libdl.so.2
- lib/libncurses.so.5
- lib/libnsl.so.1
- lib/libnss_compat.so.2
- lib/libresolv.so.2
- lib/libutil.so.1
- lib/libz.so.1
- usr/lib/libcrypto.so.0.9.8
- usr/lib/libssl.so.0.9,8
And that's it! Hope that helps. pumpichank on gentoo forums
Alternative (Simpler) Solution
I used a similar method to the above for a long time, but got tired of having to update libraries within the chroot'd jail every time I updated OpenSSL, OpenSSH and a variety of other bits and pieces. Also, the users themselves had a habit of breaking things, as they had access to the library directories, which only confused them!
In the end, I cobbled a better solution together from a variety of papers out there on the 'net, and came up with a chroot'd SFTP solution (no SCP, unfortunately) that requires no messing about with libraries and so forth.
I've written this up: http://www.minstrel.org.uk/papers/sftp/
Note: my system runs Solaris, but I've had feedback from others that have successfully followed the instructions on a variety of Linux-based systems. The page has recently been updated to include detailed instructions for OpenBSD, and I have had reports of successful builds on SuSE (with minor tweaks), RedHat and, of course, Gentoo!
Hope this helps.
Yet Another (Simpler) Alternative Solution
Building a simplified chroot jail with static builds of rssh and openssh.
The hardest (time consuming) part about the setup discussed above is chasing dynamic libraries around with ldd and getting them into the chroot jail. This especially messy if you have a separate jail for each user. To get around this we compile rssh and sftp-server as static binaries. Download openssh and rssh. Configure them as:
CC='gcc -static' ./configure your-args-here && make
Then copy (or hardlink) and setuid rssh_chroot_helper
mkdir -p /chroot/user/usr/libexec/openssh ln sftp-server /chroot/user/usr/libexec/openssh/ ln rssh_chroot_helper /chroot/user/usr/libexec/ chmod 4755 /chroot/user/usr/libexec/rssh_chroot_helper
I recommend that you use your distro version of openssh and rssh for everything except the files which need to be in the jail. There is no need to 'make install' as we don't wish to install openssh or rssh over our existing distro copies. Just copy the ones out of the static-build tree and use 'em in the chroot jail!
Sure enough, sftp-server and rssh_chroot_helper are static:
[root@backup1 testuser]# find usr/ -type f -print -exec ldd {} \;
usr/libexec/openssh/sftp-server
not a dynamic executable
usr/libexec/rssh_chroot_helper
not a dynamic executable
Since sftp-server calls getpwnam(), glibc still dynamic links in the libnss code for doing password file lookups. For this reason, you will still need all the libraries referenced by libnss_files.so.X, in addition to libnss_files.so.X itself:
[root@backup1 testuser]# ldd /lib64/libnss_files.so.2
libc.so.6 => /lib64/libc.so.6 (0x00002aaaaacc6000)
/lib64/ld-linux-x86-64.so.2 (0x00002aaaaaaab000)
These files you will need to copy to your /chroot/user/lib(64) directory or sftp-server will complain in a hard-to-troubleshoot way:
sftp-server[2361]: fatal: No user found for uid 501
We also added "-a /chroot/user/dev/log" to syslogd's command line so that jailed users can still log to syslog. Your syslog may be configured differently here.
Below are all of the files in our jail, most of which can be hard-linked. etc/passwd must contain at least the line(s) of the user(s) logging into jail.
[root@backup1 testuser]# find dev/ etc/ lib64/ usr/ -not -type d dev/log dev/null etc/passwd lib64/libnss_files.so.2 lib64/ld-linux-x86-64.so.2 lib64/libc.so.6 usr/libexec/openssh/sftp-server usr/libexec/rssh_chroot_helper
Our (simple) /etc/rssh.conf:
[root@backup1 testuser]# cat /etc/rssh.conf | grep -v \# | grep . logfacility = LOG_USER allowsftp umask = 022 user=testuser:077:00010:/chroot/user/testuser
That's it! I hope this helps simplify the task of chrooting SFTP!
The Simplest Solution of Them All
Apparently the newest OpenSSH CVS already contains support for chrooting SFTP users (ChroootDirectory directive):
http://undeadly.org/cgi?action=article&sid=20080220110039
There is only support for SFTP though (no SCP). This appeared in OpenSSH 4.9 and higher
- I've had issues with this - I can't seem to get chroot working. Although with
- ForceCommand internal-sftp it seems users can't get a shell anyway, so this is
- an OK intermediate solution (without functional chroot) for the moment. I'd
- really like to get it working, if anyone has any tips then let me know. The
- server confirms authentication (LogLevel DEBUG in /etc/ssh/sshd_config) and
- the client receives "Request for subsystem 'sftp' failed on channel 0".
Browse categories > Applications > Network > FTP > SFTP
Browse categories > Gentoo Linux Wiki > Wiki maintenance > Cleanup
Created by NickStallman.net, Luxury Homes Australia
Real estate agents should be using interactive floor plans and real estate agent tools.
