When setting up chrooted SSH access, there are strict requirements for directory ownership and permissions that often trip up even experienced sysadmins. The critical rules are:
1. The chroot directory (and all parent directories) must be owned by root
2. The chroot directory must not be writable by any other user/group
3. All parent directories must have strict permissions (755 or more restrictive)
4. The actual restricted directory (inside chroot) can be owned by the user
In your case, making the user owner of /var/www/RESTRICTED_DIR
violates rule #1. Even when you later tried changing ownership to root, other factors might still cause the error:
# Incorrect setup (will trigger the error)
chown MY_USER:MY_USER /var/www/RESTRICTED_DIR
chmod 755 /var/www/RESTRICTED_DIR
# Also problematic if parent directories are wrong:
ls -ld / /var /var/www
Here's how to properly configure the chroot environment:
# 1. Fix ownership of chroot directory and parents
sudo chown root:root /var/www/RESTRICTED_DIR
# 2. Set correct permissions
sudo chmod 755 /var/www/RESTRICTED_DIR
# 3. Verify parent directories (critical!)
sudo chown root:root /var/www
sudo chmod 755 /var/www
After fixing permissions, you'll need to set up the minimal environment inside the chroot:
# Create essential dev nodes
sudo mkdir -p /var/www/RESTRICTED_DIR/{dev,bin,lib,lib64}
sudo mknod -m 666 /var/www/RESTRICTED_DIR/dev/null c 1 3
# Copy basic binaries (adjust as needed)
sudo cp /bin/bash /var/www/RESTRICTED_DIR/bin/
sudo cp /bin/ls /var/www/RESTRICTED_DIR/bin/
# Copy required libraries
ldd /bin/bash | grep "=>" | awk '{print $3}' | xargs -I {} cp {} /var/www/RESTRICTED_DIR/lib/
For more complex setups, bind mounts can be helpful:
# Add to /etc/fstab
/var/www/RESTRICTED_REAL /var/www/RESTRICTED_DIR none bind 0 0
# Then mount and fix permissions
sudo mount /var/www/RESTRICTED_DIR
sudo chown root:root /var/www/RESTRICTED_DIR
If issues persist, check these aspects:
# 1. Verify entire path ownership
namei -l /var/www/RESTRICTED_DIR
# 2. Check SELinux context if enabled
ls -Z /var/www/RESTRICTED_DIR
# 3. Test with simplest possible chroot
sudo mkdir -p /chroot_test
sudo chown root:root /chroot_test
sudo chmod 755 /chroot_test
Here's a complete working example for sshd_config:
Match user restricted_user
ChrootDirectory /var/www/RESTRICTED_DIR
X11Forwarding no
AllowTcpForwarding no
PermitTTY yes
ForceCommand internal-sftp
When setting up a chroot environment for SSH users, the directory structure and permissions must meet strict security requirements. The chroot directory (in this case /var/www/RESTRICTED_DIR
) must be owned by root:root and have permissions set to 755 or more restrictive.
# Correct ownership and permissions:
sudo chown root:root /var/www/RESTRICTED_DIR
sudo chmod 755 /var/www/RESTRICTED_DIR
The error occurs because you made MY_USER
the owner of the chroot directory. This violates SSH's security model. The chroot directory must be owned by root to prevent privilege escalation.
After setting the correct permissions on the root directory, you'll need to create the necessary subdirectories that the user will actually work with:
# Create a writable directory for the user inside chroot
sudo mkdir -p /var/www/RESTRICTED_DIR/home/MY_USER
sudo chown MY_USER:MY_USER /var/www/RESTRICTED_DIR/home/MY_USER
sudo chmod 755 /var/www/RESTRICTED_DIR/home/MY_USER
# Create essential device files
sudo mkdir -p /var/www/RESTRICTED_DIR/dev
sudo mknod -m 666 /var/www/RESTRICTED_DIR/dev/null c 1 3
sudo mknod -m 666 /var/www/RESTRICTED_DIR/dev/zero c 1 5
sudo mknod -m 666 /var/www/RESTRICTED_DIR/dev/random c 1 8
sudo mknod -m 666 /var/www/RESTRICTED_DIR/dev/urandom c 1 9
Here's a robust configuration that works with the proper directory setup:
Match user MY_USER
ChrootDirectory /var/www/RESTRICTED_DIR
X11Forwarding no
AllowTcpForwarding no
PermitTTY no
ForceCommand internal-sftp
If you still encounter problems, check these aspects:
- Verify SELinux/AppArmor isn't blocking the chroot operation
- Ensure all parent directories of the chroot (/var, /var/www) are owned by root and not writable by others
- Check for missing libraries in the chroot environment with
ldd /bin/bash
- Review SSH logs in
/var/log/auth.log
for detailed error messages
For systems with multiple restricted users, you can use group matching:
Match Group restricted-users
ChrootDirectory /var/www/%u
AllowTCPForwarding no
X11Forwarding no
Then create individual chroots for each user following the same permission patterns.