<VirtualHost *:443> ServerName www.domaine.com DocumentRoot /data/www/www.domaine.com CustomLog /data/logs/www.domaine.com-access.log combined ErrorLog /data/logs/www.domaine.com-error.log <FilesMatch ".+\.php$"> SetHandler "proxy:unix:/run/php/php8.2-fpm.sock|fcgi://localhost" </FilesMatch> SSLEngine on SSLCertificateFile /etc/letsencrypt/live/www.domaine.com/cert.pem SSLCertificateKeyFile /etc/letsencrypt/live/www.domaine.com/privkey.pem Include /etc/letsencrypt/options-ssl-apache.conf SSLCertificateChainFile /etc/letsencrypt/live/www.domaine.com/chain.pem </VirtualHost>
<VirtualHost *:80> ServerName www.domaine.com DocumentRoot /data/www/www.domaine.com CustomLog /data/logs/www.domaine.com-access.log combined ErrorLog /data/logs/www.domaine.com-error.log RewriteEngine on RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [L,QSA,R=permanent] </VirtualHost>
<VirtualHost *:80> ServerName domaine.com CustomLog /data/logs/www.domaine.com-access.log combined ErrorLog /data/logs/www.domaine.com-error.log RedirectPermanent / https://www.autredomaine.com/ </VirtualHost>
RewriteEngine On RewriteCond %{HTTP_HOST} ^www.domaine.com$ [NC] RewriteRule ^(.*)$ http://domaine.com/$1 [R=301,L]
RewriteEngine On RewriteCond %{HTTP_HOST} ^domaine.com$ RewriteRule (.*) http://www.domaine.com$1 [R=301]
RewriteEngine On RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [L,QSA,R=permanent]
RewriteCond %{THE_REQUEST} \s[^?]*// RewriteRule ^.*$ /$0 [R=301,NE]
## Rewrites "/index.php" to "/" RewriteCond %{REQUEST_URI} ^(.*)/index\.php$ [NC] RewriteRule . %1 [R=301,L]
1.2.3.4 = IP autorisée a voir le site.
5.6.7.8 = IP aussi autorisée a voir le site.
<Directory /path/to/lesite> Require ip 1.2.3.4 Require ip 5.6.7.8 </Directory>
<Directory /path/to/lesite> SetEnvIf X-Forwarded-For "^1\.2\.3\.4" ip_ok SetEnvIf X-Forwarded-For "^5\.6\.7\.8" ip_ok Order deny,allow Deny from all Allow from env=ip_ok </Directory>
RewriteEngine On RewriteCond %{REMOTE_ADDR} !^1\.2\.3\.4 RewriteCond %{DOCUMENT_ROOT}/maintenance.html -f RewriteCond %{SCRIPT_FILENAME} !maintenance.html RewriteRule ^.*$ /maintenance.html [R=503,L] ErrorDocument 503 /maintenance.html Header Set Cache-Control "max-age=0, no-store"
AddType application/vnd.ms-fontobject .eot AddType application/x-font-ttf .ttf AddType application/x-font-opentype .otf AddType application/x-font-woff .woff AddType image/svg+xml .svg AddType text/x-javascript .js AddType image/x-icon .ico ExpiresActive on ExpiresByType image/jpeg "access plus 1 month" ExpiresByType image/png "access plus 1 month" ExpiresByType text/css "access plus 1 month" ExpiresByType text/x-javascript "access 1 month" ExpiresByType application/vnd.ms-fontobject "access plus 1 month" ExpiresByType application/x-font-ttf "access plus 1 month" ExpiresByType application/x-font-opentype "access plus 1 month" ExpiresByType application/x-font-woff "access plus 1 month" ExpiresByType image/svg+xml "access plus 1 month" ExpiresByType image/x-icon "access plus 1 month"
Header always set Strict-Transport-Security "max-age=15552001; includeSubDomains;"
Header set X-XSS-Protection "1; mode=block" Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure Header always set X-Frame-Options "DENY"
Il est a noter que X-XSS-Protection est un header obsolète !
Header set Access-Control-Allow-Origin * Header set Content-Security-Policy: "default-src * ; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'; img-src * data: ; connect-src * 'unsafe-inline'; frame-src *; font-src * data:"
Ici, l'astérisque indique que tout est ouvert ! A vous de fermer/limiter les choses :
AddOutputFilterByType DEFLATE text/plain AddOutputFilterByType DEFLATE text/html AddOutputFilterByType DEFLATE text/xml AddOutputFilterByType DEFLATE text/css AddOutputFilterByType DEFLATE application/xml AddOutputFilterByType DEFLATE application/xhtml+xml AddOutputFilterByType DEFLATE application/rss+xml AddOutputFilterByType DEFLATE application/javascript AddOutputFilterByType DEFLATE text/x-javascript
<FilesMatch ".+\.php$"> Require all denied </FilesMatch>
<Location "/coucou/"> ProxyPass http://localhost:5232/ retry=0 ProxyPassReverse http://localhost:5232/ RequestHeader set X-Script-Name /coucou/ </Location>
SSLProxyEngine On SSLProxyCheckPeerCN Off SSLProxyCheckPeerName Off SSLProxyCheckPeerExpire off SSLProxyVerify none ProxyPass / https://domain.tld/ ProxyPassReverse / https://domain.tld/ ProxyRequests Off ProxyPreserveHost On
https
peut être remplacé par h2
pour HTTP/2
SSLProxyEngine On ProxyWebsocketFallbackToProxyHttp Off <Location /coucou/> RewriteEngine on RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC] RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC] RewriteRule /coucou/(.*) ws://domain.tld/coucou/$1 [P] </Location> ProxyPass / ws://domain.tld/coucou/ retry=0 ProxyPassReverse / ws://domain.tld/coucou/
ws
peut être remplacé par wss
en cas de serveur sécurisé
<Location /> Order Deny,Allow Deny from 2a03:2880:f000::/36 Deny from 2620:0:1c00::/40 Deny from 2620:0:1cff::/48 Deny from 102.132.96.0/20 Deny from 103.4.96.0/22 Deny from 129.134.0.0/17 Deny from 157.240.0.0/17 Deny from 157.240.1.0/24 Deny from 157.240.2.0/24 Deny from 157.240.3.0/24 Deny from 157.240.6.0/24 Deny from 157.240.7.0/24 Deny from 157.240.8.0/24 Deny from 157.240.9.0/24 Deny from 157.240.10.0/24 Deny from 157.240.11.0/24 Deny from 157.240.12.0/24 Deny from 157.240.13.0/24 Deny from 157.240.14.0/24 Deny from 157.240.15.0/24 Deny from 157.240.18.0/24 Deny from 157.240.19.0/24 Deny from 157.240.21.0/24 Deny from 157.240.22.0/24 Deny from 157.240.25.0/24 Deny from 157.240.26.0/24 Deny from 157.240.27.0/24 Deny from 157.240.28.0/24 Deny from 157.240.29.0/24 Deny from 157.240.30.0/24 Deny from 157.240.192.0/18 Deny from 157.240.193.0/24 Deny from 157.240.194.0/24 Deny from 173.252.64.0/19 Deny from 173.252.88.0/21 Deny from 173.252.96.0/19 Deny from 179.60.192.0/22 Deny from 179.60.192.0/24 Deny from 179.60.193.0/24 Deny from 179.60.194.0/24 Deny from 179.60.195.0/24 Deny from 185.60.216.0/22 Deny from 185.60.216.0/24 Deny from 185.60.217.0/24 Deny from 185.60.218.0/24 Deny from 185.60.219.0/24 Deny from 204.15.20.0/22 Deny from 31.13.24.0/21 Deny from 31.13.64.0/18 Deny from 31.13.64.0/19 Deny from 31.13.64.0/24 Deny from 31.13.65.0/24 Deny from 31.13.66.0/24 Deny from 31.13.67.0/24 Deny from 31.13.68.0/24 Deny from 31.13.70.0/24 Deny from 31.13.71.0/24 Deny from 31.13.72.0/24 Deny from 31.13.73.0/24 Deny from 31.13.74.0/24 Deny from 31.13.75.0/24 Deny from 31.13.80.0/24 Deny from 31.13.81.0/24 Deny from 31.13.82.0/24 Deny from 31.13.83.0/24 Deny from 31.13.84.0/24 Deny from 31.13.85.0/24 Deny from 31.13.86.0/24 Deny from 31.13.89.0/24 Deny from 31.13.90.0/24 Deny from 31.13.91.0/24 Deny from 31.13.92.0/24 Deny from 31.13.93.0/24 Deny from 31.13.94.0/24 Deny from 31.13.95.0/24 Deny from 31.13.96.0/19 Deny from 45.64.40.0/22 Deny from 66.220.144.0/20 Deny from 66.220.144.0/21 Deny from 66.220.152.0/21 Deny from 69.171.224.0/19 Deny from 69.171.224.0/20 Deny from 69.171.239.0/24 Deny from 69.171.240.0/20 Deny from 69.171.250.0/24 Deny from 69.171.255.0/24 Deny from 69.63.176.0/20 Deny from 69.63.176.0/21 Deny from 69.63.184.0/21 Deny from 74.119.76.0/22 </Location>
/etc/letsencrypt/options-ssl-apache.conf
# Baseline setting to Include for SSL sites SSLEngine on # Intermediate configuration, tweak to your needs SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 #SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:!3DES SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH SSLHonorCipherOrder on SSLCompression off SSLOptions +StrictRequire # Add vhost name to log entries: LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" vhost_combined LogFormat "%v %h %l %u %t \"%r\" %>s %b" vhost_common #CustomLog /var/log/apache2/access.log vhost_combined #LogLevel warn #ErrorLog /var/log/apache2/error.log # Always ensure Cookies have "Secure" set (JAH 2012/1) #Header edit Set-Cookie (?i)^(.*)(;\s*secure)??((\s*;)?(.*)) "$1; Secure$3$4"
Permet d'autoriser letsencrypt a faire ses challenges de renouvellement sans arrêter le serveur apache.
<IfModule mod_proxy.c> ProxyPass /.well-known/acme-challenge ! </IfModule> Alias /.well-known/acme-challenge "/data/www/.well-known/acme-challenge" <Directory "/data/www/.well-known/acme-challenge"> Options None AllowOverride None ForceType text/plain RedirectMatch 404 "^(?!/\.well-known/acme-challenge/[\w-]{43}$)" </Directory>
Fonctionne de pair avec le script autorenew en webroot
Ressources : https://fr.wikipedia.org/wiki/Security.txt - https://securitytxt.org/
security.txt est une norme proposée pour les informations de sécurité des sites Web qui est destinée à permettre aux chercheurs en sécurité de signaler facilement les failles de sécurité
Exemple de fichier :
Contact: security@domain.tld Expires: 2030-12-31T00:00:00.000Z Preferred-Languages: fr, en
Configuration à rajouter (je l'ai mise dans /conf-enabled/security.conf mais on peut faire autrement si besoin) :
Alias /.well-known/security.txt "/data/www/.well-known/security.txt"
Ressources : https://www.jasom.net/private-prefetch-proxy-well-known-traffic-advice-apache-htaccess-nginx/
traffic-advice permet d'indiquer aux services de prefetch si ils ont le droit d'interroger le serveur, et a quel point.
Exemple de code autorisant Chrome a interroger le serveur :
[{ "user_agent": "prefetch-proxy", "google_prefetch_proxy_eap": { "fraction": 1.0 } }]
Exemple de code refusant tout traffic de prefetch :
[ {"user_agent": "prefetch-proxy", "disallow": true} ]
Attention, l'url n'ayant pas d'extension, il est préférable de forcer un type mime particulier pour cette ressource. Le type mime est application/trafficadvice+json
La conf Apache correspondante (je l'ai mise dans /conf-enabled/security.conf mais on peut faire autrement si besoin) :
<Directory /data/www/.well-known/traffic-advice> Header set Content-Type: "application/trafficadvice+json" </Directory> Alias /.well-known/traffic-advice "/data/www/.well-known/traffic-advice"
Voir cette config.