Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I needed to provide multiple users FTP logins, some able to write, some only to read, to a single FTP root directory. I very much wanted that they not see of the file system anything above that directory. After searching—it appears this is a common problem—I defined the user_local config option as the root directory and confined the users to that directory using the chroot_local_users option, or chroot jail. This basically works.

My problem is that, though I do not know why, relying on chroot jail for security is frowned upon generally and most importantly by (at least one member of) the kernel development team.

So, how can I confine my login users to (even) seeing nothing above the defined root directory without chroot jail?? (this is the "secure" part of the question alluded to in the title)

Also, for security reasons (that I do not yet understand), modern versions of vsftpd do not allow the user's root directory to be writable, thus leaving two options: 1. or to disable the security feature and leave the root writeable or 2. to remove the write bits from the root and create a writable sub-directory therein. The former is playing with fire and the latter is ugly and error prone (users trying to write into the root and getting errors…) I chose the latter.

So, how is FTP service done right? Meaning how can users be prevented from seeing irrelevant parts of the file system in secure way? Is FTP an inherently insecure way of distributing files? If so, is there a better way. Trying to get this right…

share|improve this question
Note that "chroot" generally refers to a login chroot jail, not showing only a subset of the system through a specific service (FTP, say). You don't generally say that Apache serves files out of a chroot either; it serves them out of the document root, which accomplishes the same thing: restricting what portions of the system ordinary users can access through the service in question. This difference of terms might be a contributing factor in your confusion. –  Michael Kjörling May 21 '13 at 14:04
@MichaelKjörling Thank you for that. That does clear up chroot for me and helps me better understand the problem. With apache, there is no concept of users logging in. a client makes a request and the apache process serves the request out of a defined subset of the file system, good. FTP has users logging in, granting them access to the file system. No doubt, I'm missing something, but I don't see how what you wrote illuminates my issue. But if you have a solution--the problem is all over the internet--please share for the benefit of all or point me to where I can research it and report back. –  naftalimich May 21 '13 at 14:13
The point is that both services expose a part of the server's file system to remote users. A quick Google for "vsftp restrict directory access" brought up this thread which recommends to "consider instead using virtual users, combined with the user_config_dir and user_sub_token parameters". I am not familiar with vsftpd, but it looks like local_root might also be useful, especially in combination with user_config_dir. –  Michael Kjörling May 21 '13 at 14:57

3 Answers 3

This question is all over the internet with no clear cut solution that I've found.

So here is where I stand on this now (I will update as I find out more).

Seems the fundamental problem is that FTP has users logging in and manipulating the file system, as opposed to an http client simply sending requests to an http service process.

So, it's very difficult to limit an FTP user from doing things his user has rights to do on the system were he to log in regularly. FTP users need to have execute rights for directories beyond where we want to limit his view access so that he can write or read from the his lower level branch. So the only easy way to limit his view access is to put him in chroot jail.

Chroot jail is not secure because it only "modifies pathname lookups for a process and its children so that any reference to a path starting '/' will effectively have the new root, which is passed as the single argument, prepended onto the path" but "the current working directory is left unchanged and relative paths can still refer to files outside of the new root." source http://lwn.net/Articles/252794/

What that means in a security context and how dangerous that really is relative to the FTP daemon and user rights I cannot say, but it does mean that the 'jail' in 'chroot jail' is a misnomer.

It appears that with a deep handle on linux, it's possible by defining process and user rights... to 'use' chroot in this security context, but neither I nor the myriad internet denizens struggling with this are 'there' yet.

It's also possible to harden chroot jail to where it really behaves like jail--To quote kernel developer Alan Cox, "chroot is not and never has been a security tool. People have built things based upon the properties of chroot but extended (BSD jails, Linux vserver) but they are quite different.You could probably write yourself an LSM module to do this too." I am not 'there' yet, but I do suspect that this in the end is 'the' solution, and I'd also hazard that the distribution ftp sites handle security along these or similar lines.

Practically speaking, all I can do now is use chroot jail, relying on that my server is a low priority target if one at all, and that my users are basically trustworthy. My security strategy will be to limit the damage one can do, if they do break out of the jail. Which entails configuring users appropriately, possibly virtual users, and perhaps running the whole service in a virtual machine.

As I progress in my studies, I hope to harden the chroot() concept via an LSM or the like for security, and I do note that according to the Alan Cox quote above BSD already has a 'jails' concept, so I'd might look into BSD for my FTP needs.

share|improve this answer

Here's how I created a jailed sftpuser for clients to sftp files to my server:

  1. Create the sftpgroup

    # groupadd sftpusers
  2. Create the sftpuser:

    # useradd -g sftpusers -d /incoming/client1 -s /sbin/nologin \
          client1srs passwd client1srs
  3. Modify user and make the user sftp onluy and put in sftp jail

    # usermod -g sftpusers -d /incoming -s /sbin/nologin client1srs
  4. Setup sftp-server Subsystem in sshd_config

    Modify /etc/ssh/sshd_config and comment out:

    # #Subsystem       sftp    /usr/libexec/openssh/sftp-server
  5. Then add the following:

    Subsystem       sftp    internal-sftp
  6. Specify Chroot Directory for Group

    Add the following lines at the end of /etc/ssh/sshd_config:

    Match Group sftpusers
           ChrootDirectory /sftp/%u
           ForceCommand internal-sftp
  7. Create SFTP home directory

    # mkdir /sftpdir/client1srs/incoming
    # chown client1srs:sftpusers /sftpdir/client1srs/incoming
  8. Restart sshd

    # /sbin/service sshd restart
share|improve this answer

Another possible if general answer (which may be wrong/impossible, I'm really hoping for feedback):

Create a separate partition to act as the root for the FTP users. Have nothing but relevant directories in this root partition. Use ACL's to remove execute permissions for all the FTP users for all the directories on the other partitions. Install the FTP server on the regular partition, so that the FTP user's partition isn't cluttered up with the program files.

This way the FTP users will only see the new partition's root, which I can structure as elegantly as I choose.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.