How to Fix “Bad Ownership or Modes for Chroot Directory” Error When Setting Up SFTP Jailed Users on CentOS


2 views

The key error message in /var/log/secure reveals the core issue:

fatal: bad ownership or modes for chroot directory component "/var/www/vhosts/"

This occurs when setting up SFTP chroot jails because OpenSSH requires strict directory permissions for security reasons. The entire path to the chroot directory must be owned by root and have specific permission settings.

Here's the proper way to set up chrooted SFTP users on CentOS 6.4:

# Create sftp group
groupadd sftp

# Create user with proper home directory
useradd -d /var/www/vhosts/domain.com -g sftp -s /bin/false dummyuser

# Set password
passwd dummyuser

# Set directory ownership (critical step!)
chown root:root /var
chown root:root /var/www
chown root:root /var/www/vhosts
chown root:root /var/www/vhosts/domain.com

# Set directory permissions (equally important)
chmod 755 /var
chmod 755 /var/www
chmod 755 /var/www/vhosts
chmod 755 /var/www/vhosts/domain.com

Edit /etc/ssh/sshd_config:

# Comment out the default Subsystem line
#Subsystem sftp /usr/lib/openssh/sftp-server

# Add internal-sftp configuration
Subsystem sftp internal-sftp

# Add chroot jail configuration at the BOTTOM of file
Match group sftp
    ChrootDirectory %h
    X11Forwarding no
    AllowTcpForwarding no
    ForceCommand internal-sftp

After making these changes:

# Restart SSH service
service sshd restart

# Create upload directory inside chroot
mkdir -p /var/www/vhosts/domain.com/files
chown dummyuser:sftp /var/www/vhosts/domain.com/files
chmod 755 /var/www/vhosts/domain.com/files

If you still encounter issues:

  1. Check /var/log/secure for detailed error messages
  2. Verify SELinux context with ls -Z /var/www/vhosts/
  3. Test connection locally before trying from remote clients
  4. Confirm directory permissions all the way up the path

For more complex setups, consider these additions:

# Set umask for newly created files
Match group sftp
    ChrootDirectory %h
    ForceCommand internal-sftp -u 0002

# Limit concurrent connections
Match group sftp
    MaxSessions 3

The key error message in your logs reveals everything:

fatal: bad ownership or modes for chroot directory component "/var/www/vhosts/"

This occurs because OpenSSH enforces strict permission requirements for chroot directories. Let's break down the exact requirements:

Every directory in the chroot path must:

  • Be owned by root (uid 0)
  • Have group ownership of root (gid 0)
  • Not be writable by group or others (permissions 755 or 750)

Here's the proper way to set up your directory structure:

# Set ownership and permissions for the path
chown root:root /var
chmod 755 /var

chown root:root /var/www
chmod 755 /var/www

chown root:root /var/www/vhosts
chmod 755 /var/www/vhosts

# Create the user directory (owned by root but with proper subdir)
mkdir -p /var/www/vhosts/domain.com
chown root:root /var/www/vhosts/domain.com
chmod 755 /var/www/vhosts/domain.com

# Create upload directory owned by the user
mkdir -p /var/www/vhosts/domain.com/uploads
chown dummyuser:sftp /var/www/vhosts/domain.com/uploads
chmod 770 /var/www/vhosts/domain.com/uploads

Your sshd_config looks mostly correct, but let's make it more robust:

Subsystem sftp internal-sftp

Match group sftp
    ChrootDirectory %h
    ForceCommand internal-sftp
    X11Forwarding no
    AllowTcpForwarding no
    PermitTunnel no
    AllowAgentForwarding no
    PasswordAuthentication yes
    AuthenticationMethods password

If you still encounter issues:

  1. Check SELinux context: restorecon -Rv /var/www
  2. Verify permissions recursively: namei -l /var/www/vhosts/domain.com
  3. Test with verbose logging: sftp -vvv dummyuser@localhost

For multiple jailed users with individual directories:

# Create user template
SFTP_ROOT=/sftp_users
groupadd sftp_jailed

useradd -d $SFTP_ROOT/user1 -s /sbin/nologin -G sftp_jailed user1
mkdir -p $SFTP_ROOT/user1/{uploads,config}
chown root:root $SFTP_ROOT/user1
chmod 755 $SFTP_ROOT/user1
chown user1:sftp_jailed $SFTP_ROOT/user1/uploads
  • Never set user-writable permissions on any chroot parent directory
  • Don't use symlinks in the chroot path
  • Avoid home directories under /home as they're often 755 by default
  • Ensure PAM modules aren't interfering with authentication