Wiki CgX

Parce que j'ai un cerveau, mais pas trop.

Outils pour utilisateurs

Outils du site


it:linux-selfhosting:apache

Apache

Exemples de vHosts

HTTPS letsencrypt & php8.2-fpm

vhost.conf
<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>

Redirection HTTP/HTTPS automatique avec prise en compte de l'URL

vhost.conf
<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>

Redirection permanente

vhost.conf
<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>

Directives Utiles

Retirer les www.

vhost.conf
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www.domaine.com$ [NC]
RewriteRule ^(.*)$ http://domaine.com/$1 [R=301,L]

Forcer les www.

vhost.conf
RewriteEngine On 
RewriteCond %{HTTP_HOST} ^domaine.com$ 
RewriteRule (.*) http://www.domaine.com$1 [R=301]

Forcer la redirection HTTPS

vhost.conf
RewriteEngine On
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [L,QSA,R=permanent]

Supprimer les slashes redondants

vhost.conf
RewriteCond %{THE_REQUEST} \s[^?]*//
RewriteRule ^.*$ /$0 [R=301,NE]

Supprimer le « index.php » à la fin des URL

vhost.conf
## Rewrites "/index.php" to "/"
RewriteCond %{REQUEST_URI} ^(.*)/index\.php$ [NC]
RewriteRule . %1 [R=301,L]

Limiter l'accès a une/des IP(s) précise(s)

1.2.3.4 = IP autorisée a voir le site.
5.6.7.8 = IP aussi autorisée a voir le site.

Nativement

   <Directory /path/to/lesite>
        Require ip 1.2.3.4
        Require ip 5.6.7.8
    </Directory>

Avec l'IP dans le X-Forwarded-For

   <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>

Avec une page de maintenance statique

       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"

Mise en cache navigateur de certains types de contenus statiques

  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"

HSTS

        Header always set Strict-Transport-Security "max-age=15552001; includeSubDomains;"

Protection d'injections

        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 :

Compression

        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

Empêcher l'éxécution & la consultation de code PHP

       <FilesMatch ".+\.php$">
               Require all denied
       </FilesMatch>

Reverse proxy

Depuis un serveur HTTP

        <Location "/coucou/">
            ProxyPass        http://localhost:5232/ retry=0
            ProxyPassReverse http://localhost:5232/
            RequestHeader    set X-Script-Name /coucou/
        </Location>

Depuis un serveur HTTPS / HTTP/2

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

Depuis un serveur ws/streaming

    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é

Bloquer Facebook comme des gros sauvages

<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>

Config SSL qui va bien

/etc/letsencrypt/options-ssl-apache.conf

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"

Directives .well-known

LetsEncrypt AcmeChallenge

Permet d'autoriser letsencrypt a faire ses challenges de renouvellement sans arrêter le serveur apache.

letsencrypt-acmechallenge.conf
<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

security.txt

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 :

/data/www/.well-known/security.txt
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) :

/etc/apache2/conf-enabled/security.conf
Alias /.well-known/security.txt "/data/www/.well-known/security.txt"

traffic-advice

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 :

traffic-advice
[{
  "user_agent": "prefetch-proxy",
  "google_prefetch_proxy_eap": {
    "fraction": 1.0
  }
}]

Exemple de code refusant tout traffic de prefetch :

/data/www/.well-known/traffic-advice
[
    {"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) :

/etc/apache2/conf-enabled/security.conf
<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"

Page de maintenance Express

Config vhost

Voir cette config.

maintenance.html

it/linux-selfhosting/apache.txt · Dernière modification : 23 Mar 2023 :: 16:17 de CgX