My Servers Get Scanned Every 40 Seconds. Here's How I Stopped Caring — And Fixed It Anyway

My Servers Get Scanned Every 40 Seconds. Here's How I Stopped Caring — And Fixed It Anyway

31 41 109
calendar_today agoschedule8 min read

I'm exhausted. Genuinely, professionally exhausted. Every server I stand up, no matter how boring, no matter how "it's just a staging box, nobody even knows the IP" — gets scanned before the SSL cert finishes provisioning. I used to take it personally. I used to open /var/log/auth.log, see four hundred failed logins from some IP block in a country I've never shipped a package to, and think: why me specifically?

It's not you specifically. That's actually the first thing you need to internalize before any of the technical advice below will make sense to you emotionally instead of just intellectually. Internet-wide scanning is background radiation now. GreyNoise's Global Observation Grid clocked roughly 212 exploitation attempts per second across the back half of 2025, from nearly 3 billion malicious sessions and 3.8 million unique source IPs hitting internet-facing infrastructure. You are not being hunted. You are being sampled, by the same dumb scripts that are sampling literally everyone else with a public IP, including your neighbor's smart fridge.

Once that sinks in, the panic turns into engineering, which is a much more useful emotional state. So let's do the engineering.

Myth #1: Changing the SSH Port Is "Security"

No. It isn't. I need you to hear this from someone who has changed the SSH port on every server they've ever owned: it is not security, it is noise reduction. A full port scan finds your "hidden" SSH port in about four seconds, and any attacker who is actually targeting you specifically — as opposed to sweeping the entire IPv4 space with a botnet — will find it just as fast.

What it does do, and this is legitimately worth doing, is cut out the overwhelming majority of low-effort automated scanners that only ever probe port 22 because probing every port on every IP is expensive even for a botnet. Cleaner logs. Less fail2ban noise. Fewer 3 AM "wait, is this real" moments. Do it, but do it with your eyes open: you're sweeping the porch, not installing a deadbolt.

The Actual Deadbolt: SSH Hardening That Isn't Theater

Here's the sshd config that actually matters, and I want you to notice something about it: none of it is exotic. It's the boring stuff nobody does because it involves editing a file instead of installing a shiny dashboard.

# /etc/ssh/sshd_config.d/99-hardening.conf

PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
AuthenticationMethods publickey
PermitEmptyPasswords no
MaxAuthTries 3
MaxSessions 4
LoginGraceTime 20

AllowAgentForwarding no
AllowTcpForwarding no
X11Forwarding no
PermitTunnel no

AllowUsers your_actual_username

ClientAliveInterval 300
ClientAliveCountMax 2

Generate an Ed25519 key if you're still rocking RSA-4096 out of nostalgia — it's smaller, it's faster, and the public key is about 68 characters instead of 800-plus:

ssh-keygen -t ed25519 -C "you@host"

Test your new config in a second terminal before you reload sshd. I'm not going to explain why. If you've never locked yourself out of a box at 2 AM over a typo in sshd_config, you will, and that day will teach you faster than I ever could. Just do the test-in-a-second-terminal thing now and skip the lesson.

sudo sshd -t && sudo systemctl reload sshd

Password authentication being off is the single highest-leverage change on this entire list. GreyNoise's edge report noted a credential-spraying botnet targeting exposed RDP that grew from 2,000 to 300,000 participating IPs in 72 days — a 150x jump in about two and a half months, with the majority of it riding on compromised residential connections. That's the fate of anything on the internet still accepting admin / Password123! in 2026. Don't be the box that's still allowing it out of laziness.

Default-Deny Firewall, Because "Allow Everything, Block What I Notice" Isn't a Strategy

Whatever you use — nftables, ufw, firewalld — the policy should be deny by default, allow the minimum set of ports you actually serve. Not "allow everything and block IPs after they annoy me." Deny-by-default means the scanners hitting the other 65,530 ports just get silently dropped, which also, pleasantly, makes your box slightly harder to fingerprint.

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw limit 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable

That limit instead of allow on SSH isn't a typo — ufw's rate-limiting will auto-block an IP that hits the port more than six times in thirty seconds. It's a free, built-in speed bump before fail2ban even wakes up.

Fail2ban vs CrowdSec: Pick a Fighter

This is where I watch people either overthink it or underthink it, so let's settle it cleanly.

Fail2ban watches your logs, notices repeated failures, and bans the offending IP at the firewall. It's been quietly doing this job for over a decade, it has zero external dependencies, it phones home to nobody, and on a 512MB box it barely registers. If you're running one server with SSH and maybe a web app, fail2ban is completely sufficient and there's a real argument for not overengineering past it.

# /etc/fail2ban/jail.local
[sshd]
enabled = true
maxretry = 3
bantime = 1h
findtime = 10m
ignoreip = your.own.ip.address

That last line matters more than any other line in this entire article. Add your own IP to ignoreip before you enable anything. Locking yourself out of your own server over your own typo is a rite of passage nobody actually enjoys.

CrowdSec does the same local detection but adds a crowdsourced reputation layer: your agent optionally shares anonymized attack signals and receives a community blocklist in return, so an IP that hammered someone else's Ghost blog in Estonia last week gets pre-emptively blocked on your box before it ever sends you a single packet. It splits detection from enforcement — an engine that decides, and separate "bouncers" that actually carry out the ban at the firewall, at your reverse proxy, or in front of multiple servers from one shared decision list.

If you're running a single personal box, fail2ban is fine — go ahead, sleep well. If you're running anything public-facing at scale, multiple servers, or you're just tired of every server relearning the same lessons independently, CrowdSec's shared blocklist and centralized decision-making genuinely earns its extra moving parts.

Patch the Old Stuff. No, Really, the Old Stuff

Here's the part that should offend your sense of narrative logic: GreyNoise's 2026 State of the Edge report found that pre-2015 CVEs generated roughly four times more exploitation traffic than CVEs disclosed in 2023–2024. Shellshock. Old PHP-CGI bugs. Ancient WebLogic flaws. Vulnerabilities old enough to vote are still out there generating millions of exploitation attempts, because there are still millions of boxes nobody ever patched, and scanning for a decade-old known-good exploit is cheaper and more reliable for an attacker than gambling on something novel.

Your bot army isn't targeting you with next-generation zero-days. It's targeting you with the software equivalent of trying every car door in the parking lot, because somewhere, someone genuinely still left it unlocked. Run unattended-upgrades, set a reboot window, and stop assuming "it's old, nobody cares about it anymore" is a security posture. It is, statistically, the opposite of one.

The IP-Reputation Illusion Is Over

If your entire defense strategy is "block IPs that look sketchy," I have bad news. GreyNoise's residential-proxy research, based on 4 billion malicious sessions over 90 days, found that nearly 4 in 10 attacking IPs are residential — ordinary home broadband, mobile data, small-business routers, quietly compromised and rented out as attack infrastructure. One residential proxy network Google's Threat Intelligence Group took down in January 2026 was running 9 to 11 million daily active proxies used by over 550 distinct threat groups, including state-sponsored ones. Your grandmother's router might, statistically, be more dangerous than she is.

The takeaway isn't "give up on IP blocking." It's "don't let IP blocking be your only layer," because the entire premise that you can infer intent from an IP address is, as GreyNoise's own CEO put it, broken at scale. Behavior-based detection (what CrowdSec's scenario engine does, what a WAF does) matters more now than reputation lists alone.

Troll Them Back: Tarpits Are Underrated and Extremely Funny

This is my favorite category, because most security advice is defensive and boring, and tarpits let you be defensive and petty, which is a combination I fully endorse.

Endlessh is an SSH tarpit: point it at port 22 (move your real sshd elsewhere), and it exploits a genuinely funny loophole in the SSH RFC — the server is allowed to send junk banner lines before the real version string, with no upper limit on how long it can stall. Endlessh sends an infinite trickle of random banner bytes, a few bytes every few seconds, and just… holds the connection open. Forever. Automated SSH brute-forcers, which are almost always single-threaded per target and not built to handle a server that never actually says hello, just sit there, burning a thread, going nowhere, for as long as you let them.

docker run -d -p 22:2222 -p 127.0.0.1:2222:2222 --name endlessh figiel/endlessh

Nepenthes and its cousin Iocaine do the same thing for web crawlers instead of SSH bots: an infinite maze of auto-generated fake pages, all linking back into themselves, all stuffed with Markov-chain gibberish that's just structured enough to look like content. Point a misbehaving scraper at it and it doesn't get an error, it doesn't get a block page — it gets an infinite hallway with no exit, and it keeps walking because nothing in its logic tells it to stop. It's less "you shall not pass" and more "you shall pass, forever, into nothing." Deploy it behind a Disallow in robots.txt and let anything that ignores that directive enjoy the consequences.

Neither of these replaces real hardening. Think of them as the security equivalent of leaving out a bowl of pennies for door-to-door scammers — it wastes nobody's time who matters, and it wastes a genuinely satisfying amount of time for everyone else.

Least Exposure: Turn Off What You're Not Using

Every listening service is an entry point you now have to defend, patch, and think about at 3 AM. Run ss -tulpn, look at every single line, and ask yourself honestly whether you meant to expose it.

ss -tulpn

Uninstall what you don't need. Remove build tools and compilers from production hosts — if an attacker does get a foothold, you'd rather they didn't have gcc sitting there ready to compile their next stage for them. This is unglamorous work and it will not show up in a conference talk, but it closes more real doors than any single clever tool on this list.

The Layered Reality Check

None of the above is a silver bullet, and if anyone tries to sell you one tool as "solves scanning forever," check their LinkedIn for how many "growth hacker" job titles they've had. Scanners aren't going away. GreyNoise isn't reporting billions of sessions because attackers are winning some grand campaign against you personally — they're reporting it because sweeping the entire internet costs them almost nothing and occasionally, somewhere, it works. Your job isn't to make yourself unscannable. It's to make yourself boring: patched, key-only, minimally exposed, quietly logged, and — if you're feeling generous — wasting a few bot-hours a day in a tarpit out of pure spite.

Stack the boring layers. Skip the panic. Let the bots enjoy the maze.

12 Comments

1 vote
5
3 votes
3
3
2
2 votes
0
2 votes
0
1 vote
0
🔥 Join developers growing publicly
Share your knowledge, build in public, and grow your developer presence with a global community.

More Posts

Comparison: Universal Import vs. Plaid/Yodlee

Pocket Portfolio - Mar 12

I’m a Senior Dev and I’ve Forgotten How to Think Without a Prompt

Karol Modelski - Mar 19

How I Built a React Portfolio in 7 Days That Landed ₹1.2L in Freelance Work

Dharanidharan - Feb 9

What Is SARIF and How Does It Help Security Tools Work Together?

Ganesh Kumar - Jul 4

MCP Is the USB-C of AI. So Why Are You Plugging Everything In?

Ken W. Algerverified - Jun 10
chevron_left
3.4k Points181 Badges
Canadat.co/4fpTf3dL1D
29Posts
56Comments
10Connections
Writing ForgeZero: Fixing the mess of modern build systems.
Performance overhead is my personal ene... Show more

Commenters (This Week)

3 comments

Contribute meaningful comments to climb the leaderboard and earn badges!