To configure SFTP for multiple users on a Linux machine, you must modify the SSH daemon configuration to use the internal-sftp subsystem and implement a chroot jail. This setup restricts each user to their home directory while allowing secure file transfers via the SFTP protocol without granting shell access or system-wide permissions.
Understanding the Security Model
When setting up SFTP for multiple users, the primary goal is often isolation. You want User A to see only their files, and User B to see only theirs, without the ability to traverse upward to the root filesystem or access other users' data. The standard OpenSSH server allows this through theChrootDirectory directive combined with the Subsystem sftp internal-sftp command.
This approach is superior to running separate SFTP servers because it leverages the existing, highly secure SSH infrastructure. It also simplifies management since user authentication is handled by the operating system's standard mechanisms. For environments requiring more complex authentication sources, such as LDAP or Active Directory, you might need to look into How to allow Linux PAM Authentication for non-Local users. However, for standard local Linux accounts, the built-in methods are robust and sufficient.
Preparing the Directory Structure
Before editing configuration files, you must create the necessary directory hierarchy. TheChrootDirectory requires specific ownership and permission settings to ensure security. If these are incorrect, SSH will refuse to start the service due to perceived security risks.
First, create a base directory that will serve as the root for your chrooted users. For example, you might use /srv/sftp. This directory must be owned by root and not writable by any other user or group.
sudo mkdir -p /srv/sftp
sudo chown root:root /srv/sftp
sudo chmod 755 /srv/sftp
Next, create individual directories for each user inside this base directory. These subdirectories will be the actual homes where users can write files. Crucially, these subdirectories must be owned by the respective users.
sudo mkdir -p /srv/sftp/user1/data
sudo mkdir -p /srv/sftp/user2/data
sudo chown user1:user1 /srv/sftp/user1
sudo chown user2:user2 /srv/sftp/user2
Note that the parent directory of the chroot (/srv/sftp) must remain owned by root. Only the immediate child directories (like /srv/sftp/user1) should be owned by the specific user. This structure ensures that when the user logs in, they are effectively "chrooted" to their own directory, seeing it as the root of their file system.
Configuring the SSH Daemon
The core configuration happens in/etc/ssh/sshd_config. You need to locate the existing Subsystem sftp line and modify it, or add new configuration blocks at the end of the file.
Replace or comment out the default subsystem line:
# Subsystem sftp /usr/lib/openssh/sftp-server
Then, add the following block. This configuration uses Match groups to apply specific settings only to users belonging to the sftponly group. This is a clean way to manage multiple users without creating duplicate global configurations.
Match Group sftponly
ChrootDirectory /srv/sftp/%u
ForceCommand internal-sftp
AllowTcpForwarding no
X11Forwarding no
Here, %u is a placeholder that gets replaced by the username at runtime. So, for user1, the chroot becomes /srv/sftp/user1. The ForceCommand internal-sftp ensures that even if a user tries to request a shell session, they are forced into the SFTP subsystem, preventing accidental or malicious shell access. Disabling TCP forwarding and X11 forwarding reduces the attack surface.
After making these changes, restart the SSH service to apply the new configuration:
sudo systemctl restart sshd
Creating Users and Assigning Groups
Now that the server is configured, you need to create the users and assign them to thesftponly group. When creating the users, you can set their home directories to the paths defined earlier, but note that for chrooted users, the effective home directory from the OS perspective might differ from what they see.
sudo groupadd sftponly
sudo useradd -m -g sftponly -d /srv/sftp/user1 user1
sudo passwd user1
Repeat this process for each additional user. Ensure that the home directory specified in useradd matches the path structure you created in the previous step. If a user already exists, you can add them to the group using:
sudo usermod -aG sftponly existinguser
It is critical that these users do not have sudo privileges or membership in groups that grant broad system access, as this could potentially allow them to escape the chroot environment if there are vulnerabilities in the SSH implementation.
Testing the Configuration
Verification is the final step. Use an SFTP client to connect as one of the new users. From a terminal, you can test connectivity with:sftp user1@your_server_ip
Once connected, try listing the root directory:
ls -la
You should see the contents of /srv/sftp/user1, which likely includes the data folder you created. Try changing directory to / or attempting to go up with cd ... In a properly configured chroot, these actions should either fail or simply keep you within your designated directory boundary. You cannot navigate outside the ChrootDirectory.
For more information on managing specific SFTP commands like renaming files with wildcards, refer to SFTP Rename (mv) with Wildcard. Additionally, if you encounter connection issues during setup, such as the client hanging on connecting, check out SFTP Connection Stuck: Troubleshooting 'ls0[Connecting...]' Issues.
Frequently Asked Questions
Can users upload files directly to the root of their chroot?
No, because the chroot directory itself is owned by root and not writable by the user. Users can only write to subdirectories within their chroot that they own, such as the data folder created in the preparation step. This prevents privilege escalation attempts.
What happens if I forget to set the correct permissions on the chroot directory?
The SSH daemon will reject the connection with an error message indicating that the chroot directory is too open. OpenSSH requires that the chroot path and all its parent directories are owned by root and not writable by others. Fixing the ownership and permissions immediately resolves this.
Can I use this setup for FTP instead of SFTP?
No, this configuration specifically uses the SFTP subsystem integrated into SSH. Standard FTP does not support chroot jails in the same secure manner within the SSH daemon. You would need a dedicated FTP server like vsftpd for plain FTP connections.
How do I troubleshoot if a user cannot log in at all?
Check the SSH logs at /var/log/auth.log or /var/log/secure for detailed error messages. Common issues include incorrect group membership, wrong password, or SELinux/AppArmor blocking the access. Also verify that the user shell is not set to a restricted shell that conflicts with SFTP.
Is it possible to give some users shell access while keeping others on SFTP only?
Yes, by not adding those specific users to the sftponly group, they will fall back to the default SSH behavior. The Match Group directive only applies settings to members of that group, leaving other users unaffected.