When configuring vsftpd with virtual users, many administrators encounter authentication failures when using MD5 or SHA encrypted passwords, while CRYPT (DES) passwords work fine. This occurs because of how vsftpd interacts with PAM authentication modules.
The reported configuration shows:
# vsftpd.conf
listen=YES
anonymous_enable=NO
local_enable=YES
write_enable=YES
virtual_use_local_privs=YES
guest_enable=YES
guest_username=vsftpd
# PAM configuration
auth required pam_pwdfile.so pwdfile /etc/vsftpd/ftpd.passwd crypt=2
account required pam_permit.so crypt=2
The issue stems from multiple factors:
- vsftpd's default PAM configuration may not properly handle modern hash algorithms
- The
crypt=2
parameter in PAM configuration forces DES encryption - htpasswd generates different hash formats depending on the algorithm
Here's how to properly configure the system:
1. Update PAM Configuration
Modify /etc/pam.d/vsftpd
:
auth required pam_pwdfile.so pwdfile /etc/vsftpd/ftpd.passwd
account required pam_permit.so
2. Use Proper htpasswd Command
For MD5 hashes (preferred):
sudo htpasswd -c -m /etc/vsftpd/ftpd.passwd username
For SHA1 hashes:
sudo htpasswd -c -s /etc/vsftpd/ftpd.passwd username
3. Verify Password File Format
A properly formatted password file should look like:
username:$apr1$7cYbBdgP$M7x5N3X4tL0eQ1Z9F2YvG/
username:{SHA}W6ph5Mm5Pz8GgiULbPgzG37mj9g=
If you still encounter issues, consider these alternatives:
1. Use libpam-pwdfile
Install the specialized PAM module:
sudo apt-get install libpam-pwdfile
2. Database-backed Authentication
For larger deployments, consider using MySQL/PgSQL authentication:
auth required pam_mysql.so user=ftp passwd=password host=localhost db=ftpdb table=users usercolumn=username passwdcolumn=password crypt=2
account required pam_mysql.so user=ftp passwd=password host=localhost db=ftpdb table=users usercolumn=username passwdcolumn=password crypt=2
After making changes:
sudo service vsftpd restart
ftp localhost
Verify authentication works with both existing and new users.
- Always use the strongest available encryption
- Consider using TLS/SSL for FTP connections
- Regularly audit user accounts and permissions
MD5/SHA hashes are more computationally intensive than DES, but the impact is negligible for typical FTP usage. If serving many concurrent users, consider:
- Implementing connection limits
- Using hardware acceleration where available
When configuring vsftpd with virtual users, many administrators encounter authentication failures when using MD5 or SHA encrypted passwords. The server only accepts traditional CRYPT (DES) hashes generated with htpasswd -d
, which poses security concerns.
Here's a typical working vsftpd.conf for virtual users:
listen=YES
anonymous_enable=NO
local_enable=YES
write_enable=YES
virtual_use_local_privs=YES
guest_enable=YES
guest_username=vsftpd
user_sub_token=$USER
local_root=/var/www/vhosts/$USER
chroot_local_user=YES
The critical PAM configuration in /etc/pam.d/vsftpd
:
auth required pam_pwdfile.so pwdfile /etc/vsftpd/ftpd.passwd crypt=2
account required pam_permit.so
The issue stems from vsftpd's PAM module implementation. By default, it only supports:
- Traditional Unix crypt (DES)
- MD5 hashes with specific PAM configurations
Here's how to properly configure the system:
1. Update PAM Configuration
auth sufficient pam_pwdfile.so pwdfile /etc/vsftpd/ftpd.passwd
account sufficient pam_permit.so
2. Generate Proper Password Hashes
For SHA-256:
htpasswd -c -s /etc/vsftpd/ftpd.passwd username
For bcrypt (recommended):
htpasswd -c -B /etc/vsftpd/ftpd.passwd username
3. Verify PAM Module Support
Check your PAM version supports these algorithms:
ldd /lib/security/pam_pwdfile.so
For systems lacking proper PAM support:
sudo apt-get install libpam-pwdfile
Then modify PAM configuration:
auth required pam_pwdfile.so pwdfile=/etc/vsftpd/ftpd.passwd
account required pam_permit.so
Verify authentication works:
sudo service vsftpd restart
ftp localhost
Check auth logs for errors:
tail -f /var/log/auth.log
When enabling modern hashes:
- Always use bcrypt when available
- Set proper file permissions (0600) on password files
- Consider using TLS for all connections