Run your own backend

Protect a self-hosted app from abuse and bots

The short version: defend in layers - a firewall to close everything you do not serve, rate limiting to cap requests per client, fail2ban to ban repeat offenders, and app-level limits on sensitive endpoints like login. You do not need a big CDN for the basics: nginx, ufw, and fail2ban on your own server stop most of it, with the toughest limits on the routes that matter.

Layers of defense

Firewall - close what you do not serve

Default-deny inbound, allow only 80/443 and SSH. The smallest attack surface starts here.

Rate limiting - cap per client

limit_req in nginx smooths bursts and stops a single IP from flooding your app.

fail2ban - ban repeat offenders

Watches logs and bans IPs that brute-force, scan, or keep hitting limits.

App-level limits

Throttle login and password reset, add a captcha on sensitive forms, lock accounts after repeated failures.

Set it up in three steps

1

Close the doors with a firewall

sudo ufw default deny incoming
sudo ufw allow 80,443/tcp
sudo ufw limit 22/tcp        # rate-limit SSH against brute force
sudo ufw enable
2

Rate-limit at the proxy

# nginx - strict on auth, looser elsewhere
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
location /login { limit_req zone=login burst=3 nodelay; proxy_pass http://app; }
3

Ban persistent offenders

# fail2ban watches auth/nginx logs and bans repeat IPs at the firewall.
sudo systemctl enable --now fail2ban
sudo fail2ban-client status
The principle

Tier the limits by what hurts

Not every route deserves the same limit. Make authentication and anything that costs money or sends mail the strictest, APIs moderate, and static content loose. The aim is to stop credential-stuffing, scraping, and brute force without throttling real users - so start conservative, watch for false positives, and tighten the routes that actually get abused.

Generate the configs instead of hand-writing them: the rate-limit generator, UFW firewall generator, and fail2ban generator produce ready-to-use rules for each layer.

How Infraveil handles this

Security posture, kept consistent and recorded

Abuse protection only works if it is on, the same, on every host - and drift is how a forgotten box becomes the way in. On your own servers, Infraveil helps you apply firewall, rate-limit, and ban rules consistently across the infrastructure you run, watch that they stay in place, and record changes - so “we rate-limit login” is something you can verify, not assume.

Firewall, rate-limit, and ban rules applied consistently across hosts you own
Drift watched - a host that loses its rules is surfaced
Security config changes recorded and inspectable

Frequently asked questions

Do I need Cloudflare to protect my app?

Not for the basics. A default-deny firewall, per-IP rate limiting, and fail2ban handle most bots and brute force on a single server. A CDN or scrubbing service is a layer on top for large volumetric DDoS or a global edge, not a replacement for hardening the origin.

What should I rate-limit, and to what?

Tier by sensitivity: auth and password-reset strictest (a few attempts per minute per IP), APIs moderate, static loose. Stop credential-stuffing and scraping without throttling real users - start conservative and watch for false positives.

Rate limiting vs fail2ban - what is the difference?

Rate limiting caps request speed in real time at the proxy; fail2ban watches logs and bans an IP at the firewall after a pattern of bad behavior. Complementary - one slows abuse, the other removes persistent offenders.

Can this stop a DDoS?

It stops common cases - a single abusive client, brute force, scraping. A large distributed attack that saturates bandwidth needs upstream filtering or a scrubbing/CDN provider. Hardening the origin is still worth it and is what you control.