Files
blog-ahmza-com/Caddyfile
T
ahmza ce7a72728d Use dynamic cloudflare trusted_proxies IP source
caddy-cf now includes WeidiDeng/caddy-cloudflare-ip, so replace the
hardcoded 22-range static list with 'trusted_proxies cloudflare' which
auto-fetches and refreshes Cloudflare's IPv4/IPv6 ranges (interval 12h,
timeout 15s). No static list to keep in sync when Cloudflare updates.

Kept client_ip_headers Cf-Connecting-Ip X-Forwarded-For (prefer CF's
authoritative end-user IP, fall back to XFF) and documented why.

Validated + fmt-clean and tested end-to-end against the updated caddy-cf
image: starts cleanly, serves HTTP 200 with gzip + security headers.
2026-07-25 05:01:49 +01:00

60 lines
2.2 KiB
Caddyfile

# 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.
#
# The `cloudflare` IP source (WeidiDeng/caddy-cloudflare-ip, baked into the
# caddy-cf image) auto-fetches the ranges from cloudflare.com/ips-v4 and
# /ips-v6 and refreshes them periodically, so there's no static list to
# keep in sync.
servers {
trusted_proxies cloudflare {
interval 12h
timeout 15s
}
# Read the real visitor IP from these headers (only honoured for
# requests from trusted_proxies above). Cf-Connecting-Ip is
# Cloudflare's single authoritative end-user IP; X-Forwarded-For is
# the fallback if a request ever arrives without the CF header.
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
}
}