freedzhost.cloud

Resisting DDoS when your site lives at home

Level IntermediateEstimated time an eveningRead first Before you open a website to the internet: a security audit in ten checksA word you don't know? Glossary

Let us be honest first: if someone sends more traffic than your internet line can carry, your site goes down, whatever you configure at home. The flood is stopped upstream or not at all. What you control is everything below that: robots, password guessing, application floods, and whether your home address is out there to be targeted.

What you get. A clear plan in four layers. The first two are free, take an hour, and stop the daily noise; the third, a small rented front, hides your home and keeps the site online even when the house is offline.

Internetvisitors and floodsRented frontanti-DDoS, static site, cacheHome proxythe other servicesencrypted tunneleverything else refused
Visitors and attackers reach a small rented server whose provider filters volumetric attacks. It serves the static site itself and sends the rest through an encrypted tunnel to the house. The home router accepts nothing from the internet except this tunnel: the home address is never published.

Layer 1: limits at the proxy (free, one hour)

In Nginx Proxy Manager, a custom file loaded in the http block applies to every site:

# /data/nginx/custom/http_top.conf
geo $limited { default 1; YOUR-LAN/24 0; YOUR-TAILNET-RANGE 0; 127.0.0.0/8 0; }
map $limited $limit_key { 0 ""; 1 $binary_remote_addr; }   # your own networks are never limited
limit_req_zone  $limit_key zone=perip:10m rate=30r/s;
limit_conn_zone $limit_key zone=conn:10m;
limit_req  zone=perip burst=120 nodelay;
limit_conn conn 60;
limit_req_status 429;
client_header_timeout 15s; client_body_timeout 15s; send_timeout 15s;
# keepalive_timeout is already set by the proxy: setting it twice breaks the reload

Then a working fail2ban (check it really matches, see the audit), with a jail that bans on the first probe for /.env or /.git/, and a recidive jail that bans repeat offenders for a week.

Layer 2: serve the site from memory (free, thirty minutes)

A static site can be cached by the proxy for a few seconds. A flood of identical requests is then answered from memory, without touching the site's container:

proxy_cache_path /data/cache levels=1:2 keys_zone=site:10m max_size=200m inactive=10m;
proxy_cache site;
proxy_cache_valid 200 10s;
proxy_cache_use_stale error timeout updating;

proxy_cache_use_stale also keeps serving the last good copy if the site's container restarts: the visitor never notices.

Layer 3: a rented front (about five euros a month)

This is the only layer that resists a volumetric attack. A small virtual server at a host that includes anti-DDoS filtering on its network:

  1. serves the static site itself (a copy, synchronised after each publication);
  2. forwards the other services through a WireGuard tunnel to the house;
  3. the home router no longer forwards ports 80 and 443 from the internet: only the tunnel.

Your DNS then points to the front, never to the house. An attacker can only aim at an address whose network is built to absorb it, and your site stays online even when your home connection is down.

Layer 4: a large CDN, knowingly

A free CDN plan absorbs almost anything, for nothing. The price is elsewhere: a third party terminates your encryption and sees every request. For a public static site it can be acceptable; for private services it contradicts the reason you host at home. We chose layer 3.

Traps

Whitelist your own networks in every ban and limit (ignoreip, a geo block for limits): a monitoring probe or a CI runner hammering an API looks exactly like an attacker.

Rate limits that are too low punish real visitors on a shared address (an office, a mobile operator). Start generous, watch the 429s in the logs, then tighten.

A wildcard DNS record publishes your home address under every invented name. Remove it before anything else.

Sources

Found this useful? Tell us what to measure next.