SSH Key Management at Scale: Rotating Keys and Auditing Access on Multiple VPSes

Managing SSH keys for a single VPS is straightforward: generate a key pair, copy the public key to the server, and log in. But when you manage five, ten, or fifty VPS instances, key management becomes a distributed security problem. Expired keys, orphaned authorized_keys entries, and shared unmanaged keys accumulate over time and create blind spots. This guide covers practical strategies for rotating SSH keys, auditing access, and maintaining visibility across multiple VPS environments.

Why Key Rotation Matters

SSH keys are credentials, and like any credential, they should have a limited lifespan. Static keys that never rotate present several risks: a former team member who still has access, a compromised workstation that leaks the private key, or a forgotten key added during a troubleshooting session years ago. Key rotation ensures that even if a key is compromised, the window of exposure is bounded.

For a baseline understanding of SSH security fundamentals on a single VPS, see our security and compliance guides.

Setting Up a Key Rotation Policy

A reasonable rotation policy for a production VPS environment is:

  • User keys: Rotate every 90 days
  • Service/automation keys: Rotate every 180 days
  • Root keys: Rotate every 30 days or disable password-less root login entirely
  • Emergency break-glass keys: Rotate after each use

These intervals balance security against operational overhead. With automation, the process should be nearly invisible to users.

Automating Key Rotation with a Script

The simplest way to rotate keys across multiple VPS instances is a central orchestration script. Here is a practical approach using SSH itself:

#!/bin/bash
# rotate-keys.sh - Distribute new public keys to all VPS hosts

HOSTS="vps1.example.com vps2.example.com vps3.example.com"
NEW_KEY="$HOME/.ssh/id_ed25519_new.pub"

for host in $HOSTS; do
    echo "Rotating key on $host..."
    ssh-copy-id -f -i "$NEW_KEY" "admin@$host"
    
    # Verify the new key works before removing the old one
    ssh -i "$HOME/.ssh/id_ed25519_new" "admin@$host" "echo 'New key works on $host'"
    
    if [ $? -eq 0 ]; then
        echo "Key rotation successful on $host"
        # Remove old key from authorized_keys (optional)
        ssh "admin@$host" "sed -i '/old-key-comment/d' ~/.ssh/authorized_keys"
    else
        echo "WARNING: Key rotation FAILED on $host"
    fi
done

Always verify the new key works before removing the old one. This prevents you from locking yourself out of a remote server.

Auditing Authorized Keys Across All VPS Instances

Visibility is the foundation of key management. You cannot secure what you cannot see. Run this audit script periodically to collect all authorized keys:

#!/bin/bash
# audit-keys.sh - Collect all authorized_keys across hosts

HOSTS="vps1.example.com vps2.example.com vps3.example.com"
REPORT="ssh-key-audit-$(date +%F).txt"

echo "SSH Key Audit Report - $(date)" > "$REPORT"
echo "================================================" >> "$REPORT"

for host in $HOSTS; do
    echo "" >> "$REPORT"
    echo "=== $host ===" >> "$REPORT"
    ssh "admin@$host" "
        echo '--- User keys ---'
        for u in root admin deploy; do
            if [ -f /home/\$u/.ssh/authorized_keys ]; then
                echo "User: \$u"
                awk '{print \$3}' /home/\$u/.ssh/authorized_keys
            fi
        done
        echo '--- Key count ---'
        cat /etc/ssh/ssh_host_*.pub | wc -l
    " >> "$REPORT"
done

echo "Audit written to $REPORT"

Review the report monthly. Flag any key with a comment you do not recognize, or any key older than your rotation policy.

Using SSH Certificate Authorities for Scalable Key Management

For environments with more than a handful of VPS instances, SSH certificates are a better approach than distributing public keys to every server. With an SSH CA, you sign user keys with a central CA, and each server trusts only the CA certificate. When a user’s key is revoked, you simply stop signing new certificates — no need to touch every server’s authorized_keys file.

Setting Up an SSH CA

# On the CA server, generate a CA key pair
ssh-keygen -t ed25519 -f /etc/ssh/ca_user_key -C "User CA"

# On each VPS, add the CA public key to sshd_config
echo "TrustedUserCAKeys /etc/ssh/ca_user_key.pub" >> /etc/ssh/sshd_config

# Sign a user's public key (valid for 90 days)
ssh-keygen -s /etc/ssh/ca_user_key \
    -I "[email protected]" \
    -n "admin,deploy" \
    -V +90d \
    /home/user/.ssh/id_ed25519.pub

# The signed certificate is saved as id_ed25519-cert.pub

With an SSH CA, revoking a user’s access is a single operation: stop signing their certificates. The servers never need to be updated individually.

Monitoring and Alerting on Key Changes

Set up monitoring to detect unauthorized key additions. A simple approach using auditd on each VPS:

# Monitor authorized_keys changes with auditd
auditctl -w /home/*/.ssh/authorized_keys -p wa -k ssh-key-change

# Search for recent changes
auditctl -k ssh-key-change --since "7 days ago"

Forward these audit events to your central logging system or SIEM. Any unexpected addition to authorized_keys should trigger an immediate investigation.

Key Types and Algorithm Recommendations

Not all SSH keys are equal. Use this table to choose the right algorithm for your use case:

AlgorithmKey SizeSecurity LevelRecommendation
Ed25519256 bitsHighDefault for all new keys
RSA4096 bitsHighLegacy compatibility
ECDSA256/384/521 bitsHighGood alternative to Ed25519
DSA1024 bitsLowDeprecated — do not use

Generate new keys with: ssh-keygen -t ed25519 -a 100 -C "user@host-$(date +%F)". The -a 100 flag increases the number of KDF rounds, making brute-force harder if the private key is stolen.

Operational Checklist

  • [ ] All user keys are Ed25519, no DSA keys in use
  • [ ] Key rotation script runs every 90 days via cron
  • [ ] Audit report generated and reviewed monthly
  • [ ] SSH CA is configured for environments with 5+ VPS instances
  • [ ] authorized_keys changes are monitored with auditd
  • [ ] Orphaned keys from former team members are removed
  • [ ] Root login with password is disabled

For a broader view of VPS security hardening, visit virtualserversvps.com for guides on firewall configuration, intrusion detection, and compliance auditing.

Conclusion

SSH key management at scale requires automation, visibility, and a clear rotation policy. By implementing periodic key rotation, centralized auditing, and SSH certificate authorities for larger environments, you eliminate the most common SSH security blind spots. Start with the audit script, establish your rotation cadence, and build up to CA-based management as your infrastructure grows.

Leave a Reply