≡ Menu

How to Setup Chroot SFTP in Linux (Allow Only SFTP, not SSH)

If you want to setup an account on your system that will be used only to transfer files (and not to ssh to the system), you should setup SFTP Chroot Jail as explained in this article.

In a typical sftp scenario (when chroot sftp is not setup), if you use sftp, you can see root’s file as shown below.

If you want to give sftp access on your system to outside vendors to transfer files, you should not use standard sftp. Instead, you should setup Chroot SFTP Jail as explained below.

Non-Chroot SFTP Environment

In the following example (a typical sftp environment), john can sftp to the system, and view /etc folder and download the files from there.

# sftp john@thegeekstuff.com
john@thegeekstuff's password:
sftp> pwd
Remote working directory: /home/john

sftp> ls
projects  john.txt documents 

sftp> cd /etc
sftp> ls -l passwd
-rw-r--r--    0 0        0            3750 Dec 29 23:09 passwd

sftp> get passwd
Fetching /etc/passwd to passwd
/etc/passwd     100% 3750     3.7KB/s   00:00

Chroot SFTP Environment

In the following example, john can sftp to the system, and view only the directory that you’ve designated for john to perform sftp (i.e /incoming).

When john tries to perform ‘cd /etc’, it will give an error message. Since SFTP is setup in an chroot environment, john cannot view any other files in the system.

# sftp john@thegeekstuff.com
john@thegeekstuff's password:
sftp> pwd
Remote working directory: /home/john

sftp> ls
sftp> cd /etc
Couldn't canonicalise: No such file or directory

Now that you know what Chroot SFTP environment is, let us see how to set this up.

1. Create a New Group

Create a group called sftpusers. Only users who belong to this group will be automatically restricted to the SFTP chroot environment on this system.

# groupadd sftpusers

2. Create Users (or Modify Existing User)

Let us say you want to create an user guestuser who should be allowed only to perform SFTP in a chroot environment, and should not be allowed to perform SSH.

The following command creates guestuser, assigns this user to sftpusers group, make /incoming as the home directory, set /sbin/nologin as shell (which will not allow the user to ssh and get shell access).

# useradd -g sftpusers -d /incoming -s /sbin/nologin guestuser
# passwd guestuser

Verify that the user got created properly.

# grep guestuser /etc/passwd

If you want to modify an existing user and make him an sftp user only and put him in the chroot sftp jail, do the following:

# usermod -g sftpusers -d /incoming -s /sbin/nologin john

On a related note, if you have to transfer files from windows to Linux, use any one of the sftp client mentioned in this top 7 sftp client list.

3. Setup sftp-server Subsystem in sshd_config

You should instruct sshd to use the internal-sftp for sftp (instead of the default sftp-server).

Modify the the /etc/ssh/sshd_config file and comment out the following line:

#Subsystem       sftp    /usr/libexec/openssh/sftp-server

Next, add the following line to the /etc/ssh/sshd_config file

Subsystem       sftp    internal-sftp
# grep sftp /etc/ssh/sshd_config
#Subsystem      sftp    /usr/libexec/openssh/sftp-server
Subsystem       sftp    internal-sftp

4. Specify Chroot Directory for a Group

You want to put only certain users (i.e users who belongs to sftpusers group) in the chroot jail environment. Add the following lines at the end of /etc/ssh/sshd_config

# tail /etc/ssh/sshd_config
Match Group sftpusers
        ChrootDirectory /sftp/%u
        ForceCommand internal-sftp

In the above:

  • Match Group sftpusers – This indicates that the following lines will be matched only for users who belong to group sftpusers
  • ChrootDirectory /sftp/%u – This is the path that will be used for chroot after the user is authenticated. %u indicates the user. So, for john, this will be /sftp/john.
  • ForceCommand internal-sftp – This forces the execution of the internal-sftp and ignores any command that are mentioned in the ~/.ssh/rc file.

5. Create sftp Home Directory

Since we’ve specified /sftp as ChrootDirectory above, create this directory (which iw equivalent of your typical /home directory).

# mkdir /sftp

Now, under /sftp, create the individual directories for the users who are part of the sftpusers group. i.e the users who will be allowed only to perform sftp and will be in chroot environment.

# mkdir /sftp/guestuser

So, /sftp/guestuser is equivalent to / for the guestuser. When guestuser sftp to the system, and performs “cd /”, they’ll be seeing only the content of the directories under “/sftp/guestuser” (and not the real / of the system). This is the power of the chroot.

So, under this directory /sftp/guestuser, create any subdirectory that you like user to see. For example, create a incoming directory where users can sftp their files.

# mkdir /sftp/guestuser/incoming

6. Setup Appropriate Permission

For chroot to work properly, you need to make sure appropriate permissions are setup properly on the directory you just created above.

Set the owenership to the user, and group to the sftpusers group as shown below.

# chown guestuser:sftpusers /sftp/guestuser/incoming

The permission will look like the following for the incoming directory.

# ls -ld /sftp/guestuser/incoming
drwxr-xr-x 2 guestuser sftpusers 4096 Dec 28 23:49 /sftp/guestuser/incoming

The permission will look like the following for the /sftp/guestuser directory

# ls -ld /sftp/guestuser
drwxr-xr-x 3 root root 4096 Dec 28 23:49 /sftp/guestuser

# ls -ld /sftp
drwxr-xr-x 3 root root 4096 Dec 28 23:49 /sftp

7. Restart sshd and Test Chroot SFTP

Restart sshd:

# service sshd restart

Test chroot sftp environment. As you see below, when gusetuser does sftp, and does “cd /”, they’ll only see incoming directory.

# sftp guestuser@thegeekstuff.com
guestuser@thegeekstuff's password:

sftp> pwd
Remote working directory: /incoming

sftp> cd /
sftp> ls

When guestuser transfers any files to the /incoming directory from the sftp, they’ll be really located under /sftp/guestuser/incoming directory on the system.

Add your comment

If you enjoyed this article, you might also like..

  1. 50 Linux Sysadmin Tutorials
  2. 50 Most Frequently Used Linux Commands (With Examples)
  3. Top 25 Best Linux Performance Monitoring and Debugging Tools
  4. Mommy, I found it! – 15 Practical Linux Find Command Examples
  5. Linux 101 Hacks 2nd Edition eBook Linux 101 Hacks Book

Bash 101 Hacks Book Sed and Awk 101 Hacks Book Nagios Core 3 Book Vim 101 Hacks Book

Comments on this entry are closed.

  • Suresh Danda March 28, 2012, 2:54 am


    Nice post Ramesh Natarajan.

    It helps for single sftp user environment … we can do like below in easy way also.

    and also it works for multiple users also.

    If we are using (openssh-server-4.3p2-30.el5) which is shipped in Red Hat enterprise Linux 5.4

    1.Create a specific chrooted directory.
    #mkdir /chroot/home
    2.Mount it to /home as follows:
    mount -o bind /home /chroot/home
    3.Edit /etc/ssh/sshd_config as follows:
    ChrootDirectory /chroot
    Subsystem sftp internal-sftp
    4.Save & Exit
    4.service sshd restart


  • Eric March 28, 2012, 3:18 am


    Take into account that the match keyword is not supported in older versions (<5) on SSH so your solution will not work on for example RHEL 5.7 which has version 4.X installed. An upgrade of openssh will be necessary.

    Kind regards,


  • pat March 28, 2012, 3:24 am

    To increase security just a little bit more: Add the rssh shell to this setup.

  • Jalal Hajigholamali March 28, 2012, 6:10 am


    Very Nice post

    Thanks a lot for your nice topics….

  • Babar Singh March 28, 2012, 6:32 am

    Thanks for the post. Helped a lot

  • Luis Rojas March 28, 2012, 8:22 am

    Very nice post, just in time to help me set up precisely this kind of access at my company.

    Thank you!

  • bob March 28, 2012, 9:35 am

    nice post. But what does the acronmym “chroot” stand for. If you explain that it will make it easier to recall it in a few months.

  • Chroot March 28, 2012, 4:03 pm

    chroot = change root directory, a chrooted service doesn’t ‘see’ the rest of the filesystem (well, roughly, there’s the headache of running binaries in a chrooted environment and whatnot, but that’s another story!)

  • tohid ansari June 11, 2012, 10:16 pm

    good document and easy.thank

  • Alberto June 29, 2012, 12:44 am

    Great post !!!!!

  • Itamar July 24, 2012, 2:32 am

    I am trying with server CentOS 6.2 with openssh 5.3 (Eric is right) and WinSCP client.
    I have did everything exactly how it’s written here, but I am getting this error on the WinSCP client:
    Error listing directory ‘incoming’
    Permission denied.
    Error code: 3
    Error message from server: Permission denied
    Request code: 11
    Any ideas?

  • Soultani July 31, 2012, 9:08 pm

    Hi Itamar..

    I’m facing the same problem to not so long ago.. it turn out SELinux was the culprit. I did:

    # setenforce 0 (press enter)

    for more details here. and it works!! hope the same goes for you…..

  • Itamar August 4, 2012, 11:59 pm

    Hi Soultani,

    Thanks for the replay.

    The Selinux is not the issue in my case, it is disabled.
    FYI,I created a sub directory (under the user root-home) and gave the user full permissions, there the user is able to put his files. fine by me for now.

  • Preashant September 5, 2012, 9:07 pm

    Hi Soultani,

    Thanks for the replay. I have spend 3 days to resolve this issue thanks for your help

  • Marcos September 12, 2012, 9:18 am

    I sucessfully followed the instructions and it worked fine. Now I need to set the sftp user to connect without password, using certificates, but it doesn’t work. Any ideas?


  • FWord3 September 26, 2012, 12:56 pm

    Make sure the following ownership and permissions are set for your chroot sFTP account (Example is based on the user information in Ramesh’s artical above). It’s important that the guestusers home is owned by root. The permissions are also important especially for the home dir, .ssh dir, and authorized_keys file.

    # ls -ld ~guestuser
    drwxr-x-r-x 5 root root 4096 Sep 25 17:11 /sftp/guestuser

    #ls -al ~guestuser
    drwxr-x-r-x 5 root root 4096 Sep 25 17:11 .
    drwxr-x-r-x 5 root root 4096 Sep 25 17:11 ..
    drwx——- 5 guestuser sftpusers 4096 Sep 25 17:11 .ssh
    drwxr-x-r-x 5 guestuser sftpusers 126976 Sep 25 17:11 incoming

    # ls -l ~ddtocai/.ssh
    -rw——– 1 guestuser sftpusers 5522 Sep 25 17:11 authorized_keys

    NOTE: To further troubleshoot your access issue, use the sftp command with the -v flag set to enable verbose mode of the command. This will show you all the intraction between the sftp site and the user attempting access. You can also startup another sshd daemon on your sftp site in debug mode to listen on another port without interruption to your current running sshd daemons. Do the following to accomplish this.

    On the sftp device (you do not have to use port 3377, any open port will do):
    # /usr/local/sbin/sshd -p 3377 -d

    On the device attempting access:
    # sftp -P 3377 -v guestuser@sftpdevice

    The sshd daemon on port 3377 should exit after the first access attempt. If not use ctrl-c to exit.

  • Raghava September 27, 2012, 1:02 pm

    My requirement is like.. allow the user to sftp only but not SSH and want to share secure files eventually (either through hard liks/ soft links/ mount). I am fresh bee to RHEL with internal sftp, Please point me with the guidelines or solution ASAP.

  • Leticia September 30, 2012, 4:43 pm

    Thanks. Had a problem with sftp. This solved it.

  • Benoit October 17, 2012, 9:08 pm

    Thank you . Very clear and helpful.

  • James October 18, 2012, 7:46 am


    I followed the instructions but on the ssh restart i got:

    Starting sshd: /etc/ssh/sshd_config: line 131: Bad configuration option: Match
    /etc/ssh/sshd_config: line 132: Bad configuration option: ChrootDirectory
    /etc/ssh/sshd_config: line 133: Bad configuration option: ForceCommand
    /etc/ssh/sshd_config: terminating, 3 bad configuration options

    Do I need to upgrade ssh as suggested?

  • FWord3 October 18, 2012, 10:38 am

    Yes you have to upgrade your ssh version to at least 5.9 if I’m not mistaken.

  • Raghava October 18, 2012, 10:42 am

    I used sshpass tool to connect to remote sshd service. its connecting to that when I run it from command line but not get connecting when I run the same command through shell script. It shown command not found. what might be the issue?


  • FWord3 October 18, 2012, 10:48 am

    Your script runs in a seperate shell from your user account. You’ll need to add the path to the sshpass app in your script.

    Here is an example using tnsping. Just replace tnsping with sshpass for your use.

    # which tnsping

    Add the following line somewhere at the top of your script.

    export PATH=$PATH:/opt/oracle/bin

    NOTE: You’ll be replaceing /opt/oracle/bin with the path where sshpass was installed on your device.

  • Petr October 24, 2012, 5:37 am

    Very nice tutorial, I only have one question; What is the /incoming folder for and what is the sftp/$user/incoming from? Why are we setting the newly created user’s home folder to /incoming in step 2 (“useradd -g sftpusers -d /incoming -s /sbin/nologin guestuser”) but then creating a sftp folder in step 5 (“mkdir /sftp/guestuser/incoming”). Are steps 2 and 5 alternatives? Or what is /incoming folder in step2 the just somehow linked to the /sftp/guestuser/incoming? I appologize if that should be obvious, I’m just a poor rails programmer forced to do server admin stuff 😉

  • Petr October 24, 2012, 7:08 am

    Ok, things seem to be working even without me understanding how the /income folder gets mapped to /sftp/$user/income as the user’s home directory, but now I have another question, about allowing (possibly even only) public key access. Where do I now put the .ssh/authorized_keys? Again, maybe a stupid question, moderator if you feel like other people find it too stupid to ask, would you maybe just throw me a quick answer to my email?

    Also, one thing I had to change. Instead of using /sbin/nologin as user’s terminal, I had to change it to /usr/sbin/nologin, then it started working. I am on Ubuntu 10.04.

  • Conor November 22, 2012, 7:39 am

    Works great. Thanks a lot for this.
    For Ubuntu 12.04 I also had to use /usr/sbin/nologin for step 2

  • Dio December 16, 2012, 11:59 pm

    hi Ramesh, would like to ask. How about if we allow both sftp and ssh?

  • kumar January 18, 2013, 4:52 am

    with the set up i have created a user and its is working fine, but my requirement is i have to share the user say Kumar’s directory for another user Raja so that they both will be sharing the file.ie /sftp/kumar ‘s directory for raja too so that they can share files. How to do this.

  • Nic January 18, 2013, 11:27 pm

    Fyi, setting the shell to /sbin/nologin doesn’t seem to matter. The internal-sftp bit seems to take care of restricting ssh, but it seems like best practice anyway.

  • xman February 18, 2013, 7:08 am

    Works great. Thanks a lot for this.
    Linux 3.4.28-2.20-desktp
    openSUSE 12.2 (x86_64) – KDE 4.10.00 “release 550” openSSH 6.0p1-2.3.3-x86_64

  • Pascual February 20, 2013, 12:22 pm


    I think one of you found a similar problem:

    [root@ippbxtest ~]# service sshd restart
    Stopping sshd: [ OK ]
    Starting sshd: /etc/ssh/sshd_config: line 121: Bad configuration option: Match
    /etc/ssh/sshd_config: terminating, 1 bad configuration options
    [root@ippbxtest ~]# service sshd restart
    Stopping sshd: [FAILED]
    Starting sshd: /etc/ssh/sshd_config: line 121: Bad configuration option: Match
    /etc/ssh/sshd_config: terminating, 1 bad configuration options
    [root@ippbxtest ~]# service sshd start
    Starting sshd: /etc/ssh/sshd_config: line 121: Bad configuration option: Match
    /etc/ssh/sshd_config: terminating, 1 bad configuration options
    [root@ippbxtest ~]# service sshd start
    Starting sshd: /etc/ssh/sshd_config: line 121: Bad configuration option: Match
    /etc/ssh/sshd_config: terminating, 1 bad configuration options
    [root@ippbxtest ~]# service sshd stop
    Stopping sshd: [FAILED]
    [root@ippbxtest ~]# service sshd start
    Starting sshd: /etc/ssh/sshd_config: line 121: Bad configuration option: Match
    /etc/ssh/sshd_config: terminating, 1 bad configuration options
    [root@ippbxtest ~]# service sshd stop
    Stopping sshd: [FAILED]
    [root@ippbxtest ~]# service sshd start
    Starting sshd: /etc/ssh/sshd_config: line 121: Bad configuration option: Match
    /etc/ssh/sshd_config: terminating, 1 bad configuration options
    I am using CentOS 5.8. I have no idea on what version of openssh comes with this CentOS version so openssh must be in older versions (<5).

    Any suggestion apart from upgrading openssh?

  • mike March 7, 2013, 8:50 am

    Hi Pascual

    rpm -qa | grep openssh

    BTW whats in your /etc/ssh/sshd_config on line 121 ?
    there a slightly differences in naming of sftp, s maybe u have to change it a bit.

    @all , setenforce 0 is not really a solution it’s a dirty workaround.
    you should set the policies accordingly

  • Sultan April 17, 2013, 4:03 am

    Not so long ago, I told you to disabled the SELinux…. well, not anymore.. Just now I found a good tutorial about it here. for more detail and sample about SELinux, you can watch this RedHat Summit . Hopefully this is clear up what we need to enable sftp withoud disabled the SELinux.

  • Pedro Azevedo May 27, 2013, 3:32 am


    I do not want the incoming folder
    I want /sftp/user
    No /sftp/user/incoming

    But if i change the user home to / (not /incoming), i can not do anything (like make dir, add files) because the user not have permissions.

    If i cange the /sftp/user folder owner i can not login.

  • jithinsha May 29, 2013, 5:36 am

    This is the excellent post. I have tried this and its working very fine. But i tried the same with /var/www/html as the directory.

    ls -ld /var/www/html/
    drwxr-xr-x. 5 pop test 4096 May 25 11:07 /var/www/html/

    ls -ld /var/www
    drwxrwx–x. 7 root root 4096 May 21 15:28 /var/www

    but when using sftp i get the output as

    sftp pop@localhost
    Connecting to localhost…
    pop@localhost’s password:
    Write failed: Broken pipe
    Couldn’t read packet: Connection reset by peer

    Hope someone could help me out.

  • Amit June 4, 2013, 9:53 pm

    I have created a user and added him to a group and allows access to /sftp/guestuser/incoming Now i want to allow him to access new directory and its subdirectories which is “home/admin/domain.com/public_html/assets/, How can i do it ?? Can anyone help ?

  • BurninLeo June 14, 2013, 9:18 am

    Very good tutorial, thank you!

    It may prevent some disasters to add a point 6a: Check SSH configuration ( here )

    If you access your server via SSH and, e.g., place the “Match Group sftpusers” order at the wrong position, you’re locked out. Nasty thing.. Running “sudo /usr/sbin/sshd -t” in advance is, therefore, a good advice 🙂

  • Nada_Surf July 19, 2013, 3:42 am

    Great tutorial, thanks very much!

  • Lux August 7, 2013, 11:23 am

    Nice tutorial, but a few caveats:

    1) That odd “/incoming” directory in the useradd command should be the chrooted home. There should only be one home directory for the jailed user. The user’s home directory must be owned by root. You should create a directory inside that is then owned by the user and the sftp group.

    2)If you’re on openssh 4.3 and you follow Suresh’s first note above, all of your users will no longer be able to ssh in. You best update to 5.4 which supports the Match keyword.

  • Andrea Garbarini October 16, 2013, 6:56 am

    Great howto, thanks, but the home dir for the sftp user (in etc/passwd) should be relative to the system’s root, and NOT the chrooted environment. Took me hours to figure this out, public key authentication was not working because of sshd looking for the authorized_keys file in the wrong location (and this was not clear at all from sshd debug messages)

  • Shahil October 25, 2013, 10:39 am

    Dear Sir,

    Can I use same home dir for Multiple users with case of chroot sftp ??

  • Nurettin November 1, 2013, 4:51 am

    Thanks for that great article.

    Now i need detailed logging. I’m using rhel 6.4. How can i accomplish that ?

  • Girish December 20, 2013, 1:16 pm

    Nice article.. worked well on Centos 6.2.

    Thank you!


  • vinay December 24, 2013, 4:36 am

    after follow all the above step when i test chroot sftp it shows error:

    sftp guestuser@thegeekstuff.com
    guestuser@thegeekstuff’s password:

    Write failed: Broken pipe
    Couldn’t read packet: Connection reset by peer

    help me guys
    thanks in advance

  • Michael Curtis March 10, 2014, 5:23 am

    We had the broken pipe error. We hadn’t made the /incoming folder. We had tried to use our own structure and got a bit confused 🙂

  • mehar April 8, 2014, 10:02 am

    After doing this ..now i am not able to do ssh with root user to server 🙁 ..as i am able to do sftp with chroot to new ftp user

    what could be the reason as i didn’t do anything with root user..
    now i have post the ticket to rackspace to check the same..
    but how can i set chroot jail to single user so that can access server with ssh root

  • Bob May 22, 2014, 1:57 pm

    the next tutorial should be how to set up pre-shared keys for the sftonly users. So ??

  • Chris July 2, 2014, 2:11 pm

    Hey, Just wanted to thank you for making this available and so easy to follow.

    I found by accident that the landing folder can’t be owned by the chrooted user. I had put chown -R guestuser:sftpusers /myfolder/ and got
    Network error: Software caused connection abort
    until I changed myfolder back to root ownership.

    Thanks again.

  • Lucas Leite August 21, 2014, 8:37 am

    It work’s for me. Great tutorial!

  • Antony October 2, 2014, 3:27 am

    Great post. I got permission denied on Centos and found the following link really helpful: here – in short you can enable/disable selinux which allows access. Hope that helps.

  • Anonymous October 16, 2014, 5:37 pm

    Hi , I have created two users p10 and d10.
    uid=11010(d10) gid=201(dba) groups=201(dba)
    uid=11009(p10) gid=201(dba) groups=201(dba),11009(sftpusers)

    In sshd_config, I have mentioned
    Match Group sftpusers

    But still I am able to do sftp with d10 user.

    Kindly suggest.

    Harshad More

  • leonardo December 4, 2014, 5:13 pm





    userdel -r $USERNAME
    umount /sftp/$DIRBET/$USER_DIR/incoming

    useradd -g $GROUP -d /incoming -s /sbin/nologin $USERNAME
    passwd $USERNAME

    mkdir /sftp
    chown root:root /sftp

    mkdir /sftp/$DIRBET
    chown root:root /sftp/$DIRBET

    mkdir -p /sftp/$DIRBET/$USER_DIR/incoming
    chown root:root /sftp/$DIRBET/$USER_DIR
    chown $USERNAME:$GROUP -R /sftp/$DIRBET/$USER_DIR/*
    #chown $USERNAME:$GROUP -R /sftp/$DIRBET/$USER_DIR

    mkdir -p /var/www/html/repository/uploadcsv/$USER_DIR
    chown $USERNAME:$GROUP /var/www/html/repository/uploadcsv/$USER_DIR
    mount –bind /var/www/html/repository/uploadcsv/$USER_DIR /sftp/$DIRBET/$USER_DIR/incoming

    echo ‘Match User ‘ $USERNAME >> /etc/ssh/sshd_config
    #echo ‘Match Group ‘ $GROUP >> /etc/ssh/sshd_config
    ##echo ‘ ChrootDirectory /sftp/%u’/ >> /etc/ssh/sshd_config
    echo ‘ ChrootDirectory /sftp/’$DIRBET/$USER_DIR >> /etc/ssh/sshd_config
    echo ‘ ForceCommand internal-sftp’ >> /etc/ssh/sshd_config
    ##echo ‘ AllowTcpForwarding no’ >> /etc/ssh/sshd_config

    tail /etc/ssh/sshd_config
    grep $USERNAME /etc/passwd
    ls -ld /sftp/$DIRBET/$USER_DIR/incoming
    ls -ld /sftp/$DIRBET/$USER_DIR
    ls -ld /sftp/$DIRBET
    ls -ld /sftp

    setenforce 0
    service sshd restart
    sftp $USERNAME@localhost

  • Anonymous December 8, 2014, 12:06 am

    how to restrict the other directory only access the that particular sftp directory

  • Scott Genevish December 12, 2014, 2:33 pm

    On step 2, you may want to add the -M option:

    useradd -M -g sftpusers -d /incoming -s /sbin/nologin guestuser

    Otherwise it will create an /incoming folder at the root. It’s not a huge problem (and the extra folder can be safely deleted).

  • odie February 9, 2015, 9:14 am

    Great post. tried this and works prefect..

    But when I tried this to an existing directory i got permission denied..

    appreciate your help.. thanks

    In my case:

    i have an existing directory: /home/apps/logs << owned by other user..

    I created new user guestuser and add to /home/apps/logs as home directory

    [root@venus ~]# grep guestuser /etc/passwd

    below is the configuration:

    # tail /etc/ssh/sshd_config
    Match Group sftpusers
    ChrootDirectory /home/%u
    ForceCommand internal-sftp

  • mafro February 12, 2015, 2:24 am

    Incredibly helpful! Thanks a tonne!

  • Harsh Vardhan Kaushik February 12, 2015, 11:26 pm

    While found “permission denied” problem after follow all the instructions as it is. This problem got rectified after disabling selinux in /etc/selinux/config and restart of server.

  • selcuk March 5, 2015, 4:53 am


    Why Redhat El5 uses ssh 4.3p2 ? in 4.3 it dowesnt work shrooted sftp

    so boring.

  • fdsf March 9, 2015, 11:46 am


    it dos not make any sense, why do you set the homeidr of the user as “incoming”
    while it should be /home/guestuser

  • fdsf March 9, 2015, 12:30 pm

    please help me out

    my user can sftp everywhere in the system this chroot tutorial dont work at all
    sometimes it goes to its home directory specified in the config
    sometimes it goes straight to /

  • gfd March 9, 2015, 3:04 pm

    how do you do this when one user needs rw access and the other r access
    in the end to the same /var/www for instance

  • swain March 12, 2015, 4:48 am

    Hi Ramesh ,
    Thanks for the post.
    If I need to put more than 1 user is sftp jail , how I am going to do it ?
    Because in sshd_config , I am not able to pass 2 statements. later one is not working while putting the file from some other server.

    Match Group sftpusers
    #ChrootDirectory /sftp/sftp_user1
    ChrootDirectory /sftp/sftp_user


  • Nishanth March 18, 2015, 5:13 am

    I want to login with a user to a document root or a folder, I must not access the other folders in a different path. It must tell that permission is denied.

    in LINUX


  • Nawar May 5, 2015, 2:06 am


    I am using centOS 6.5, I followed the previous steps and I am still getting permission denied everytime I try sftp guestuser@MyIp

    any idea why would that happen?

    thnx 🙂

  • Arjun May 20, 2015, 12:27 am

    Thank You very much Soultani @Soultani. Your comment on SElinux Helped me a lot…

  • Shrikant June 26, 2015, 1:47 am

    permission denied to icoming folder . Ho wto get rid of it ?

  • Kr1o July 7, 2015, 10:02 am

    Best article! THX!

  • Johnxiao Xiao July 20, 2015, 11:14 pm

    Thank you for this article, very useful.

  • Muyiwa Alabi July 23, 2015, 12:13 pm

    Many thanks for this article. Very helpful.

  • Deepak September 22, 2015, 7:11 am

    Nice Article 🙂

  • Sandeep November 16, 2015, 4:57 am

    Thanks for the tutorial.
    It was very helpful.

  • Max Zhen December 7, 2015, 10:40 am

    Is there a way to give read only access for those user that is not belong to chroot group in sftp jail?

  • Paul January 12, 2016, 6:36 am

    Hi all,

    I have discovered a solution to resolving a permission denied error, when running sshd with a chroot configuration. It will occur when you try to connect using sftp to the home path of the user and run a ls command, or attempt to read the file system. The error will resemble something like ‘remote readdir(“/ftp”): Permission denied’

    The issue is related to selinux. All you need to do is type the following command:
    setsebool -P ssh_chroot_full_access 1

    You’ll find when selinux is ‘enforcing’, that you’ll need to run a command to allow chroot to have full access to ssh. here.

  • ram February 4, 2016, 9:18 am

    nice post. chrooted user can push file into his home folder as per above method.
    but if another user want to pull this file from chrooted home directory how do to that!thanks

  • steveh March 4, 2016, 9:41 am

    I’ve been doing enterprise *nix stuff for 20 years but don’t always have time to do the level of research I’d like when I need to things quickly – like set up chrooted jails. I’ve found a number of really useful articles on your site wanted to say that I appreciate your site and find it very useful. Thanks very much !!


  • vinay March 31, 2016, 5:34 am

    i need passwordless for sftp. how can i create with above user.. please explain

  • Rick Foos April 14, 2016, 9:39 am

    I have a system with Publickey access only.

    This doesn’t work with a .ssh/authrized_keys file in /sftp/sftpusers, or /sftp/sftpusers/incoming.

    The sftpusers home directory is /incoming, which assumes that chroot will place them in /sftp/sftpusers/incoming.

    Auth takes places BEFORE chroot.

    So you need to put your keys in /incoming/.ssh.

    A little odd, but the sftpusers cannot see or modify the .ssh files this way, so it is still secure.

  • Akshay May 14, 2016, 1:48 pm

    This is not working with godaddy shared hosting.
    Is there any way to do that?

  • shirish shukla May 26, 2016, 4:04 am

    getting Error ..
    Received message too long 1416128883

  • Raul Baron July 4, 2016, 2:21 am

    Excellent article. Thanks for sharing, Ramesh. It really helped me a lot last friday !!!

  • Weizhong July 11, 2016, 5:47 am

    This tutorial has inconsistency issue, in one place, the sftponly account was created with /incoming as home, but in another it says it’s /sftp/%u.
    But my main concern with this kind of setup is, what will happen if the user can update the .ssh/authorized_keys file? Isn’t that a security issue?

  • Matheus Alves January 10, 2017, 7:04 am


    Works like a charm, thanks!

  • datta March 3, 2017, 1:41 am

    when i did all steps and restart the ssh service following error showing and i can’t open the server in another session, Please help me out.

    Starting sshd: /etc/ssh/sshd_config line 148: Directive ‘Protocol’ is not allowed within a Match block