Error Medic

How to Fix SSH Permission denied (publickey) Error in Linux

Resolve the "Permission denied (publickey)" SSH error quickly. Learn how to fix incorrect file permissions, missing keys, and sshd_config issues on Linux.

Last updated:
Last verified:
1,252 words
Key Takeaways
  • Incorrect file permissions on the remote server's ~/.ssh directory (requires 700) or authorized_keys file (requires 600) trigger StrictModes rejection.
  • Missing or mismatched public keys between the client's ssh-agent and the remote server's authorized_keys file prevent authentication.
  • Legacy RSA keys (ssh-rsa) are deprecated in OpenSSH 8.8+ and will result in silent publickey rejections unless explicitly permitted or upgraded to ED25519.
  • Quick fix summary: Run 'ssh -v' to identify the failing key, ensure client keys are loaded via 'ssh-add', and enforce strict ownership and permissions on the remote ~/.ssh directory.
Fix Approaches Compared
MethodWhen to UseTimeRisk
Fixing Directory/File PermissionsServer logs show 'Authentication refused: bad ownership or modes'2 minsLow
Adding Key via ssh-copy-idPublic key is entirely missing from the remote server1 minLow
Modifying sshd_configServer globally rejects public keys or uses custom AuthorizedKeysFile paths5 minsMedium
Restoring SELinux ContextsOn RHEL/CentOS when permissions are correct but access is still denied3 minsLow

Understanding the Error

The user@hostname: Permission denied (publickey) error is a security mechanism enforced by the SSH daemon (sshd). It occurs when the SSH server and client fail to negotiate a mutually acceptable cryptographic key for authentication. Unlike password authentication, which simply checks a string, public key authentication requires the server to verify that the client possesses the private half of a public key listed in the target user's ~/.ssh/authorized_keys file.

When sshd rejects the connection, it drops the connection to prevent brute-force attacks. The underlying root cause almost always falls into one of four categories: incorrect file permissions (triggering StrictModes), missing keys, client-side configuration issues, or server-side security policies (like SELinux or sshd_config directives).

Step 1: Diagnose the Handshake

Before changing configurations, you must identify exactly where the failure occurs. Use verbose mode on the SSH client to trace the authentication steps:

ssh -vvv user@remote_server_ip

Analyze the output for the following critical lines:

  • debug1: Offering public key: /home/user/.ssh/id_rsa RSA SHA256:...: This confirms your client is attempting to use a specific key.
  • debug1: send_pubkey_test: no mutual signature algorithm: This indicates a modern OpenSSH client rejecting an older RSA key algorithm.
  • debug1: Authentications that can continue: publickey: The server is explicitly demanding a public key and rejecting the ones offered.

If you have root access to the remote server via an out-of-band console, tail the secure log to see the server's perspective:

tail -f /var/log/auth.log   # Debian/Ubuntu
tail -f /var/log/secure     # RHEL/CentOS/Rocky

Look for errors like Authentication refused: bad ownership or modes for directory /home/user/.ssh.

Step 2: Fix Server-Side File Permissions and Ownership

By default, OpenSSH enforces StrictModes yes. This means if your .ssh directory or authorized_keys file is readable or writable by other users, SSH will silently ignore your keys to protect you from compromised local accounts.

Execute the following commands on the remote server to enforce the correct security posture:

  1. Fix ownership (ensure the user owns their own files):
    sudo chown -R $USER:$USER ~/.ssh
    
  2. Fix directory permissions (Read/Write/Execute for owner ONLY):
    chmod 700 ~/.ssh
    
  3. Fix file permissions (Read/Write for owner ONLY):
    chmod 600 ~/.ssh/authorized_keys
    

Step 3: Address OpenSSH 8.8+ RSA Deprecation

If you recently upgraded your OS (e.g., to Ubuntu 22.04 or macOS Ventura), OpenSSH 8.8 disabled ssh-rsa signatures using the SHA-1 hash algorithm due to security vulnerabilities. If you are using an old RSA key, the server will reject it.

Best Practice Fix: Generate a new, secure ED25519 key.

ssh-keygen -t ed25519 -C "your_email@example.com"
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@remote_server_ip

Temporary Workaround: If you must use the legacy RSA key (e.g., connecting to a legacy network appliance), edit your client-side ~/.ssh/config:

Host remote_server_ip
    PubkeyAcceptedKeyTypes +ssh-rsa

Step 4: Verify sshd_config on the Server

If permissions are correct and keys are modern, the SSH daemon itself might be configured to reject public keys. Check the configuration file on the server:

sudo nano /etc/ssh/sshd_config

Ensure the following directives are set (and not commented out):

PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_keys2

If you made changes, restart the SSH service:

sudo systemctl restart sshd

Step 5: Resolve SELinux Contexts (RedHat/CentOS)

On SELinux-enforcing systems, if the ~/.ssh directory was copied or moved incorrectly, it might have the wrong security context, making it invisible to the sshd process.

Restore the default SELinux contexts for the SSH directory:

restorecon -Rv ~/.ssh

This command forces SELinux to apply the default labels specified in the system policy to your SSH configuration files.

Frequently Asked Questions

bash
#!/bin/bash
# Diagnostic and remediation script for remote server SSH permissions
# Run this ON THE REMOTE SERVER for the affected user

USER_HOME=$(eval echo ~$USER)
SSH_DIR="$USER_HOME/.ssh"
AUTH_KEYS="$SSH_DIR/authorized_keys"

echo "[+] Fixing SSH permissions for $USER at $USER_HOME"

# 1. Ensure home directory isn't group/world writable
chmod go-w "$USER_HOME"
echo "[-] Set $USER_HOME permissions to block group/world write."

# 2. Create .ssh if missing and set directory permissions
if [ ! -d "$SSH_DIR" ]; then
    mkdir -p "$SSH_DIR"
    echo "[-] Created $SSH_DIR directory."
fi
chmod 700 "$SSH_DIR"
echo "[-] Set $SSH_DIR permissions to 700 (drwx------)."

# 3. Create authorized_keys if missing and set file permissions
if [ ! -f "$AUTH_KEYS" ]; then
    touch "$AUTH_KEYS"
    echo "[-] Created $AUTH_KEYS file."
fi
chmod 600 "$AUTH_KEYS"
echo "[-] Set $AUTH_KEYS permissions to 600 (-rw-------)."

# 4. Enforce ownership
chown -R $USER:$USER "$SSH_DIR"
echo "[-] Enforced ownership of $SSH_DIR to $USER:$USER."

# 5. Fix SELinux contexts if applicable (RHEL/CentOS)
if command -v restorecon &> /dev/null; then
    restorecon -Rv "$SSH_DIR"
    echo "[-] Restored SELinux security contexts for $SSH_DIR."
fi

echo "[+] Remediation complete. Please try authenticating again."
E

Error Medic Editorial

A collective of Senior Site Reliability Engineers and Linux Systems Administrators dedicated to documenting production-grade troubleshooting methodologies.

Sources

Related Guides