Fix SSH Permission Denied with Public Key Authentication
When SSH public key authentication fails with 'Permission denied', it's often due to incorrect file permissions on the server. This guide covers fixing permissions for ~/.ssh, authorized_keys, and related files.
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.
Was this solution helpful?