Installer et optimiser Apache2

Apache2 c’est un peu le dinosaure du web. Le serveur de la fondation du même nom n’a plus à être présenté. Moderne, hyper configurable, puissant, quoi qu’on en dise, il reste un incontournable et répond à la plupart des besoins. Voyons tout de même en détail comme l’installer et l’optimiser.

Mesdames, Messieurs, oui, j’ai bien dit l’optimiser. On a l’habitude d’installer Apache avec un simple coup d’apt-get et puis s’en vont. Or s’il est vrai que la configuration par défaut suffit à bien des usages, il ne fait aucun mystère qu’une config plus fine apportera sécurité, rapidité et scalabilité.

Installation

Toutes les commandes exécutées ci-après sont exécutées en root. Pensez donc à passer en root avec sudo su ou à faire précéder vos commandes de sudo.

Le serveur Apache est bien entendu disponible dans les dépôts de Débian et d’Ubuntu. Pour l’installer, nous pouvons nous contenter d’un :

apt-get install apache2

Cependant, si l’on veut profiter des dernières fonctionnalités, telle que le http2, il va falloir installer une version plus moderne que celle proposée dans les dépôts.

add-apt-repository ppa:ondrej/apache2
apt-get update
apt-get install apache2

On a ici au préalable ajouté un depôt « ppa » non officiel contenant les dernières versions d’Apache. Ce dernier dépôt est maintenu par le mainteneur de PHP des dépôts Debian. On peut donc s’y fier sans trop de craintes. Je n’ai pas vérifié, mais ça marche normalement aussi sur Debian.

C’est tout pour l’installation. Entrez maintenant l’adresse ip de votre serveur dans un navigateur, si tout s’est bien déroulé, vous devriez obtenir ce message :

It works!

This is the default web page for this server.

The web server software is running but no content has been added, yet.

Le dossier dans lequel se trouvent les fichiers HTML par défaut se situe dans /var/www et le texte que vous venez de lire est tout simplement ce qui est contenu dans /var/www/index.html.

Configuration

Bien qu’on puisse utiliser apache out of the box, en plaçant simplement nos fichiers html dans le dossier www, nous allons explorer les options de configuration les plus courantes.

Les modules complémentaires

Selon les besoins de votre site, il vous faudra peut-être activer des modules supplémentaires. Par exemple, si vous utilisez l’URL-rewriting, il faudra activer le module mod_rewrite :

a2enmod rewrite
Enabling module rewrite.
To activate the new configuration, you need to run:
  service apache2 restart

Il nous est dit qu’il faut redémarrer le serveur : To activate the new configuration, you need to run: service apache2 restart. Alors redémarrez-le.

Apache possède de très nombreux modules qui viennent élargir ses fonctionnalités. Vous trouverez sur le site officiel la liste de tous les modules disponibles.

Puisque nous parlons des modules, nous allons aussi en désinstaller quelques uns dont nous n’avons pas l’utilité. Une bonne politique dans la gestion d’un serveur est que tout ce qui ne sert pas peut être désactivé et supprimé. D’une part ceci nous permet d’économiser des ressources (les modules d’apache prennent de la place en mémoire), d’autre part, ce sont autant de failles potentielles que l’on supprime.

En ce qui me concerne, je ne vire que le mod CGI (et il sera utile pour ceux utilisant PHP-FMP), la plupart de ceux pre-activés servent souvent.

Vous utiliserez pour désactiver les mods la commande a2dismod suivi du nom du mode à désactiver. Ex : a2dismod autoindex. Il peut être judicieux de ne pas tous les supprimer d’un coup et de tester après chaque désactivation si tout marche bien. Vous pouvez aussi utiliser la commande apache2ctl configtest qui vérifie la syntaxe de vos fichiers de config. Ça peut s’avérer intéressant si par exemple vous désactivez un mod dont vous avez besoin et auquel vous faites appel dans vos fichiers dans /etc/apache2/sites-enabled.

Note : je dis supprimer, mais n’allez pas supprimer ensuite le fichier du module, ça ne sert à rien pour le peu d’espace que vous allez gagner, et si vous en avez besoin pour une raison x ou y plus tard, vous serez content de n’avoir qu’à le réactiver.

Au besoin, vous trouverez dans mon article regroupant les commandes Linux les plus utiles, une partie web qui reprend l’ensemble des commandes Apache utiles.

Par ailleurs, si vous souhaitez exécuter du php, il va falloir installer le paquet du même nom. Sans lui, notre serveur Apache servira vos fichiers de code php tels quels. Admettons le, c’est moyen…

deflate pour les performances

Petite digression concernant deflate. Ce module, activé par défaut, permet de compresser avec gzip ou deflate – of course – les fichiers servis par Apache. Dans 99% du temps vous n’avez rien à faire. Cependant, il y a un type de media non compressé par défaut et qui peut pourtant avantageusement en profiter, il s’agit des images svg.

Pour permettre à Apache de les configurer à la volée, rendez-vous dans le fichier de configuration dudit module : /etc/apache2/deflate.conf

<IfModule mod_deflate.c>
        <IfModule mod_filter.c>
                # these are known to be safe with MSIE 6
                AddOutputFilterByType DEFLATE text/html text/plain text/xml

                # everything else may cause problems with MSIE 6
                AddOutputFilterByType DEFLATE text/css
                AddOutputFilterByType DEFLATE application/x-javascript application/javascript applic$
                AddOutputFilterByType DEFLATE application/rss+xml
                AddOutputFilterByType DEFLATE application/xml

                # j'ai ici ajouté le type MIME du svg
                AddOutputFilterByType DEFLATE image/svg+xml
        </IfModule>
</IfModule>

On recharge ensuite la configuration avec un savant coup de service apache2 reload et en voiture Simone !

Création des VirtualHosts

L’hébergement virtuel (virtual hosting) est une méthode que les serveurs tels que serveurs Web utilisent pour accueillir plus d’un nom de domaine sur le même ordinateur, parfois sur la même adresse IP.

Wikipedia

Vous pouvez grâce à cette technique, héberger plusieurs sites sur le même serveur apache. Attention cependant, pour qu’apache puisse savoir vers quel site il doit vous rediriger, il faut que vous y accédiez via un nom de domaine, c’est grâce à ce dernier qu’il sera en mesure de vous présenter le bon site. Ceci ne marchera donc pas si vous entrez directement l’adresse ip du serveur dans votre navigateur. Néanmoins, pour les besoins de tests, vous pouvez modifier votre fichier hosts pour simuler une résolution DNS.

Nous allons créer un fichier dans /etc/apache2/sites-available pour configurer notre site.

nano mon_site
******************
# Apache doit écouter sur le port 80 (http)
<VirtualHost *:80>
    # nom d'hôte que le serveur utilise
    ServerName buzut.fr
        
    # noms alternatifs que le serveur utilise pour servir le même contenu
    ServerAlias www.buzut.fr blog.buzut.fr
       
    # email de contact de l'administrateur
    ServerAdmin adresse@mail.com

    # endroit par défaut où le contenu à servir va se trouver
    DocumentRoot /var/www/
       
    # instructions par défaut qui s'appliquent à la racine 
    # ainsi qu'à tous les fichiers et dossiers descendants 
    <Directory />
        AllowOverride None
        Order deny,allow
        deny from all
    </Directory>

    # les règles ci-dessus sont redéfinies par les suivantes
    # on peut donc respécifier les règles pour différentes parties du site
    # ces nouvelles règles viennent donc écraser les précédentes pour le dossier concerné
    <Directory /var/www/>
        # interdiction de lister les fichiers dossier 
        # au cas où pas de page index présente
        # suivre les liens symboliques (gain de performance)
        Options -Indexes +FollowSymLinks

        # .htaccess peut redéfinir ces paramètres [All|None]
        # on gagne en performance à mettre à none
        # on perd néanmoins en souplesse de configuration 
        AllowOverride None

        # on précise que tous les utilisateurs ont accès au dossier web
        # ainsi, en cas de maintenance, on peut s'autoriser uniquement soi même
        Order allow,deny
        Allow from all
    </Directory>
</VirtualHost>

Le VirtualHost par défaut est configuré pour répondre à toutes les requêtes sur le port 80 : *:80.

Néanmoins, cela ne signifie pas que ce VirtualHost gère toutes les requêtes vers ce serveur sur ce port. Apache utilise le VirtualHost le plus spécifique correspondant à une requête pour y répondre. Pour configurer un autre VHost, il suffit de spécifier un autre bloc avec un ServerName différent. D’ailleurs, si vous n’avez qu’un VHost, ou pour en utiliser un par défaut, vous pouvez tout à fait omettre la directive ServerName.

Vous mettrez ensuite vos instructions concernant les répertoires entre les balises Directory, exactement de la même manière que nous l’avons vu dans l’exemple plus haut.

SSL/TLS et HTTP/2

SSL/TLS, je ne pense pas avoir besoin de l’expliquer. Mais HTTP/2, qu’est-ce que c’est ? Tout simplement la dernière version du protocole de la norme HTTP. Cette version apporte de nombreux avantages dont un sérieux gain en performances.

Réduction de la latence pour améliorer les temps de chargement des navigateurs web notamment via :

  • la compression de données des en-têtes HTTP
  • le nouveau mécanisme de push de HTTP/2 permettant au serveur d’envoyer au client des données nécessaires mais qu’il n’a pourtant pas encore sollicitées
  • le nouveau mécanisme de pipelining des requêtes, rapprochable à ce qui se fait pour les processeurs
  • Résolution de problèmes propres à HTTP 1.x (voir HTTP pipelining ou head-of-line blocking)
  • Multiplexage de plusieurs requêtes au travers d’une seule connexion TCP
Wikipedia

HTTP/2 ne fonctionne qu’en TLS. De toute façon, avec l’émergence de Let’s Encrypt et ses certificats TLS gratuits, nous n’avons plus aucune excuse pour ne pas offrir une connexion sécurisée à nos sites.

Pour installer un certificat Let’s encrypt, je vous laisse entre les mains de la doc officielle.

Vous voilà en possession de vos certificats, voyons donc à quoi ressemble notre VHost TLS et HTTP/2.

# on redirige le http vers le https
<VirtualHost buzut.fr:80>
    ServerName buzut.fr
    ServerAdmin adresse@mail.com
    Redirect permanent / https://buzut.fr/
</VirtualHost>

<VirtualHost buzut.fr:443>
    # on active le http/2 avec fallback vers le http/1.1
    # tous les navigateurs ne sont pas compatibles
    Protocols h2 http/1.1
    ServerName buzut.fr

    ServerAdmin adresse@mail.com
    DocumentRoot /var/www/buzut

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    # on active le ssl/tls et on renseigne les certificats
    # ce sont ici les paths spécifiques à let's encrypt
    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/buzut.fr/cert.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/buzut.fr/privkey.pem
    SSLCertificateChainFile /etc/letsencrypt/live/buzut.fr/chain.pem

    # on active HSTS pour 6 mois pour le domaine et les sous-domaines
    # on autorise aussi l'ajout du site dans les listes pre-chargées
    Header always set Strict-Transport-Security "max-age=15768000; includeSubDomains; preload"
</VirtualHost>

Si vous souhaitez en savoir plus sur le HSTS, je vous laisse avec l’article Wikipedia qui est bien détaillé.

Les fichiers de log

Par défaut, apache écrits ses logs dans /var/log/apache2. Il y a trois fichiers distincts :

  • Le error.log, qui regroupe toutes les erreurs de apache ainsi que de ces modules (c’est donc là que vous retrouverez par exemple les erreurs de php),
  • L’access.log, qui regroupe les logs d’accès au serveur principal,
  • Le other_vhosts_access.log, qui logue les accès des autres VHosts.

En réalité, la définition du fichier de log des accès se fait dans le VHost. Si vous voulez écrire vos logs dans le access.log au lieu du other_vhosts_access.log, ou même définir vous-même le nom de fichier de log, il va vous falloir rajouter une ligne dans le VHost.

CustomLog ${APACHE_LOG_DIR}/access.log combined

Vous pouvez remplacer access.log par le nom qui vous plaît si vous voulez en changer. Quant à combined, cela concerne le format des logs. Pour en savoir plus à ce sujet, je vous invite à aller consulter la doc.

Petit point de détail cependant, si vous ne spécifiez pas explicitement le access.log dans votre VHost, les logs iront automatiquement dans other_vhosts_access.log. Ce comportement peut ne pas convenir.

Nous pourrions par exemple vouloir ne pas activer les logs d’accès (pour des questions de performances par exemple). Dans ce cas, il va falloir désactiver une configuration. Laissez-moi donc introduire la commande a2disconf. Vous l’aurez deviné, elle va de paire avec a2enconf. Pour désactiver le other_vhosts_access.log, il faut donc exécuter :

a2disconf other-vhosts-access-log

Enfin, pour activer ce petit VHost, nous allons désactiver le site default, et activer le notre. Pour se faire, nous allons utiliser deux commandes :

  • a2dissite, qui permet de désactiver un vhost,
  • a2ensite, qui, à l’inverse, permet de les activer.
a2dissite default
Site default disabled.
To activate the new configuration, you need to run:
  service apache2 reload

a2ensite mon_site
Enabling site default.
To activate the new configuration, you need to run:
  service apache2 reload

service apache2 reload
 * Reloading web server config apache2
   ...done.

Le serveur nous spécifie la commande à effectuer pour que les modifications soient prisent en compte. Il n’est pas ici nécessaire de redémarrer apache, un simple rechargement avec la commande service apache2 reload suffit.

Sécurité

Le fichier de configuration security

Il existe un fichier de configuration relatif à la sécurité d’apache : /etc/apache2/conf-available/security. Les réglages qu’il apporte ne sont en réalité pas déterminants pour la sécurité de notre serveur. Voyons néanmoins les paramètres qu’il contient :

  • ServerTokens : Envoi des informations relative à l’OS et la version d’apache dans l’en-tête serveur,
  • ServerSignature : Donne des informations en bas de pages créées par le serveur (page d’erreur, 404 etc),
  • TraceEnable : La méthode TRACE est réservée pour le débogage.

On va donc placer ServerTokens à Prod, ServerSignature à Off et TraceEnable à Off. C’est tout pour ce fichier.

Empêcher de parcourir les fichiers

Au niveau de la configuration de votre site, il est prudent de préciser quelques paramètres concernant la racine de fichiers :

<VirtualHost *:80>
    ServerAdmin contact@monsite.fr
    DocumentRoot /var/www

    <Directory />
        # empêche un fichier .htaccess de redéfinir ces paramètres
    	AllowOverride None

        # empêche de parcourir le syteme de fichiers
        # il faudra donc bien placer cette directive à allow 
        # dans le(s) répertoire(s) contenant votre/vos site(s) 
	Order allow,deny
        deny from all
    </Directory>

    <Directory /var/www/monsite/>
        …
    </directory>
</VirtualHost>

Les modules complémentaires relatifs à la sécurité

Parmi les modules d’apache, certains permettent d’améliorer la sécurité. Je n’expliquerai pas ici leur fonctionnement, parce que cela nécessiterait un article complet, mais je vais vous donner les liens qui vont bien.

Pour ma part, je ne les utilise pas. Vous pouvez installer fail2ban pour améliorer la sécurité de votre serveur. Le pare-feu iptables, vous permet de bien vous prémunir contre les attaques DDoS.

Optimisation des performances

On parle beaucoup de Nginx dès lors que l’on mentionne les performances dans le web. Je dédis d’ailleurs moi même un article à ce sujet. Cependant, Apache reste un serveur extraordinaire et qui sait se montrer très performant.

On commence rapidement par vérifier quel est le module MPM utilisé, à savoir, prefork ou worker. Si vous avez installé sans compiler, ne cherchez pas plus loin, par défaut, vous être en prefork.

# affiche les modules disponibles
apache2ctl -M 

Nous ne traiterons ici pas des réglages spécifiques au MPM worker. Sachez juste que prefork est aussi performant tout en consommant un peu plus de RAM que worker. Il est également légèrement plus stable.

Parmi les optimisations que nous allons aborder, la plupart se trouvent dans /etc/apache2/apache2.conf ou httpd.conf sur Debian. En revanche, celles qui s’appliquent au module MPM se trouvent directement dans le fichier de conf du module, /etc/apache2/mods-enabled/mpm_prefork.conf pour le MPM prefork.

MaxRequestWorkers

Permet de déterminer le nombre maximal de requêtes pouvant être traitées simultanément. Au delà, toutes les requêtes iront dans une file d’attente. Pour le prefork, cela correspond au nombre maximum de processus enfants qui pourront être lancés. Pensez que cette valeur est limitée par ServerLimit. Il vous faudra donc l’augmenter si vous voulez fixer un nombre de worker plus grands.

Enfin, pour calculez cela, c’est assez simple : (RAM totale – RAM utilisée par les autres processus) / taille moyenne d’un processus Apache. Munissez-vous de top et ps aux pour cette mission ! Et si vous être vraiment des gros flemmards, j’ai la formule magique qu’il vous faut pour calculer le poids moyen d’un process Apache :

# grep apache pour Ubuntu / grep httpd pour Debian
ps aux | grep apache | awk '{print $6/1024;}' | awk '{avg += ($1 - avg) / NR;} END {print avg " MB";}'
38.1419 MB
MaxConnectionsPerChild

Fixé par défaut à 0 (infini), cette directive permet de faire « mourir » un processus après qu’il ait servit un certain nombre de requêtes. Cela peut-être intéressant dans le cas de fuites mémoires. Par exemple, avec PHP, si les processus ont tendances à avoir une emprunte mémoire qui grossit indéfiniment, on pourra les limiter à un certain nombre de requêtes et un nouveau prendra la relève. Comme la création de nouveaux processus consomme du CPU, il s’agit de trouver le juste équilibre.

StartServers

Cette directive, qu’on utilise en général conjointement avec MinSpareServers et MaxSpareServers, spécifie le nombre de processus enfants qu’Apache doit lancer au démarrage.

La création et l’arrêt de processus est dynamique. Cependant, dans le cas de sites à très fort trafic, il peut être judicieux de démarrer directement avec de nombreux processus pour pouvoir affronter la charge sans un temps de warm up. Aussi, on jouera avec les directives (min|max)SpareServers afin de :

  • toujours avoir un minimum de processus enfants prêts à réceptionner des requêtes,
  • ne pas tuer des processus lors d’une baisse momentannée de trafic alors qu’une autre vague risque d’arriver, obligeant une couteuse opération de killing/re-creation.
KeepAlive & KeepAliveTimeout

Cette option offerte par le HTTP/1.1 permet de servir plusieurs requêtes dans la même connexion TCP. Ainsi, on garde littéralement ouverte une connexion TCP afin de pouvoir servir de nouvelles requêtes en évitant de perdre du temps en refaisant un handshake TCP. C’est particulièrement utile pour servir tous les assets d’une page sans ouvrir 10000 connexions (typiquement JS, CSS, images).

C’est bien beau tout cela, mais notre petit KeepAlive bousille littéralement la capacité d’Apache de faire face à la charge. On l’a vu, Apache est limité par MaxRequestWorkers, or si on conserve les connexions ouvertes, forcement, on peut moins en servir en même temps…

KeepAlive permet quand même d’améliorer l’expérience utilisateur sur les connexion à forte latence (mobile et connexion géographiquement éloignées Europe/USA par exemple). De même, cela permet d’améliorer les performances dans le cas de polling Ajax.

Néanmoins, l’intérêt baisse quelque peu avec le HTTP/2 car il permet le multiplexache et le pipelining. Faites vos calculs, mais si vous avez un peu de charge, il est conseillé de clairement abaisser les 30 secondes par défaut.

FollowSymLinks

Nous l’avons déjà mentionné plus haut, mais il vaut mieux préciser cette option. En son absence, ou dans le cas où il est explicitement indiqué de ne pas les suivre, Apache devra faire des appels système supplémentaires afin de vérifier si le pointeur est un lien symbolique ou non. De plus, dans la mesure où le résultats ne sont pas mis en cache par Apache, c’est le bingo à chaque requête.

AllowOverride

Nous l’avons déjà mentionné aussi. Cette directive permet d’activer les fichiers .htaccess, grande spécificité de Apache. Ces petits fichiers de configuration permettent une grande souplesse car ils offrent la possibilité de configurer le comportement de sous-répertoires directement depuis ces derniers.

Ainsi, il est possible de laisser les utilisateurs ou les développeurs gérer eux-mêmes le comportement des répertoires dont ils sont responsables (rewriting etc). Dans une équipe où développeurs et administrateurs ont des rôles bien différents, cela laisse plus de latitudes aux développeurs.

Néanmoins, c’est au sacrifice d’un peu de performances puisque Apache devra vérifier dans chaque répertoire le présence ou non d’un fichier de config, et le lire le cas échéant.

DirectoryIndex

Cette directive permet de spécifier le fichier à servir par défaut lors de la requête d’un répertoire. Typiquement la racine d’un site par exemple : buzut.fr et non pas buzut.fr/index.php. Apache sert donc automatiquement index.php lorsqu’on requête ce répertoire.

Il est possible – et on le voit souvent – de ne spécifier que le nom de base sans l’extension index. Cela permet à Apache de servir index.php, index.html, index.pl etc. On gagnera en performance à spécifier les types, et il est possible d’établir une liste. Dans ce cas, les fichiers à gauche seront servis en priorité sur ceux à droite dans la liste.

DirectoryIndex index.php index.html index.pl

Sachant tout cela, après avoir laissé tourner le serveur quelques temps, il peut être judicieux de lancer un script qui analysera la config et différents paramètres afin de vous fournir quelques voies d’optimisations. Le script en question s’appelle apache2buddy et pour le lancer, rien de plus simple :

curl -L http://apache2buddy.pl/ | perl

On en a fini avec la configuration d’apache. Je vous laisse quand même avec la doc officielle (qui est bien conçue et en français), au cas où vous voudriez creuser certains points.

Il n'y a pas encore de commentaire

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *