440,000+ attempts to hack my VPS
A dive into 440K+ SSH attacks on 8 VPS providers. Despite hosting nothing of note, I have been targeted and have been surprised by the data I found.
Published on 2025-07-23 | 9m 26s
One day, I logged into my Hetzner server and was greeted by this message at the top:
There were 4025 failed login attempts since the last successful login.
This server hosts nothing public. It is where I do most of my experimentation on in regards to self hosting. It's also where I run tasks like running a long running code if I need to. Basically, no one except me and Hetzner should even be interested in it.
That's the day I learned a fundamental truth about the internet: the moment you connect a server online, you become a target. It doesn't matter if your server hosts nothing but a "Hello World" page - attackers will find it and probe it relentlessly.
While I wasn't worried as I use an SSH key to log in, this discovery sparked my curiosity. I then created a script to upload the failed logins for analysis. In just three months, I got over 440,000 failed login attempts over my 8 VPS providers.
I mean, some of them were definitely from me mistyping my username or whatnot but I definitely did not do the bulk of those failed logins.
By the way, don't ask why I have 8 VPS providers. I also don't know the answer.
The Security Fundamentals (Skip if You Know This)
Before diving into the data, let me quickly cover the basic security measures I implement on every new VPS:
What I DO:
-
Disable password authentication and enable public key authentication only. Generate an SSH key and log in only using that key. That alone is usually enough to stop all attacks. It's also more convenient as there's no typing involved so that's also a plus for you.
-
Close unnecessary ports using the firewall. Keep only 22/SSH, 80/HTTP, and 443/HTTPS. If I need a port, I will temporarily enable it. However, under most circumstances there's no reason to keep more than these three open. Sometimes, I even close HTTP and HTTPS ports if I just need it to run a script.
Note that closing a port will only close inbound connections and not necessarily outbound ones. So if you're worried that your server will become useless, it won't. If an app communicated with an HTTPS API, it will still be able to do so.
Also, you might not know this but if you're using Docker, it bypasses your firewall. I legitimately did not know this until around 1 month after using it. Thankfully, no attacks has occured, but this really made me furious on Docker's behavior.
-
Set
PermitRootLogin no
. Usesudo
to do your root activities. There's no good reason to allow root access in SSH. Even if you somehow need root, you can log in as a sudo user and then dosudo su -
. -
Install Tailscale. Most of the services I host on my VPS are not meant for other people. So by installing Tailscale, I can make sure that these services bind only to the local port (
127.0.0.1
orfe80::1
) yet still be accessible everywhere.Note that these are things I do. I find Tailscale to be really easy to setup but it really is just Wireguard under the hood. Thus, if you don't need Tailscale's other features or are distrustful of them, you can just use Wireguard. It will do the same thing.
-
For publicly accessible websites, proxy through Cloudflare. I use Cloudflare, but you can use any other CDN or DDOS protection service. Doing a proxy hides your IP address so if someone wanted to DDOS you, they will have to go through Cloudflare first - which is extremely good at doing this. If I have a public site, any
nslookup
usually results in CloudFlare IPs. The exceptions are private IP addresses. Like, good luck attacking100.64.0.0/10
as that's a CGNAT address.
These five steps alone eliminate 99% of successful attacks. But even if you do the first three steps, you can prevent most attacks. I do suggest you invest in DDOS protection if you're hosting anything public as you cannot underestimate how bad it can get.
What I DON'T Do (And Why):
-
Change SSH port: While changing from port 22 to something like 2200 reduces attack volume, it's security through obscurity. The inconvenience of remembering custom ports outweighs the minimal security benefit for me.
-
Install fail2ban: Since I've disabled password authentication, even if attackers somehow guessed my password correctly, they still couldn't log in without my private key.
It's true that fail2ban can also work for other services but given that I only access most things I host through a VPN, it's more likely that I will lock myself out for 10 minutes (or whatever I set) than locking out an attacker. For my threat model, it wasn't worth it.
-
Whitelist IP addresses: I don't have a static IP, so I'd likely lock myself out when my ISP rotates addresses. The operational risk isn't worth it. I do have a VPN in Tailscale but I enable SSH access for the cases where Tailscale isn't working or isn't available (for example, I might want to use another VPN). I also don't want to accidentally lock myself out the moment I travel to another place.
Building the Monitoring System
Linux always logs every authentication attempt by default - whether successful or failed. The system I used was somewhat simple:
- Log Collection Script: A bash script that uploads auth logs to an R2 database. I have thought of doing an sftp to a home server but R2 is very reliable so I decided it wasn't worth the hassle.
- Data Processing: The logs are parsed and stored in PostgreSQL. Initially, I used SQLite but I started needing features like IP address lookups that were incredibly slow on SQLite (it crashed my PC many times).
- IP Enrichment: Each IP is enhanced with geolocation and ASN data for analysis.
Here's the core upload script:
#!/bin/bash
DEVICE="device_name"
UPLOAD_URL="https://endpoint"
TEMP_FILE="${LOG_FILE}.upload"
# OS Detection & Log Path Setup
if [ -f /etc/redhat-release ]; then
LOG_FILE="/var/log/secure" # RHEL/CentOS
elif [ -f /etc/debian_version ]; then
LOG_FILE="/var/log/auth.log" # Debian/Ubuntu
else
echo "Unsupported OS. Exiting."
exit 1
fi
# Copy, upload, and truncate on success
cp --preserve "$LOG_FILE" "$TEMP_FILE"
response=$(curl -s -o /dev/null -w "%{http_code}" \
-F "file=@$TEMP_FILE" \
-H "device:$DEVICE" \
-H "type:ssh" \
"$UPLOAD_URL")
if [ "$response" -eq 200 ]; then
echo "Upload succeeded. Truncating original log."
sudo truncate -s 0 "$LOG_FILE"
rm -f "$TEMP_FILE"
else
echo "Upload failed (HTTP $response). Log preserved."
rm -f "$TEMP_FILE"
exit 1
fi
The Data: 440,000+ Attacks Across 8 Providers
This turned out to be a bit more interesting than I expected. That said, I'm a nerd and I don't think a random person would find this interesting at all. Or maybe they would. Who knows?
Attack Volume by Provider
Most of my providers are from Europe and the US. The Asian landscape is pretty barren when it comes to affordable VPS. Compared between the two, European VPS providers are much more attacked:
Provider | Attack Count |
---|---|
Servitro | 135942 |
Hetzner | 78982 |
Layer 7 | 73918 |
Servarica | 59808 |
Contabo | 54191 |
GCloud (TWN) | 28383 |
Racknerd | 11701 |
In general, per day the most hit is Servitro. I don't know why this VPS provider gets so much hate but it's not something they can do much about. And graphing it out, it looks like you can generally expect ~1000 attacks per day on each VPS you place in the internet. |

Geographic Distribution of Attacks
That being said, I was also incredibly curious about where attackers come from. Now, take this data with a grain of salt - there are many caveats here. First, I don't know if these are from the attackers computers or something they infected. I also don't know if the data I got my IP from is accurate at locating the data. This is really more of a "huh - that's interesting" kind of data than something to act on.

Country | Count |
---|---|
RUS 🇷🇺 | 134621 |
CHN 🇨🇳 | 53476 |
USA 🇺🇸 | 30614 |
VNM 🇻🇳 | 21975 |
GBR 🇬🇧 | 19092 |
HUN ðŸ‡ðŸ‡º | 16325 |
SGP 🇸🇬 | 16129 |
NLD 🇳🇱 | 15067 |
IND 🇮🇳 | 12423 |
KOR 🇰🇷 | 11071 |
Other Countries | 112122 |
No surprises here - Russia, China, and the US dominate the attack landscape, accounting for nearly half of all attempts (~49.4%). Then again, we don't know how many of these are "legitimate IPs being used to attack". Some of these could be a random IoT camera infected with malware or a VPS from a provider in this country. It is pretty interesting to see the trends play out though.
Most Problematic ASNs (Internet Service Providers)
ASN or Autonomous System Number is kind of how you can determine who owns which IP addresses. That's how sites like "What's my IP" generally figure out what your internet provider is. I was pretty interested in which providers were bad.

ASN Provider | Attacks |
---|---|
Proton66 OOO | 128658 |
DigitalOcean, LLC | 37295 |
SS-Net | 16291 |
UNMANAGED LTD | 14836 |
cheapy.host LLC | 13281 |
Viettel Corporation | 10532 |
Zhengzhou Fastidc Technology Co.,Ltd. | 9818 |
Limited Network LTD | 8524 |
Korea Telecom | 8120 |
CHINANET-BACKBONE | 7003 |
Other | 188505 |
Proton66 stands out dramatically. I didn't hear of the provider before so I searched and just recently they have been said to be harboring cybercriminals. Makes sense why they have almost 3.5x the attacks as the next.
DigitalOcean's presence in the top 5 is concerning but not entirely surprising - as one of the largest cloud providers, it's bound to have some abusive users. However, the volume suggests they may need better abuse detection systems.
Seriously, I expected them to appear somewhere on the list but Top 2? Digital Ocean, you may need to vet your customers better.
The Most Targeted Usernames
Perhaps what surprised me the most is actually the data on the most targeted usernames:
Username | Count |
---|---|
admin | 97263 |
user | 84295 |
root | 34588 |
ubuntu | 15096 |
invalid | 14104 |
debian | 10462 |
test | 5804 |
oracle | 3949 |
jackson | 3469 |
ftpuser | 2972 |
Other | 170923 |
admin and user beats root as the most targeted username. Honestly, it weirds me out that this is the case since I expected root to be the clear winner. I'm not going to say to stop using these as if you enable SSH authentication, it shouldn't be too much of a worry. However, how did this beat root ? |
Random names like jackson
appear frequently (possibly from leaked databases). Is Jackson a common IT nickname? I'm calling every incompetent IT person Jackson now.
Conclusion
I recently got an IPv6 address (yay!) so this data actually prepared me. NAT doesn't exist anymore so the firewall is actually mine to manage now. I'll probably post one soon when I can.
That being said, I actually scoured my data for IPv6 attacks. There are no attacks. Not almost none - none at all. All attacks come from IPv4 which I guess should mean upgrading to IPv6 can give some security benefit. That being said, this is short-lived as most of the valuable targets are still on IPv4 infrastructure like corporations.
Again - IPv6 is NOT a security feature. It's just that if you are dealing with someone who is convinced that NAT somehow protects them, I guess this can be a counterargument (though a bad one to be sure).
While seeing 440K+ failed login attempts might seem alarming, it's actually reassuring evidence that proper security measures work. Not a single attack succeeded across any of my servers. And I don't think they will anytime soon.
Want to implement similar monitoring? The complete code and setup instructions are available in my GitHub repository.