--- title: SSH Hardening description: Practical SSH server hardening guidance for Linux systems in homelab and self-hosted environments tags: - security - ssh - linux category: security created: 2026-03-14 updated: 2026-03-14 --- # SSH Hardening ## Introduction SSH is the primary administrative entry point for many Linux systems. Hardening it reduces the likelihood of credential attacks, accidental privilege exposure, and overly broad remote access. ## Purpose This guide focuses on making SSH safer by: - Disabling weak authentication paths - Reducing exposure to brute-force attacks - Limiting which users can log in - Preserving maintainability by relying on modern OpenSSH defaults where possible ## Architecture Overview SSH hardening has three layers: - Transport and daemon configuration - Network exposure and firewall policy - Operational practices such as key handling and logging For most self-hosted systems, the best model is: ```text Admin workstation -> VPN or trusted network -> SSH server ``` ## Step-by-Step Guide ### 1. Use key-based authentication Generate a key on the client and copy the public key to the server: ```bash ssh-keygen -t ed25519 -C "admin@example.com" ssh-copy-id admin@server.example ``` ### 2. Harden `sshd_config` Baseline example: ```text PermitRootLogin no PasswordAuthentication no KbdInteractiveAuthentication no PubkeyAuthentication yes MaxAuthTries 3 LoginGraceTime 30 X11Forwarding no AllowTcpForwarding no AllowAgentForwarding no AllowUsers admin ``` If you need port forwarding for a specific workflow, enable it deliberately instead of leaving it broadly available. ### 3. Validate the configuration ```bash sudo sshd -t ``` ### 4. Reload safely Keep an existing SSH session open while reloading: ```bash sudo systemctl reload sshd ``` Distribution-specific service names may be `ssh` or `sshd`. ### 5. Restrict network exposure - Prefer VPN-only or management-VLAN-only access - Allow SSH from trusted subnets only - Do not expose SSH publicly unless it is necessary and monitored ## Configuration Example Example host firewall intent: ```text Allow TCP 22 from 192.168.10.0/24 Allow TCP 22 from Tailscale tailnet range Deny TCP 22 from all other sources ``` ## Troubleshooting Tips ### Locked out after config change - Keep the original session open until a new login succeeds - Validate the daemon config with `sshd -t` - Check the service name and logs with `journalctl -u sshd` or `journalctl -u ssh` ### Key authentication fails - Check file permissions on `~/.ssh` and `authorized_keys` - Confirm the server allows public key authentication - Verify the client is offering the intended key with `ssh -v` ### Automation jobs break - Review whether the workload depended on password auth, port forwarding, or agent forwarding - Create narrowly scoped exceptions rather than reverting the whole hardening change ## Best Practices - Rely on current OpenSSH defaults for ciphers and algorithms unless you have a specific compliance need - Disable password-based interactive logins on internet-reachable systems - Use individual user accounts and `sudo` instead of direct root SSH - Combine SSH hardening with network-level restrictions - Review SSH logs regularly on administrative systems ## References - [OpenBSD `sshd_config` manual](https://man.openbsd.org/sshd_config) - [OpenSSH](https://www.openssh.com/) - [Mozilla OpenSSH guidelines](https://infosec.mozilla.org/guidelines/openssh)