When managing multiple websites on a cPanel/CentOS server, many administrators fall into the trap of granting full SFTP access with shell privileges. This creates significant security vulnerabilities, as we've seen with compromised FTP credentials leading to server-wide breaches.
The fundamental issue lies in SSH's default behavior where SFTP access typically requires shell access. However, OpenSSH provides configuration options to create SFTP-only accounts with strict filesystem isolation:
# Example of dangerous default configuration
Match User client1
ForceCommand internal-sftp
ChrootDirectory /home/client1
X11Forwarding no
AllowTcpForwarding no
While this seems restrictive, the chroot still technically provides shell environment access.
The solution involves using OpenSSH's Subsystem directive combined with cPanel's account isolation:
# /etc/ssh/sshd_config addition
Subsystem sftp internal-sftp -u 0002
Match Group sftponly
ChrootDirectory %h
ForceCommand internal-sftp -u 0002
AllowTcpForwarding no
X11Forwarding no
PermitTTY no
1. Create Dedicated SFTP Group
groupadd sftponly
2. Configure User Accounts
For each cPanel account (example for domain example.com):
useradd -G sftponly -s /usr/sbin/nologin -d /home/example example_sftp
passwd example_sftp
chown root:root /home/example
chmod 755 /home/example
3. Directory Structure Setup
mkdir -p /home/example/public_html
chown example_sftp:sftponly /home/example/public_html
chmod 770 /home/example/public_html
Test the setup by attempting shell access:
ssh example_sftp@yourserver.com
You should receive "This service allows sftp connections only" message.
For additional protection:
# Limit IP access
echo "sshd : ALL except 192.0.2.0/24" >> /etc/hosts.deny
# Configure fail2ban
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/secure
maxretry = 3
If users report connection problems:
- Verify directory permissions (chroot must be owned by root)
- Check SELinux contexts:
restorecon -Rv /home/example
- Confirm proper group membership:
id example_sftp
html
When managing a cPanel/WHM server on CentOS, you might need to provide secure file transfer capabilities without granting shell access. Traditional FTP is insecure (as you've experienced with password breaches), while regular SFTP often comes with unwanted shell access.
The solution lies in modifying the SSH daemon configuration. Here's what you need to know:
# Main SSH config file
/etc/ssh/sshd_config
# User-specific restrictions
/etc/shells
/home/username/.ssh/authorized_keys
First, create a special shell for SFTP-only users:
# Create SFTP-only shell
echo '/usr/libexec/openssh/sftp-server' | sudo tee -a /etc/shells
# Create a chroot directory
sudo mkdir -p /var/sftp/chroot
Then modify the SSH configuration:
# Edit sshd_config
sudo nano /etc/ssh/sshd_config
# Add these lines at the end:
Match Group sftpusers
ChrootDirectory /var/sftp/chroot
ForceCommand internal-sftp
AllowTcpForwarding no
X11Forwarding no
For cPanel accounts, use this approach:
# Create system user (replace 'sftpuser' with actual username)
sudo useradd -g sftpusers -s /usr/libexec/openssh/sftp-server sftpuser
sudo passwd sftpuser
# Set up chroot environment
sudo mkdir -p /var/sftp/chroot/home/sftpuser
sudo chown root:root /var/sftp/chroot
sudo chmod 755 /var/sftp/chroot
sudo chown sftpuser:sftpusers /var/sftp/chroot/home/sftpuser
Here's a bash script to handle multiple users:
#!/bin/bash
for USER in $(ls /var/cpanel/users/); do
USERHOME=/home/$USER
if [ -d "$USERHOME" ]; then
useradd -g sftpusers -s /usr/libexec/openssh/sftp-server $USER
mkdir -p /var/sftp/chroot$USERHOME
chown root:root /var/sftp/chroot
chmod 755 /var/sftp/chroot
chown $USER:sftpusers /var/sftp/chroot$USERHOME
ln -s $USERHOME/public_html /var/sftp/chroot$USERHOME/public_html
fi
done
Remember these critical points:
- Always use SSH keys instead of passwords when possible
- Regularly audit your SFTP users and permissions
- Monitor /var/log/secure for authentication attempts
- Consider implementing fail2ban for additional protection
If users can't connect, check:
# Verify permissions:
namei -l /var/sftp/chroot/home/username
# Check logs:
tail -f /var/log/secure
# Test connection:
sftp -v username@yourserver.com
For simpler setups, consider cPanel's "jailed shell" feature:
# In WHM:
1. Navigate to "Manage Shell Access"
2. Select "Jailed Shell" for the user
3. Ensure "SFTP Access" is enabled