When your SSH server silently falls back to password authentication despite having properly configured keys, you're witnessing one of the most frustrating OpenSSH behaviors. The default logging won't tell you why the key was rejected - just that it happened. Here's how to extract the real reasons.
First, ensure your /etc/ssh/sshd_config
contains these critical settings:
# Minimum required for debugging:
LogLevel VERBOSE
PubkeyAuthentication yes
AuthenticationMethods publickey,password
# Additional debug options:
ChallengeResponseAuthentication no
PasswordAuthentication yes # Temporarily enable for testing
Restart sshd with sudo systemctl restart sshd
after changes.
The Failed publickey
log entry you see is just the symptom. To get the root cause, we need additional logging parameters. Add this to your sshd_config:
# Extended debug logging
LogLevel DEBUG3
StrictModes yes
Here are typical failure modes and how to identify them:
# 1. Permission issues (most common)
Nov 1 10:15:22 server sshd[12345]: Authentication refused: bad ownership or modes for directory /home/user/.ssh
# Solution:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chown -R user:user ~/.ssh
# 2. SELinux context problems
Nov 1 10:17:45 server sshd[12346]: fatal: bad ownership or modes for context user_u:object_r:ssh_home_t:s0
# Solution:
restorecon -R -v ~/.ssh
Enable verbose output on the client:
ssh -vvv user@host
Key things to check in client output:
debug1: Server accepts key: pkalg ssh-rsa blen 279
debug2: input_userauth_pk_ok: fp SHA256:xxxxxx
debug3: sign_and_send_pubkey: RSA SHA256:xxxxxx
debug1: Authentication succeeded (publickey)
For temporary deep debugging without config changes:
sudo /usr/sbin/sshd -d -p 2222
Then connect with:
ssh -p 2222 user@host
The -d
flag makes sshd run in foreground with maximum debug output.
Here's a quick script to verify all permission requirements:
#!/bin/bash
check_ssh_perms() {
local dir="$1"
[ "$(stat -c %a "$dir")" == "700" ] || echo "Bad .ssh permissions"
[ "$(stat -c %a "$dir/authorized_keys")" == "600" ] || echo "Bad authorized_keys permissions"
[ "$(stat -c %U:%G "$dir")" == "$USER:$USER" ] || echo "Bad ownership"
}
check_ssh_perms ~/.ssh
Remember that SSH is extremely sensitive to file permissions and ownership. Even subtle differences can cause silent failures.
When troubleshooting SSH public key authentication failures, the default OpenSSH logging often leaves us with frustratingly vague messages like "Failed publickey" without revealing the underlying cause. Let's explore how to extract meaningful diagnostics from sshd.
First, ensure your /etc/ssh/sshd_config
contains these critical settings:
# Minimum required for detailed logging
LogLevel VERBOSE
SyslogFacility AUTH
# For extreme debugging (temporary use only!)
#LogLevel DEBUG3
#AuthenticationMethods publickey,password
SSH is notoriously strict about file permissions. Here's how to verify them:
# On the server:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod 755 ~
# On the client:
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub
For deeper inspection, run sshd in debug mode:
sudo /usr/sbin/sshd -d -p 2222
Then connect with:
ssh -vvv -p 2222 user@host
Here are typical rejection reasons and their solutions:
# 1. Key format mismatch
sshd[1234]: userauth_pubkey: key type ssh-rsa not in PubkeyAcceptedKeyTypes
# Fix: Update sshd_config with:
PubkeyAcceptedKeyTypes ssh-rsa,rsa-sha2-256,rsa-sha2-512
# 2. SELinux context issue
sshd[1234]: Authentication refused: bad ownership or modes
# Fix:
restorecon -Rv ~/.ssh
Use this grep command to extract meaningful authentication attempts:
grep -E "sshd.*(Failed|Accepted|Invalid|Did not|Found)" /var/log/auth.log
Always combine server logs with client-side verbosity:
ssh -vvv user@host 2>&1 | grep -A10 "Offering public key"
Create this validation script on your server:
#!/bin/bash
KEY=$(ssh-keygen -lf $1 | awk '{print $2}')
grep "$KEY" ~/.ssh/authorized_keys || echo "Key not found"
stat -c "%a %U:%G %n" ~/.ssh ~/.ssh/authorized_keys ~