feat: implémentation initiale du reverse proxy de maintenance
Reverse proxy Nginx (image stable-alpine) qui sert l'app upstream ou une page de maintenance 503 selon l'IP du client. - Modes whitelist/blacklist commutables via MAINTENANCE_MODE - Liste IPv4 via MAINTENANCE_IP_LIST (séparée par virgules, validée au boot) - Logique en directives Nginx natives (geo + map), zéro Lua/njs - Page statique sobre HTML+CSS inline, zéro JS, zéro réseau sortant - Log dédié /var/log/nginx/maintenance.log pour les requêtes bloquées - Validation des env vars dans /docker-entrypoint.d/10-init.sh - Stack Docker + docker-compose pour dev local et tests - 6 cas de tests d'intégration (whitelist/blacklist x autorisée/bloquée + log + nginx -t) - Lint shellcheck propre sur tous les scripts shell
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
include /etc/nginx/snippets/maintenance-log.conf;
|
||||
|
||||
# Liste des IP générée au boot par scripts/build-ip-list.sh à partir
|
||||
# de MAINTENANCE_IP_LIST. Définit la variable $ip_in_list (0 ou 1).
|
||||
include /etc/nginx/snippets/_generated_geo.conf;
|
||||
|
||||
# Décision finale en croisant le mode et l'appartenance à la liste.
|
||||
# whitelist : on bloque si l'IP n'est PAS dans la liste (ip_in_list=0)
|
||||
# blacklist : on bloque si l'IP EST dans la liste (ip_in_list=1)
|
||||
map "${MAINTENANCE_MODE}:$ip_in_list" $is_in_maintenance {
|
||||
default 0;
|
||||
"whitelist:0" 1;
|
||||
"blacklist:1" 1;
|
||||
}
|
||||
|
||||
server {
|
||||
listen ${LISTEN_PORT};
|
||||
server_name ${SERVER_NAME};
|
||||
|
||||
access_log /var/log/nginx/access.log combined;
|
||||
access_log /var/log/nginx/maintenance.log maintenance_log if=$is_in_maintenance;
|
||||
error_log /var/log/nginx/error.log warn;
|
||||
|
||||
error_page 503 /__maintenance.html;
|
||||
|
||||
# Page statique servie uniquement via error_page (jamais directement accessible).
|
||||
location = /__maintenance.html {
|
||||
internal;
|
||||
root /usr/share/nginx/html;
|
||||
try_files /maintenance.html =500;
|
||||
add_header Retry-After 3600 always;
|
||||
add_header Cache-Control "no-store" always;
|
||||
}
|
||||
|
||||
location / {
|
||||
# if + return est l'un des seuls usages sûrs de `if` en location (cf. If is Evil).
|
||||
if ($is_in_maintenance) {
|
||||
return 503;
|
||||
}
|
||||
|
||||
proxy_pass http://${UPSTREAM_HOST};
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header Connection "";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user