While disabling password-based SSH authentication is a security best practice, allowing passwordless SSH keys creates another vulnerability vector. The ideal configuration requires:
- Enforcing passphrase protection on all private keys
- Preventing unauthorized key generation
- Implementing centralized key management
Option 1: ForceCommand Wrapper Script
Create a script to verify key passphrase protection:
#!/bin/bash
if [[ -n "$SSH_ORIGINAL_COMMAND" ]]; then
# Check for agent forwarding
if [[ -z "$SSH_AUTH_SOCK" ]]; then
echo "ERROR: No SSH agent detected - passphrase required"
exit 1
fi
# Verify loaded keys have passphrases
ssh-add -l | grep -v "The agent has no identities" > /dev/null || {
echo "ERROR: No passphrase-protected keys loaded in agent"
exit 1
}
exec $SHELL -c "$SSH_ORIGINAL_COMMAND"
else
exec $SHELL
fi
Then configure in sshd_config:
Match Group developers
ForceCommand /usr/local/bin/check_passphrase.sh
For enterprise environments, implement SSH certificate authentication:
# Generate CA key (secured offline)
ssh-keygen -t ed25519 -f ssh_ca
# Sign user keys with expiration
ssh-keygen -s ssh_ca -I user@company -n developer -V +52w user_key.pub
# Configure sshd_config
TrustedUserCAKeys /etc/ssh/ca.pub
RevokedKeys /etc/ssh/revoked_keys
Combine these technical controls with policy:
- Set restrictive permissions on .ssh directories:
- Implement filesystem monitoring:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
# Audit rule for new SSH key generation
-a always,exit -F arch=b64 -S creat -F dir=/home -F uid!=0 -F name=id_*.pub -k ssh_key_gen
For high-security environments, consider:
- Yubikey PIV integration
- Smart card authentication
- Temporary certificate issuance
Example Yubikey configuration:
# Configure PAM module
auth required pam_u2f.so authfile=/etc/u2f_mappings cue
When disabling password-based SSH authentication, many administrators face a dilemma: allowing passwordless SSH keys creates a significant security risk, while completely restricting SSH key usage hampers productivity. The ideal solution lies in enforcing passphrase-protected SSH keys without falling back to weaker authentication methods.
The OpenSSH server provides configuration options to control key authentication. While there's no direct "require passphrase" setting, we can implement workarounds:
# /etc/ssh/sshd_config
PasswordAuthentication no
PubkeyAuthentication yes
AuthenticationMethods publickey
To ensure users generate keys with passphrases, implement organizational policies for key creation:
# Force passphrase during generation
ssh-keygen -t ed25519 -a 100 -f ~/.ssh/id_ed25519
The -a
flag increases KDF rounds, making brute-force attacks more difficult.
For enterprises, consider these robust alternatives:
SSH Certificate Authority
Implement an SSH CA to sign user keys with expiration dates:
# CA signs user key (valid for 30 days)
ssh-keygen -s ca_key -I user_identity -n username -V +30d user_key.pub
Commercial SSH Management Tools
- Teleport (open source & commercial)
- Hashicorp Boundary
- Smallstep SSH certificates
This bash script checks for passphrase-protected keys in authorized_keys:
#!/bin/bash
for key in $(cut -d' ' -f2 ~/.ssh/authorized_keys | sort -u); do
if grep -q "ENCRYPTED" <(ssh-keygen -P "" -y -f <(echo "ssh-rsa $key")); then
echo "VALID: Key $key has passphrase protection"
else
echo "INVALID: Key $key lacks passphrase - removing"
sed -i "/$key/d" ~/.ssh/authorized_keys
fi
done
Implement regular audits of SSH keys in your environment:
# Find passwordless private keys
find /home -name "id_*" ! -name "*.pub" -exec ssh-keygen -y -P "" -f {} \; 2>&1 | grep "incorrect passphrase"
For maximum security, combine SSH keys with second factors:
# Google Authenticator PAM setup
auth required pam_google_authenticator.so
auth required pam_sss.so use_first_pass