What is it? #
An SSH key pair is two matching files: a private key you keep, and a public key you install on servers.
Authentication works by proof rather than by secret transfer. The server sends a challenge, your client signs it with the private key, and the server verifies the signature with the public key. The private key never leaves your machine.
Keys are both more secure and more convenient than passwords. They cannot be guessed, they are not typed, and they work with automation.
Once keys are working, password authentication should be disabled on the server. That single change eliminates brute-force login attempts entirely.
Think of it like this #
A lock that can only be opened by a key you never hand over. The lock issues a puzzle that only the matching key can solve, and you return the solution.
Anyone can see the lock. Nobody learns anything useful from watching you open it.
Simple example #
You generate a key pair, install the public key on three servers, protect the private key with a passphrase, load it into an agent so you type that passphrase once a day, and then disable password login on the servers.
Code #
# Generate a modern key pair
ssh-keygen -t ed25519 -C "ravi@laptop" -f ~/.ssh/id_ed25519
# ed25519: fast, short and secure. Use rsa -b 4096 only for old servers.
# Set a passphrase when prompted — it protects the key if the laptop is stolen.
ls -l ~/.ssh/
# -rw------- id_ed25519 the PRIVATE key — never leaves this machine
# -rw-r--r-- id_ed25519.pub the PUBLIC key — safe to share
# Install the public key on a server
ssh-copy-id -i ~/.ssh/id_ed25519.pub [email protected]
# The manual equivalent
cat ~/.ssh/id_ed25519.pub | ssh [email protected] \
"mkdir -p ~/.ssh && chmod 700 ~/.ssh && \
cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
# The agent: type your passphrase once per session
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
ssh-add -l # list loaded keys
ssh-add -D # remove all loaded keys
# macOS: store the passphrase in the keychain
ssh-add --apple-use-keychain ~/.ssh/id_ed25519
# /etc/ssh/sshd_config — after confirming key login works
PubkeyAuthentication yes
PasswordAuthentication no # the single biggest win
PermitRootLogin no
ChallengeResponseAuthentication no
MaxAuthTries 3
AllowUsers ravi deploy # only these accounts may log in
# Apply — and keep your existing session open until you have tested a new one
sudo sshd -t # check the config for syntax errors first
sudo systemctl reload sshd
Permissions SSH insists on
~/.ssh 700 only you
~/.ssh/id_ed25519 600 private key
~/.ssh/id_ed25519.pub 644 public key
~/.ssh/authorized_keys 600 on the server
SSH silently refuses keys with permissions that are too open.
"Permission denied (publickey)" with correct keys is usually this.
How it works #
ssh-keygen -t ed25519 creates the pair. Ed25519 is the current default recommendation: short keys, fast verification and strong security. RSA with 4096 bits remains valid for older systems.
The passphrase encrypts the private key file. Without it, anyone who copies the file can use it; with it, they also need the passphrase.
ssh-copy-id appends your public key to ~/.ssh/authorized_keys on the server and sets the permissions correctly. The manual version shows exactly what it does.
The agent holds the decrypted key in memory so you type the passphrase once rather than on every connection. It is what makes passphrases practical.
Disabling PasswordAuthentication is the most valuable line in the server configuration. Servers with password login enabled see constant automated login attempts; with it off, those attempts fail immediately regardless of password strength.
sshd -t validates the configuration before you reload. A syntax error plus a reload can lock you out of the machine entirely, so testing first — and keeping an existing session open — is the standard precaution.
The permissions table explains the most common confusing failure. SSH refuses to use keys or authorized_keys files that others can read, and reports only a generic permission denied.
Real-world use #
Every professional server setup uses key authentication with passwords disabled. It is usually the first thing done after creating a machine.
Deployment systems use a dedicated key with limited access rather than a personal one, so it can be rotated without affecting people.
Keys can be restricted in authorized_keys with options such as command= and from=, limiting a key to one command or one source address. That is how automated backup and deployment keys are constrained.
Certificate-based SSH scales better in larger organisations: a short-lived certificate signed by a trusted authority, so access expires automatically and revocation does not mean editing files on every server.
Rotation matters. Keys that belonged to people who left should be removed, which is much easier if authorized_keys files are managed by configuration rather than edited by hand.
Common mistakes #
- Copying the private key to a server. Only the public key is ever installed.
- Generating a key with no passphrase and storing it on a laptop.
- Disabling password authentication before confirming key login works.
- Wrong permissions on ~/.ssh or authorized_keys, causing a confusing denial.
- Sharing one key between people and automation, so it cannot be rotated.
Practice #
Generate an ed25519 key with a passphrase, install the public key on a test server, load it into the agent, and confirm you can connect without typing a password. Then validate an sshd config that disables password authentication, reload it, and test from a new session before closing the old one.