
September 11, 2026
11 min read
By Kokil Thapa | Last reviewed: September 2026
Every production Linux box I maintain still gets hammered on port 22 within hours of going live. If you harden SSH on Linux servers before that traffic arrives, you cut brute-force noise and real breach risk in one pass. This guide walks through the same baseline I apply on Linux system administration engagements: key-only login, a minimal sshd_config, firewall limits, and fail2ban. It assumes Ubuntu 22.04 or 24.04 LTS, though the steps transfer to Debian and most RHEL-family distros with small path changes.
/etc/ssh/sshd_config, restrict users and ciphers, allow SSH only from trusted IPs in UFW or nftables, and add fail2ban on port 22 or your custom port.Why should you harden SSH on Linux servers before anything else?
SSH is the front door to your server. Laravel apps, WordPress sites, and database hosts all share the same risk profile here. An open SSH service with password auth enabled is a magnet for credential stuffing. Bots do not care whether you host a law-firm portal or a WooCommerce shop.
On sister sites I deploy with Deployer 7 and GitLab CI, SSH is how releases land. Lock it down wrong and you break deploys. Lock it down right and you still push code while attackers bounce off. That balance is what this article targets.
Start with a checklist mindset aligned with CIS benchmarks for server hardening:
- Authentication: keys only, no empty passwords, no root login.
- Configuration: modern ciphers, sensible timeouts, limited users.
- Network: firewall allowlists, optional non-default port.
- Detection: fail2ban or similar, plus log review.
- Recovery: console access tested before you restart sshd.
If you are building from scratch, read Ubuntu SSH server setup first. Then return here for production-grade tightening. For broader context, see Ubuntu server security best practices and how to secure your website and server in Nepal.
How do you set up SSH key authentication and disable passwords?
Key-based auth is the single highest-impact change when you harden SSH on Linux servers. Passwords leak through reuse, support tickets, and screenshots. Keys do not.
Generate a modern key pair on your workstation
Use Ed25519. It is fast, short, and widely supported on current OpenSSH builds shipped with Ubuntu 22.04 and 24.04.
ssh-keygen -t ed25519 -a 100 -C "deploy@yourcompany" -f ~/.ssh/id_ed25519_prod Passphrase-protect the private key. Store backups offline. For team deploy keys, use a dedicated user per environment rather than sharing one private key across five developers.
Need a strong passphrase? Use the password generator and store secrets in a manager, not a spreadsheet.
Create a non-root deploy user on the server
sudo adduser deploy
sudo usermod -aG sudo deploy
sudo mkdir -p /home/deploy/.ssh
sudo chmod 700 /home/deploy/.ssh Copy your public key into /home/deploy/.ssh/authorized_keys. Permissions matter. OpenSSH ignores the file if ownership or mode is wrong.
sudo nano /home/deploy/.ssh/authorized_keys
sudo chown -R deploy:deploy /home/deploy/.ssh
sudo chmod 600 /home/deploy/.ssh/authorized_keys Details on ownership rules live in Linux file permissions and ACLs explained.
Test key login before you disable passwords
Open a second terminal. Keep your current root session alive. Test from your IP:
ssh -i ~/.ssh/id_ed25519_prod deploy@203.0.113.10 Only after a successful login should you edit sshd_config. I have seen teams lock themselves out by skipping this step on a Friday evening. Do not be that team.
Which sshd_config settings should you change to harden SSH?
The main file is /etc/ssh/sshd_config on Ubuntu and Debian. Always validate syntax before restart. The OpenSSH project documents every directive in the official OpenSSH manual.
Recommended production baseline
Create a drop-in file so package upgrades do not overwrite your edits:
sudo nano /etc/ssh/sshd_config.d/99-hardening.conf Add these directives:
Port 2222
Protocol 2
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
ChallengeResponseAuthentication no
PubkeyAuthentication yes
AuthenticationAttempts 3
AllowUsers deploy
MaxAuthTries 3
MaxSessions 3
LoginGraceTime 30
ClientAliveInterval 300
ClientAliveCountMax 2
X11Forwarding no
AllowTcpForwarding no
PermitEmptyPasswords no
UsePAM yes
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org Validate and reload:
sudo sshd -t
sudo systemctl reload ssh If sshd -t prints an error, fix it before reload. A broken config can drop every active session on restart.
For AllowUsers, list every account that needs shell access. Omit service accounts unless they truly require SSH. On legal-tech portals and eCommerce hosts I maintain, only deploy and one admin user get in.
Match this work with SSH key auth, fail2ban, and port hardening for a focused companion read. Server hardening for Ubuntu web servers covers the full stack beyond SSH.
Should you change the default SSH port on Linux servers?
Changing the port is security through obscurity. It is not a substitute for keys and firewall rules. It does cut log noise. That alone is worth it on busy hosts.
If you move SSH from 22 to 2222, update three places at once:
Portdirective insshd_config.- UFW or nftables allow rule for the new port.
- Your CI deploy config and local
~/.ssh/config.
Example client stanza:
Host prod-law-portal
HostName 203.0.113.10
User deploy
Port 2222
IdentityFile ~/.ssh/id_ed25519_prod
IdentitiesOnly yes On GitLab CI deploy jobs, pass -p 2222 or set the port in Deployer’s host() config. I have fixed more broken pipelines from forgotten port changes than from actual attacks.
| Control | Security value | Ops cost | Verdict |
|---|---|---|---|
| Disable password auth | Very high | Low once keys work | Always do this |
| Ed25519 keys with passphrase | Very high | Low | Always do this |
| AllowUsers restriction | High | Low | Strongly recommended |
| Firewall IP allowlist | Very high | Medium if IPs change | Best when IPs are stable |
| Non-default port | Low–medium | Medium | Nice extra, not core |
| fail2ban | Medium | Low | Recommended on public IPs |
Port knocking and VPN-only SSH are valid for high-value systems. For a typical Laravel or WordPress VPS in Nepal, key auth plus UFW from office and CI IPs gets you most of the way there. See set up a WireGuard VPN server if you want SSH reachable only over VPN.
How do you combine firewall rules and fail2ban to protect SSH?
SSH hardening without network controls leaves key brute-force and exploit probes hitting sshd directly. Layer a host firewall first. Add fail2ban second.
UFW example for Ubuntu
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow from 198.51.100.20 to any port 2222 proto tcp comment 'Office IP'
sudo ufw allow from 203.0.113.50 to any port 2222 proto tcp comment 'GitLab CI'
sudo ufw enable
sudo ufw status verbose Prefer nftables on newer stacks? The same logic applies. Compare approaches in iptables vs nftables Linux firewalls and nftables: the modern Linux firewall.
Install and configure fail2ban
sudo apt update
sudo apt install fail2ban
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local Minimal SSH jail override:
[sshd]
enabled = true
port = 2222
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
findtime = 600
bantime = 3600
ignoreip = 127.0.0.1/8 198.51.100.20 Restart and verify:
sudo systemctl enable fail2ban
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd The fail2ban project wiki at fail2ban installation docs covers distro-specific paths. On RHEL-family systems, auth logs may live under journald instead of /var/log/auth.log.
Pair this with monitoring. Linux server monitoring with Netdata and alerts catches unusual auth spikes even when fail2ban handles the noise.
How do you audit and maintain SSH hardening over time?
Hardening is not a one-time task. Package updates rewrite defaults. New developers ask for temporary password auth. CI IP ranges change after a provider migration.
Quick audit commands
sudo sshd -T | grep -E 'permittrootlogin|passwordauthentication|pubkeyauthentication|allowusers|port'
sudo grep "Failed password" /var/log/auth.log | tail -20
sudo grep "Accepted publickey" /var/log/auth.log | tail -20 Run these after every openssh-server upgrade. Ubuntu’s security notices at ubuntu.com/security/notices flag OpenSSH CVEs that may require urgent patching.
Automate compliance checks
Tools like Lynis or OpenSCAP against CIS profiles help on audit-heavy clients. For small teams, a monthly calendar reminder plus the commands above is enough. Document your SSH policy in the same place you keep backup runbooks. Tie backups to Ubuntu server backup strategies so you can recover if lockout happens.
On production Laravel hosts such as Adventure Third Pole Trek and sister legal-tech sites on shared EC2, SSH stays limited to deploy users. Application logs and queue workers never share the same UNIX account as the human admin. That separation limits blast radius if a key ever leaks.
If you tunnel for database admin, read SSH tunneling and port forwarding explained. Disable forwarding in sshd_config unless you actively need it.
For ongoing help after launch, support and maintenance and domain registration and hosting cover the ops side many Nepal teams outsource. Ubuntu server setup guide remains the right starting point for fresh VMs.
Key Takeaways
- Enforce Ed25519 key authentication and set
PasswordAuthentication nobefore exposing any production host. - Keep a live root or sudo session open while testing a new
sshd_configin a second terminal. - Restrict SSH with
AllowUsers, modern ciphers, andPermitRootLogin noin a drop-in undersshd_config.d. - Combine UFW or nftables IP allowlists with fail2ban rather than relying on a non-default port alone.
- Re-audit SSH settings after every OpenSSH package upgrade and CI infrastructure change.
- Document deploy user keys, ports, and console recovery steps alongside your backup runbooks.
People Also Ask
Is it safe to disable password authentication for SSH?
Yes, once every legitimate admin and CI job uses key auth and you have console or IPMI access as a fallback. Disabling passwords removes the main target for brute-force bots. The risk is lockout if keys are missing or permissions on authorized_keys are wrong. Test before you reload sshd.
What is the best SSH key type for Linux servers in 2026?
Ed25519 is the default choice for new keys. It is shorter and faster than RSA while meeting current OpenSSH security guidance. Use RSA 4096 only when you must support legacy clients that lack Ed25519. Always passphrase-protect private keys on workstations.
Does changing the SSH port stop hackers?
It reduces automated scan volume but does not stop targeted attacks. Anyone can port-scan your host. Treat port changes as a log-noise filter. Pair them with key-only auth, firewall allowlists, and fail2ban for real protection.
How often should you review SSH hardening settings?
Review after every OpenSSH security update, when staff or contractors change, and when CI provider IP ranges move. A monthly quick audit of sshd -T output and recent auth.log entries catches drift before it becomes an incident.
Next steps: lock the door, then monitor the house
You now have a practical baseline to harden SSH on Linux servers without blocking your own deploys. Keys first. Config second. Firewall and fail2ban third. Audit monthly. If you want this done on production hosts you already run, or baked into a new web development launch, contact us and we can review your SSH posture alongside the rest of your stack. For a wider hardening pass, see diagnose high CPU and memory usage on a Linux server and keep your Notary Kathmandu-class deployments on the same secure footing.
Frequently Asked Questions
0 Comments
Leave a comment
Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

