Logo Khaganat
Traductions de cette page?:

Configuration d'Apache

Apache est un serveur web, que nous utilisons sur certains de nos serveurs. Une autre solution populaire est Nginx. Les deux sont très bien, répondant à des logiques similaires et adapté à de nombreuses situations. Dans le cas des ordinateurs les moins puissants (type Raspberry), on préférera tout de même des logiciels plus léger comme Lighttpd.

Apache est un composant de première importance pour les sites web. Son paramétrage correct et l'attention à certaines options améliorent la sécurité globale du serveur ; à l'inverse, oublier certains détails peut amener des failles exploitables par des attaquants.

Apache a un avantage dans le cas d'une architecture “pare-feu qui protège des serveurs”, il est assez facile d'avoir une communication mixte entre le pare-feu et les serveurs, avec et sans chiffrement. Certains logiciels ont besoin que toutes les communications soient protégés ; par exemple Teampass ne fonctionne pas sans https sur le serveur où il est installé (même si le pare-feu, lui, sert l'accès à l'internaute en https).

Pour l'installation, sur Debian et dérivées :

sudo apt install apache2

Pour connaître sa version d'apache :

apache -v

Tester la configuration et relancer le service

C'est une manipulation à refaire après avoir modifié les fichiers, alors autant donner les commandes dès le début…

Pour vérifier avant tout que la syntaxe est propre :

sudo apachectl -t

Pour relancer le serveur apache :

sudo apachectl graceful

Cette commande redémarre le démon Apache httpd en douceur. Si le démon n'est pas en cours d'exécution, il est démarré. À la différence d'un redémarrage normal, les connexions en cours ne sont pas fermées. Comme effet de bord, les anciens fichiers journaux ne seront pas fermés immédiatement. Cela signifie que si l'on utilise un script de rotation des journaux, un délai suffisant sera nécessaire afin d'être sûr que les fichiers journaux seront bien fermés avant leur traitement par le script de rotation. Cette option vérifie automatiquement les fichiers de configuration (de la même manière que l'option configtest ) avant de lancer le redémarrage, afin d'être sûr que le fonctionnement du démon ne sera pas compromis. Équivalent à apachectl -k graceful.

Renseigner les vhosts de son site

Pour chaque domaine et sous-domaine, on crée un fichier conf dans /etc/apache2/sites-available/. Pour s'y retrouver, mieux vaut donner le nom du sous-domaine au fichier en question… Il y a toujours deux fichiers à faire : celui pour “http” et celui pour “https”, qu'on appelle vhosts. Dans les faits, le http renvoie directement sur https, aussi il va être très sobre.

Cela ressemblera à quelque chose comme ça :

txt /etc/apache2/sites-available/monsite-org.conf
<VirtualHost *:80>
    ServerName monsite.org
    DocumentRoot /var/www/monsite

    RewriteEngine On
    RewriteCond %{REQUEST_URI} !.well-known/acme-challenge
    RewriteRule ^(.*)$ https://%{SERVER_NAME}$1 [R=301,L]

</VirtualHost>
  • VirtualHost *:80 : indique le port concerné, 80 c'est http (et ça ne se bidouille pas !). Toutes les informations concernant le site sont entre ces deux balises “VirtualHost”.
  • ServerName : à renseigner obligatoirement. C'est le nom de domaine qui permet d'accéder au site.
  • DocumentRoot : nécessaire aussi ! Indique où sont les fichiers du site web sur le serveur. Astuce “bonne pratique”, créez un dossier dans /var/www au nom de votre domaine/sous-domaines.
  • RewriteEngine On : indique d'utiliser la réécriture des URL (voir plus bas)
  • Les deux lignes suivantes sont là pour rediriger en https ; la première est lié à l'usage de let_s_encryptcertbot et s'adapte suivant quel sorte de certificat SSL vous utilisez.

Le vhosts en https a un port différent, et c'est là qu'on configurera toutes les options : alias, etc.

txt /etc/apache2/sites-available/monsite-org-ssl.conf
<VirtualHost *:443>
    ServerName monsite.org
    DocumentRoot /var/www/monsite
 
    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/monsite.org/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/monsite.org/privkey.pem

    Alias /dokuwiki /var/www/monsite/undossier/unautredossier/dokuwiki

        <Directory /var/www/monsite/ >
                Options FollowSymLinks MultiViews
                AllowOverride All
                Require all granted
        </Directory>

</VirtualHost>
  • Le port, cette fois, est 443.
  • Il faut renseigner à nouveau ServerName et DocumentRoot, comme pour le 80.
  • SSLEngine on : active la prise en charge du certificat SSL, ce qui est un peu obligatoire (ceci dit, quand le module est actif, oublier cette option dans le vhost ne semble pas gêner la prise en charge du certificat…).
  • SSLCertificateFile et SSLCertificateKeyFile : indique le chemin des deux fichiers du certificat. Il faut évidement adapter le chemin au nom de domaine, et avoir généré le certificat (on voit ça plus bas).
  • Alias : permet de faire des URL plus élégantes. Une option parmi d'autres… Ici, sans alias, le dokuwiki serait accessible avec le lien “monsite.org/undossier/unautredossier/dokuwiki” ce qui est longuet ; l'alias permet que le lien “monsite.org/dokuwiki” serve le dokuwiki. On peut même pointer un dossier hors de /var/www (par exemple /home/moi/unboutdesite. Il y a parfois des bonnes raisons de le faire ;). Voir plus bas le détail !
  • Directory : va permettre de déclarer diverses options, rendant le dossier (et donc le site web associé) utilisable pour la navigation web, en tirant partie par exemple des possibilités de php, mais aussi en indiquant ce qui est permis et interdit et contribue donc un peu à la sécurité. Ici, ce sont des options classiques qui fonctionnent dans 90% des cas. Mais il faut adapter parfois suivant les dossiers :
    • Options : attention à déclarer uniquement ce qui est utile.
      • Indexes permet de lister les fichiers dans un répertoire si aucun fichier index (comme index.html ou index.php) n'est présent, ce qui peut poser des problèmes de sécurité. Donc on peut éviter ?
      • FollowSymLinks : Autorise Apache à suivre les liens symboliques (symlinks) dans le répertoire. Voir aussi la doc sur SymLinksIfOwnerMatch (usage plus spécifique).
      • MultiViews : Permet à Apache de servir différentes versions d'un même fichier selon la requête du client (langue, type de contenu, etc.)
      • ExecCGI, Includes, IncludesNOEXEC sont intéressants mais allez voir la doc officielle, parce que c'est assez pointu comme usage.
      • None : pour interdire toutes les options dans un répertoire.
    • AllowOverride All permet l'utilisation de fichiers .htaccess ; cela peut avoir un impact sur les performances. Mais pas mal de CMS utilisent les htaccess.
    • Require all granted : Remplace les anciennes directives Order allow,deny et allow from all. Cela autorise toutes les requêtes à accéder à ce répertoire.
      • Require all denied pour interdire l'accès (utile pour s'assurer que certains dossiers ne seront pas du tout accessibles)
      • Require ip : Permet de restreindre l'accès à des adresses IP spécifiques ou à des plages d'adresses IP.
      • Require host : Permet d'autoriser l'accès basé sur le nom d'hôte de la requête.
      • Require user et Require valid-user : Permet d'accorder l'accès à des utilisateurs spécifiques ce qui demande d'utiliser des mécanismes d'authentification
      • Require env : Permet d'accorder l'accès en fonction d'une variable d'environnement, ça commence à être assez pointu comme usage.
      • Require expr : Permet d'utiliser une expression conditionnelle pour contrôler l'accès. Par exemple toutes les ip du réseau interne.

Après chaque modification de ces fichiers, afin que ce soit pris en compte, vérifiez la configuration et relancez le service apache

sudo apachectl -t && sudo apachectl graceful

Modifier les urls pour aller aux dossiers (Alias)

Avec une configuration basique, Apache indique qu'il faut lire le répertoire renseigné dans DocumentRoot comme répertoire de base du site, chaque dossier se rajoutant à l'adresse. Par exemple si l'option est DocumentRoot /var/www/monsite et que votre dossier a la hiérarchie suivante :

  • var
    • www
      • monsite
        • dossier1
          • dossier2
          • index.html

Alors pour accéder via le web à page1 il faudra mettre dans la barre d'adresse du navigateur monsite.org/dossier1/dossier2/index.html

On change ça en faisant des alias dans le fichier /etc/apache2/sites-enable/000-default.conf, de cette façon :

Alias /adresse /var/www/monsite/dossier1/dossier2

Changez /adresse par ce que vous voulez. Ici, dans cet exemple, notre page “index.html” sera à présent accessible à l'adresse monsite.org/adresse/index.html

Vous pouvez aussi pointer vers des adresses hors de /var/www , par exemple pointer vers home/user/monsite, ce qui vous permet de travailler dans un répertoire avec des droits utilisateurs basique.

Droits sur www

Plusieurs possibilités pour permettre, en tant qu'utilisateur Lambda1), de modifier ce qui se trouve dans le dossier /var/www.

Le plus simple et rapide est d'attribuer les droits de ce dossier au groupe www-data, et de mettre lambda dans le groupe www-data.

sudo adduser lambda www-data
chown -R www-data: /var/www

Méthode alternative :

Pour ajouter l'utilisateur lambda à www-data, il y a aussi la commande

usermod -a -G www-data lambda

Les deux sont similaires.

Relancer la session pour que les droits soient pris en compte pour l'utilisateur en cours.

Il vaut mieux laisser le groupe www-data gérer les droits, de base, parce que sinon c'est un beau bazar. Ajouter l'utilisateur “lambda” dans ce groupe permet de modifier tout sans se prendre la tête.

Si certains cms posent problèmes, la suite de commande suivante sur le dossier en question peut réattribuer les droits à www-data et permettre de les résoudre :

sudo chgrp -R www-data Dossier
sudo chown -R www-data Dossier
sudo chmod -R g+w Dossier
  • chgrp pour réaffecter le groupe propriétaire
  • chown pour changer le propriétaire tout court (moins important, en théorie chgrp devrait déjà régler la plupart des soucis)
  • chmod pour donner les bonnes permissions de lecture/écriture sur le dossier (g pour groupe, + pour ajouter, w pour write, donc “écrire”).
  • L'option -R permet la récursivité (que le changement s'applique dans les sous-dossiers).

Cacher la version d'apache

Ceci est une option améliorant la sécurité.

En principe nos serveurs sont à jours, hein. Mais en cas d'oubli, ne facilitons pas la tâche des observateurs :

nano /etc/apache2/conf-available/security.conf
# Cacher la version d'Apache2
ServerTokens Prod
ServerSignature Off
service apache2 restart

À refaire sur chacun de ses serveurs !

On peut aussi paramétrer (et modifier) ces options dans /etc/apache2/apache2.conf mais c'est moins élégant.

Il faut activer le fichier, non ? Cette partie du tuto demande à être vérifiée.

Activation et paramétrage des modules

Par défaut, Apache est assez “sobre”. Il faut activer divers modules pour bénéficier de certaines fonctionnalités. Certains sont nécessaires pour la sécurité, d'autres sont juste tellement utiles qu'on s'en passe rarement.

Dans les modules à activer quoi qu'il arrive (voir plus bas le détail) :

sudo a2enmod headers ssl

Module SSL

Aujourd'hui, rien ne permet de justifier la navigation non chiffrée. SSL est une mesure de sécurité, qui ne vous coûte rien en tant que sysadmin (grâce à Let's Encrypt) et qui peut éviter un certain nombre de soucis. Alors, par défaut, vos sites doivent être en https. C'est tout.

Pour connaître sa version d'apache et d'openssl :

apache -v
openssl version

À utiliser sur Mozilla SSL Configuration Generator pour générer les options de base à mettre dans sa configuration, ce sera probablement plus à jour que ce tutoriel au fil du temps.

Activer le module ssl dans Apache si ce n'est pas déjà fait :

a2enmod ssl

Puis modifiez le fichier /etc/apache2/mods-available/ssl.conf suivant ces informations :

  • Enlever le protocole SSL3 et SSLv2 qui ne sont plus considérés comme sûrs (notez le “-” devant SSLv3 et SSLv2)
  • Interdire la compression d'échanges chiffrés (oui oui cela introduit une possibilité d'attaque)
  • Lister la liste des algorithmes de chiffrement autorisés et interdits
  • Imposer de négocier ces protocoles dans l'ordre, donc du plus sûr au moins sûr (notez le “!” devant certains nom d'algorithme pour les interdire, par exemple : !PSK, !RC4, etc… et le + devant ceux à favoriser)
  • Le dernier morceau concerne OCSP qui accélère un peu les échanges en https, voir aussi Accélérer votre réponse SSL/TLS avec l’OCSP Stapling
SSLProtocol +TLSv1.2
SSLCompression off
SSLCipherSuite HIGH:!aNULL:!eNULL:!LOW:!MEDIUM:!EXP:!RC4:!3DES:!MD5:!PSK:!kRSA:!SRP:-DH:+ECDH
SSLHonorCipherOrder On

# OCSP Stapling, only in httpd 2.3.3 and later
SSLUseStapling          on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
SSLStaplingCache        shmcb:/var/run/ocsp(128000)

Pour la liste SSLCipherSuite, consulter les préconisations de Mozilla SSL Configuration Generator et lire tranquillement l'explication si dessous avant de modifier la proposition mise à jour le 29 novembre 2017.

À partir de la version 2.4.11 d'apache, vous pouvez ajouter dans le fichier /etc/apache2/mods-available/ssl.conf :

SSLSessionTickets Off

Explications

Ce qui suit est extrait d'une conversation avec TychoBrahe ; j'ai conservé son style fleuri si savoureux.

zatalyz 2016/12/30 13:27

Une ciphersuite est un ensemble de 4 algorithmes différents, chacun servant à un rôle distinct :

  • 1 pour faire un échange de clés
  • 1 pour faire du chiffrement asymétrique
  • 1 pour faire du chiffrement symétrique
  • 1 pour le contrôle

Un exemple : DHE-RSA-AES256-SHA256

  • DHE : diffie hellman, c'est l'échange de clés
  • RSA pour l'asymétrique, en particulier pour la signature
  • AES avec une clé de 256 bits pour le chiffrement symétrique
  • et enfin sha256 pour calculer les empreintes des sommes de contrôle

On pourrait croire qu'il y a 5 algorithmes, par exemple avec ECDHE-RSA-AES128-GCM-SHA256. En fait, GCM est un des modes de fonctionnement d'AES, donc AES128-GCM désigne de l'AES en mode GCM avec une clé de 128 bits. Pour info, les EC devant ECDHE et parfois ECDSA c'est pour elliptic curve, donc l'utilisation de courbes elliptiques au lieu de nombres premiers.

SSL et TLS permettent d'utiliser non pas une seule combinaison, mais plusieurs, ce qui fait que ces protocoles intègrent une phase de négociation de la cipher suite. Chaque version de SSL ou TLS autorise ou non certaines cipher suites etc, bref c'est le bordel, sachant qu'il faut, avant ça, négocier la version de SSL ou TLS utilisée. Soit dit en passant, il existe une cipher suite NULL qui dit qu'il n'y a aucun chiffrement, du coup cette phase de négociation a été attaquée, un MITM2) permettant de forcer une cipher suite (genre NULL ou une faible).

Afin d'éviter les ennuis, on va dire au serveur de n'utiliser que certaines cipher suites et pas d'autres : c'est l'option SSLCipherSuite. Chaque cipher suite est séparée par : et s'il y a un ! devant son nom, c'est pour explicitement l'interdire.

Le site de Mozilla cite toutes les ciphersuites, c'est sans doute bien, mais ils ont juste oublié un truc : à tout citer explicitement, il faut faire évoluer la liste avec les avancées en matière de recherche. Personnellement j'utilise et recommande d'utiliser des familles. Ces familles sont définies par la librairie SSL/TLS utilisée :

  • ALL ← on autorise tout
  • !aNULL:!eNULL ← on interdit les familles de NULL
  • !LOW:!MEDIUM ← on interdit les cipher suites disposant d'une clé de 128 bits (MEDIUM) ou moins (LOW)
  • !EXP ← ce sont les variantes d'exportation, donc fortement affaiblies, de certains algos
  • !RC4 ← RC4 est un algo de chiffrement symétrique qui a été démoli mais un truc bien grave alors qu'il était très populaire
  • !3DES ← pareil, on interdit cette merde
  • !MD5 ← celui qui utilise encore md5 pour du checksum crypto est un grand malade
  • !PSK ← pareil, une merde de plus de virée
  • +HIGH ← et enfin on autorise la famille des cipher suites reconnues comme fortes

Du coup on fait confiance dans les familles définies dans les lib crypto, mais en imposant des restrictions sur certains trucs trop limite pour y être inclus mais qui ont des chances de tout de même s'y retrouver.

Les librairies ont un outil pour lister les familles, qui liste soit toutes les cipher suites supportées, soit, si on précise, la liste de ce qui est autorisé :

openssl ciphers
openssl ciphers HIGH
openssl ciphers 'HIGH:!AES'

Voir aussi

man 1 ciphers
L'échange de clefs

C'est un mécanisme permettant l'échange de clefs en toute confidentialité, sans qu'un tiers puisse avoir connaissance de celles-ci.

Le chiffrement a/symétrique

La différence entre le chiffrement symétrique et le chiffrement asymétrique est que dans le premier cas, il n'y a besoin que d'une seule clef, qui permet aussi bien de chiffrer un message que de le déchiffrer. Pour le chiffrement asymétrique, on utilise une clef pour le chiffrement, et une autre clef différente de la première pour le déchiffrement. C'est pour cela qu'on parle de clef dite publique (celle que tout le monde peut voir et avec laquelle on va chiffrer les messages qui nous sont destinés) et de clef dite privée (celle avec laquelle on va déchiffrer notre message ; si on n'a pas accès à cette clef privée, on ne peut pas déchiffrer le message).

Le contrôle

Afin de vérifier l'intégrité des messages que l'on transmet, on calcule une somme de contrôle que l'on envoie avec le message. Une fois le message et sa somme de contrôle réceptionnés, on peut recalculer la somme de contrôle du message et vérifier qu'elle correspond bien à celle qui a été transmise. Si elles diffèrent, c'est que le message a été altéré (ou qu'il y a une collision, c'est à dire que pour deux messages différents on obtient la même somme de contrôle, mais ce cas ne devrait quasiment presque jamais arriver).

Module header

Activer les headers dans Apache si ce n'est pas déjà fait :

sudo a2enmod headers

Puis modifiez le fichier /etc/apache2/mods-available/headers.conf :

# Ce qui suit vient de
# https://blog.adminrezo.fr/2016/12/securiser-serveur-apache-https-headers/
# Contrôler l’accès des bots de facon plus fine qu'avec robots.txt :
Header set X-Robots-Tag "index,follow,noarchive"
# Évite que le contenu soit interprété différemment que définit dans le mime Type
Header set X-Content-Type-Options nosniff
# Protection contre le clickjacking
Header set X-Frame-Options "SAMEORIGIN"
# Protection contre les failles X-XSS
Header set X-XSS-Protection "1; mode=block"
# Faille spécifique IE8, on espère que plus personne ne l'utilise, mais...
Header set X-Download-Options noopen;
# Interdire l'embarquement de tout ou partie de votre site dans un site ou logiciel tiers 
Header set X-Permitted-Cross-Domain-Policies none
# X-Clacks, ça sert à rien, c'est donc vital.
header set X-Clacks-Overhead "GNU Terry Pratchett"
# Enfin, les CSP permettent de vérifier l'origine des éléments du site
# CSP, pour éviter de charger des scripts d'ailleurs. /!\ partie complexe à gérer suivant vos CMS
Header set Content-Security-Policy "default-src 'self' *.monsite.org 'unsafe-eval' 'unsafe-inline' "

Les explications :

Content Security Policy (CSP)

Les CSP améliorent grandement la sécurité d'une installation, en interdisant à certaines ressources de s'exécuter, par exemple des scripts malicieux injectés dans vos sites webs.

Mais il est difficile de faire marcher les CMS tout en ayant une politique sécurisée sur les CSP.

Le site de référence est https://content-security-policy.com/. En anglais, mais il contient toute la documentation officielle sur le sujet.

  • Premier cas : pas de politique CSP. Certains CMS permettent aux utilisateurs d'appeler “des bouts de web” venant d'ailleurs, généralement les images, mais dans certains cas aussi du code… Un attaquant peut se servir de ça pour appeler sur le serveur un code malicieux. Un CMS sécurisé réduit beaucoup les possibilités, mais le risque zéro n'existe pas, et la plupart des CMS ont des failles, c'est un fait.
  • Second cas : une politique CSP stricte (paramétrée uniquement sur self). Ici, plus moyen d'appeler un truc d'ailleurs. Par contre cela va bloquer le fonctionnement légitime de certains CMS, entre autre ce qui concerne les scripts (pourquoi, je n'ai pas pas encore bien compris, mais c'est un fait).
  • Troisième cas : ajouter des règles comme unsafe-eval et unsafe-inline. Cela va permettre aux scripts en question de fonctionner MAIS cela permet aussi à certains attaquant d'utiliser des failles : comme leur nom l'indique, cela est considéré comme “non sécurisé”. Ils autorisent explicitement certains trucs à marcher, sans plus de vérification. Cela ouvre la porte à des injections. Cependant, d'après mes tests, les scripts ayant une adresse externe ne sont PAS exécutés sur le domaine. Ne vous sentez pas en confiance pour autant.
  • Quatrième cas : exécuter localement uniquement les scripts validés explicitement. Cela demande de rajouter la variable nonce ou hash, puis d'ajouter dans chacun des scripts de notre serveur la clé associée (un hash sur les scripts, ou bien une clé dans ces derniers). Cela veut donc dire : avoir la main sur tout… c'est assez irréaliste dans la majorité des cas, et entre autre pour les CMS qui embarquent trop de scripts et qui écraseront nos modifications à chaque mise à jour. Cela demande aussi un certain niveau de développement, or la plupart des sysadmin/webmestres sont surtout des bidouilleuses, pas des développeuses.
Quelques exemples

L'option suivante permet à Dokuwiki et Simple Machine Forum de marcher, mais pas à Etherpad, et ne vaut rien aux yeux de l'Observatoire Mozilla. Cependant, même l'etherpad de Mozilla ne fait pas mieux.

Header set Content-Security-Policy "default-src 'self' *khaganat.net; script-src 'self' 'unsafe-inline' *khaganat.net; style-src 'self' 'unsafe-inline'; img-src * "

img-src * ici accepte tout, mais sans ça, on n'affiche plus les images en lien, par exemple dans le forum, ce qui demande une solution interne pour les héberger.

Pour onlyoffice, après de nombreuses galères : la solution a été la CSP frame-ancestors pour permettre l'accès à une autre instance Onlyoffice par plusieurs instances nextcloud. Dans ce cas sur nginx avec le module more_headers, ça a donné ça :

more_set_headers "Content-Security-Policy : frame-ancestors https://site1.example.com/nextcloud https://site2.example.com/ https://site3.example.com/nextcloud ";

La règle suivante, assez générique, va “fonctionner” pour la plupart des CMS. La mettre dans une règle sur le proxy, appelée par les diverses configurations :

add_header Content-Security-Policy "default-src 'self' *.monsite.org 'unsafe-eval' 'unsafe-inline'; ";

Activer la réécriture des URLs

Pour la ferme de wiki ou le pastebin (entre autre), il faut activer la réécriture des URLs.

Lancez la commande :

sudo a2enmod rewrite

Dans les vhosts (/etc/apache2/sites-available/monsite-ssl.conf), mettez l'option AllowOverride sur All là où il y a besoin de réécriture d'url. Généralement, tout le dossier /var/www pour pas se compliquer la tâche.

txt /etc/apache2/sites-available/monsite-org-ssl.conf
<VirtualHost *:443>
    ServerName monsite.org
    DocumentRoot /var/www/monsite

        <Directory /var/www/monsite/ >
                Options Indexes FollowSymLinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all
        </Directory>
    [...]
</VirtualHost>

Options lorsqu'un proxy est actif

Le proxy permet d'avoir un intermédiaire qui relaie les requêtes aux serveurs cibles. Typiquement quand on a une seule ipv4 et des VM sur le réseau interne, c'est un peu obligé ; mais cela peut aussi s'appliquer dans d'autres cas, par exemple pour faire du load balancing, de la mise en cache, pour des aspects de sécurité, etc.

Il faut bien activer les modules apache correspondants :

a2enmod proxy
a2enmod proxy_http

Les arguments proxy

  • ProxyPass indique qu’Apache redirige toutes les requêtes du nom de domaine renseigné avec ServerName vers l'adresse ip et le port du serveur cible.
    • ProxyPass [path] [url] [key=value …], par exemple ProxyPass / http://backend_server:8080/
    • path peut être un chemin, par exemple /app ; dans ce cas seules les requêtes à http://example.org/app seront redirigées vers le serveur backend.
    • les key=value peuvent être retry, timeout, etc.
  • ProxyPassReverse ajuste les en-têtes HTTP (Location, Content-Location et URI) pour que les liens dans les réponses du serveur backend soient corrects pour le client.
  • ProxyPreserveHost permet de contrôler si le serveur Apache transmet l'en-tête Host d'origine du client au serveur backend. Si c'est sur On, on aura donc l'ip/le domaine du visiteur disponible sur le serveur backend dans les logs, sinon l'ip/le domaine du proxy. C'est plutôt utile sur la modération.
    • ProxyPreserveHost On
  • ProxyPassMatch est similaire à ProxyPass, mais permet d'utiliser des expressions régulières pour définir les chemins à rediriger. Puissant mais pas toujours évident.
  • ProxyErrorOverride force Apache sur le proxy à renvoyer ses propres pages d'erreur au lieu de celles du serveur backend
    • ProxyErrorOverride On
  • ProxyVia permet d'ajouter des en-têtes Via aux requêtes traitées par un serveur proxy. Utile au débogage mais a un impact sur la confidentialité (permet à des tiers de savoir qu'il y a un proxy).
  • ProxyRequests : permet (ou non) au serveur de servir de proxy à des clients externes.
    • On : proxy ouvert, ce qui peut poser des soucis de sécurité, il faut bien paramétrer <Proxy *> ensuite. En dehors de cas d'usages très spécifique, à éviter.
    • Off : mettez ça par défaut.

Les options concernant le cache et les buffers (absolument dispensable) :

  • ProxyTimeout définit le temps d'attente maximum pour une connexion vers le serveur backend. Utile pour éviter les temps d'attente trop longs si le backend est lent.
  • ProxyReceiveBufferSize configure la taille du buffer de réception (des histoires de cache).
  • ProxyIOBufferSize contrôle la taille des buffers d'entrée/sortie.

Load Balancing (voir plus bas pour un exemple plus concret) :

  • BalancerMember : adresses des serveurs qui serviront à répartir la charge
  • ProxySet pour configurer des paramètres supplémentaires (timeout, retry, status, etc)
    • lbmethod=byrequests distribue les requêtes équitablement entre les serveurs
    • status=+H indique l’hôte principal

Sur le serveur même : servir un port particulier

Certains services sont accessibles via des ports particuliers. C'est ce que fait Etherpad par exemple : lors de son installation, il est accessible à l'adresse https://monserveur.org:9001.

Pour qu'on puisse y accéder via l'adresse web https://monserveur.org/pad, il faut mettre un proxy en place dans Apache.

Commencer par activer les modules de proxy :

sudo a2enmod proxy proxy_http

Puis ajouter ce genre d'information dans /etc/apache2/sites-availables/monsite.conf :

<VirtualHost *:443>
[...]

  ProxyVia On
  ProxyRequests Off
  ProxyPass /pad/ http://localhost:9001/
  ProxyPassReverse /pad/ http://localhost:9001/
  ProxyPreserveHost on
  <Proxy *>
    Options FollowSymLinks MultiViews
    AllowOverride All
    Order allow,deny
    allow from all
  </Proxy>
  
[...]
</VirtualHost>

Relancez le service apache

sudo apachectl -t && sudo apachectl graceful

Votre etherpad devrait être accessible à la bonne adresse !

Un serveur pare-feu et d'autres derrière

Dans certaines architectures (et entre autre chez Khaganat), nous fonctionnons avec un pare-feu. Toute communication entrante arrive au même endroit, est filtrée, puis redistribuée à diverses VM/containers afin d'isoler les services suivant leurs contraintes.

Dans ce cas, chaque vhost sur le serveur du pare-feu doit contenir ceci :

ServerName sousdomaine.monserveur.net

# Proxy : permet de renvoyer vers l'adresse ip du serveur. 
# Ici l'exemple est dans le cas de VM Xen, c'est donc une adresse locale.
ProxyPass / http://192.168.20.43/
ProxyPassReverse / http://192.168.20.43/

ProxyRequests off
ProxyPreserveHost on
                <Proxy *>
                Options FollowSymLinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all
                </Proxy>

# SSL
    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/monsite.org/certificate.pem
    SSLCertificateFile /etc/letsencrypt/live/monsite.org/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/monsite.org/privkey.pem

# HSTS (mod_headers requis) (15768000 seconds = 6 months)(63072000 = 24 mois)
Header set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"

HSTS (module Header) permet de déclarer au client directement dans la réponse HTTP qu'il faut communiquer en HTTPS. Cet en-tête permet d'éviter le vol de cookies et le downgrade SSL.

# Le paramètre suivant est valide si vous avez amélioré la clé Diffie Hellman
SSLDHParametersFile /etc/letsencrypt/live/MONSITE.COM/dhparams.pem

Je n'ai sans doute pas tout compris, ou alors ce n'est pas compatible avec ma version d'apache, mais si je l'ajoute ça me fait une erreur.

zatalyz 2017/01/01 18:33

Faire suivre les IP derrière les reverse proxy

Si vous avez une VM (A) qui sert de pare-feu avant de redistribuer le trafic aux autres VM (B) de votre serveur, il y a un petit souci : les VM B croient que tout le trafic vient de l'ip de la VM A. Ce qui pose un gros souci dans le cas où vous avez du spam et que votre CMS favori permet de bannir par IP… si vous bannissez la VM A, plus rien ne passera, même les utilisateurs légitimes.

Il faut donc activer le transfert des IP sur les VMs destinataires (pas toucher au pare-feu, ce n'est pas là que ça se joue).

Créer /etc/apache2/conf-available/remoteip.conf et lui donner ceci :

RemoteIPHeader X-Forwarded-For
RemoteIPInternalProxy 192.168.20.35

Remplacer 192.168.20.35 par l'IP interne de la VM pare-feu.

Activer le module remoteip qui fait ça :

a2enmod remoteip
a2enconf remoteip
apache2ctl configtest && service apache2 restart

Cela devrait marcher. À répeter sur chaque VM du réseau.

Load balancing

C'est utile pour les services critiques ou fortement sollicités. Je met la doc ici mais nous n'avons pas (encore) eu l'occasion de vraiment essayer ça.

Un fichier de conf sur le proxy ressemblera à ceci :

<VirtualHost *:80>
    ServerName example.org

    # Proxy vers un backend principal avec timeout
    ProxyPass /app http://backend_server/app retry=5 timeout=60
    ProxyPassReverse /app http://backend_server/app

    # Configuration d'un cluster de load balancing
    <Proxy balancer://mycluster>
        BalancerMember http://backend1.example.org
        BalancerMember http://backend2.example.org status=+H
        ProxySet lbmethod=byrequests
    </Proxy>

    ProxyPass /cluster balancer://mycluster/
    ProxyPassReverse /cluster balancer://mycluster/
    
    # Ajustement des en-têtes
    ProxyPreserveHost On
    ProxyErrorOverride On
</VirtualHost>

Lorsqu'une visiteuse arrive sur example.org, elle est renvoyée aléatoirement vers le serveur backend1 ou backend2, afin d'éviter de surcharger. retry=5 pour la directive ProxyPass indique qu'Apache essaiera jusqu'à cinq fois de se reconnecter au serveur backend, et s'arrêtera après 60 secondes à chercher (ce qui est long !).

Configuration personnalisées

On peut se faire un fichier de configuration appelant diverses modifs sur tous les sites, par exemple dans /etc/apache2/conf-available/bidouilles.conf.

Ensuite on peut l'appeler dans chaque config de site en ajoutant la ligne suivante (dans /etc/apache2/sites-enabled/monsite-ssl.conf, entre les balises VirtualHost) :

Include /etc/apache2/conf-available/bidouilles.conf

Cela évite de réécrire les mêmes règles partout.

Virer le tracker de Facebook

Facebook changeant régulièrement ses règles, vérifiez que cette bidouille est toujours pertinente.

Quand on partage un lien sur Facebook, et qu'on arrive sur le site, Facebook fait de l'injection pour suivre ses internautes. Vos visiteurs vont visiter vos pages avec un tracker collé à l'url, du type https://monsite.org/?fbclid=IwAR1RNFCx5Gu9SHRAbuj67ebqbu3Hc7YGgkOKh. C'est pas propre, et puis ça peut mettre le bazar dans certains sites.

On peut régler ça au niveau d'Apache et mettre Facebook dehors, en ajoutant cela dans un fichier de conf (par exemple dans /etc/apache2/conf-available/bidouilles.conf comme expliqué juste avant) :

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{QUERY_STRING} ^(.*)(?:^|&)fbclid=(?:[^&]*)((?:&|$).*)$ [NC]
  RewriteCond %1%2 (^|&)([^&].*|$)
  RewriteRule ^(.*) $1?%2 [R=301,L]
</IfModule>

Il faut bien sûr avoir le module rewrite activé.

Relancez apache ;)

Astuce tirée de ce site avec quelques aménagements.

Could not reliably determine the server's fully qualified domain name

À chaque modif du serveur, vous avez sans doute droit à ce message d'erreur :

apache2: Could not reliably determine the server's fully qualified domain name, using [IP]. Set the 'ServerName' directive globally to suppress this message

On va donc configurer ça… juste pour ne pas avoir ce message. Nos sites sont configurés par ailleurs, donc cette demande a peu de sens ; on peut l'ignorer, on peut aussi la supprimer. On va créer un fichier de conf globale pour ça !

sudo nano /etc/apache2/conf-available/full-qualified-domain-name.conf

Ajoutez uniquement la ligne suivante (sans rien changer) :

ServerName localhost

Puis activez tout cela :

sudo a2enconf full-qualified-domain-name
sudo apachectl graceful

Et voilà.

Liens utiles

1)
oui, notre utilisateur test s'appelle “Lambda”.
CC Attribution-Share Alike 4.0 International Driven by DokuWiki
fr/apache.txt · Dernière modification : 2024/10/26 15:22 de zatalyz

Licences Mentions légales Accueil du site Contact