This week's roundup: SSH attacks every 39 seconds, public-facing apps as the top initial access vector, and why default configurations keep failing audits. Plus, a practical hardening walkthrough you can run through this week.
If your server has a public IP and port 22 open, it is being probed right now. A University of Maryland study found that an internet-facing SSH service is attacked on average every 39 seconds. That number is old enough to vote, and it has not improved with age.
The threat picture this week looks familiar in shape but sharper in detail:
Verizon's 2023 DBIR notes that over 90% of successful cyberattacks begin with phishing. For internet-facing Linux servers, however, automated SSH brute-force remains a leading initial access vector. Different attack, same outcome: someone gets a shell they shouldn't have.
The uncomfortable truth is that Linux defaults prioritize usability over security. That's a reasonable design choice for a distribution. It is a terrible configuration for a production server.
What follows is a step-by-step hardening guide for intermediate admins — people who can read a config file and run systemctl without hand-holding, but who want a structured checklist rather than a 400-page benchmark document.
Key Takeaway: Default Linux installs are not insecure by design flaw — they're insecure by omission. Hardening is the act of closing the gaps the installer left open.
SSH is the most attacked service on most Linux servers, and it's also the one with the most well-understood hardening path.
CIS Benchmark 5.2.8 recommends disabling direct root login over SSH. The reasoning is straightforward: root is a known username with unlimited privileges. If an attacker can't guess the username, brute-force attempts against root are wasted effort. Set PermitRootLogin no in /etc/ssh/sshd_config and use sudo from a regular account instead.
Passwords are brute-forceable. SSH key pairs are not — not computationally, anyway. The workflow:
ssh-keygen -t ed25519 -C "admin@host"
ssh-copy-id user@server
Then edit /etc/ssh/sshd_config and set PasswordAuthentication no. Reload the daemon with systemctl reload sshd. Test the key login in a second terminal before you close your current session. This is the single most common way admins lock themselves out.
Key-based auth is strong, but keys can be stolen from a compromised workstation. Adding a second factor — TOTP via libpam-google-authenticator, or a hardware key with pam_u2f — means a stolen private key alone isn't enough.
Moving SSH to a non-standard port reduces scan noise in your logs. It does not make you secure. Automated scanners will find you eventually; targeted attackers will port-scan. Treat it as log hygiene, not a control.
ssh-agent so you're not typing it constantly.~/.ssh/authorized_keys regularly — stale keys are a common finding in incident response.Key Takeaway: Disabling root login and switching to key-based auth eliminates the vast majority of automated SSH attacks. Everything else is incremental.
Allow only what you actually serve. For a typical web server:
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
NIST SP 800-123 is explicit about this: default-deny inbound, allow only necessary ports and services. If you're on a RHEL-family system, firewall-cmd does the same job.
Fail2ban watches log files and temporarily bans IPs that show malicious signs — repeated failed SSH logins being the classic case.
sudo apt install fail2ban
Then create /etc/fail2ban/jail.local and enable the sshd jail. Default ban times are short; consider extending them to a week or more for repeat offenders.
They solve different problems:
You want both.
Run ss -tulpn and look at every listening socket. Do you recognize all of them? Is anything bound to 0.0.0.0 that should be on 127.0.0.1? The SANS Linux Security Checklist treats this as a baseline exercise for a reason — it catches surprises.
Every installed package is potential attack surface. If you're not running a print server, remove CUPS. If you don't use Avahi, disable it. This isn't paranoia; it's arithmetic.
Key Takeaway: A firewall defines what's reachable. Fail2ban reduces the noise hitting what's reachable. Neither replaces the other.
The exploits that hurt most are usually not novel. Shellshock (2014), WannaCry (2017), Log4Shell (2021) — each had a patch available before mass exploitation began. The breaches happened because patching was slow.
On Debian and Ubuntu:
sudo dpkg-reconfigure --priority=low unattended-upgrades
Then edit /etc/apt/apt.conf.d/50unattended-upgrades to confirm security updates are enabled and to configure automatic reboots if your workload tolerates them. On RHEL-family systems, dnf-automatic does the equivalent.
A firewall blocks traffic from outside. It doesn't block:
Updates close the vulnerability itself. Firewalls reduce exposure. You need both.
Key Takeaway: The gap between patch release and patch application is where most real-world breaches live. Automate the boring part.
Standard Linux permissions are discretionary — the file owner decides who gets access. Mandatory Access Control (MAC) adds a policy layer the owner can't override.
SELinux originated at the NSA and has been in the mainline kernel since 2003. It confines processes with fine-grained labels, so even a compromised web server can't wander into /etc/shadow.
AppArmor, first released in SUSE in 2005, uses per-program profiles that are easier to write and read than SELinux policies. Ubuntu ships it enabled by default.
Which to use? Whatever your distro defaults to. RHEL, Fedora, and CentOS use SELinux. Ubuntu, Debian, and SUSE use AppArmor. Fighting the default is a waste of time.
Verify enforcement:
getenforce # SELinux
sudo aa-status # AppArmor
NIST SP 800-53 frames this as part of least privilege: processes should have only the access they need, enforced by the kernel rather than by good intentions.
Key Takeaway: MAC is the difference between "the attacker got a shell" and "the attacker got a shell that can't do anything useful."
You cannot respond to what you cannot see.
AIDE and Tripwire create a cryptographic baseline of your filesystem and alert you when files change. AIDE setup:
sudo aideinit
sudo mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db
Schedule daily checks via cron or a systemd timer. Investigate every alert — false positives are common after updates, but so are real intrusions.
NIST SP 800-92 is the reference here: logs on the compromised host are logs the attacker can delete. Ship them somewhere else — a syslog server, a SIEM, or a managed log service. Configure logrotate so disks don't fill.
Run one of these monthly. Fix the high-severity findings. Re-run.
/var/log/auth.log (Debian) or /var/log/secure (RHEL) is where failed logins, sudo usage, and session opens live. A quick daily skim catches the weird stuff — logins at 3 AM from countries you don't operate in.
A few high-value settings in /etc/sysctl.d/:
net.ipv4.ip_forward = 0
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.rp_filter = 1
kernel.randomize_va_space = 2
These mitigate network-level attacks and make exploitation harder. They're not a substitute for patching, but they raise the cost of an attack.
Key Takeaway: Detection is not optional. Assume something will get through, and build the visibility to notice when it does.
Hardening reduces the odds of compromise. Backups determine whether a compromise is a bad week or a company-ending event.
Integrate backup verification into your hardening routine. If a restore takes three days because nobody documented the process, you don't have a recovery plan.
Key Takeaway: Backups are the only control that works after everything else has failed. Treat them accordingly.
Myth: Changing the SSH port makes you secure. It reduces scan noise. It does not stop targeted attacks or automated scanners that try all ports.
Myth: Strong passwords are enough for SSH. Key-based auth is categorically stronger. Passwords should be disabled entirely on internet-facing SSH.
Myth: Linux is inherently secure. Linux is inherently auditable. Defaults prioritize usability. Security is what you configure.
Myth: A firewall alone suffices. Firewalls are one layer. You need patching, authentication hardening, MAC, monitoring, and backups.
Myth: Updates can be skipped behind a firewall. Insider threats, supply-chain compromises, and exposed services all bypass this logic. Patch anyway.
PermitRootLogin no, PasswordAuthentication no, keys deployed, 2FA consideredWhy should I disable root SSH login? Root is a known username with unlimited privileges. Disabling direct login removes a high-value target and forces attackers to guess both a username and a credential.
Is changing the SSH port enough to secure SSH? No. It reduces log noise from automated scanners. It does not replace key-based auth, disabled root login, or 2FA.
What is the difference between a firewall and fail2ban? A firewall applies static allow/deny rules to ports and addresses. Fail2ban dynamically bans IPs based on log patterns, like repeated failed logins.
How often should I apply security updates? Automatically, as soon as they're available. Manual patching on a schedule leaves a window of exposure that attackers actively exploit.
Do I need SELinux or AppArmor? If your distro enables one by default, keep it in enforcing mode. It confines compromised processes and is one of the highest-value controls available.
What is the best way to manage SSH keys?
Strong passphrases, ssh-agent for convenience, scheduled rotation, and regular audits of authorized_keys files. Remove keys for departed staff immediately.
How can I monitor my server for intrusions? AIDE or Tripwire for file integrity, centralized logging for event correlation, and regular reviews of auth logs. Lynis or OpenSCAP for periodic audits.
Should I use a non-standard SSH port? It's fine as a minor noise-reduction measure. Don't treat it as a security control.
What is the role of backups in server hardening? Backups are the recovery mechanism when prevention fails. They're essential against ransomware and destructive attacks, and they must be tested.
How do I audit my server's security? Run Lynis or OpenSCAP against a known benchmark (CIS, STIG), review the findings, remediate, and repeat monthly or after major changes.
Ready to harden your Linux server? Start with the checklist above. For a deeper dive, download our free Linux Security Hardening Cheat Sheet. Stay tuned for next week's roundup, where we'll cover advanced intrusion detection with OSSEC and the ELK stack.