Add .htaccess for origin hardening, HTTPS redirect, and cache headers
This commit is contained in:
55
public/.htaccess
Normal file
55
public/.htaccess
Normal file
@@ -0,0 +1,55 @@
|
||||
# ---------------------------------------------------------------
|
||||
# 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