Génération contrib : vhosts nginx h3 edge + appsettings (jq) + QUIC logiciel Kestrel

Vhosts nginx (contrib/template.vhost + Makefile, envsubst allowlist) :
HTTP/3 edge per contrib/quic.md — listen 443 quic reuseport (Org only),
http2/http3 on, Alt-Svc, ssl_protocols TLSv1.3. Cibles generate-nginx /
generate-nginx-prod -> generated/nginx/ (gitignoré). Allowlist préserve
les variables nginx intrinsèques ($host, $scheme, ...).

Appsettings (contrib/template.appsettings-{org,api,blogs}.json + Makefile) :
génération via jq (et non envsubst) car le mot de passe SMTP contient un qui cassait le JSON. Substitue $DOMAIN (DOMAIN_ROOT) partout et injecte
$SMTP_PASSWORD depuis env (échappement JSON, secret non exposé en cmd).
Cible generate-appsettings -> generated/appsettings/.

QUIC logiciel : Kestrel:Endpoints:Https:Protocols = Http1AndHttp2AndHttp3
sur les 3 templates appsettings (capacité, non joignable derrière nginx).

Fix bonus : générateur systemd HTTP_PORT"$($*_PORT)" (était
"$*_$(HTTP_PORT)" -> port vide localhost:Org_).

Runbook contrib/README.nginx.md. Prérequis host : nginx http_v3_module,
UDP 443, libmsquic (Kestrel h3).

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
Paul Schneider 2026-09-25 13:31:56 +01:00
commit 5553f2f290
Signed by: notazof
GPG key ID: AD4B9B545FBD7D12
6 changed files with 132 additions and 83 deletions

View file

@ -1,34 +1,49 @@
# Généré depuis contrib/template.vhost par `make generate-nginx` — NE PAS ÉDITER.
# Vhost $DOMAIN — backend $BACKEND_SCHEME://$HTTP_HOST:$BACKEND_PORT
# HTTP/3 (QUIC) termine au edge nginx ; Kestrel reste en h1/h2 backend.
#
# HTTP/3 (QUIC) termine au edge nginx (plan contrib/quic.md). Requiert un
# nginx compilé avec http_v3_module (≥ 1.25 ; `http3 on` ≥ 1.27.4) + UDP 443
# ouvert. Kestrel reste backend h1/h2 (mais configure aussi h3 côté logiciel,
# cf. template.appsettings-*.json — capacité, non joignable derrière nginx).
#
# Variables substituées par envsubst (allowlist) :
# DOMAIN BACKEND_SCHEME HTTP_HOST BACKEND_PORT QUIC_OPTS
# $QUIC_OPTS = "reuseport" sur un seul vhost (Org), vide sur les autres
# (règle : reuseport une seule fois par addr:port, cf. contrib/quic.md).
# Les variables nginx intrinsèques ($host, $scheme, $remote_addr, …) sont
# préservées (hors allowlist).
# Port 80 : redirection vers HTTPS. (Certbot/nginx-plugin gère les
# challenges ACME ; ne pas servir l'app en HTTP clair.)
# Port 80 : redirection vers HTTPS. (Certbot/nginx-plugin gère les challenges
# ACME ; ne pas servir l'app en HTTP clair.)
server {
listen 80;
listen [::]:80;
server_name $DOMAIN;
return 301 https://$host$request_uri;
}
server {
# 1. TCP : HTTPS classique + HTTP/2
listen 443 ssl;
listen 443 quic $QUIC_OPTS; # HTTP/3 (UDP 443) — reuseport sur un seul vhost
http2 on; # HTTP/2 sur TCP
listen [::]:443 ssl;
http2 on;
# 2. UDP : HTTP/3 (QUIC). reuseport sur UN seul vhost (Org via QUIC_OPTS).
listen 443 quic $QUIC_OPTS;
listen [::]:443 quic $QUIC_OPTS;
http3 on;
server_name $DOMAIN;
# Annonce HTTP/3 au client sur le même port 443/udp. `always` pour
# émettre l'en-tête même sur les réponses d'erreur. Le navigateur
# fait d'abord h1/h2 puis upgrade en h3.
add_header Alt-Svc 'h3=":443"; ma=86400' always;
# 3. Certificats Let's Encrypt (Certbot).
ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem; # managed by Certbot
ssl_protocols TLSv1.2 TLSv1.3; # QUIC exige TLS 1.3 ; TLS 1.2 gardé pour le fallback TCP
# QUIC exige TLS 1.3. (TLS 1.2 conservable pour le fallback TCP :
# `ssl_protocols TLSv1.2 TLSv1.3;` — QUIC reste en 1.3.)
ssl_protocols TLSv1.3;
# 4. Annonce h3 au navigateur sur 443/udp. `always` = émis même en erreur.
add_header Alt-Svc 'h3=":443"; ma=86400' always;
location / {
proxy_pass $BACKEND_SCHEME://$HTTP_HOST:$BACKEND_PORT;