The Starting Point for SSH Security — Audit Your Current Settings
SSH server defaults favor convenience, which leaves a wide attack surface. Before you change anything, check the values that are actually in effect.
sudo sshd -T | grep -Ei "permitrootlogin|passwordauthentication|^port|maxauthtries|allowusers|allowgroups"This guide focuses on sshd_config hardening and access control. For automatic brute-force blocking and IP bans, apply the Blocking SSH Brute-Force Attacks with fail2ban guide as well.
Core Hardening for /etc/ssh/sshd_config
# Change the port (default 22 → custom port, reduces automated scan noise)
Port 2222
# Block direct root login
PermitRootLogin no
# Disable password authentication (apply after key setup is complete)
PasswordAuthentication no
KbdInteractiveAuthentication no # Older versions: ChallengeResponseAuthentication no
# Disallow empty passwords
PermitEmptyPasswords no
# Auth attempt limit / login grace time
MaxAuthTries 3
LoginGraceTime 20
# Auto-close idle sessions (disconnect after 5 minutes of no response)
ClientAliveInterval 300
ClientAliveCountMax 0
# Disable unnecessary features
X11Forwarding no
AllowAgentForwarding no
AllowTcpForwarding noBefore applying, always validate the syntax then reload — this prevents lockouts caused by a bad config.
sudo sshd -t && sudo systemctl reload ssh # Debian/Ubuntu: ssh, RHEL family: sshdPrevent lockouts: Keep one extra SSH session open while you change settings. Do not close the existing session until you have confirmed access with a new session.
Setting Up SSH Key-Based Authentication
On the client (your PC) — Ed25519 keys are recommended (short, fast, and secure).
ssh-keygen -t ed25519 -C "deploy@myserver" -f ~/.ssh/myserver_ed25519
cat ~/.ssh/myserver_ed25519.pubOn the server — register the public key only (never copy the private key to the server).
mkdir -p ~/.ssh && chmod 700 ~/.ssh
echo "ssh-ed25519 AAAA... deploy@myserver" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keysssh-copy-id can do the above in a single command.
ssh-copy-id -i ~/.ssh/myserver_ed25519.pub -p 2222 deploy@server-ip
ssh -i ~/.ssh/myserver_ed25519 -p 2222 deploy@server-ip # Verify key-based loginApply PasswordAuthentication no in sshd_config only after you have confirmed key-based login works.
Advanced Access Control — AllowGroups and Match Blocks
Managing access by group is simpler than listing every user in AllowUsers.
# Create an SSH-allowed group and add users to it
sudo groupadd sshusers
sudo usermod -aG sshusers deploy# sshd_config
AllowGroups sshusersMatch blocks let you apply per-condition policies. For example, key-only authentication for a deploy account, or allowing connections only from a specific network range.
# SFTP-only with chroot for a specific user
Match User backup
ForceCommand internal-sftp
ChrootDirectory /srv/backup
AllowTcpForwarding no
# Allow password authentication only from the internal network (exception policy)
Match Address 10.0.0.0/8
PasswordAuthentication yesMulti-Factor Authentication (MFA) — Key + TOTP
To add another layer if a key is leaked, add TOTP (Google Authenticator, etc.).
sudo apt install libpam-google-authenticator
google-authenticator # Interactive: scan the QR code, then save the emergency codes# Add at the top of /etc/pam.d/sshd
auth required pam_google_authenticator.so
# /etc/ssh/sshd_config
KbdInteractiveAuthentication yes
AuthenticationMethods publickey,keyboard-interactiveLogin now requires both the key and the OTP.
Expose Only the SSH Port with UFW
sudo ufw allow 2222/tcp
sudo ufw enable
sudo ufw status verboseNext steps: For automatic blocking, see Blocking SSH Brute-Force Attacks with fail2ban. For a full initial check of a new server, see New Linux Server Initial Security Setup Checklist.
AI tools may assist drafting. Check the evidence in each guide for whether commands were run and which environment was used. Confirm the current docs for your version before applying instructions, and email us about errors. email us
Questions & answers
Ask a question about this guide. We'll review and reply.