# Caddyfile for the blog behind Cloudflare. # # Topology: Cloudflare (terminates TLS) -> Caddy (HTTP :80) -> SWS (blog:80) # # Cloudflare handles the public HTTPS cert, so Caddy serves plain HTTP on :80 # and does NOT need the Cloudflare DNS-01 / automatic-HTTPS setup. Set the # Cloudflare SSL/TLS mode to "Full" so CF->origin is encrypted at the network # layer (e.g. over your tunnel/Netbird), even though this listener is HTTP. # # Copy this file to /etc/caddy/Caddyfile on the caddy_cf host and reload: # docker exec caddy_cf caddy reload --config /etc/caddy/Caddyfile # or restart the container. { # Trust only Cloudflare's edge IPs so real visitor IPs (Cf-Connecting-Ip / # X-Forwarded-For) are honoured only when the request actually comes from # Cloudflare. This prevents header spoofing from any other source. # # Ranges from https://www.cloudflare.com/ips-v4/ and /ips-v6/ . # Keep in sync when Cloudflare updates them (rarely). If you rebuild # caddy-cf with the caddy-dynamic-cloudflare / caddy-cloudflare-ip plugin, # this static list can be replaced with `trusted_proxies cloudflare`. servers { trusted_proxies static \ 173.245.48.0/20 \ 103.21.244.0/22 \ 103.22.200.0/22 \ 103.31.4.0/22 \ 141.101.64.0/18 \ 108.162.192.0/18 \ 190.93.240.0/20 \ 188.114.96.0/20 \ 197.234.240.0/22 \ 198.41.128.0/17 \ 162.158.0.0/15 \ 104.16.0.0/13 \ 104.24.0.0/14 \ 172.64.0.0/13 \ 131.0.72.0/22 \ 2400:cb00::/32 \ 2606:4700::/32 \ 2803:f800::/32 \ 2405:b500::/32 \ 2405:8100::/32 \ 2a06:98c0::/29 \ 2c0f:f248::/32 client_ip_headers Cf-Connecting-Ip X-Forwarded-For } } # Bind to the hostname on the HTTP port only. Because the address has an # explicit ":80" scheme/port, Caddy will NOT try to provision a TLS cert. http://blog.ahmza.com { # THE responder: proxy every request to the blog (SWS) container. # This is what was missing before (requests fell through to a NOP -> blank page). reverse_proxy blog:80 # Compression happens here (SWS has it disabled on purpose). encode zstd gzip # Security headers (single source of truth; SWS has security-headers off). header { Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" X-Content-Type-Options "nosniff" X-Frame-Options "SAMEORIGIN" Referrer-Policy "strict-origin-when-cross-origin" # Drop Caddy's default Server header. -Server } log { output stdout format console } }