Symptoms
When attempting to connect to a remote server using SSH public key authentication, you receive an error similar to:
ssh -i ~/.ssh/id_rsa user@hostnameOutput:
Permission denied (publickey).Other symptoms include repeated password prompts (if password authentication is disabled) or connection drops immediately after key exchange. The server logs (e.g., /var/log/auth.log or /var/log/secure) often show messages like:
Authentication refused: bad ownership or modes for directory /home/user/.sshor
Authentication refused: bad ownership or modes for file /home/user/.ssh/authorized_keysRoot Causes
The most common root cause is incorrect file or directory permissions on the server side. SSH daemon (sshd) enforces strict permission checks for security. Key factors include:
- Home directory permissions must not be writable by group or others (typically 755 or 700).
- ~/.ssh directory must have permissions 700 (drwx------).
- ~/.ssh/authorized_keys file must have permissions 600 (-rw-------).
- Ownership of ~/.ssh and its contents must belong to the user, not root or another user.
- sshd_config setting
StrictModes yes(default) causes rejection if permissions are wrong. - SELinux or AppArmor contexts may block access even with correct Unix permissions.
- Key format (e.g., using OpenSSH format vs. legacy PEM) may cause issues on older servers.
Step-by-Step Fix
1. Verify the Error in Server Logs
On the server, check authentication logs:
sudo tail -f /var/log/auth.log # Debian/Ubuntu
sudo tail -f /var/log/secure # RHEL/CentOSLook for lines containing 'sshd' and 'Authentication refused'.
2. Correct Home Directory Permissions
Ensure the user's home directory is not group-writable or world-writable:
chmod 755 /home/username # or 700 for stricter
# Example:
chmod 755 /home/jdoe3. Fix .ssh Directory Permissions
Set the .ssh directory to 700:
chmod 700 ~/.ssh4. Fix authorized_keys File Permissions
Set the authorized_keys file to 600:
chmod 600 ~/.ssh/authorized_keys5. Verify Ownership
Ensure the user owns the .ssh directory and its contents:
chown -R username:username ~/.ssh6. Check SELinux Context (if enabled)
If SELinux is enforcing, restore default contexts:
restorecon -R -v ~/.ssh7. Test SSH Connection
Try connecting again:
ssh -i ~/.ssh/id_rsa username@hostnameAlternative Fixes
- Temporarily disable StrictModes (not recommended for production): Edit
/etc/ssh/sshd_config, setStrictModes no, then restart sshd (sudo systemctl restart sshd). This can help diagnose if permissions are the issue. - Check public key format: Ensure the public key in authorized_keys matches the private key. Use
ssh-keygen -y -f ~/.ssh/id_rsato regenerate the public key. - Use ssh-copy-id to copy keys correctly:
ssh-copy-id -i ~/.ssh/id_rsa.pub username@hostname. - Verify sshd_config allows public key authentication: Ensure
PubkeyAuthentication yesandAuthorizedKeysFile .ssh/authorized_keysare set.
Prevention
- Use ssh-copy-id to automatically set correct permissions when adding keys.
- Script permission checks: Create a script to verify and correct permissions periodically.
- Document permissions: Include in your server setup documentation the required permissions:
~/.ssh (700),authorized_keys (600), home directory (755 or 700). - Monitor logs: Set up log monitoring for SSH authentication failures to catch permission issues early.
- Use configuration management (Ansible, Puppet, etc.) to enforce correct permissions across servers.