- 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
16 lines
753 B
Markdown
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
|