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):

bash
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 directory

The user sees:

bash
Connection closed by 192.168.1.100 port 22

Or during authentication:

bash
Could not chdir to home directory /home/user: No such file or directory
Connection closed by remote host

Why 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:

bash
sudo grep -i chroot /etc/ssh/sshd_config

You'll see configurations like:

bash
Match User restricteduser
    ChrootDirectory /home/chroot/restricteduser
    ForceCommand internal-sftp

Step 2: Check if Directory Exists

Verify the chroot directory exists:

bash
ls -la /home/chroot/restricteduser

If it doesn't exist, create it:

bash
sudo mkdir -p /home/chroot/restricteduser

Step 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:

bash
namei -l /home/chroot/restricteduser

This 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:

bash
sudo mkdir -p /home/chroot/restricteduser/home/restricteduser
sudo chown restricteduser:restricteduser /home/chroot/restricteduser/home/restricteduser
sudo chmod 700 /home/chroot/restricteduser/home/restricteduser

Then configure SSH to use this as the home:

bash
Match User restricteduser
    ChrootDirectory /home/chroot/restricteduser
    HomeDirectory /home/restricteduser

Step 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:

bash
Match User restricteduser
    ChrootDirectory /home/chroot/restricteduser
    ForceCommand internal-sftp
    AllowTcpForwarding no
    X11Forwarding no

This avoids the need for shell binaries inside the chroot.

Step 8: Validate SSH Configuration

Test the configuration for syntax errors:

bash
sudo sshd -t

Step 9: Restart SSH and Test

Restart the SSH daemon:

bash
sudo systemctl restart sshd

Test the chroot connection:

bash
ssh -v restricteduser@localhost

For SFTP:

bash
sftp -v restricteduser@localhost

Verify the Fix

After connecting, verify the user is chrooted:

bash
# As the restricted user
pwd

The 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:

bash
# As the restricted user
ls /etc/passwd

This should fail or show the chroot's passwd file, not the system one.

In server logs, confirm successful authentication:

bash
sudo tail -20 /var/log/auth.log | grep restricteduser