Chroot Directory for SFTP

I have my folks’ computers getting backup to my NAS. My folks do not have any business to the NAS other than backing up their computer via the SFTP; therefore, they don’t need a /home or SSH access. What I am trying to accomplish here is to provide just SFTP only access and lock the user to his/her own directory. By allowing SFTP only, I could utilize an application such as Duplicati to backup my and my folks’ computers to the NAS.

SFTP group and users

To get started, we need create a group for the SFTP users.

groupadd sftpusers

Then we need to add the users to this new group called sftpusers.

# For existing users
# useradd -aG <groupname> <username>
usermod -aG sftpusers karlo

# For new users with no /home and no login
useradd -M -s /usr/sbin/nologin john
usermod -aG sftpusers john

We need to create a new directory where we want to store the backups for each user. Since I am using my NAS and I want the backup to be protected by SnapRAID. I am going to create the chroot directories on the mergerfs pool. We also need to create the users’ directory where they can read and write within this chroot directory.

mkdir -p /mnt/pool/backup_workstation/karlo/backup
mkdir -p /mnt/pool/backup_workstation/john/backup

To break down the directory structure real quick. The chroot directory will be /mnt/pool/backup_workstation/<username>. This directory needs to be owned by the root user and the permission needs to be 750 or 755; otherwise, you will get the error below when you tried to connect to the server. Basically, there should be no other users or groups that have write access to the absolute path before the username directory other than the root user.

client_loop: send disconnect: Broken pipe
Connection closed.

The directory called backup (chroot-directory’s sub-directory) is going to be owned by the user and he/she will have read-write access to this directory. Therefore, we are going to change the owner and permissions of each chroot directory and its subdirectory for each user.

## Repeat for each user
cd /mnt/pool/backup_workstation/
chown root:karlo karlo
chmod 750 karlo
chown karlo:karlo karlo/backup

SFTP server and chroot directory

Now that we got some users and working directories. We going to modify the /etc/ssh/sshd_config. Comment out this line. We want to disable the sftp-server and use the internal-sftp instead. Check this link if you are curious about the difference between the two SFTP.

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

Now we need to enable the internal-sftp and we need to create a Match Group block for our users. Add the config below at the bottom of the /etc/ssh/sshd_config. For the Token info, check this link.

ClientAliveInterval 10 # This will allow the server to send keep alive to the client every 10 seconds
ClientAliveCountMax 30 # If there is no response after 300 seconds, the server will terminate the sshd process.

# Enable internal-sftp
Subsystem sftp internal-sftp

# The tokens are %u for user
Match Group sftpusers
	ChrootDirectory /mnt/pool/backup_workstation/%u
	ForceCommand internal-sftp
	X11Forwarding no
	AllowTcpForwarding no

Once done, restart sshd.

systemctl restart sshd.service

Just like that and we are done with the server side. Hope you’ll find this useful.


Notify of

Inline Feedbacks
View all comments
Would love your thoughts, please comment.x