Phase 4 · Run over SSH
Security Hardening
SSH key authentication, custom port, SELinux labels, firewalld, and Fail2ban.
Critical ordering — do NOT skip ahead
This phase has a strict sequence. Specifically, the SELinux label for port 22022 must be applied before you restart sshd, and you must test the new SSH port in a separate terminal before closing your existing session. Doing these out of order will lock you out of the server.
Step 1 — Label Port 22022 in SELinux¶
SELinux controls which ports sshd is allowed to bind to. By default, only port 22 has the ssh_port_t label. If you tell sshd to use port 22022 without labelling it first, SELinux silently blocks the bind and sshd fails — you cannot get back in.
Verify it worked:
Expected output: ssh_port_t tcp 22022, 22
Step 2 — Generate SSH Keys¶
SSH key authentication replaces passwords with a cryptographic key pair. The private key stays on your personal computer. The public key goes on the server. Only your private key can prove your identity — password brute-forcing becomes impossible.
Run these commands on your personal computer (not the server):
# Generate the key pair
ssh-keygen -t ed25519
# Copy the public key to the server
scp $env:USERPROFILE\.ssh\id_ed25519.pub username@192.168.1.50:~/id_ed25519.pub
# Add the key to authorized_keys on the server
ssh username@192.168.1.50 "mkdir -p ~/.ssh && cat ~/id_ed25519.pub >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys && rm ~/id_ed25519.pub"
Step 3 — Create the SSH Hardening Config¶
Back on the server, create a configuration drop-in that changes the SSH port, disables password login, and restricts access to your user:
sudo tee /etc/ssh/sshd_config.d/99-hardening.conf > /dev/null << EOF
Port 22022
PubkeyAuthentication yes
PasswordAuthentication no
PermitRootLogin no
MaxAuthTries 3
LoginGraceTime 20
AllowUsers $(whoami)
EOF
Validate the config file (no errors should be reported):
Expected: No output = no errors. Any output means there's a problem — do not proceed.
Step 4 — Open the Firewall and Restart SSH¶
sudo firewall-cmd --permanent --add-port=22022/tcp
sudo firewall-cmd --reload
sudo systemctl restart sshd
Test in a NEW terminal window before closing this one
Open a second terminal on your personal computer and connect using the new port:
If this works — great! Proceed to remove port 22. If it doesn't work, your old terminal is still open and you can diagnose the problem.Once you've confirmed the new port works, remove the standard port 22:
From now on, all SSH connections use: ssh -p 22022 username@192.168.1.50
Step 5 — Configure Fail2ban¶
Fail2ban monitors your SSH log and automatically bans IP addresses that have too many failed login attempts. This prevents brute-force attacks.
sudo tee /etc/fail2ban/jail.local > /dev/null << 'EOF'
[sshd]
enabled = true
port = 22022
ignoreip = 127.0.0.1/8 ::1 192.168.0.0/16 10.0.0.0/8 172.16.0.0/12
backend = systemd
banaction = firewallcmd-rich-rules
EOF
The ignoreip line ensures your local network (192.168.x.x) is never accidentally banned.
✅ Phase 4 Complete¶
Your server is now significantly hardened:
- ✅ SSH listens only on port 22022
- ✅ Password authentication is disabled (key-only)
- ✅ Root login is disabled
- ✅ Fail2ban is blocking brute-force attempts
- ✅ SELinux allows sshd on port 22022