There’s a temptation to skip security setup and go straight to installing Nginx. The server is brand new, nobody knows it exists yet, there’s nothing on it worth stealing.
That reasoning is wrong on all three counts.
What the Auth Log Actually Shows
After your first SSH session on a new server, run this:
sudo tail -50 /var/log/secure
On a server that has been online for even a few hours, you will likely see something like this:
Jun 8 09:12:03 sshd[1234]: Failed password for root from 185.220.101.45 port 54321 ssh2
Jun 8 09:12:05 sshd[1235]: Failed password for admin from 185.220.101.46 port 12345 ssh2
Jun 8 09:12:07 sshd[1236]: Failed password for ubuntu from 193.32.127.11 port 23456 ssh2
Jun 8 09:12:09 sshd[1237]: Failed password for oracle from 45.142.212.10 port 34567 ssh2
Jun 8 09:12:11 sshd[1238]: Failed password for root from 185.220.101.47 port 54322 ssh2
Different IPs. Different usernames. Consistent interval. This is not someone specifically targeting your server — this is automated software running continuously across the entire public internet, trying common username and password combinations against every IP that responds on port 22.
Your server appeared in their scan within minutes of being created. By the time you type your second command, the attempts have already started.
How This Works
Botnets — networks of compromised machines — run port scanners that sweep IP ranges looking for servers with port 22 open. When they find one, they start trying credentials from a dictionary of common username/password combinations:
- Usernames:
root,admin,ubuntu,debian,user,oracle,postgres,pi - Passwords:
password,123456,admin,root,changeme,qwerty
If your server uses password authentication with a weak or common password, this works. Not always immediately, but eventually.
The good news: this is entirely preventable. SSH key authentication with password login disabled means none of these attempts can ever succeed, regardless of how long they run.
The Bot Traffic You Might See in Analytics
If you have Google Analytics or a similar tool on your WordPress sites, you may notice something odd: traffic from locations like China or Singapore with session durations of 0.1 seconds and bounce rates of 100%.
My working theory on what these are: automated crawlers and scanners, not real users. They hit the URL to verify it responds — checking if the server is alive, what software it runs, whether there are known vulnerable endpoints — and move on immediately. They are not reading your content.
Unless you see unusual patterns alongside this traffic — sudden CPU spikes, unfamiliar processes running, strange entries in Nginx access logs — this is background internet noise. Worth knowing about, not worth losing sleep over.
What would actually concern me: requests to /wp-admin/, /xmlrpc.php, or /wp-login.php appearing repeatedly in Nginx logs from the same IPs. Those are targeted WordPress probing attempts, and they indicate someone is specifically looking for vulnerable WordPress installations.
WordPress Malware — Server vs Plugin
I’ve dealt with Japanese SEO spam on a WordPress site. This specific attack pattern — hundreds of pages with Japanese titles appearing in Google Search Console, often for products or pharmaceuticals — is well-documented and almost always comes through a vulnerable plugin or theme, not through the server itself.
What happens: a plugin with a known vulnerability gets exploited. The attacker gains file write access to the WordPress installation and injects malicious files or modifies existing ones. These injected files create the spam pages that Google then indexes.
The fix involves: removing the malicious files, identifying and updating or removing the vulnerable plugin, and auditing the entire WordPress installation for other modifications. It is tedious. It takes hours.
What Part 3 Covers
Four steps, in the order you should do them:
3.2 — Change SSH port and disable root login Moving SSH off port 22 eliminates most automated scanning noise immediately. The auth log goes quiet. Disabling root login means even if someone gets the port right, they cannot log in directly as root.
3.3 — Configure firewalld Rocky Linux uses firewalld (not UFW). You open exactly the ports you need — SSH custom port, HTTP, HTTPS — and close everything else. This is the firewall layer that sits in front of everything.
3.4 — Install and configure Fail2ban Fail2ban reads your auth log and automatically bans IPs that exceed a threshold of failed login attempts. It works alongside the firewall as an automated response layer.
3.5 — Disable password authentication entirely The final step: only SSH key authentication is allowed. No password, no dictionary attack possible. This is the step that makes the auth log failures irrelevant — they can try forever and get nowhere.
None of these steps are complicated. Together they take about 30 minutes. They should be done before you install Nginx, before you configure PHP-FPM, before you put anything worth protecting on the server.
My Current Setup for Reference
For context on what “done” looks like: on my Vultr VPS I run SSH on a custom port, have root login disabled, use SSH key authentication only (keys on three separate machines — two Macs and one Windows), and have Fail2ban running. I check the auth log occasionally. It is quiet.
The three-machine key setup comes from learning the hard way that if your only SSH key is on one laptop and that laptop dies, you need a recovery path. Part 2.5 covered how to handle multiple keys for multiple machines.