Configuración Caddy para el sitio web¶
Tras la auditoría forense de junio 2026, se detectaron las siguientes deficiencias en el proxy inverso Caddy que sirve el sitio web público:
| Problema | Impacto | Solución |
|---|---|---|
| Sin compresión gzip/zstd | 202 KB → 35 KB (-83%) | encode gzip zstd |
| Sin HSTS | Vulnerable a downgrade attacks | Cabecera Strict-Transport-Security |
| Sin CSP | Sin protección contra XSS/injection | Cabecera Content-Security-Policy |
| Sin otras cabeceras de seguridad | Clickjacking, MIME sniffing, fuga de referrer | X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy |
| Sin Cache-Control para assets | Navegadores no cachean | Cabecera Cache-Control con max-age=31536000 |
Caddyfile recomendado¶
Reemplazar el bloque de tonatiuh.duckdns.org en el Caddyfile del servidor (probablemente ~/Caddyfile o /etc/caddy/Caddyfile) por:
tonatiuh.duckdns.org {
# COMPRESIÓN — 202 KB → 35 KB (-83%)
encode gzip zstd
# CABECERAS DE SEGURIDAD
header {
Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
X-Frame-Options "SAMEORIGIN"
X-Content-Type-Options "nosniff"
X-XSS-Protection "1; mode=block"
Referrer-Policy "strict-origin-when-cross-origin"
Permissions-Policy "camera=(), microphone=(), geolocation=(), interest-cohort=()"
Content-Security-Policy "default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; script-src 'self' 'unsafe-inline'; font-src 'self'; frame-ancestors 'self';"
}
# CACHE CONTROL PARA ASSETS — 1 año
@staticAssets {
path *.css *.js *.svg *.png *.jpg *.jpeg *.gif *.ico *.woff2 *.woff
}
header @staticAssets Cache-Control "public, max-age=31536000, immutable"
# ROOT + FILE SERVER
root * /home/tonatiuh/SmallCountry/web/site
file_server
# REDIRECCIÓN .well-known/security.txt → security.txt
redir /.well-known/security.txt /security.txt permanent
# CUSTOM ERROR PAGES
handle_errors {
rewrite * /404.html
file_server
}
}
Aplicación¶
# 1. Editar el Caddyfile
nano ~/Caddyfile # o donde esté
# 2. Reemplazar el bloque de tonatiuh.duckdns.org con el de arriba
# 3. Validar sintaxis
caddy validate --config ~/Caddyfile
# 4. Recargar sin downtime
sudo systemctl reload caddy
# 5. Verificar compresión (-80% tamaño esperado)
curl -s -o /dev/null -w "Size: %{size_download}\n" https://tonatiuh.duckdns.org/ --compressed
# Debe mostrar ~35000, no ~202000
# 6. Verificar cabeceras de seguridad
curl -sI https://tonatiuh.duckdns.org/ | grep -iE "strict-transport|content-security|x-frame|x-content|referrer|cache-control|content-encoding"
# Debe mostrar al menos 6 cabeceras
# 7. Verificar que security.txt es accesible
curl -sI https://tonatiuh.duckdns.org/security.txt | grep -E "HTTP/|Content-Type"
curl -sI https://tonatiuh.duckdns.org/.well-known/security.txt | grep -E "HTTP/|Content-Type"
# Ambos deben devolver 200