This episode covers securing and using SSH on Rocky Linux: secure sshd configuration, ed25519 key authentication, SSH tunneling, and hardening with fail2ban and restrictions on users and login attempts.

In the previous episode 14, you secured the system from within with SELinux. But there's one door that's almost always open to the server: SSH. For attackers, SSH is the most attacked entry point — thousands of bot login attempts per day are not unusual. Protecting SSH is one of the highest-impact hardening steps.
This episode is split in two: making full use of SSH (keys, agent, tunneling) and securing it (modern sshd configuration, fail2ban, restrictions). Both go hand in hand — a comfortable and secure SSH is the foundation of remote server administration.
The SSH daemon configuration lives in /etc/ssh/sshd_config. Before changing anything, always back it up:
cat /etc/ssh/sshd_configsshd -tsshd -t checks the configuration syntax — a must before restarting to avoid locking yourself out.
Best practice number one: disable password login, use keys. A server that doesn't accept passwords is immune to password brute-force attacks:
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin prohibit-passwordsystemctl restart sshdPasswordAuthentication no closes the password path. PermitRootLogin prohibit-password forbids root login with a password but still allows root login with a key — a balance many use.
Warning
Change these settings only after your public key is proven to work. The rule: test the key login from a new terminal first, then restart sshd with PasswordAuthentication no. Never disable access before the alternative path is verified.
ed25519 is a modern key algorithm that is fast, secure, and produces small keys — the recommended default choice:
ssh-keygen -t ed25519 -a 100 -C "arman@laptop"ssh-copy-id -i ~/.ssh/id_ed25519.pub arman@192.168.1.100ssh arman@192.168.1.100-a 100 increases the KDF iterations to strengthen key passphrase protection. After ssh-copy-id, the public key is installed in ~/.ssh/authorized_keys on the server.
For servers with many user groups, use Match blocks — different rules for different users or groups:
Match group developers
PasswordAuthentication no
Match user backup-bot
AllowTcpForwarding no
ForceCommand /usr/local/bin/backup.shMatch blocks give flexibility: the developers group is banned from using passwords, while a dedicated account is restricted to its command. ForceCommand locks an account to running only a specific command.
Using a passphrase-protected key for every login is annoying. ssh-agent stores the decrypted key in memory:
eval "$(ssh-agent)"
ssh-add ~/.ssh/id_ed25519ssh-add -lOnce added, the key is used automatically without typing the passphrase repeatedly during the session.
Three ways to transfer files over SSH:
scp backup.tar.gz arman@192.168.1.100:/tmp/rsync -avz ./app/ arman@192.168.1.100:/opt/app/sftp arman@192.168.1.100rsync -avz is the top choice for synchronization — it only transfers changed files and supports compression. sftp provides an interactive transfer session that's safer than bare FTP.
SSH tunnels send application traffic through an encrypted SSH connection — very useful for secure access to internal services:
ssh -L 8080:localhost:80 arman@192.168.1.100ssh -R 9090:localhost:9090 arman@192.168.1.100ssh -J arman@bastion.example.com arman@10.0.1.20-L forwards a local port to a service on the server side — a safe way to access an admin panel that only listens on localhost. -J goes through a bastion host to reach servers without a public IP.
fail2ban monitors login logs and blocks IPs that fail repeatedly:
dnf5 install fail2ban
systemctl enable --now fail2bancat > /etc/fail2ban/jail.local <<'EOF'
[sshd]
enabled = true
maxretry = 5
bantime = 3600
EOFfail2ban-client status sshdfail2ban blocks IPs through the firewalld from episode 13 — when an IP exceeds maxretry, it enters the block zone for bantime seconds.
Other very effective settings:
MaxAuthTries 3
AllowUsers arman jokogrep "Failed password" /var/log/secureMaxAuthTries 3 limits password attempts per connection. AllowUsers limits who can log in at all — the least privilege principle from episode 6 applied to the front door.
For an extra layer (optional), port knocking hides SSH entirely: the port only opens after a sequence of connections to certain ports in the correct order. This hides SSH's existence from casual scanners, but adds operational complexity and is not a replacement for strong passwords or keys.
In this episode 15, you mastered SSH on Rocky Linux: modern sshd configuration with key authentication and password blocking, ed25519 keys with ssh-keygen and ssh-copy-id, ssh-agent, file transfer with scp, rsync, and sftp, tunneling with -L, -R, and -J, and hardening with fail2ban, MaxAuthTries, and AllowUsers.
Key takeaways:
sshd -t before restarting the configuration — don't lock yourself out.In the next episode 16, we will discuss TLS, certificates, and PKI — OpenSSL for creating keys, CSRs, and certificates, the trust store with update-ca-trust, self-signed vs Let's Encrypt certificates, and the CRL and OCSP concepts. The door is locked; now it's time to install a trustworthy padlock!