docs+ci: own security headers at Cloudflare, drop dead .htaccess path
All checks were successful
ci / build-test (push) Successful in 3m33s
All checks were successful
ci / build-test (push) Successful in 3m33s
Hetzner Webhosting L runs Apache with AllowOverride None on the user docroot, so file-based .htaccess is silently ignored — directives in public/.htaccess never applied. Confirmed via direct-origin tests: neither Header, Rewrite, nor FilesMatch fired regardless of the file being present and readable. The only origin-side override path on this tier is konsoleH's per- directory Serverkonfiguration UI, which writes to a separate Apache config file outside the user's filesystem (and thus outside any deploy pipeline). Make the architecture honest: - Delete public/.htaccess (dead code Apache never reads). - Remove the "Copy .htaccess into dist" CI step (now a no-op). - Update deploy.yml header comment to point at Cloudflare for headers. - Update OPERATOR-CHECKLIST.md §1 with the three Webhosting-L gotchas: port 222 for SSH, SFTP_PATH must match the actual vhost docroot (default is bare public_html/), and AllowOverride None. - Update §5 to reflect manual workflow_dispatch (no auto-deploy on push) and 5-header expectation. - Update README.md deploy section likewise. Headers (HSTS, CSP, XFO, X-Content-Type-Options, Referrer-Policy, Permissions-Policy) are now owned by Cloudflare Transform Rules, documented in OPERATOR-CHECKLIST.md §2. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,55 +0,0 @@
|
||||
# ---------------------------------------------------------------
|
||||
# www.cameleer.io — Apache config at the Hetzner origin.
|
||||
# Defense in depth: Cloudflare handles most of this at the edge;
|
||||
# these rules make sure the origin is hardened even without the CDN.
|
||||
# ---------------------------------------------------------------
|
||||
|
||||
# Enable rewriting
|
||||
RewriteEngine On
|
||||
|
||||
# Force HTTPS — redundant with Cloudflare but belts-and-braces.
|
||||
RewriteCond %{HTTPS} !=on
|
||||
RewriteCond %{HTTP:X-Forwarded-Proto} !=https
|
||||
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
|
||||
|
||||
# Redirect apex -> www.
|
||||
RewriteCond %{HTTP_HOST} ^cameleer\.io$ [NC]
|
||||
RewriteRule ^(.*)$ https://www.cameleer.io/$1 [L,R=301]
|
||||
|
||||
# Disable directory listings.
|
||||
Options -Indexes
|
||||
|
||||
# Block access to dotfiles and sensitive extensions that should never be here.
|
||||
<FilesMatch "^\.|\.(env|ini|log|sh|bak|sql|git)$">
|
||||
Require all denied
|
||||
</FilesMatch>
|
||||
|
||||
# Prevent MIME sniffing, clickjacking, etc. (primary copy also comes from Astro middleware
|
||||
# and Cloudflare Transform Rules — these apply if either layer is bypassed).
|
||||
<IfModule mod_headers.c>
|
||||
Header always set X-Content-Type-Options "nosniff"
|
||||
Header always set X-Frame-Options "DENY"
|
||||
Header always set Referrer-Policy "strict-origin-when-cross-origin"
|
||||
Header always set Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=(), usb=()"
|
||||
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
|
||||
|
||||
# Cache hashed build assets aggressively; HTML must be revalidated.
|
||||
<FilesMatch "\.(css|js|woff2|svg|png|jpg|jpeg|webp|ico)$">
|
||||
Header set Cache-Control "public, max-age=31536000, immutable"
|
||||
</FilesMatch>
|
||||
<FilesMatch "\.html$">
|
||||
Header set Cache-Control "public, max-age=3600, must-revalidate"
|
||||
</FilesMatch>
|
||||
|
||||
# Remove Server header leak where possible.
|
||||
Header unset X-Powered-By
|
||||
</IfModule>
|
||||
|
||||
# Compression (Hetzner supports mod_deflate).
|
||||
<IfModule mod_deflate.c>
|
||||
AddOutputFilterByType DEFLATE text/html text/css application/javascript application/json image/svg+xml text/plain
|
||||
</IfModule>
|
||||
|
||||
# Custom error pages (optional — fall back to default if not present).
|
||||
ErrorDocument 404 /404.html
|
||||
ErrorDocument 403 /404.html
|
||||
Reference in New Issue
Block a user