selfhostedops-stack/caddy/README.md
Maximilian Grimm bed41cfaf3 Episode 10: hardening - firewall rules Docker cannot bypass, Caddy access log and rate limiting, fail2ban in the right chain
- hardening/: ufw after.rules block for DOCKER-USER (ctorigdstport, not dport),
  fail2ban jail.local with sshd (systemd backend) and caddy-probes (chain DOCKER-USER),
  filter for the JSON access log, sshd hardening.conf, README with the order and
  the two traps measured in the episode
- caddy/Dockerfile: xcaddy build with caddy-ratelimit, compose builds the image
- Caddyfile: common snippet (JSON access log, Server header stripped), vault /admin 404,
  rate_limit zones on the vault token endpoint and the git login form
- HARDENING.md: firewall and fail2ban sections rewritten around what the port scan saw

Claude-Session: https://claude.ai/code/session_017iP581CYtPfxdZYPPAyWZA
2026-09-11 10:20:56 +02:00

16 lines
753 B
Markdown

# caddy/ (episode 10)
Custom Caddy image with the rate limiting plugin compiled in.
The stock `caddy:2-alpine` has no `rate_limit` directive; it is not a runtime
flag, the module must be built into the binary with `xcaddy`. `compose.yml`
carries both `image:` and `build: ./caddy`, so `docker compose build caddy`
produces `selfhostedops/caddy:ratelimit` locally and `docker compose up -d`
uses it.
Do not build on a small box while the stack is running - a Go build can push a
2 GB machine into OOM and take the live services down with it. Build it
elsewhere (a bigger machine, or a throwaway host) and move it over:
docker build -t selfhostedops/caddy:ratelimit ./caddy
docker save selfhostedops/caddy:ratelimit | ssh root@box docker load