nginx-tls.conf
208 lignes · 9106 octets
# ============================================================================= # Gitrust — Reverse proxy Nginx avec TLS (Let's Encrypt) # ============================================================================= # Déploiement : # sudo cp template/reverse-proxy/nginx-tls.conf /etc/nginx/sites-available/gitrust # sudo ln -s /etc/nginx/sites-available/gitrust /etc/nginx/sites-enabled/gitrust # sudo nginx -t && sudo systemctl reload nginx # # TLS (Let's Encrypt, après que le bloc HTTP ci-dessous soit actif) : # sudo certbot --nginx -d <YOUR_DOMAIN> # # SSH git : # Nginx HTTP ne peut pas proxifier SSH. Deux options : # 1) Exposer le port 2222 directement dans le firewall (recommandé, simple) # 2) Proxy stream nginx sur :22 → 127.0.0.1:2222 (voir commentaire en bas) # Prérequis : paquet libnginx-mod-stream + bloc stream{} dans nginx.conf # ============================================================================= upstream gitrust_backend { server 127.0.0.1:4000; keepalive 32; } # ============================================================================= # HTTP — redirection HTTPS + ACME challenge Let's Encrypt # ============================================================================= server { listen 80; listen [::]:80; server_name <YOUR_DOMAIN>; # Remplacer par le FQDN de l'instance # Répertoire de validation certbot — doit être accessible avant TLS location /.well-known/acme-challenge/ { root /var/www/html; } # Tout le reste → HTTPS permanent location / { return 301 https://$host$request_uri; } } # ============================================================================= # HTTPS — reverse proxy vers gitrust # ============================================================================= server { listen 443 ssl; listen [::]:443 ssl; # Syntaxe nginx >= 1.25. Pour nginx <= 1.24, remplacer les deux lignes # listen ci-dessus par : # listen 443 ssl http2; # listen [::]:443 ssl http2; http2 on; server_name <YOUR_DOMAIN>; # Remplacer par le FQDN de l'instance # ------------------------------------------------------------------------- # TLS — certificats Let's Encrypt (remplis automatiquement par certbot) # ------------------------------------------------------------------------- # Décommenter après : sudo certbot --nginx -d <YOUR_DOMAIN> # ssl_certificate /etc/letsencrypt/live/<YOUR_DOMAIN>/fullchain.pem; # ssl_certificate_key /etc/letsencrypt/live/<YOUR_DOMAIN>/privkey.pem; # include /etc/letsencrypt/options-ssl-nginx.conf; # ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # Certificat auto-signé pour valider la config avant certbot (commenter après) ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem; ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key; # Hardening TLS ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 1d; # ------------------------------------------------------------------------- # En-têtes de sécurité # ------------------------------------------------------------------------- # HSTS : force HTTPS pendant 1 an, inclut sous-domaines. # Attention : n'activer includeSubDomains que si TOUS les sous-domaines ont TLS. add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; # Empêche le navigateur de détecter automatiquement le type MIME (MIME sniffing) add_header X-Content-Type-Options "nosniff" always; # Politique referrer : envoie l'origine complète pour requêtes same-origin, # uniquement l'origine (sans path) pour requêtes cross-origin HTTPS. add_header Referrer-Policy "strict-origin-when-cross-origin" always; # Empêche l'intégration dans des iframes d'autres origines add_header X-Frame-Options "SAMEORIGIN" always; # ------------------------------------------------------------------------- # Taille max des corps de requête # ------------------------------------------------------------------------- # 1G pour les git push HTTP de gros dépôts (monorepos, dépôts avec LFS, # binaires commités). Réduire si l'espace disque est contraint. # La location git spécifique ci-dessous passe à 2G pour les push volumineux. client_max_body_size 1G; client_body_buffer_size 128k; # ------------------------------------------------------------------------- # Timeouts étendus pour clone/push de gros dépôts # ------------------------------------------------------------------------- proxy_connect_timeout 300s; proxy_send_timeout 3600s; proxy_read_timeout 3600s; send_timeout 3600s; # ------------------------------------------------------------------------- # Logs # ------------------------------------------------------------------------- access_log /var/log/nginx/gitrust.access.log; error_log /var/log/nginx/gitrust.error.log warn; # ========================================================================= # Route principale — toutes les pages et l'API REST # ========================================================================= location / { proxy_pass http://gitrust_backend; proxy_http_version 1.1; # En-têtes forwarded proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Port $server_port; # Keep-alive vers l'upstream (connexion réutilisée) proxy_set_header Connection ""; # SSE et WebSocket — désactiver la mise en tampon pour : # - notifications temps réel (/notifications/stream) # - logs CI en streaming (/repos/.../ci/.../logs) # - HTMX SSE proxy_buffering off; proxy_cache off; proxy_set_header X-Accel-Buffering no; } # ========================================================================= # Git smart HTTP — clone et push via HTTPS # ========================================================================= # Pattern : /<owner>/<repo>.git/info/refs, /git-upload-pack, /git-receive-pack location ~ ^/[^/]+/[^/]+\.git/ { proxy_pass http://gitrust_backend; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # Désactiver la mise en tampon côté client ET serveur pour les push/clone proxy_buffering off; proxy_request_buffering off; proxy_cache off; # Push de gros dépôts peut dépasser 1G (monorepos lourds) client_max_body_size 2G; } # ========================================================================= # Assets statiques — optionnel : servir directement depuis le filesystem # ========================================================================= # Décommenter si les fichiers /opt/gitrust/static/ sont lisibles par www-data. # Réduit la charge sur gitrust pour CSS/JS/images (cache navigateur 7 jours). # location ^~ /static/ { # alias /opt/gitrust/static/; # expires 7d; # add_header Cache-Control "public, immutable"; # try_files $uri @gitrust; # } # location @gitrust { # proxy_pass http://gitrust_backend; # } } # ============================================================================= # BONUS — Proxy SSH git via nginx stream (port 22 → gitrust SSH :2222) # ============================================================================= # ATTENTION : ce bloc `stream {}` est de niveau RACINE nginx et NE PEUT PAS # être placé dans ce fichier (qui est inclus dans le bloc http{}). # Le décommenter ici provoquerait : nginx: [emerg] "stream" directive is not allowed here # # Méthode correcte : ajouter le bloc ci-dessous À LA FIN de /etc/nginx/nginx.conf # (hors du bloc http{}), ou dans /etc/nginx/conf.d-stream/gitrust-ssh.conf # inclus au niveau racine. # # Prérequis : # - paquet libnginx-mod-stream installé (apt install libnginx-mod-stream) # - sshd système déplacé sur un autre port (ex: 2022) si l'hôte est aussi administré par SSH # # stream { # upstream gitrust_ssh { # server 127.0.0.1:2222; # } # server { # listen 22; # listen [::]:22; # proxy_pass gitrust_ssh; # proxy_timeout 1h; # proxy_connect_timeout 30s; # error_log /var/log/nginx/gitrust-ssh-stream.log; # } # } # =============================================================================
GitRust