Step-by-Step Guide: Setting Up SFTP Jail on Linux

Step-by-Step Guide: Setting Up SFTP Jail on Linux

Setting Up SFTP Jail on Linux

SFTP jail, often referred to as a chroot jail or SFTP chroot, is a security mechanism used to restrict users to a specific directory and its sub-directories when they connect via the Secure File Transfer Protocol (SFTP).

The term "jail" is used to convey the idea that the user is confined to a designated area, unable to navigate beyond it.

User/Group configurations

This setup was tested on a debian server. You will find as well an automated script at the end to manage the sftp configurations.

Create a group

By assigning users to a specific group associated with the SFTP jail, you can implement fine-grained access control. Group membership allows you to define permissions for the jail directory and its contents.

GROUP_NAME=jail_group
sudo groupadd $GROUP_NAME

Create a user

For security reasons, the user to be used by the SFTP jail should not have a login shell.

In addition, it's better to disable password authentication and only use ssh key-based authentication:

USER_NAME=user1
GROUP_NAME=jail_group
useradd -g $GROUP_NAME -d /home/$USER_NAME/ -m -s /sbin/nologin $USER_NAME

This will set the home directory for the user1 to /home/user1, create the home directory using the -m option, add the user to the created group and disable ssh access by setting the shell to /sbin/nologin

Set the correct permissions

When the user and group are ready, it's time to configure the permissions correctly

USER_NAME=user1
GROUP_NAME=jail_group
chown root:root /home/$USER_NAME
chmod 755 /home/$USER_NAME
mkdir -p /home/$USER_NAME/.ssh/
touch /home/$USER_NAME/.ssh/authorized_keys
chmod 600 /home/$USER_NAME/.ssh/authorized_keys
chmod 700 /home/$USER_NAME/.ssh
chown -R $USER_NAME:$GROUP_NAME /home/$USER_NAME/.ssh
mkdir /home/$USER_NAME/data
chown -R $USER_NAME:$GROUP_NAME /home/$USER_NAME/data
chmod 700 /home/$USER_NAME/data

This will set the correct permission for the ssh directory used for the user authentication and make sure the data directory is owned by the required user only with a read/write/execute permissions.

DNS Shield for ads blocking and malwares
DnsShield is a powerful and user-friendly script designed to automate the updating process of blocklists for Dnsmasq. With DnsShield, you can effortlessly maintain an up-to-date and comprehensive blocklist, enhancing security and privacy by blocking access to malicious or unwanted domains.

Configure SFTP jail

Enable the SFTP subsystem

Usually, the sshd config file is located at /etc/ssh/sshd_config.

The subsystem is an alternative implementation of SFTP provided internally by the SSH server itself. It's designed to improve performance and security by integrating SFTP functionality directly into the SSH server process, rather than relying on an external SFTP server process.

Edit the /etc/ssh/sshd_config to disable the old SFTP subsystem then enable the new one

#Subsystem	sftp	/usr/lib/openssh/sftp-server
Subsystem       sftp    internal-sftp

Configure the user/group jails

To make the management easier, I will create two configuration files.

The /etc/ssh/sshd_config.d/sftp-jail-group.conf to hold the jail group configurations with the following content:

Match Group jail_group
ChrootDirectory /home/%u
PubkeyAuthentication yes
ChallengeResponseAuthentication no
PasswordAuthentication no
AllowTcpForwarding no
PermitTunnel no
X11Forwarding no
PermitTTY no

The ChrootDirectory is a directive used in the SSH daemon to specify the root directory for a user after they successfully authenticate and connect via SSH or SFTP.

The %u is used to match the username.

💡
This directory should be owned by root so the user will not be able to write to it directly

The other remaining configs will make sure that the password-based authentication is disabled and only the key-based authentication is enabled for this group.In addition, the port forwarding and TTY should be disabled for security reasons.

This is the purpose of creating the /home/$USER_NAME/data directory which is owned by the user with the read/write/execute permissions.

This configs will be applied for all users in the jail_group group because of Match Group jail_group.

The /etc/ssh/sshd_config.d/sftp-jail-user.conf:

Match User user1
ForceCommand internal-sftp -d /data
AuthorizedKeysFile /home/%u/.ssh/authorized_keys

This will hold the user configurations.

The ForceCommand directive is used to specify a command to be executed for all connections, regardless of what command the client requested to execute. In the case of SFTP, internal-sftp is a built-in subsystem of OpenSSH that handles SFTP connections.

The -d option provided alongside internal-sftp specifies the directory to which the SFTP session will be chrooted. So when the user1 login using SFTP, he will be chrooted to the data directory by default.

As I will be using key-based authentication, the AuthorizedKeysFile will be used to set the authorized_keys path.

💡
Make sure to add your pubic key to this file otherwise you will get a permission denied issue

Finally restart sshd using:

systemctl restart sshd
💡
Make sure to open another root shell before restarting sshd

Testing

This can be tested using the sftp command.

test@test:~$ sftp [email protected]
Connected to 192.168.1.50.
sftp> put test
Uploading test to /data/test
test                                                                        
sftp> ls
test  
sftp> pwd
Remote working directory: /data
sftp> cd /
sftp> pwd
Remote working directory: /
sftp> put test
Uploading test to /test
dest open "/test": Permission denied
sftp> 

As you see, the default working directory is /data. If you navigate to the outside of the data directory, you will get a permission denied issue. Same when trying to upload file to any directory outside the /data

Enable/Disable user

If you want to prevent the user from login, you can simply disable the user using:

USER_NAME=user1
usermod -e 1 $USER_NAME

If the user try to login, he should get the following message:

test@test:~$ sftp [email protected]
Your account has expired; please contact your system administrator.
Connection closed by 192.168.1.50 port 22
Connection closed.  
Connection closed

If you want to enable it again, this can be done using:

USER_NAME=user1
usermod -e "" $USER_NAME

Automation

I've developed a fully automated script to streamline the management of user/group SFTP jails. You can find the script in my GitHub repository.

SFTP jails offer a robust and secure solution for restricting user access to designated directories, enhancing data protection and system security. By confining users to their respective directories, SFTP jails help enforce access control policies and minimize the risk of unauthorized data access or manipulation.

buy me a coffe