Files
Knowledge-Base/40 - Guides/security/ssh-hardening.md

136 lines
3.4 KiB
Markdown

---
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)