How to Enable SFTP Password Authentication While Maintaining SSH Key-Only Login for Other Services on CentOS


33 views

On CentOS servers configured for SSH key authentication (PasswordAuthentication no), we often need to maintain strict security for shell access while allowing password-based authentication for specific services like SFTP. This is particularly common when integrating with applications like Drupal that may require password authentication for file transfers.

The OpenSSH server provides granular control through its configuration file (/etc/ssh/sshd_config). Here's how to implement selective authentication:

# Global setting remains key-only
PasswordAuthentication no

# Match block for SFTP users
Match Group sftpusers
    PasswordAuthentication yes
    ForceCommand internal-sftp
    ChrootDirectory /var/sftp/%u
    PermitTunnel no
    AllowAgentForwarding no
    AllowTcpForwarding no
    X11Forwarding no

Here's the complete procedure with concrete examples:

  1. Create an SFTP user group:
    groupadd sftpusers
  2. Add your Drupal service user:
    useradd -G sftpusers drupal_user
    passwd drupal_user
  3. Set up chroot environment:
    mkdir -p /var/sftp/drupal_user/upload
    chown root:root /var/sftp/drupal_user
    chmod 755 /var/sftp/drupal_user
    chown drupal_user:sftpusers /var/sftp/drupal_user/upload

After restarting sshd (systemctl restart sshd), verify the setup:

# Test regular SSH (should fail with password)
ssh drupal_user@yourserver.com

# Test SFTP (should succeed with password)
sftp drupal_user@yourserver.com

When implementing this setup:

  • Use strong passwords for SFTP accounts
  • Regularly audit SFTP user activity
  • Consider implementing fail2ban for SFTP attempts
  • Set appropriate umask values in the SFTP chroot

For more granular control, you can match specific users instead of groups:

Match User drupal_user,backup_user
    PasswordAuthentication yes
    ForceCommand internal-sftp

Many server administrators face this dilemma: needing password-based SFTP access for specific applications while enforcing key-only authentication for SSH shell access. This is particularly common with CMS platforms like Drupal that rely on SFTP for file operations but where shell access should remain secured by SSH keys.

The solution lies in properly configuring Match blocks in /etc/ssh/sshd_config. Here's a working example:

# Global settings (applies to all connections)
PasswordAuthentication no
PubkeyAuthentication yes

# Special rules for SFTP subsystem
Match Group sftpusers
    ForceCommand internal-sftp
    PasswordAuthentication yes
    PubkeyAuthentication no
    ChrootDirectory /var/sftp
    PermitTunnel no
    AllowAgentForwarding no
    AllowTcpForwarding no
    X11Forwarding no

1. Create a dedicated group for SFTP users:

sudo groupadd sftpusers

2. Create a chroot directory with proper permissions:

sudo mkdir -p /var/sftp/uploads
sudo chown root:root /var/sftp
sudo chmod 755 /var/sftp
sudo chown sftpuser:sftpusers /var/sftp/uploads

3. Add your Drupal service user to the group:

sudo usermod -a -G sftpusers drupal_user

4. Configure the Drupal settings.php to use SFTP:

$settings['file_chmod_directory'] = 0775;
$settings['file_private_path'] = '/var/sftp/uploads/private';
$config['system.file']['path']['temporary'] = '/var/sftp/uploads/tmp';

When implementing this setup:

  • Use strong passwords for SFTP accounts
  • Regularly rotate passwords
  • Monitor SFTP login attempts
  • Consider implementing fail2ban for SFTP connections
  • Set appropriate umask values (022 recommended)

If connections fail, check:

sudo tail -f /var/log/secure
# Common errors include:
# - Incorrect directory permissions
# - SELinux context issues (run: restorecon -Rv /var/sftp)
# - Missing ForceCommand directive