SSH is the front door of a Linux server. Default settings work, but they allow password logins, which bots try around the clock. These steps make SSH resistant to brute-force attacks and limit damage if a key is lost.
Don’t lock yourself out. Keep your current SSH session open while changing settings, test in a second terminal, and know how to reach your server’s VNC console from the control panel.
1. Use SSH keys
On your computer:
ssh-keygen -t ed25519 -C "you@laptop"
ssh-copy-id deploy@YOUR_SERVER_IP
Use a passphrase on the key; an SSH agent saves you typing it. Test: ssh deploy@YOUR_SERVER_IP should log in without the account password.
2. Harden sshd_config
Debian reads extra settings from /etc/ssh/sshd_config.d/*.conf. Create one file with your changes:
nano /etc/ssh/sshd_config.d/10-hardening.conf
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
AuthenticationMethods publickey
# Only these users may log in
AllowUsers deploy
MaxAuthTries 3
LoginGraceTime 30
ClientAliveInterval 300
ClientAliveCountMax 2
X11Forwarding no
AllowAgentForwarding no
Validate and reload:
sshd -t && systemctl reload ssh
Open a new terminal and log in again before closing the old session.
3. Use modern algorithms
Current OpenSSH defaults are already strong. To remove older algorithms explicitly:
KexAlgorithms [email protected],curve25519-sha256,[email protected]
Ciphers [email protected],[email protected],[email protected]
MACs [email protected],[email protected]
HostKeyAlgorithms ssh-ed25519,rsa-sha2-512,rsa-sha2-256
Check that your SSH clients (including automation tools and old IDEs) still connect after this change.
4. Firewall SSH
ufw allow OpenSSH
# or, better, only from your IP / VPN:
ufw allow from 203.0.113.50 to any port 22 proto tcp
5. Fail2ban
apt install -y fail2ban
cat > /etc/fail2ban/jail.d/sshd.local <<'EOF'
[sshd]
enabled = true
backend = systemd
maxretry = 4
findtime = 10m
bantime = 1h
EOF
systemctl restart fail2ban
fail2ban-client status sshd
With key-only authentication, brute force can’t succeed anyway; Fail2ban mainly reduces noise and resource use.
6. Change the port (optional)
Moving SSH from port 22 to, say, 2222 reduces automated log noise. It’s not real protection, so do it after the steps above:
# in 10-hardening.conf
Port 2222
ufw allow 2222/tcp
sshd -t && systemctl restart ssh
# test: ssh -p 2222 deploy@YOUR_SERVER_IP
ufw delete allow OpenSSH
On Debian 13, SSH may be socket-activated (ssh.socket); if the port change doesn’t take effect, run systemctl daemon-reload && systemctl restart ssh.socket.
7. Two-factor authentication (optional)
Combine keys with a TOTP code for high-value servers:
apt install -y libpam-google-authenticator
sudo -u deploy google-authenticator # scan the QR code in your authenticator app
In /etc/pam.d/sshd, add auth required pam_google_authenticator.so. In your sshd drop-in:
KbdInteractiveAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
Reload and test carefully in a second session.
8. Audit
journalctl -u ssh --since "24 hours ago" | grep -E 'Accepted|Failed'
last -n 10
Remove old keys from ~/.ssh/authorized_keys when team members leave.
Checklist
- Key-based login, passwords disabled
- Root login disabled,
AllowUsersset - Firewall limits SSH
- Fail2ban active
- Automatic security updates (unattended upgrades)
New to SSH? Start with SSH into your VPS. Our Debian VPS plans include a VNC console so you can always get back in.