If you self-host anything, there is a good chance it sits behind Nginx Proxy Manager (NPM). Add a domain, pick a container, click Let's Encrypt, done. I used it for exactly that reason.
Then you open the logs of anything exposed to the internet and see this, every day:
GET /.env GET /wp-config.php GET /../../etc/passwd GET /?id=1 UNION SELECT password FROM users
Enter fullscreen mode
Exit fullscreen mode
You don't run WordPress and you don't have a .env in your web root, but the scanners don't care. At some point I wanted three things: see what is actually hitting my services, block the obvious junk, and keep some control when traffic spikes.
The usual answer
The common setups are:
NPM + CrowdSec (or fail2ban) to ban bad IPs from the logs.
A WAF container in front of or behind NPM: SafeLine, BunkerWeb, ModSecurity…
All good tools. But you end up with more containers, more config screens, and when a request is blocked you jump between three places to find out why.…