Chapter 5: Security
Interview Questions
This chapter answers to the following questions:
How Do You Harden SSH on a Linux Server?
SSH (Secure Shell) is the primary remote access protocol on Linux servers. Because it is almost always exposed to the network, it is also one of the most targeted services — brute-force attacks, credential stuffing, and exploit attempts against outdated SSH daemons are constant. Hardening SSH means reducing the attack surface by disabling what is not needed and enforcing what is.
All SSH server configuration lives in a single file:
/etc/ssh/sshd_config
After any change, reload the daemon to apply it without dropping active sessions:
sudo sshd -t # test config syntax before applying
sudo systemctl reload sshd # apply without dropping active sessions
⚠️ IMPORTANT: KEEP A SECOND SESSION OPEN
Always keep an existing SSH session open while testing configuration changes. If you make a mistake that locks you out, the live session lets you recover without needing console access.
Disable Root Login
Direct root login over SSH gives an attacker a known username with full system privileges. Disable it and use a regular user with sudo instead.
# /etc/ssh/sshd_config
PermitRootLogin no
| Value | Behaviour |
|---|---|
no | Root cannot log in at all |
prohibit-password | Root can log in with a key only (not password) |
yes | Root can log in with password or key (default on some distros — avoid) |
Enforce Key-Based Authentication and Disable Passwords
Password authentication is vulnerable to brute-force attacks. Key-based authentication replaces the password with a cryptographic key pair that cannot be guessed.
# /etc/ssh/sshd_config
PubkeyAuthentication yes
PasswordAuthentication no
AuthenticationMethods publickey
Before disabling passwords, make sure your public key is installed on the server:
# On your local machine
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server
# Or manually on the server
mkdir -p ~/.ssh && chmod 700 ~/.ssh
echo "<your-public-key>" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
✍️ ED25519 VS RSA
Prefer
ed25519keys overrsafor new key pairs. Ed25519 uses elliptic-curve cryptography, producing smaller keys that are faster to verify and considered more secure than RSA-2048 at equivalent strength. Generate one withssh-keygen -t ed25519.
Restrict Which Users and Groups Can Log In
Limit SSH access to only the accounts that need it. Even if another account’s credentials are compromised, it cannot be used to get in.
# /etc/ssh/sshd_config
# Allow only specific users
AllowUsers alice bob deploy
# Or allow all members of a group (pick one approach)
AllowGroups sshusers
# Create the group and add users to it
sudo groupadd sshusers
sudo usermod -aG sshusers alice
Change the Default Port
Port 22 is scanned continuously by automated bots. Moving SSH to a non-standard port does not improve security fundamentally, but it eliminates nearly all automated noise from logs and reduces exposure to opportunistic scanners.
# /etc/ssh/sshd_config
Port 2222
Update your firewall and ~/.ssh/config on client machines accordingly:
# ~/.ssh/config (on your local machine)
Host myserver
HostName server.example.com
Port 2222
User alice
IdentityFile ~/.ssh/id_ed25519
✍️ SECURITY THROUGH OBSCURITY
Changing the port is not a security control — a targeted attacker will port-scan and find it. It is a noise reduction measure. Never rely on it as a substitute for strong authentication or firewall rules.
Set an Idle Session Timeout
Unattended SSH sessions are an open door. Terminate idle connections automatically.
# /etc/ssh/sshd_config
ClientAliveInterval 300 # send keepalive every 300 seconds (5 min)
ClientAliveCountMax 2 # disconnect after 2 missed keepalives (10 min total)
The server sends a keepalive packet every ClientAliveInterval seconds. If the client does not respond ClientAliveCountMax times in a row, the connection is terminated.
Disable Unused Features
Each enabled feature is a potential attack surface. Disable everything your server does not use.
# /etc/ssh/sshd_config
X11Forwarding no # disable GUI forwarding (almost never needed on servers)
AllowTcpForwarding no # disable tunnel/proxy use unless required
AllowAgentForwarding no # disable SSH agent forwarding
PermitEmptyPasswords no # never allow accounts with no password
PrintMotd no # suppress message of the day (minor noise reduction)
MaxAuthTries 3 # lock out after 3 failed attempts per connection
LoginGraceTime 30 # disconnect unauthenticated sessions after 30 seconds
Enforce Strong Cryptography
Older SSH implementations support weak ciphers and MAC algorithms retained for compatibility. Explicitly allow only modern, strong algorithms.
# /etc/ssh/sshd_config
KexAlgorithms curve25519-sha256,diffie-hellman-group16-sha512
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
Verify what your current server supports:
ssh -Q kex # supported key exchange algorithms
ssh -Q cipher # supported ciphers
ssh -Q mac # supported MACs
Block Brute-Force Attacks with fail2ban
fail2ban monitors SSH log entries and temporarily bans IPs that exceed a threshold of failed authentication attempts.
sudo apt install fail2ban
# /etc/fail2ban/jail.local
[sshd]
enabled = true
port = 2222 # match your SSH port
maxretry = 5 # ban after 5 failures
bantime = 3600 # ban for 1 hour
findtime = 600 # within a 10-minute window
sudo systemctl enable --now fail2ban
# Check ban status
sudo fail2ban-client status sshd
# Unban an IP manually
sudo fail2ban-client set sshd unbanip 1.2.3.4
Restrict SSH Access at the Firewall
Only allow SSH connections from known, trusted IP ranges. Everything else should be dropped before it reaches sshd.
# UFW (Ubuntu/Debian)
sudo ufw allow from 10.0.0.0/8 to any port 2222
sudo ufw deny 2222
# iptables
sudo iptables -A INPUT -p tcp --dport 2222 -s 10.0.0.0/8 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 2222 -j DROP
Hardened sshd_config Reference
A complete minimal hardened configuration for an Ubuntu server:
Port 2222
PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
AuthenticationMethods publickey
PermitEmptyPasswords no
AllowUsers alice deploy
X11Forwarding no
AllowTcpForwarding no
AllowAgentForwarding no
MaxAuthTries 3
LoginGraceTime 30
ClientAliveInterval 300
ClientAliveCountMax 2
KexAlgorithms curve25519-sha256,diffie-hellman-group16-sha512
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
Verification Checklist
# Confirm sshd is running with the expected config
sudo sshd -T | grep -E "permitrootlogin|passwordauthentication|port|allowusers"
# Check which port sshd is listening on
ss -tlnp | grep sshd
# Inspect recent authentication attempts
sudo journalctl -u ssh --since "1 hour ago" | grep -i "failed\|accepted"
# Scan your own server for weak ciphers (from another machine)
ssh-audit server.example.com
💡 Interview tip: A complete answer to “how do you harden SSH?” covers four layers: authentication (keys only, no root, no empty passwords), access control (AllowUsers, firewall rules), session hygiene (timeouts, MaxAuthTries), and cryptography (modern ciphers and MACs only). Mentioning
fail2banandssh-auditas operational tools shows the interviewer you think beyond just config files.
💪 PRACTICE