What's Actually Happening
When you configure SSH chroot to restrict users to a specific directory, connections fail because the chroot directory doesn't exist, has incorrect permissions, or doesn't meet SSH's strict security requirements. The user cannot authenticate at all or gets disconnected immediately after authentication.
The Error You'll See
In the server logs (/var/log/auth.log or /var/log/secure):
fatal: bad ownership or modes for chroot directory "/home/chroot/user"
fatal: chroot into directory "/home/chroot/user" failed: No such file or directory
fatal: chroot directory "/home/chroot/user" is not owned by root
sshd[1234]: fatal: chroot path "/chroot/user" component is not a directoryThe user sees:
Connection closed by 192.168.1.100 port 22Or during authentication:
Could not chdir to home directory /home/user: No such file or directory
Connection closed by remote hostWhy This Happens
SSH chroot has strict security requirements: - The chroot directory must be owned by root - The chroot directory must not be writable by any other user or group - All parent directories in the path must also be owned by root and not writable by others - The directory must exist and be a valid directory (not a symlink) - The user's shell and required binaries must exist within the chroot
Step 1: Verify Chroot Configuration
Check the SSH configuration for ChrootDirectory settings:
sudo grep -i chroot /etc/ssh/sshd_configYou'll see configurations like:
Match User restricteduser
ChrootDirectory /home/chroot/restricteduser
ForceCommand internal-sftpStep 2: Check if Directory Exists
Verify the chroot directory exists:
ls -la /home/chroot/restricteduserIf it doesn't exist, create it:
sudo mkdir -p /home/chroot/restricteduserStep 3: Fix Ownership and Permissions
The chroot directory and all parent directories must be root-owned and not group/world-writable:
```bash # Fix ownership of the chroot directory sudo chown root:root /home/chroot/restricteduser
# Set correct permissions (no write for group/other) sudo chmod 755 /home/chroot/restricteduser
# Also fix parent directories sudo chown root:root /home/chroot sudo chmod 755 /home/chroot ```
Step 4: Verify Parent Directory Permissions
Every directory in the path must meet security requirements:
namei -l /home/chroot/restricteduserThis shows permissions for each component. Look for non-root ownership or writable permissions.
Step 5: Set Up Home Directory Inside Chroot
Create a writable home directory for the user inside the chroot:
sudo mkdir -p /home/chroot/restricteduser/home/restricteduser
sudo chown restricteduser:restricteduser /home/chroot/restricteduser/home/restricteduser
sudo chmod 700 /home/chroot/restricteduser/home/restricteduserThen configure SSH to use this as the home:
Match User restricteduser
ChrootDirectory /home/chroot/restricteduser
HomeDirectory /home/restricteduserStep 6: Set Up Required Binaries for Shell Access
For shell access (not just SFTP), copy required binaries:
```bash # Create directory structure sudo mkdir -p /home/chroot/restricteduser/{bin,lib,lib64,dev,etc}
# Copy shell sudo cp /bin/bash /home/chroot/restricteduser/bin/
# Copy required libraries sudo ldd /bin/bash | grep -o '/lib[^ ]*' | xargs -I{} cp {} /home/chroot/restricteduser/lib/
# Create device nodes sudo mknod -m 666 /home/chroot/restricteduser/dev/null c 1 3 sudo mknod -m 666 /home/chroot/restricteduser/dev/zero c 1 5 sudo mknod -m 666 /home/chroot/restricteduser/dev/tty c 5 0 ```
Step 7: Use Internal SFTP (Simpler Alternative)
For SFTP-only access, use the internal-sftp subsystem which requires no chroot setup:
Match User restricteduser
ChrootDirectory /home/chroot/restricteduser
ForceCommand internal-sftp
AllowTcpForwarding no
X11Forwarding noThis avoids the need for shell binaries inside the chroot.
Step 8: Validate SSH Configuration
Test the configuration for syntax errors:
sudo sshd -tStep 9: Restart SSH and Test
Restart the SSH daemon:
sudo systemctl restart sshdTest the chroot connection:
ssh -v restricteduser@localhostFor SFTP:
sftp -v restricteduser@localhostVerify the Fix
After connecting, verify the user is chrooted:
# As the restricted user
pwdThe output should show / or the relative path inside the chroot, not the actual system root.
Check that the user cannot access files outside the chroot:
# As the restricted user
ls /etc/passwdThis should fail or show the chroot's passwd file, not the system one.
In server logs, confirm successful authentication:
sudo tail -20 /var/log/auth.log | grep restricteduser