diff --git a/scripts/Caddyfile b/scripts/Caddyfile index cd9f5b7..224ca40 100644 --- a/scripts/Caddyfile +++ b/scripts/Caddyfile @@ -1,14 +1,31 @@ # ICE Watch Caddy Configuration # Replace yourdomain.com with your actual domain +# +# This configuration automatically: +# - Obtains SSL certificates from Let's Encrypt +# - Redirects HTTP to HTTPS +# - Serves on ports 80 and 443 +# Main site configuration yourdomain.com { - # Reverse proxy to Node.js app - reverse_proxy localhost:3000 + # Automatic HTTPS (default behavior) + # Caddy automatically: + # - Listens on :80 and :443 + # - Redirects HTTP to HTTPS + # - Gets SSL cert from Let's Encrypt - # Security headers + # Reverse proxy to Node.js app + reverse_proxy localhost:3000 { + # Health check + health_uri /api/locations + health_interval 30s + health_timeout 5s + } + + # Security headers for ICE Watch header { - # Enable HSTS - Strict-Transport-Security max-age=31536000; + # Enable HSTS (force HTTPS for 1 year) + Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" # Prevent clickjacking X-Frame-Options DENY # Prevent content type sniffing @@ -17,22 +34,55 @@ yourdomain.com { X-XSS-Protection "1; mode=block" # Referrer policy Referrer-Policy strict-origin-when-cross-origin + # Content Security Policy + Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' unpkg.com api.mapbox.com; style-src 'self' 'unsafe-inline' unpkg.com; img-src 'self' data: *.tile.openstreetmap.org; connect-src 'self' api.mapbox.com nominatim.openstreetmap.org" } # Gzip compression - encode gzip + encode gzip zstd - # Rate limiting (optional) - # rate_limit { - # zone static_ip_10rs { - # key {remote_host} - # events 10 - # window 1s - # } - # } + # Logging for security monitoring + log { + output file /var/log/caddy/icewatch.log { + roll_size 100MB + roll_keep 5 + } + format json + } + + # Rate limiting for API endpoints + rate_limit { + zone api { + key {remote_host} + events 30 + window 1m + } + zone submit { + key {remote_host} + events 5 + window 1m + } + } + + # Apply rate limits to specific paths + @api path /api/* + rate_limit @api api + + @submit path /api/locations method POST + rate_limit @submit submit } -# Optional: Redirect www to non-www +# Redirect www to non-www (with HTTPS) www.yourdomain.com { redir https://yourdomain.com{uri} permanent } + +# HTTP redirect (explicit, though Caddy does this automatically) +# This is just for clarity +http://yourdomain.com { + redir https://yourdomain.com{uri} permanent +} + +http://www.yourdomain.com { + redir https://yourdomain.com{uri} permanent +}