Master SSH Security: Keys, Port Hiding, 2FA, Jump Hosts & Zero Trust
This guide walks through hardening SSH against massive brute‑force attacks by switching to ed25519 key authentication, disabling password logins, obscuring the default port, tightening user permissions, adding two‑factor authentication, configuring bastion hosts, setting connection limits, centralizing logs, rotating keys regularly, and adopting a zero‑trust architecture with HashiCorp Vault.
Why SSH Needs Hardening
Brute‑force attacks on SSH exceed 400,000 attempts per day, making the default port 22 a prime target. Strengthening SSH is essential for protecting servers and preventing unauthorized access.
Key‑Based Authentication: Ditch Passwords
Generate an ed25519 key pair, which offers stronger security with shorter keys than RSA.
ssh-keygen -t ed25519 -C "[email protected]"Copy the public key to the server:
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@serverDisable password authentication in /etc/ssh/sshd_config:
sudo vim /etc/ssh/sshd_config
PasswordAuthentication noRestart the SSH service and verify that key‑based login works before locking out password access.
Port Obfuscation: Hide the Door
Change the listening port from 22 to a non‑standard value (e.g., 2233) in sshd_config and update firewall rules. Port 2233 Allow the new port and block the old one:
sudo ufw allow 2233
sudo ufw deny 22Least‑Privilege User Access
Create a dedicated operations account and restrict SSH logins to it.
sudo adduser ops
sudo usermod -aG sudo opsIn sshd_config set:
AllowUsers ops
PermitRootLogin noTwo‑Factor Authentication (2FA)
Install Google Authenticator and bind it to SSH via PAM. sudo apt install libpam-google-authenticator Run google-authenticator for each user, then add to /etc/pam.d/sshd: auth required pam_google_authenticator.so Enable challenge‑response authentication and require both public‑key and keyboard‑interactive methods:
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactiveBastion (Jump) Host
Configure a jump host to centralize access. On the bastion, limit connections with Match blocks, then on the client define shortcuts:
Host jump
HostName jump.company.com
User admin
Port 2233
Host web1
HostName 10.0.1.10
User ops
ProxyJump jump
Host db1
HostName 10.0.1.20
User ops
ProxyJump jumpConnection Timeouts and Limits
Prevent idle sessions and limit authentication attempts by adding the following to sshd_config:
ClientAliveInterval 300
ClientAliveCountMax 2
MaxAuthTries 3
MaxSessions 3
MaxStartups 10:30:100Comprehensive Logging
Set verbose logging and forward logs to a central server for analysis. LogLevel VERBOSE Configure rsyslog to send SSH logs: auth,authpriv.* @@logserver.company.com:514 View live logs with:
sudo journalctl -u ssh -fNetwork‑Level Access Control
Use iptables (or cloud security groups) to allow SSH only from trusted IP ranges.
# Flush existing rules
sudo iptables -F
# Allow loopback and established connections
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allow trusted IPs on the custom port
sudo iptables -A INPUT -p tcp -s 192.168.1.100 --dport 2233 -j ACCEPT
sudo iptables -A INPUT -p tcp -s 10.0.1.0/24 --dport 2233 -j ACCEPT
# Drop all other SSH attempts
sudo iptables -A INPUT -p tcp --dport 2233 -j DROP
# Save rules
sudo iptables-save > /etc/iptables/rules.v4Key Rotation Automation
A Bash script generates a new key, distributes it, tests connectivity, and replaces the old key if successful. Schedule it with cron to run every 90 days.
#!/bin/bash
# Generate new key
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_new -N "" -C "rotated-$(date +%Y%m%d)"
# Distribute to servers
for server in web1 web2 db1 db2; do
ssh-copy-id -i ~/.ssh/id_ed25519_new.pub $server
done
# Test new key
for server in web1 web2 db1 db2; do
ssh -i ~/.ssh/id_ed25519_new -o PasswordAuthentication=no $server "echo 'New key works on $server'"
done
# Replace old key if tests passed
if [ $? -eq 0 ]; then
mv ~/.ssh/id_ed25519_new ~/.ssh/id_ed25519
mv ~/.ssh/id_ed25519_new.pub ~/.ssh/id_ed25519.pub
echo "Key rotation completed successfully"
else
echo "Key rotation failed"
rm ~/.ssh/id_ed25519_new*
fiAdd to crontab:
0 2 1 */3 * /home/ops/rotate_ssh_keys.sh >> /var/log/ssh_key_rotation.log 2>&1Zero‑Trust Architecture with HashiCorp Vault
Use Vault as an SSH Certificate Authority to issue short‑lived certificates.
wget https://releases.hashicorp.com/vault/1.15.2/vault_1.15.2_linux_amd64.zip
unzip vault_1.15.2_linux_amd64.zip
sudo mv vault /usr/local/bin/
# Start Vault in dev mode
vault server -dev -dev-listen-address="0.0.0.0:8200"
# Set environment variables
export VAULT_ADDR='http://127.0.0.1:8200'
export VAULT_TOKEN="your-root-token"
# Enable SSH engine and generate CA key
vault auth enable ssh
vault write ssh/config/ca generate_signing_key=true
# Create a role for ops users
vault write ssh/roles/ops \
key_type=ca \
default_user=ops \
allowed_users=ops,admin \
default_extensions="permit-pty,permit-user-rc" \
ttl=10m
# Sign a public key to obtain a short‑lived certificate
vault write -field=signed_key ssh/sign/ops \
public_key=@$HOME/.ssh/id_ed25519.pub > ~/.ssh/id_ed25519-cert.pub
# Use the certificate for login
ssh -i ~/.ssh/id_ed25519 -i ~/.ssh/id_ed25519-cert.pub user@serverRevoking a user’s access is as simple as removing their policy in Vault, instantly invalidating all certificates issued to them.
Conclusion
By combining key‑based authentication, port obfuscation, strict user permissions, two‑factor authentication, bastion hosts, connection limits, centralized logging, firewall controls, automated key rotation, and a Vault‑backed zero‑trust model, you can dramatically reduce the attack surface of SSH and maintain a robust, auditable security posture.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
ITPUB
Official ITPUB account sharing technical insights, community news, and exciting events.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
