SFTP (SSH File Transfer Protocol) runs over SSH and encrypts both credentials and data in transit, making it a secure alternative to plain FTP. This guide walks you through setting up an SFTP-only server on Debian 11 or 12 with chroot isolation: users in a dedicated group get only internal-sftp (no shell) and are restricted to their own directory under /srv/sftp.
In this guide you’ll:
- Install and enable OpenSSH server (which provides SFTP)
- Create SFTP-only users with
/usr/sbin/nologinand a chroot layout under/srv/sftp/<username>/upload - Configure
sshd_configwithMatch Group sftpusers,ChrootDirectory, andForceCommand internal-sftp - Test access with the
sftpclient and optionally add extra directories inside the chroot
Related guides:
- How to install and set up SFTP server in Ubuntu 22.04
- How to install and set up SFTP server in Ubuntu 20.04
- How to set up an SFTP server on OpenSUSE Leap 15.3
- How to set up an SFTP server on CentOS 8 / RHEL 8
- How to set up an SFTP server on Alma/Rocky Linux 9
- How to work with SFTP client in Linux (10 SFTP commands)
- Download files from SFTP server using Python
- List, upload and download files from an SFTP server using Go
Prerequisites
To follow along this guide ensure you have the following:
- A Debian 11 or Debian 12 server
- Root access to the server or a user with sudo access
- Internet access from the server
Ensuring that the server is up to date
Before proceeding, ensure your system is up to date. Use this command to refresh the system packages and update them.
| |
Ensuring that the SSH service is installed
Install OpenSSH server (this provides both SSH and SFTP):
| |
Now that it is installed, enable and start the service:
| |
Confirm its status
| |
Create SFTP users and directories (chroot layout)
We will store SFTP users under /srv/sftp using this layout:
/srv/sftp/<username>: chroot directory (must be owned by root and not writable)/srv/sftp/<username>/upload: writable directory owned by the user (where file uploads go)
Create the base directory:
| |
Create an umbrella group for SFTP-only users:
| |
Create an SFTP-only user called citizix (no shell login):
| |
The above options do the following:
-g sftpusers: Set the primary group tosftpusers-d /upload: Set the home directory (inside the chroot we will create)-s /usr/sbin/nologin: Disable shell access (SFTP-only)- Finally, username
citizix
Now create the chroot directory and the writable upload directory with correct ownership and permissions:
| |
Then add password to the created user using this command:
| |
Configure SSH for SFTP-only users (chroot)
Now we’ll configure OpenSSH so users in the sftpusers group:
- can only use SFTP (no shell)
- are chrooted to
/srv/sftp/%u - land in
/uploadon login
Edit the SSH server config:
| |
Ensure the SFTP subsystem uses internal-sftp (this is often the default, but it’s safe to set explicitly):
| |
Add this content at the bottom of the file:
| |
Then restart SSH to reload the config:
| |
Verify that SSH is running as expected:
| |
Verifying that the set up is working as expected
After successfully creating the user and adding SFTP configurations, let’s test the setup:
| |
Try a few commands:
| |
If everything is configured correctly, the user will be restricted to the chroot and should start in /upload.
Adding shared directories inside the chroot (optional)
If you want users to access additional directories, they must still be inside the chroot (/srv/sftp/<username>/...). Also remember: the chroot directory itself must be root-owned and not writable.
Example: create a shared directory under the chroot and make a subdirectory writable:
Create the directory
| |
Users in the chroot will then see and use the new directory (e.g. paymentfiles/upload).
Optional hardening tips
- Disable direct root login over SSH by setting
PermitRootLogin noin/etc/ssh/sshd_config. - If you only need SFTP for these accounts, keep shell access disabled (
/usr/sbin/nologin) as shown above. - Consider using key-based authentication for admin users and restricting SSH access with
AllowUsers/AllowGroups.
Frequently Asked Questions (FAQ)
What is SFTP?
SFTP (SSH File Transfer Protocol) is a secure file transfer protocol that runs over SSH. Unlike traditional FTP, it encrypts authentication and data in transit. OpenSSH provides the SFTP subsystem (internal-sftp), so no separate FTP server is needed.
What port does SFTP use?
SFTP uses the same port as SSH: port 22. There is no separate SFTP port; the SSH server handles both SSH sessions and SFTP subsystem requests.
What is chroot for SFTP?
Chroot restricts an SFTP user to a specific directory (e.g. /srv/sftp/username) so they cannot see or access the rest of the filesystem. The chroot directory must be owned by root and not writable by the user; you give the user a writable subdirectory (e.g. upload) for their files.
How do I allow only SFTP (no SSH shell)?
Set the user’s shell to /usr/sbin/nologin and use a Match Group block in /etc/ssh/sshd_config with ForceCommand internal-sftp -d /upload and ChrootDirectory /srv/sftp/%u. Users in that group will only get an SFTP session, not a login shell.
Why use internal-sftp?
internal-sftp is the SFTP subsystem built into OpenSSH. It is simpler and more secure than the deprecated sftp-server and works correctly with ChrootDirectory for per-user chroot jails.
Conclusion
You now have an SFTP-only server on Debian 11/12 with chroot isolation: users in the sftpusers group can only use SFTP (no shell), are restricted to /srv/sftp/<username>, and use the upload directory for file transfers. For client usage, see how to work with the SFTP client in Linux or automate transfers with Python or Go.