Site personnel courcellematthi.eu
This commit is contained in:
@@ -0,0 +1,212 @@
|
||||
# =============================================================================
|
||||
# nginx.conf.example — Configuration serveur pour courcellematthi.eu
|
||||
# -----------------------------------------------------------------------------
|
||||
# À adapter puis inclure dans la configuration Nginx.
|
||||
# Couvre : redirections canoniques, en-têtes de sécurité, cache, compression.
|
||||
#
|
||||
# Sans ces réglages, un site statique parfaitement écrit reste noté médiocre
|
||||
# par les outils d'audit (Lighthouse, Mozilla Observatory, securityheaders.com)
|
||||
# et sert des fichiers non compressés.
|
||||
# =============================================================================
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# REDIRECTION HTTP -> HTTPS
|
||||
# Le certificat est supposé géré par Certbot ou acme.sh.
|
||||
# -----------------------------------------------------------------------------
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name courcellematthi.eu www.courcellematthi.eu;
|
||||
|
||||
# Laisse passer la validation ACME avant de rediriger
|
||||
location /.well-known/acme-challenge/ {
|
||||
root /var/www/certbot;
|
||||
}
|
||||
|
||||
location / {
|
||||
return 301 https://www.courcellematthi.eu$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# REDIRECTION DU DOMAINE NU VERS WWW
|
||||
# Une seule URL canonique évite la dilution du référencement et le contenu
|
||||
# dupliqué. Le choix www / sans-www est indifférent, la constance ne l'est pas.
|
||||
# La valeur retenue ici doit correspondre à <link rel="canonical"> dans le HTML.
|
||||
# -----------------------------------------------------------------------------
|
||||
server {
|
||||
listen 443 ssl;
|
||||
listen [::]:443 ssl;
|
||||
http2 on;
|
||||
server_name courcellematthi.eu;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/courcellematthi.eu/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/courcellematthi.eu/privkey.pem;
|
||||
|
||||
return 301 https://www.courcellematthi.eu$request_uri;
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# SERVEUR PRINCIPAL
|
||||
# -----------------------------------------------------------------------------
|
||||
server {
|
||||
listen 443 ssl;
|
||||
listen [::]:443 ssl;
|
||||
http2 on;
|
||||
server_name www.courcellematthi.eu;
|
||||
|
||||
root /var/www/courcellematthi.eu;
|
||||
index index.html;
|
||||
charset utf-8;
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# TLS
|
||||
# TLS 1.2 minimum : les versions antérieures sont obsolètes et vulnérables.
|
||||
# -------------------------------------------------------------------------
|
||||
ssl_certificate /etc/letsencrypt/live/courcellematthi.eu/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/courcellematthi.eu/privkey.pem;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_prefer_server_ciphers off; # Laisse le client choisir : recommandé
|
||||
# depuis TLS 1.3
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_timeout 1d;
|
||||
ssl_session_tickets off;
|
||||
|
||||
# Agrafage OCSP : le serveur fournit lui-même la preuve de non-révocation
|
||||
# du certificat, ce qui évite au navigateur une requête vers l'autorité.
|
||||
ssl_stapling on;
|
||||
ssl_stapling_verify on;
|
||||
resolver 1.1.1.1 8.8.8.8 valid=300s;
|
||||
|
||||
# =========================================================================
|
||||
# EN-TÊTES DE SÉCURITÉ
|
||||
# =========================================================================
|
||||
|
||||
# HSTS — force HTTPS pendant deux ans, y compris sur les sous-domaines.
|
||||
# ATTENTION : ne l'activer qu'une fois le HTTPS confirmé fonctionnel
|
||||
# partout. Un HSTS émis par erreur rend le site inaccessible jusqu'à
|
||||
# expiration, sans possibilité d'annulation côté serveur.
|
||||
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
|
||||
|
||||
# CSP — liste blanche des sources autorisées. Défense principale contre
|
||||
# l'injection de scripts.
|
||||
# default-src 'self' : tout provient du domaine par défaut
|
||||
# style-src ... 'unsafe-inline' : requis par le CSS injecté de Google Fonts
|
||||
# font-src fonts.gstatic.com : fichiers de police
|
||||
# script-src 'self' 'unsafe-inline' : 'unsafe-inline' n'est nécessaire
|
||||
# que pour l'attribut onclick du bouton d'impression. Le retirer si
|
||||
# ce bouton est déplacé dans un module.
|
||||
# frame-ancestors 'none' : interdit l'inclusion en iframe (clickjacking)
|
||||
# base-uri 'self' : empêche la réécriture des URL relatives
|
||||
# form-action 'self' : limite les cibles de soumission
|
||||
add_header Content-Security-Policy "default-src 'self'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; script-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'; object-src 'none'; upgrade-insecure-requests" always;
|
||||
|
||||
# Empêche le navigateur de deviner le type MIME d'un fichier, technique
|
||||
# utilisée pour faire exécuter une image comme du script.
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
|
||||
# Ne transmet le référent complet qu'en navigation interne ; vers
|
||||
# l'extérieur, seul le domaine est envoyé. Compromis usuel entre mesure
|
||||
# d'audience et confidentialité.
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
|
||||
# Désactive des API sensibles jamais utilisées par ce site.
|
||||
add_header Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=(), usb=(), interest-cohort=()" always;
|
||||
|
||||
# Redondant avec frame-ancestors, conservé pour les navigateurs anciens.
|
||||
add_header X-Frame-Options "DENY" always;
|
||||
|
||||
# =========================================================================
|
||||
# COMPRESSION
|
||||
# Gzip partout ; Brotli en plus si le module est disponible (taux
|
||||
# supérieur de 15 à 20 % sur du texte).
|
||||
# =========================================================================
|
||||
gzip on;
|
||||
gzip_vary on; # Ajoute « Vary: Accept-Encoding » : sans lui,
|
||||
# un proxy peut servir la version compressée
|
||||
# à un client qui ne la supporte pas.
|
||||
gzip_comp_level 6; # Au-delà, le gain marginal ne compense plus
|
||||
# le coût CPU.
|
||||
gzip_min_length 256; # En dessous, l'en-tête coûte plus que le gain.
|
||||
gzip_types
|
||||
text/plain
|
||||
text/css
|
||||
text/xml
|
||||
text/javascript
|
||||
application/javascript
|
||||
application/json
|
||||
application/manifest+json
|
||||
application/xml
|
||||
image/svg+xml;
|
||||
|
||||
# Décommenter si le module ngx_brotli est compilé
|
||||
# brotli on;
|
||||
# brotli_comp_level 6;
|
||||
# brotli_types text/plain text/css application/javascript application/json image/svg+xml;
|
||||
|
||||
# =========================================================================
|
||||
# CACHE
|
||||
# Stratégie en deux niveaux :
|
||||
# - Les ressources d'assets changent rarement : cache long.
|
||||
# - Le HTML change à chaque mise à jour de contenu : jamais mis en cache
|
||||
# durablement, sinon les visiteurs voient une version périmée.
|
||||
#
|
||||
# NOTE : « immutable » suppose des noms de fichiers versionnés
|
||||
# (style.a1b2c3.css). Sans versionnement, garder une durée modérée
|
||||
# pour pouvoir publier un correctif.
|
||||
# =========================================================================
|
||||
|
||||
location ~* \.(css|js|woff2?|ttf|otf|eot)$ {
|
||||
expires 30d;
|
||||
add_header Cache-Control "public, max-age=2592000";
|
||||
access_log off;
|
||||
}
|
||||
|
||||
location ~* \.(png|jpe?g|gif|svg|webp|avif|ico)$ {
|
||||
expires 90d;
|
||||
add_header Cache-Control "public, max-age=7776000";
|
||||
access_log off;
|
||||
}
|
||||
|
||||
location = /index.html {
|
||||
add_header Cache-Control "public, max-age=0, must-revalidate";
|
||||
}
|
||||
|
||||
location ~* \.(txt|xml|webmanifest)$ {
|
||||
expires 1d;
|
||||
add_header Cache-Control "public, max-age=86400";
|
||||
}
|
||||
|
||||
# =========================================================================
|
||||
# TYPES MIME PARTICULIERS
|
||||
# =========================================================================
|
||||
location = /site.webmanifest {
|
||||
types { } default_type application/manifest+json;
|
||||
}
|
||||
|
||||
location = /llms.txt {
|
||||
types { } default_type text/plain;
|
||||
charset utf-8;
|
||||
}
|
||||
|
||||
location = /.well-known/security.txt {
|
||||
types { } default_type text/plain;
|
||||
charset utf-8;
|
||||
}
|
||||
|
||||
# =========================================================================
|
||||
# ROUTAGE
|
||||
# =========================================================================
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
# Refuse l'accès aux fichiers cachés, sauf .well-known (RFC 8615)
|
||||
location ~ /\.(?!well-known) {
|
||||
deny all;
|
||||
return 404;
|
||||
}
|
||||
|
||||
# Page d'erreur : renvoyer vers l'accueil plutôt qu'une page vide
|
||||
error_page 404 /index.html;
|
||||
}
|
||||
Reference in New Issue
Block a user