When configuring SFTP with chroot (restricted access), users might fail to connect with errors like:
$ sftp restricteduser@server.example.com
Connection closedOr in the server logs:
sshd[12345]: fatal: bad ownership or modes for chroot directory component "/home/restricteduser/"
sshd[12345]: Chroot directory /home/restricteduser must be owned by root and not writable by anyone elseChroot SFTP restricts users to a specific directory tree, preventing them from accessing other parts of the filesystem. SSH is strict about directory requirements for security.
Understand Chroot Requirements
For a chroot directory to work, it must:
- 1.Be owned by root
- 2.Not be writable by group or others
- 3.Not be writable by the user
- 4.Have proper permissions on all parent directories
The user's files must be in a subdirectory that they own and can write to.
Check Current Configuration
First, see your current SSH configuration for the user:
sudo grep -A 10 "Match User restricteduser" /etc/ssh/sshd_configOr check the subsystem:
sudo grep -i subsystem /etc/ssh/sshd_configA typical chroot configuration looks like:
``` Subsystem sftp /usr/lib/openssh/sftp-server
Match User restricteduser ChrootDirectory /home/restricteduser ForceCommand internal-sftp AllowTcpForwarding no X11Forwarding no PermitTTY no ```
Fix Directory Ownership
The chroot directory must be owned by root:
ls -ld /home/restricteduserIf it shows the user as owner:
drwx------ 2 restricteduser restricteduser 4096 Apr 3 10:00 /home/restricteduserFix it:
sudo chown root:root /home/restricteduserFix Directory Permissions
The directory must not be writable by anyone other than root:
sudo chmod 755 /home/restricteduserOr more restrictive:
sudo chmod 750 /home/restricteduserVerify:
ls -ld /home/restricteduserShould show:
drwxr-xr-x 2 root root 4096 Apr 3 10:00 /home/restricteduserCreate User-Writable Subdirectory
Since the user can't write to the chroot root, create a subdirectory:
sudo mkdir /home/restricteduser/files
sudo chown restricteduser:restricteduser /home/restricteduser/files
sudo chmod 755 /home/restricteduser/filesThe user can now write to files/ which appears as /files/ inside their chroot.
Check Parent Directory Permissions
All parent directories must also have proper permissions:
ls -ld /homeMust not be writable by group or others:
drwxr-xr-x 5 root root 4096 Apr 3 10:00 /homeIf /home has wrong permissions:
sudo chmod 755 /home
sudo chown root:root /homeUse Internal-SFTP vs SFTP-Server
The internal-sftp is preferred for chroot:
Match User restricteduser
ChrootDirectory /home/restricteduser
ForceCommand internal-sftpThis doesn't require a separate process and works better with chroot.
If using sftp-server, you need:
Subsystem sftp /usr/lib/openssh/sftp-server -l INFOBut internal-sftp is simpler and recommended.
Configure for Group Chroot
To chroot multiple users to the same structure:
Match Group sftpusers
ChrootDirectory /home/sftp/%u
ForceCommand internal-sftp
AllowTcpForwarding noCreate directories for each user:
sudo mkdir -p /home/sftp/user1/files
sudo chown root:root /home/sftp/user1
sudo chown user1:user1 /home/sftp/user1/filesHandle Home Directory in Chroot
The chroot becomes the user's root, so paths change. The user sees /files/ instead of /home/restricteduser/files/.
If you want the user to land in their writable directory:
Match User restricteduser
ChrootDirectory /home/restricteduser
ForceCommand internal-sftp -d /filesThe -d option sets the starting directory within the chroot.
Test the Configuration
Test the SSH config syntax:
sudo sshd -tIf errors exist, fix them before restarting.
Test the SFTP connection:
sftp -v restricteduser@server.example.comLook for:
debug1: subsystem request for sftp
debug1: Received subsystem request for sftpInside the SFTP session:
sftp> pwd
Remote working directory: /
sftp> ls
files
sftp> cd files
sftp> pwd
Remote working directory: /filesCommon Chroot Directory Structures
Single User Chroot
/home/restricteduser/ (root:root, 755)
files/ (user:user, 755)
uploads/ (user:user, 755)Group-Based Chroot
/home/sftp/ (root:root, 755)
user1/ (root:root, 755)
files/ (user1:user1, 755)
user2/ (root:root, 755)
files/ (user2:user2, 755)Shared Upload Directory
/home/sftpshared/ (root:root, 755)
uploads/ (root:sftpgroup, 775)
downloads/ (root:sftpgroup, 755)Troubleshoot Connection Refused
If users can't connect at all:
sudo journalctl -u sshd -fConnect from another terminal and watch:
Apr 3 10:15:22 server sshd[12345]: Connection from 192.168.1.50 port 22
Apr 3 10:15:22 server sshd[12345]: Accepted password for restricteduser
Apr 3 10:15:22 server sshd[12345]: fatal: bad ownership or modes for chroot directoryFix ownership based on the log message.
Handle Symbolic Links
Symbolic links in the chroot can cause issues. Don't use symlinks that point outside the chroot:
```bash # Bad - points outside chroot ln -s /var/www /home/restricteduser/www
# Good - within chroot ln -s files/uploads /home/restricteduser/uploads ```
SELinux Considerations
On SELinux systems, you need correct context:
ls -ldZ /home/restricteduserSet proper context:
sudo semanage fcontext -a -t ssh_home_t "/home/restricteduser(/.*)?"
sudo restorecon -R -v /home/restricteduserOr temporarily disable SELinux for testing:
sudo setenforce 0Debug Chroot Path Issues
If the chroot path has issues, SSH will reject it:
fatal: directory "/home/restricteduser/files" is not a chroot directoryRemember: the chroot must be the parent of user-writable directories.
Resolution Checklist
- 1.Chroot directory owned by root:
chown root:root /path - 2.Chroot directory not writable:
chmod 755 /path - 3.User-writable subdirectory:
mkdir /path/files; chown user:user /path/files - 4.Parent directories also owned by root
- 5.Use
internal-sftpnotsftp-server - 6.Test config:
sshd -t - 7.Test connection:
sftp -v user@server - 8.Check logs:
journalctl -u sshd
Chroot directory errors are almost always ownership and permission issues. The strict requirements exist to prevent users from escaping their restricted environment. Follow the root-ownership rule exactly.