apachenginxtls
MDstable
NoteSnippetChecklistPlaybook
Serveur Web — Configuration & Durcissement
Apache et Nginx : TLS, headers de sécurité, hardening, virtual hosts, reverse proxy
snippetintermediate 2026-05-14 5 min read
apachenginxtlshttpshardeningheadersreverse-proxycsphstsssl
Apache
Installation et structure
bash
apt install apache2a2enmod ssl rewrite headers http2# Structure/etc/apache2/apache2.conf # config principale/etc/apache2/sites-available/ # vhosts disponibles/etc/apache2/sites-enabled/ # vhosts actifs (symlinks)/etc/apache2/conf-available/ # configs supplémentaires
Masquer la version et le banner
apache
# /etc/apache2/conf-available/security.confServerTokens Prod # affiche "Apache" uniquement, sans versionServerSignature Off # supprime la signature dans les pages d'erreurTraceEnable Off # désactive la méthode HTTP TRACE
Virtual Host HTTPS
apache
# /etc/apache2/sites-available/example.com.conf<VirtualHost *:80>ServerName example.comRedirect permanent / https://example.com/</VirtualHost><VirtualHost *:443>ServerName example.comDocumentRoot /var/www/example.comSSLEngine onSSLCertificateFile /etc/ssl/certs/example.com.crtSSLCertificateKeyFile /etc/ssl/private/example.com.keySSLCertificateChainFile /etc/ssl/certs/ca-bundle.crt# TLS — désactiver les protocoles obsolètesSSLProtocol all -SSLv3 -TLSv1 -TLSv1.1SSLCipherSuite ECDH+AESGCM:ECDH+CHACHA20:DH+AESGCM:!aNULL:!MD5:!RC4SSLHonorCipherOrder onSSLCompression offSSLSessionTickets off# Headers de sécuritéHeader always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"Header always set X-Frame-Options "DENY"Header always set X-Content-Type-Options "nosniff"Header always set Referrer-Policy "strict-origin-when-cross-origin"Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()"Header always set Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:"# Supprimer les headers qui exposent la stackHeader unset X-Powered-ByHeader unset Server# Interdire le listing de répertoires<Directory /var/www/example.com>Options -Indexes -FollowSymLinksAllowOverride NoneRequire all granted</Directory># LogsErrorLog ${APACHE_LOG_DIR}/example.com_error.logCustomLog ${APACHE_LOG_DIR}/example.com_access.log combined</VirtualHost>
Reverse Proxy Apache
apache
a2enmod proxy proxy_http proxy_balancer lbmethod_byrequests<VirtualHost *:443>ServerName app.example.comSSLEngine on# ... (cert TLS comme ci-dessus)# Proxy vers le backendProxyPreserveHost OnProxyPass / http://127.0.0.1:8080/ProxyPassReverse / http://127.0.0.1:8080/# Timeout backendProxyTimeout 60# Masquer le backend dans les réponsesHeader unset X-Powered-By</VirtualHost>
Limiter les méthodes HTTP
apache
<Directory /var/www/example.com><LimitExcept GET POST HEAD>Require all denied</LimitExcept></Directory>
Commandes de gestion
bash
# Vérifier la configurationapachectl configtest# Activer/désactiver un vhosta2ensite examplecomconfa2dissite examplecomconfsystemctl reload apache2# Vérifier les modules actifsapache2ctl -M | sort# Voir les vhosts configurésapache2ctl -S
Nginx
Configuration globale — /etc/nginx/nginx.conf
nginx
user www-data;worker_processes auto;pid /run/nginx.pid;events {worker_connections 1024;multi_accept on;}http {# Masquer la version Nginxserver_tokens off;# Timeouts (protection contre slowloris)client_body_timeout 12;client_header_timeout 12;keepalive_timeout 15;send_timeout 10;# Taille max des requêtesclient_max_body_size 10M;# Logsaccess_log /var/log/nginx/access.log;error_log /var/log/nginx/error.log warn;include /etc/nginx/mime.types;include /etc/nginx/conf.d/*.conf;include /etc/nginx/sites-enabled/*;}
Virtual Host HTTPS — /etc/nginx/sites-available/example.com
nginx
# Redirection HTTP → HTTPSserver {listen 80;server_name example.com www.example.com;return 301 https://$host$request_uri;}server {listen 443 ssl http2;server_name example.com www.example.com;root /var/www/example.com;index index.html;# TLSssl_certificate /etc/ssl/certs/example.com.crt;ssl_certificate_key /etc/ssl/private/example.com.key;ssl_dhparam /etc/ssl/certs/dhparam.pem; # openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048ssl_protocols TLSv1.2 TLSv1.3;ssl_ciphers ECDH+AESGCM:ECDH+CHACHA20:DH+AESGCM:!aNULL:!MD5:!RC4;ssl_prefer_server_ciphers on;ssl_session_cache shared:SSL:10m;ssl_session_timeout 1d;ssl_session_tickets off;# OCSP Staplingssl_stapling on;ssl_stapling_verify on;resolver 1.1.1.1 8.8.8.8 valid=300s;# Headers de sécuritéadd_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;add_header X-Frame-Options "DENY" always;add_header X-Content-Type-Options "nosniff" always;add_header Referrer-Policy "strict-origin-when-cross-origin" always;add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline';" always;# Interdire le listing de répertoiresautoindex off;# Bloquer les méthodes non nécessairesif ($request_method !~ ^(GET|POST|HEAD)$) {return 405;}location / {try_files $uri $uri/ =404;}# Bloquer l'accès aux fichiers sensibleslocation ~ /\. {deny all;}location ~* \.(env|log|conf|bak|sql|git)$ {deny all;}}
Reverse Proxy Nginx
nginx
upstream backend {server 127.0.0.1:8080;server 127.0.0.1:8081 backup;keepalive 32;}server {listen 443 ssl http2;server_name app.example.com;# ... (TLS et headers comme ci-dessus)location / {proxy_pass http://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;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "upgrade";proxy_read_timeout 60s;# Masquer les headers du backendproxy_hide_header X-Powered-By;proxy_hide_header Server;}}
Commandes de gestion
bash
# Générer le paramètre Diffie-Hellmanopenssl dhparam -out /etc/ssl/certs/dhparam.pem 2048# Vérifier la configurationnginx -t# Recharger sans interruptionsystemctl reload nginx# Voir les vhosts actifsnginx -T | grep server_name# Activer un vhostln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
Certificats SSL/TLS
bash
# Let's Encrypt (Certbot) — Apacheapt install certbot python3-certbot-apachecertbot --apache -d examplecom -d wwwexamplecom# Let's Encrypt — Nginxapt install certbot python3-certbot-nginxcertbot --nginx -d examplecom# Renouvellement automatique (cron)certbot renew --dry-run# Certificat auto-signé (tests internes)openssl req -x509 -nodes -days 365 -newkey rsa2048-keyout /etc/ssl/private/self-signed.key-out /etc/ssl/certs/self-signed.crt-subj "/CN=srv-web.example.local/O=Example/C=FR"
Vérification et tests
bash
# Headers HTTP retournéscurl -sI https//example.com# Audit TLS complettestsslsh https//example.com# Points à valider : TLS 1.0/1.1 désactivés, Forward Secrecy, HSTS# Ciphers disponiblesnmap --script ssl-enum-ciphers -p 443 examplecom# Méthodes HTTP autoriséescurl -sI -X OPTIONS https//example.com | grep Allowcurl -sI -X TRACE https//example.com # doit retourner 405# Listing de répertoirescurl -s https//example.com/images/ | grep -i "Index of"# Vérifier le banner serveur (doit être absent ou générique)curl -sI https//example.com | grep -iE "^Server:|^X-Powered-By:"
Checklist0/14
💡 Tip —
Générer le paramètre Diffie-Hellman personnalisé (openssl dhparam 2048) avant de déployer HTTPS — sans ça, Nginx utilise des paramètres DH par défaut parfois faibles selon la version.
OPS·BRAIN v1.027 notes · Networklocal