The perimeter is talking back.
For too long the logs were just noise. Scripted knocks, dictionary sprays, the endless background radiation of the internet trying doors. I got tired of flying blind.
So I raised the watchtower.
GoAccess now feeds a live report at /attacks/. Four fail2ban jails are running (sshd, nginx-http-auth, badbots, wordpress, plus a custom toomanyrequests limiter). Every five minutes a cron job wakes up, rebuilds the report, dumps the current banned list, and answers the question “welcher browser welche IP hat?” in a neat little text file.
The whole thing is password-protected for now. Curiosity is fine. Letting the whole world see the raw siege map in real time… maybe later. For the operator it is the best live view of who is actually kicking the door.
This is self-hosting the way it should be. Your machine. Your logs. Your rules. No faceless analytics platform slurping visitor data to sell it back to you or train their models. Just a cheap Hetzner box, Nginx, PHP 8.3, MariaDB, Redis object cache humming in the background, and a theme called Forest Nature because even the resistance likes a bit of green.
Hardened configs. Manual updates via wp-cli because automatic is how you get owned by surprise. File permissions locked down so only the right users can touch the important bits. SSH key-only, no password games. The usual paranoid checklist, because the internet is hostile by default and trusting “the cloud” is how you become someone else’s data point.
Some of the recent life hacks that went into this build:
# crontab -l (refreshes attacks view every 5 min)
*/5 * * * * /usr/bin/goaccess /var/log/nginx/access.log -o /var/www/doode.info/attacks/index.html --log-format=COMBINED --real-time-html --ignore-crawlers --no-query-string 2>/dev/null || true
*/5 * * * * /usr/bin/sh -c 'fail2ban-client status | grep "Banned IP list" | awk -F: "{print \$2}" > /var/www/doode.info/attacks/banned-ips.txt'
*/5 * * * * /usr/bin/bash -c 'for ip in $(fail2ban-client status | grep "Banned IP list" | awk -F: "{print \$2}"); do echo "=== $ip ==="; grep "$ip" /var/log/nginx/access.log | awk "{print \$12}" | sort | uniq -c | sort -rn | head -3; done > /var/www/doode.info/attacks/attacking-ips-with-browsers.txt 2>/dev/null || true'
Nginx location block for the protected attacks area (basic auth via htpasswd):
location /attacks/ {
auth_basic "Restricted Area - Doode Attacks";
auth_basic_user_file /etc/nginx/.htpasswd;
alias /var/www/doode.info/attacks/;
index index.html;
autoindex off;
}
If you’re reading this on doode.info, you either came in clean or you’re one of the persistent ones. Either way, the door is watched now.
Run your own node. Look at your own logs. Build your own little radar. The big boys don’t need any more eyes on the wire.
Stay dangerous.
— the operator