en
SSH Key Authentication Setup on VPS: Complete Guide
SSH key authentication replaces password-based login with cryptographic key pairs, making brute-force attacks mathematically infeasible. Every production VPS should use SSH keys exclusively. This guide covers key generation, server configuration, managing multiple keys, and troubleshooting common issues.
Need this done for your project?
We implement, you ship. Async, documented, done in days.
Generating SSH Key Pairs
Generate your key pair on your local machine, not the server. The private key stays on your local machine and must never be copied to the server. Run `ssh-keygen -t ed25519 -C "your-label-here"`. The ed25519 algorithm is preferred over the legacy RSA because it provides equivalent security with a much shorter key (256 bits vs 4096 bits), faster operations, and resistance to certain side-channel attacks.
When prompted for a passphrase, use one. A passphrase encrypts the private key file so that someone who obtains the file cannot use it without the passphrase. SSH agents (ssh-agent on Linux/Mac, Pageant on Windows) can hold decrypted keys in memory so you only type the passphrase once per session. The convenience cost is minimal; the security gain if your laptop is stolen is significant.
The command generates two files: `~/.ssh/id_ed25519` (private key - never share this) and `~/.ssh/id_ed25519.pub` (public key - safe to share and copy anywhere). If you need to support multiple servers or service accounts, generate separate keys with the `-f` flag: `ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_anubizhost -C "anubizhost-vps"`. Using separate keys means compromising one key does not expose all your servers.
Deploying Public Keys to Your VPS
Copy your public key to the server with `ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server-ip`. This command automatically appends the key to `~/.ssh/authorized_keys` on the server with correct permissions. If `ssh-copy-id` is not available, manually copy: log in with your password, run `mkdir -p ~/.ssh && chmod 700 ~/.ssh`, then paste the contents of your local `id_ed25519.pub` into `~/.ssh/authorized_keys` and set `chmod 600 ~/.ssh/authorized_keys`.
Permissions are critical. SSH will silently refuse to use an `authorized_keys` file with wrong permissions. The `~/.ssh` directory must be `700` (owner rwx only), `authorized_keys` must be `600` (owner rw only). If you are troubleshooting a key that is not working, check permissions with `ls -la ~/.ssh/`. The SSH daemon logs authentication failures with reasons in `/var/log/auth.log` - run `tail -f /var/log/auth.log` in one terminal while attempting login in another to see exactly what is failing.
For multiple administrators, add each person's public key on its own line in `authorized_keys`. You can add a comment after the key to identify whose key it is. To revoke access for a specific user, delete their line from `authorized_keys`. This is far simpler than managing shared passwords and provides perfect audit trails since each key is unique to an individual.
Disabling Password Authentication and Hardening SSH
Once you have confirmed key-based login works, disable password authentication. Open `/etc/ssh/sshd_config` and set `PasswordAuthentication no`, `ChallengeResponseAuthentication no`, and `UsePAM no`. Test your config with `sshd -t` - a syntax error here will not take effect until you restart, but an erroneous config could lock you out after the next restart. After confirming the test passes, restart SSH: `systemctl restart sshd`.
Open a second terminal and verify you can still log in before closing your current session. If something went wrong and you cannot connect, your current session remains open and you can fix the issue. This is a critical workflow discipline - always maintain at least one active session while making SSH changes, and test from a second connection before confirming the change.
Additional hardening in `sshd_config`: set `MaxAuthTries 3` to limit key authentication attempts per connection, `MaxSessions 10` to cap simultaneous sessions from a single TCP connection, `ClientAliveInterval 300` and `ClientAliveCountMax 3` to kill zombie sessions, and `AllowUsers specificuser` to restrict which system users can authenticate via SSH. The combination of these settings with key-only authentication makes SSH extremely difficult to attack successfully.
Related Services
Why Anubiz Host
100% async — no calls, no meetings
Delivered in days, not weeks
Full documentation included
Production-grade from day one
Security-first approach
Post-delivery support included
Ready to get started?
Skip the research. Tell us what you need, and we'll scope it, implement it, and hand it back — fully documented and production-ready.