When setting up SFTP with chroot (jailed) directories, administrators often face a common dilemma: how to grant users access to files outside their home directory while maintaining security. The standard chroot approach prevents users from escaping their designated directory, which is good for security but limits flexibility.
Creating symbolic links (symlinks) to directories outside the chroot jail doesn't work because:
ln -s /var/www/html /home/user/webroot
The chroot environment treats the symlink as invalid since it references a path outside the jail. Even though the link appears to exist, attempts to access it will fail.
The most reliable method is using bind mounts in your /etc/fstab:
/var/www/html /home/user/webroot none bind 0 0
Then mount it with:
mount --bind /var/www/html /home/user/webroot
For more dynamic access, consider using SSHFS:
sshfs user@localhost:/var/www/html /home/user/webroot -o allow_other
Ensure your sshd_config has these settings:
Match Group sftpusers
ChrootDirectory /home/%u
ForceCommand internal-sftp
AllowTcpForwarding no
X11Forwarding no
Remember to set proper ownership:
chown root:root /home/user
chown user:user /home/user/webroot
Verify the configuration works with:
sftp user@localhost
cd webroot
put testfile.txt
When configuring SFTP with chroot jails, symbolic links become problematic because the chroot environment intentionally breaks path resolution beyond the jailed directory. Here's why standard symlinks fail:
# This won't work in chroot:
ln -s /var/www/html /home/user/webroot
The system resolves symlinks before applying the chroot restriction, but the jailed user cannot traverse back up the directory tree.
Bind Mounts as Symlink Replacements
Bind mounts provide filesystem-level access without breaking chroot security:
# /etc/fstab entry:
/var/www/html /home/user/webroot none bind 0 0
After adding to fstab:
mount -a
Advanced SSH Configuration
For OpenSSH 7.5+, use the ChrootDirectory
directive with ForceCommand internal-sftp
in /etc/ssh/sshd_config
:
Match Group sftpusers
ChrootDirectory /home/%u
ForceCommand internal-sftp
AllowTcpForwarding no
X11Forwarding no
PermitTunnel no
Key permission requirements for chrooted SFTP:
chown root:root /home/user
chmod 755 /home/user
For bind-mounted directories:
setfacl -R -m u:user:rwx /var/www/html
For environments where bind mounts aren't feasible, implement inotify-based syncing:
#!/bin/bash
inotifywait -m -r /home/user/sync_dir -e create -e modify |
while read path action file; do
rsync -avz --delete /home/user/sync_dir/ /var/www/html/
done