Symptoms
When attempting to connect to a remote server via SSH using public key authentication, you receive the error message: Permission denied (publickey). This occurs even though the public key has been added to the authorized_keys file on the server. The SSH client may also show debug messages indicating that the key was offered but rejected.
Root Causes
The most common root causes include:
- Incorrect permissions on the
.sshdirectory or its files on the client or server side. - The
authorized_keysfile has incorrect ownership or permissions. - The SSH server configuration (
sshd_config) disables public key authentication or restricts key usage. - The private key file on the client has overly permissive permissions.
- The public key is not properly appended to the
authorized_keysfile (e.g., line breaks or extra characters). - SELinux or AppArmor policies blocking key-based authentication.
Step-by-Step Fix
Step 1: Check Client-Side Permissions
On the client machine, ensure the private key file (e.g., ~/.ssh/id_rsa) has strict permissions:
chmod 600 ~/.ssh/id_rsaAlso verify the .ssh directory itself:
chmod 700 ~/.sshStep 2: Verify Server-Side Permissions
On the remote server, check the home directory permissions. The home directory should not be writable by group or others:
chmod go-w ~Set correct permissions for the .ssh directory and authorized_keys file:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keysStep 3: Check Ownership
Ensure the .ssh directory and its contents are owned by the correct user:
chown -R $USER:$USER ~/.sshStep 4: Validate the Public Key
Make sure the public key is correctly appended to ~/.ssh/authorized_keys. It should be a single line starting with ssh-rsa (or similar) and matching the client's public key exactly. Use:
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keysStep 5: Check SSH Server Configuration
On the server, edit /etc/ssh/sshd_config and verify these settings are present and not commented out:
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
PasswordAuthentication no (if you want key-only)Then restart the SSH service:
sudo systemctl restart sshdStep 6: Enable Debug Logging
Run SSH with verbose output to see detailed error messages:
ssh -vvv user@hostnameLook for lines like debug1: Offering public key and debug1: Authentication refused: bad permissions.
Step 7: Check SELinux/AppArmor
If SELinux is enabled, restore default contexts:
restorecon -Rv ~/.sshFor AppArmor, check logs in /var/log/syslog for denials.
Alternative Fixes
- Use ssh-copy-id: Run
ssh-copy-id user@hostnameto automatically add the public key with correct permissions. - Check known_hosts: If the server's host key changed, remove old entry with
ssh-keygen -R hostname. - Agent forwarding: If using an SSH agent, ensure the key is added:
ssh-add ~/.ssh/id_rsa. - Disable strict host key checking: Temporarily add
StrictHostKeyChecking noin~/.ssh/config(not recommended for production).
Prevention
- Always use
ssh-copy-idto add public keys to remote servers. - Set file permissions immediately after creating SSH keys:
chmod 600 ~/.ssh/id_rsaandchmod 700 ~/.ssh. - Regularly audit
~/.ssh/authorized_keysfor old or unused keys. - Enable SSH logging to monitor authentication attempts: set
LogLevel VERBOSEinsshd_config. - Use configuration management tools (Ansible, Puppet) to enforce correct permissions across servers.