Happy Dussehra! May good always win. Happy Diwali! Wishing you a bright year ahead. Merry Christmas! Warm wishes from Vizag. Happy New Year! Here’s to a great year ahead.

Archive · Linux

SSH Keys and a Safer sshd

Replace passwords with keys, harden sshd_config safely without locking yourself out, restrict users, and add basic brute-force protection.

3 min read

  • Ubuntu 18.04.3 LTS
  • OpenSSH 7.6
  • CentOS 7.7
  • OpenSSH 7.4
  • fail2ban

SSH is the front door to nearly every Linux server, and the first thing internet scanners try. Passwords get guessed; keys do not. This post creates keys, moves the server to key-only login, and applies a hardened configuration in a way that cannot lock you out.

Versions in use on this date. OpenSSH 7.6 on Ubuntu 18.04.3 LTS and OpenSSH 7.4 on CentOS 7.7 (released 17 September 2019). Ed25519 keys are supported by both. DSA keys are disabled by default and RSA keys under 2048 bits should not be used.

The login flow with keys

flowchart TB
  C[Your laptop<br/>private key stays here] -->|connect to port 22| S[sshd on server]
  S --> HK[Server proves identity<br/>host key checked in known_hosts]
  HK --> CH[Server sends challenge]
  CH --> SG[Client signs with private key]
  SG --> V{Public key listed in<br/>authorized_keys?}
  V -->|yes| SH[Shell as that user]
  V -->|no| DN[Denied and logged]

Your private key never leaves your machine; only a signature is sent. Protect it with a passphrase, and use ssh-agent so you type it once per session.

Generate and install a key

ssh-keygen -t ed25519 -C "ravi@laptop-2019" 
# older servers: ssh-keygen -t rsa -b 4096
ssh-copy-id -i ~/.ssh/id_ed25519.pub ravi@server1
ssh -i ~/.ssh/id_ed25519 ravi@server1

Permissions matter or sshd silently ignores the key:

chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys

Check the server’s host key fingerprint the first time you connect (ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub on the server) instead of blindly typing “yes”.

Client convenience (~/.ssh/config)

Host web1
  HostName 203.0.113.10
  User ravi
  IdentityFile ~/.ssh/id_ed25519
  ServerAliveInterval 30

Then ssh web1. Use ssh -J bastion web1 (ProxyJump, OpenSSH 7.3+) to reach private servers through a jump host.

Harden sshd_config safely

Edit /etc/ssh/sshd_config:

PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
ChallengeResponseAuthentication no
PermitEmptyPasswords no
MaxAuthTries 3
LoginGraceTime 30
AllowGroups ssh-users
ClientAliveInterval 300
ClientAliveCountMax 2
X11Forwarding no

Do it in this order to avoid lockout:

  1. Confirm key login works in one terminal and keep that session open.
  2. Test the configuration: sudo sshd -t (no output means valid).
  3. Reload: sudo systemctl reload sshd (the unit is ssh on Ubuntu: sudo systemctl reload ssh).
  4. In a second terminal, open a fresh connection to confirm you can still log in.
  5. Only then close the first session.

Create the allowed group with sudo groupadd ssh-users && sudo usermod -aG ssh-users ravi. Changing the port from 22 reduces log noise but is not security; it must also be opened in the firewall and SELinux on CentOS (semanage port -a -t ssh_port_t -p tcp 2222).

Per-key restrictions

In authorized_keys, prefix a key to limit what it can do, for example a backup job:

from="10.0.1.5",command="/usr/local/bin/backup-only",no-pty,no-port-forwarding ssh-ed25519 AAAA... backup@host

Brute-force protection and visibility

sudo apt install fail2ban              # CentOS: yum install epel-release fail2ban
sudo tee /etc/fail2ban/jail.local <<'EOT'
[sshd]
enabled = true
maxretry = 5
bantime = 3600
EOT
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd

With key-only login, brute force cannot succeed, but fail2ban cuts log noise and load. Also restrict port 22 by firewall to known addresses where you can (see the firewall post), and review sudo grep -E 'Accepted|Failed' /var/log/auth.log regularly (/var/log/secure on CentOS).

Key hygiene

  • One key per person per device; remove keys of leavers from authorized_keys.
  • Never copy a private key between machines or commit it to Git.
  • Rotate keys when a laptop is lost, and audit with ssh-keygen -lf fingerprints.
  • Verify the effective settings with sudo sshd -T | grep -E 'permitrootlogin|passwordauthentication'.