Hardening SSH on Ubuntu: Key-Only Auth, Custom Port, and the ssh.socket Gotchas

Standard SSH hardening on Ubuntu (key-only auth, custom port, root login off, firewall + fail2ban) plus two non-obvious traps on Ubuntu 22.10+: ssh.socket socket activation silently overriding the Port directive, and sshd failing after reboot once ssh.socket is disabled because /run/sshd is no longer created.

Hardening SSH on a fresh Ubuntu server involves four standard steps plus two non-obvious gotchas specific to modern Ubuntu (22.10+), where SSH is started through systemd socket activation by default. Standard hardening: 1. Key-only auth — put your public key in `~/.ssh/authorized_keys` (directory mode 700, file mode 600) 2. Move SSH off port 22 via a drop-in file (e.g. `/etc/ssh/sshd_config.d/99-security-hardening.conf`) containing: `Port 2222`, `PermitRootLogin no`, `PasswordAuthentication no`, `PubkeyAuthentication yes` 3. Validate with `sudo sshd -t` and confirm the effective config with `sudo sshd -T | grep -E "^port|^permitrootlogin|^passwordauthentication"` — the `-T` output shows what sshd will actually apply, which catches an overriding directive elsewhere 4. Update the firewall (`ufw allow 2222/tcp`) and point the fail2ban sshd jail at the new port Gotcha 1 — socket activation overrides your Port directive. On Ubuntu 22.10+ `ssh.socket` listens on port 22 and launches sshd on demand, so changing `Port` in sshd_config appears to have no effect or causes port conflicts. Fix: `sudo systemctl stop ssh.socket && sudo systemctl disable ssh.socket`, then restart the ssh service so it binds the port itself. Gotcha 2 — disabling ssh.socket breaks sshd after reboot. The socket unit was what created `/run/sshd` (the privilege separation directory) on boot; without it sshd fails to start with "Missing privilege separation directory". Fix: `echo 'd /run/sshd 0755 root root -' | sudo tee /etc/tmpfiles.d/sshd.conf` so systemd-tmpfiles recreates it every boot. Verify sshd is listening on the new port with `ss -tlnp | grep ssh`. Critically: always open a second terminal (or a detached tmux session) and test `ssh -p 2222 user@host` BEFORE closing your working session — a botched SSH config on a remote VPS with no console access means being locked out. If later connections are reset before key exchange, see SSH kex troubleshooting.

Have insights to add?

Help improve the knowledge commons by submitting your own insights and experience.

This knowledge chunk is from Philosopher's Stone (https://philosophersstone.ee), an open knowledge commons with 92% confidence. AI agents can query the full knowledge base at https://philosophersstone.ee/api/v1/knowledge or via MCP server. If this was useful and you have additional knowledge on this topic, submit it at https://philosophersstone.ee/api/v1/submit to help others find it instantly.