Linux sftp restrict user to specific directory | setup sftp chroot jail


In this article I will share step by step guide on how to configure sftp server in Linux with examples covering the below topics in detail:

  • Install sftp on Linux
  • Configure sftp chroot
  • Create sftp user/Create sftp group
  • sftp restrict user to specific directory
  • sftp chroot multiple directories

sftp is a file transfer program, similar to ftp, which performs all operations over an encrypted ssh transport. It may also use many features of ssh, such as public key authentication and compression.

Lab Environment

I have created two Virtual Machines with CentOS 8 on Oracle VirtualBox in Linux server. I will use these two Virtual Machines to configure and verify sftp restrict user to specific directory and sftp chroot multiple directories with examples. Most of the steps from this article should also work on other Linux distributions such as SuSE, Ubuntu etc, if you face any issues do let me know using the comment section from this page.

We will configure sftp chroot jail on server2 and use server1 to connect to server2 using sftp user deepak

server1 server2
IP Address
Setup SFTP as client
(which initiates sftp connection)
as server
(sftp server)
OS CentOS 8 CentOS 8

Step 1: Install sftp on Linux

On most Linux distributions sftp should be installed by default. On RHEL/CentOS 7 and 8 Linux you can use yum or dnf to install sftp which is provided as part of openssh-clients rpm in RHEL/CentOS distro.

Step 2: Create SFTP User

I will create sftp user ( deepak ) for sftp restrict user to specific directory in Linux on server2 .

To create sftp user " deepak ", use below command.

Check user details:

The user’s home directory is owned by deepak with 700 permission so that no other user (other than root) can access this directory .

Assign password to sftp user deepak:

Change the shell of the sftp user to /bin/false instead of /bin/bash . Without a valid shell the sftp user will not be allowed to login.

Verify the user deepak’s properties

Step 3: Create SFTP Group (Optional)

In this article to demonstrate sftp restrict user to specific directory, I will use sftp user instead of sftp group. But if you have a requirement to implement group level sftp chroot jail then you can also create sftp group using below steps:

Add your user to this sftpusers group

Now you can use this group " sftpusers " for sftp restrict user to specific directory.

Step 4: Configure SFTP chroot jail

To configure SFTP chroot jail we will modify /etc/ssh/sshd_config

Why we use internal-sftp instead of sftp-server for ChrootDirectory?

  • Both sftp-server and internal-sftp are part of OpenSSH. sftp-server is a standalone binary.
  • internal-sftp is just a configuration keyword that tells sshd to use SFTP server code built-into sshd, instead of running another process (typically the sftp-server ).
  • sftp-server is now redundant and is kept for a backward compatibility.
  • The main advantage of internal-sftp is, that it requires no support files when used with ChrootDirectory directive.
  • Administrator may rely on a login shell configuration to prevent certain users from logging in.
  • Switching to the internal-sftp would bypass the restriction, as the login shell is no longer involved.
  • Using sftp-server binary (being a standalone process) you can use some hacks, like running the SFTP under sudo.
  • For SSH-1 (if anyone is still using it), Subsystem directive is not involved at all.
  • An SFTP client using SSH-1 tells the server explicitly, what binary the server should run. So legacy SSH-1 SFTP clients have sftp-server name hard-coded.

Next restart sshd service to activate sftp chroot jail configuration.

Step 5: SFTP restrict user to specific directory (with password authentication)

Step 5.1: Create sftp chroot jail directories

If you wish to sftp restrict user home directory then you can ignore these steps and only use /home/user as chroot jail. But to cover sftp restrict user to specific directory, we need a directory structure.

In this article we will implement sftp chroot jail on /opt/sftp-jails/username/exchange .

Step 5.2: Assign permissions on chroot jail directories

Our sftp user deepak will login to /opt/sftp-jails/username using sftp

User will have no write permission on /opt/sftp-jails/username . There is another directory " exchange " under /opt/sftp-jails/username/ where sftp user will perform write operation.

As you see the user directory is owned by root with 755 permission to allow user deepak to login and sftp restrict user to specific directory /opt/sftp-jails/deepak

We will change user owner to deepak to allow him write in this sftp chroot jail directory

Also change the permission to 750 to restrict others from writing in this exchange directory

Verify the permission:

Below is the tree structure of the directories we have created to configure sftp restrict user to specific directory

Step 5.3: Verify SSH and SFTP connectivity and permissions

Since we have blocked ssh access for our sftp user deepak , from server1 , first we try to do SSH to server2 using deepak user to make sure this configuration is working as expected.

As expected we are getting " This service allows sftp connections only ".

How to fix packet_write_wait: Connection to X.X.X.X port 22: Broken pipe?

It is possible that if your configuration has some issues, you will get " packet_write_wait: Connection to X.X.X.X port 22: Broken pipe " error instead of " This service allows sftp connections only ."

Now this error does not gives much detail of the underlying problem. So in such case we must check /var/log/messages on server node which you are trying to connect which for us is server2 . We will use journalctl to analyse the error " packet_write_wait: Connection to X.X.X.X port 22: Broken pipe "

Using journalctl -f I found error " fatal: bad ownership or modes for chroot directory "

Now this error " fatal: bad ownership or modes for chroot directory " itself tells you that the permission on your chroot directory provided under /etc/ssh/sshd_config is incorrect.

From the man page of sshd_config for ChrootDirectory , All components of the pathname must be root-owned directories that are not writable by any other user or group

So you can validate the permission you have provided for your chroot directory to fix " fatal: bad ownership or modes for chroot directory " and re-attempt the ssh.

Next attempt SFTP communication from server1 to server2 using deepak user

Step 6: Setup passwordless sftp authorized_keys

In the above example we configured sftp restrict user to specific directory where user authenticates itself using password. You may face issues when you try to use sftp chroot jail in script to automate some tasks as every time sftp communication will prompt for user password.

In this example we will setup passwordless sftp authorized_keys between our servers to sftp restrict user to specific directory.

Step 6.1: Create sftp authorized_keys file

On server2 create sftp authorized_keys file which will store the public key content from server1 . Here I have created a hidden folder .ssh inside which I will create authorized_keys file

Create a hidden directory .ssh where we will store our sftp authorized_keys file

The .ssh directory must be owned by deepak user and must not be accessible by world

Create sftp authorized_keys file

Change ownership and permission of this file

Verify the permissions:

Step 6.2: Generate SSH key pair to setup passwordless sftp

We are creating key pair using root user without using any password to sftp restrict user to specific directory. The private public key pair will be created under the home folder of root user inside /root/.ssh

Copy the content of your public key to server2 and place it in /opt/sftp-jails/deepak/exchange/.ssh/authorized_keys which we created under Create sftp authorized_keys file. Below as you see I have appended my content to /opt/sftp-jails/deepak/exchange/.ssh/authorized_keys

Step 6.3: Setup sftp chroot jail with authorized_keys

In your existing sftp chroot jail configuration of sshd_config , we will add one more line as highlighted with the location of sftp authorized_keys

Restart sshd service to activate the sftp authorized_keys changes

Below is a tree structure of our sftp chroot jail directory with all the permissions:

Step 6.4: Verify SFTP connectivity and permissions

Perform sftp connection from server1 to server2.

So our passwordless sftp authorized_keys configuration is successful and is working as expected.

Step 7: Setup SSH client for passwordless sftp

By default when you do sftp, the tool looks under the home folder of the user for any available passphrase to perform passwordless sftp . In our case since the private key exists inside root’s home folder the SFTP passwordless worked flawlessly.

But if you attempt to use any other user for sftp passwordless connection then it would fail. Below I try to do sftp using amit user on server1

As you see the sftp communication is prompting for password and passwordless sftp authorized_keys is not working.

To overcome this restriction for sftp restrict user to specific directory without password we have two solutions:

Solution 1: Perform passowrdless sftp with private key

You must define the private key you want to use for performing sftp communication to perform passwordless sftp. For example:

I will copy the private key I generated under a path which is accessible by user amit

I created a temporary directory /tmp/sftp_keys which will be accessible by all the users

Copy the private key from to this location and make it readable by all users of server1

Next attempt to perform passwordless sftp to server2

Solution 2: Create ssh config file for individual user

We can also create a local ssh config file for individual user of the node to perform passwordless sftp to server2 using sftp authrorized_keys .
To achieve this we will create a config file under the home folder of amit user ( /home/amit/.ssh ), inside . ssh directory

You can check the permissions and ownership I have assigned for all the files and directories under amit’s home folder:

Below is the content of /home/amit/.ssh/config , which you can modify based on your requirement to perform passwordless sftp. I have copied the private key inside /home/amit/.ssh which we created earlier.

Next verify the passwordless sftp communication

Step 8: SFTP chroot multiple directories

Similar to the sshd_config configuration file from sftp restrict user to specific directory, we will add more templates with match block for any number of users or groups to implement sftp chroot jail for multiple directories in Linux.

For example in the below configuration from /etc/ssh/sshd_config , we do sftp chroot multiple directories for different users and groups

All other steps from this article would be the same to sftp chroot multiple directories, you just have to take care of user and group permission on individual sftp chroot jail directories

Lastly I hope the steps from the article to configure sftp and setup sftp restrict user to specific directory, sftp chroot multiple directories on RHEL/CentOS 7/8 Linux was helpful. So, let me know your suggestions and feedback using the comment section.

Related Searches: could not chdir to home directory, configure sftp centos, sftp user permissions, sctp chroot tutorial, how to configure sftp server in linux step by step, create linux user with limited access to one folder only, sftp server linux redhat

Didn’t find what you were looking for? Perform a quick search across GoLinuxCloud

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can either use the comments section or contact me form.

Thank You for your support!!

Subscribe GoLinuxCloud

7 thoughts on “Linux sftp restrict user to specific directory | setup sftp chroot jail”

You might mention SELinux issues in your article.
dnf -y install policycoreutils-python-utils
semanage fcontext -a -e /home/foo/.ssh /var/www/html/bar/.ssh
restorecon -R -v /var/www/html/bar/.ssh

Yes thank you for highlighting this, I don’t use SELinux and somehow I forget to mention about this. I will try to add this info in my next articles.