Table of Contents

Apache

Apache est le plus répandu des serveurs web/HTTP dont les fonctionnalités sont extensibles grâce à un système de modules chargés au besoin.

Les fichiers de configuration diffèrent selon la distribution Linux utilisée : sous Redhat-like le fichier de conf principal est /etc/httpd/httpd.conf, sous Debian-like il est sous /etc/apache2/apache2.conf. Le DocumentRoot par défaut (le répertoire qui contient les pages .html) est /var/www/html, les logs sont rangés, respectivement, dans /var/log/httpd/*.log ou /var/log/apache2/*.log.

Configuration

Dans les versions les plus récentes d'Apache, on dépose les configurations de chaque site web dans un fichier dédié, rangé dans le dossier site-available/ ; lorsqu'on souhaite activer ce site, on créé un lien symbolique de ce dernier dans site-enabled/. Ce lien peut être simplement créer via la commande a2ensite <nom du fichier sans l'extension>, par exemple a2ensite 000-default.

De même pour les modules, avec les dossiers mods-available/ et mods-enabled/, et la commande a2enmod <nom du module>, et plus récemment des bouts de conf déposés dans conf-available/ / conf-enabled/ avec la commande a2enconf.

Exemple de directives de configuration commentées :

Vérifications

Il existe 3 syntaxes pour vérifier la configuration d'Apache :

httpd -t
apachectl -t
# cette commande produit un code de sortie, 0 pour OK et 1 en cas d'erreur (retour = "Syntax OK")
 
# les 2 commandes ci-dessous indique où est l'erreur
apachectl configtest
service httpd configtest
# cette dernière commande est un alias de la commande précédente (sous Redhat)

Virtualhost

Un Virtualhost est un site virtuel ; cela permet à Apache de gérer plusieurs sites webs sur une même machine. On peut grâce à cela avoir un site en HTTP et un en HTTPS par exemple.

Exemple de configuration basique :

NameVirtualHost 192.168.0.1:80
 
<VirtualHost 192.168.0.1:80>
   ServerName    server1
   DocumentRoot  /var/www/server1
   ServerAlias   www.server1
</VirtualHost>
 
<VirtualHost 192.168.0.1:80>
   ServerName    server2
   DocumentRoot  /var/www/server2
   ServerAlias   www.server2 srv2
</VirtualHost>

server1 est accessible par http://server1 et server2 par http://serveur2. Si un client demande http://server (aucun ServerName ni aucun ServerAlias ne correspond) le premier virtualhost listé sera affiché.

Une exception cependant : http://localhost affiche toujours le DocumentRoot global, /var/www/html.

Bien sur, pour être accessibles, les noms et les alias doivent être inscrits dans le DNS.

Droits d'accès

Il est possible de limiter l'accès à certains répertoires de 2 manières :

Quelque soit la manière, la syntaxe reste la même.

On peut surcharger la méthode globale avec un .htaccess situé dans un répertoire ; cette possibilité se configure avec la directive AllowOverride qui permet de définir quelles sont les options que l'on peut surcharger.

<Directory /stuff>
   AllowOverride Authconfig | None
</Directory>

Depuis la version 2.4 d'Apache il est recommandé d'utiliser la directive Require, les directives allow, deny et order étant désormais obsolètes. Des exemples d'utilisation de Require sont listés dans la partie mod_proxy.

Les droits d'accès sont définis principalement par les directives Allow, Deny et Order. Order permet de modifier l'ordre de traitement des 2 directives précédente ; voici la façon dont les vérifications sont traitées (source : doc apache) :

Ordering is one of:

* Allow,Deny : First, all Allow directives are evaluated; at least one must match, or the request is rejected. Next, all Deny directives are evaluated. If any matches, the request is rejected. Last, any requests which do not match an Allow or a Deny directive are denied by default.
* Deny,Allow : First, all Deny directives are evaluated; if any match, the request is denied unless it also matches an Allow directive. Any requests which do not match any Allow or Deny directives are permitted.

Pour être plus clair, voici le tableau de décision d'Apache :

Match Allow,Deny result Deny,Allow result
Match Allow only Request allowed Request allowed
Match Deny only Request denied Request denied
No match Default to second directive: Denied Default to second directive: Allowed
Match both Allow & Deny Final match controls: Denied Final match controls: Allowed

ex d'accès restreint

Création du htpasswd

Le fichier .htpasswd va contenir les correspondace login/hash du mot de passe des utilisateurs valides. Pour cela, on va se servir d'un programme situé dans apache/bin/ nommé htpasswd. Voici la syntaxe :

htpasswd -c <.htpasswd> <login> (sans l'option “-c” si le fichier .htpaswd existe déjà) Le programme demande un mot de passe et de le confirmer, puis ajoutera l'utilisateur ainsi que le mot de passe hashé dans le fichier spécifié.

Méthode globale

<Location "/prive">
   Options        None
   AllowOverride  None
   AuthName       "Accès restreint"
   AuthType       Basic
   AuthUserFile   "/chemin_absolu_vers/.htpasswd"
   AuthGroupFile  "/chemin_absolu_vers/.htgroup"
   Require        valid-user
</Location>

Ces lignes sont à placer soit dans la configuration d'un virtualhost (dans sites-available par exemple) ou dans la configuration globale d'apache, et s'appliqueront au répertoire /prive relatif à la racine de la section (directive DocumentRoot).

Le fichier .htpasswd est modifié par la commande htpasswd comme vu précédemment ; le fichier .htgroup est éditable à la main ; il est structuré ainsi :

# syntaxe : <groupe>: <user1> <user2>
potos: toto titi
papotos: trudi

Explications :

AllowOverride est une directive qui sert à gérer les droits des fichiers .htaccess.

Méthode locale

Les lignes sont les suivantes ; elles doivent être placées dans un fichier .htaccess à déposer directement dans le répertoire à protéger (/prive).

AuthName "accès restreint"
AuthType Basic
AuthUserFile "/chemin_absolu_vers/.htpasswd"
require valid-user

On peut également limiter l'accès par IP :

Order Deny, Allow
Deny from all
Allow from 127.0.0.1 192.168.0

Ceci va limiter l'accès au localhost (127.0.0.1) et le réseau local (192.168.0.0/24)

ex2 : filtrage des accès aux répertoires autres que /

<Directory ~ "/var/www/.+">
 AuthName "Restricted area"
 AuthType Basic
 AuthUserFile "/var/www/private/.htpasswd"
 require valid-user
</Directory>

Proxy / mod_proxy

Ce module permet d'activer la fonctionnalité de serveur mandataire d'Apache. Il nécessite l'activation d'autres mod pour fonctionner correctement :

Activer ceux qu'il faut en fonction des besoins ; dans mon cas :

a2enmod proxy proxy_http proxy_connect headers

Exemple de configuration commentée :

# ref : https://httpd.apache.org/docs/2.4/fr/mod/mod_proxy.html
<IfModule mod_proxy.c>
 
# active la fonctionnalité de mandataire direct
# ne concerne pas les directives ProxyPass (reverse proxy, voir plus bas)
ProxyRequests On
 
<Proxy *>
   AddDefaultCharset off
# on refuse tout par défaut
   Require all denied
# restriction sur un domaine/nom d'hote
# attention cela provoque une double requete DNS + inverse de la part du serveur
#   Require host .rv
# restriction au localhost (127/8, ::1, IP du serveur local)
   Require local
# restriction des IPs clientes au seul LAN
   Require ip 192.168.1
# NB :
# - si des directives doivent être toutes validées (aucune négative et au moins une positive),
#      on encadre par <RequireAll> ... </RequireAll>
# - si au moins l'une doit être positive, on encadre par <RequireAny>
# - si aucune ne doit retourner de résultat positif on utilise <RequireNone>
</Proxy>
 
# ajout automatique du suffixe aux noms d'hôte non qualifiés (redirection)
ProxyDomain ".rv"
# connexion sans mandataire
NoProxy     "192.168.1.0/24" ".rv"
# définit le proxy suivant pour toutes (*) les requêtes
#ProxyRemote * http://next-mandataire:8080
# ProxyRemote ftp ftp://proxy-ftp.exemaple.com:8080
# ProxyRemoteMatch est identique à ceci près que le premier paramètre est une regexpr
 
# Créer un "alias" vers un site distant (~mirroring) / mandataire inverse (reverse proxy) ou passerelle
# ex : http://mon_proxy/pteu/ -> http://pteu.fr/
<Location "/pteu/">
   ProxyPass "http://pteu.fr/"
</Location>
# syntaxe alternative, moins performante si présente en grand nombre :
#ProxyPass "/pteu/" "http://pteu.fr/"
 
# Enable/disable the handling of HTTP/1.1 "Via:" headers.
# ("Full" adds the server version; "Block" removes all outgoing Via: headers)
# Set to one of: Off | On | Full | Block
ProxyVia Off
 
# définit le nombre max de proxys traversés / pour éviter les boucles infinies
ProxyMaxForwards 5
# timeout réponse d'un site destination; par défaut = Timeout = 60s
#ProxyTimeout 60
# préserve l'entête Host: de la requête cliente
#ProxyPreserveHost Off
 
#
# Filtrages destinations
#
# bloquer via nom d'hote, de domaine ou tld
# attention les DNS sont résolus au démarrage d'Apache, ce qui le ralentit si en grand nombre
ProxyBlock ".sex" "example.com"
</IfModule>
 
<IfModule mod_proxy_connect.c>
# controle utilisation de la methode CONNECT sur certains ports seulement
# défaut : AllowCONNECT 443 563
   AllowCONNECT 21 443
</IfModule>

HTTPS / mod_ssl

Pour activer le mod SSL qui permet le chiffrement des données :

a2enmod ssl

mod_rewrite

Le mod_rewrite permet de manipuler les requêtes entrantes du serveur http.

Activation du module Apache :

a2enmod rewrite

Syntaxe

source : https://httpd.apache.org/docs/current/fr/mod/mod_rewrite.html#rewriterule

Exemple de blocage de sites :

<IfModule mod_rewrite.c>
   RewriteCond %{HTTP_HOST} sex.com [NC,OR]
   RewriteCond %{HTTP_HOST} poker.fr [NC,OR]
   RewriteCond %{HTTP_HOST} drugs.com [NC] # pas de OR pour le dernière condition...
   RewriteRule ^(.*)$ - [F,L]
</IfModule>

On enchaine différentes conditions RewriteCond (avec le drapeau NC pour NoCase, insensible à la casse) suivis d'un OU logique (OR), puis on définit la règle RewriteRule qui contient l'action F (envoi une erreur 403 : Forbidden au navigateur) et L (last) pour arrêter le processus de réécriture.

Exemple de mise ne place d'une redirection (permanente=301 par défaut) : ajouter ces lignes dans le fichier de configuration du vhost (/etc/apache2/site-enable/vhost_redir dans mon cas) :

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^(.*)$ http://pteu.fr$1 [R,L]
</IfModule>

Syntaxe : RewriteRule <regex> <url de redirection> [<paramètres>]

dans l'exemple ci-dessus, on redirige tout (^(.*)$) vers pteu.fr, avec un code HTTP 301 (qui correspond à une redirection permanente). On peut préciser une redirection temporaire (code=302) avec :

[..]
RewriteRule ^(.*)$ http://pteu.fr$1 [R=302,L]

Variables utilisables

https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewritecond

Générer un certificat

Sous Redhat :

cd /etc/pki/tls/certs/Makefile
# pour créer uncertificat auto-signé
make testcert
# pour créer un certificat à valider auprès d'une autorité de certification
make certreq

Ensuite on génère le certificat :

apache2-ssl-certificate

Dans certains cas (certaines versions de Debian/Ubuntu) il semble que la commande n'existe plus (bug ?). On peut alors utiliser le paquet ssl-cert :

aptitude install ssl-cert

Le problème du script est qu'il génère un certificat valide 1 mois seulement. Pour changer cela il faut modifier le script make-ssl-cert en ajoutant -days 730 à la ligne suivante (~ ligne 118) :

vi /usr/sbin/make-ssl-cert
openssl req -config $TMPFILE -new -x509 -nodes -out $output -keyout $output -days 730 > /dev/null 2>&1

730 est la durée de validité du certificat, donc 2 ans dans notre cas. Plus d'info sur openssl.

On va maintenant générer le certificat dans /etc/apache2/ssl ; la syntaxe est make-ssl-cert ssleay.cnf nom_du_fichier.pem

mkdir /etc/apache2/ssl
/usr/sbin/make-ssl-cert /usr/share/ssl-cert/ssleay.cnf /etc/apache2/ssl/pteu.hd.free.fr.pem

On peut s'assurer que le fichier /etc/apache2/ssl/pteu.hd.free.fr.pem est bien en permissions 600 (rw pour le root seulement) car il contient la clé privée.

On doit renseigner le certificat dans la config du mod ssl :

vi /etc/apache2/mods-available/ssl.conf
SSLCertificateFile /etc/apache2/ssl/pteu.hd.free.fr.pem

On créé un vhost qui utilisera le SSL :

cp /etc/apache2/sites-available/default /etc/apache2/sites-available/ssl

On active le SSL et on le fait écouter sur le port 443 (port par défaut pour le HTTPS) :

vi /etc/apache2/sites-available/ssl
NameVirtualHost *:443
<VirtualHost *:443>
 [..]
 SSLEngine on
</VirtualHost>

On active ce vhost (cela revient à créer un lien symbolique du fichier de conf dans sites-enabled)

a2ensite ssl

Si on garde le serveur sur le port 80 (HTTP de base, le vhost par défaut) il faut le faire écouter spécifiquement le port 80 :

vi /etc/apache2/sites-available/default
NameVirtualHost *:80
<VirtualHost *:80>
 [..]
</VirtualHost>

Puis il faut que le serveur écoute sur le port 443 (en plus du 80, le cas échéant) :

vi /etc/apache2/ports.conf
Listen 80
Listen 443

Enfin, recharger Apache :

/etc/init.d/apache2 force-reload

Sous Windows

cette partie n'est très certainement plus à jour !

Apache existe en version précompilée pour Windows ; cependant il existe aussi des packs faciles à installer, comme par exemple EasyPHP. NB : Autant EasyPHP est idéal pour le développement, autant il est déconseillé de l'utiliser sur une plate-forme de production.

logo Nous allons nous servir d'EasyPHP, qui est un logiciel regroupant Apache, PHP et MySQL. Il permet une installation et une utilisation facile de ces serveurs de façon à pouvoir tester des pages sans trop de problèmes de configuration. La dernière version est la 1.8 ; elle regroupe :

Vous pouvez la télécharger , c'est un programme gratuit (comme tous ses composants d'ailleurs).

Alors lancez l'installation, et installez tout par défaut. Lancez easyphp.exe, un icône se met dans la barre des taches. Si vous voyez un rond rouge qui clignote, ca marche ! Sinon faites un clique droit dessus/démarrer (il faut parfois répéter cette opération plusieurs fois avant que ca marche :/) Vous pouvez par ailleurs vérifier que les processus apache et mysqld sont bien lancés en faisant un “ctrl alt suppr” et en allant dans l'onglet processus.

Allez dans C:\Program files\EasyPHP1.7\ : c'est le répertoire d'installation par défaut. Voici les différents répertoires présents :

Pour tester si le serveur PHP marche, créez un fichier html, et placez-y ces quelques lignes :

<?php phpinfo(); ?>

Nommez ce fichier test.php et placez-le dans C:\Program files\EasyPHP\www\. Vous pouvez maintenant lancer votre navigateur et taper l'addresse “http://localhost/test.php” (“localhost” désigne votre ordinateur en local ; cela équivaut à l'IP 127.0.0.1). Si pleins d'infos s'affichent, c'est bingo ça marche et ça vaut mieux parce que sinon il va falloir consulter la FAQ officielle !

Vous pouvez arrêter là la manipulation d'EasyPHP pour vous consacrer entièrement à votre site, ou alors lire cet article jusqu'au bout :)

Tapez “http://localhost/home/” dans votre navigateur préféré. Vous tombez sur le fichier “index.php” du répertoire “home” que je vous ai brièvement décrit tout à l'heure. Elle vous permet de :

Bien sur il est possible de modifier tout cela autrement qu'en passant par cette section d'administration : c'est ce que nous allons voir maintenant.

Chaque composant d'EasyPHP a un fichier de configuration spécifique.

Pour modifier la configurations de l'un des serveurs, il suffit d'éditer son fichier de configuration (avec n'importe quel éditeur de texte), de le modifier, et de sauveguarder. (utilisez la fonction rechercher pour trouver les lignes citées ci dessous) NB : dans tous les fichiers suivant, les commentaires sont précédés d'un dièze (#) ATTENTION : il redémarrer les serveurs pour qu'ils prennent en compte la nouvelle configuration (clic droit sur l'icône d'EasyPHP situé dans la barre des taches/Redémarrer)

De l'utilisation d'apache2ctl

Utilisation de l'outil de diagnostique apache2ctl (ou apachectl, c'est un alias pour la “compatibilité ascendante”) :

apachectl -V
Server version: Apache/2.4.29 (Unix)
Server built:   Oct 26 2017 16:18:29
Server's Module Magic Number: 20120211:68
Server loaded:  APR 1.6.2, APR-UTIL 1.6.0
Compiled using: APR 1.6.2, APR-UTIL 1.6.0
Architecture:   64-bit
Server MPM:     worker
  threaded:     yes (fixed thread count)
    forked:     yes (variable process count)
Server compiled with....
 -D APR_HAS_SENDFILE
 -D APR_HAS_MMAP
[..]
apache2ctl -S
VirtualHost configuration:
wildcard NameVirtualHosts and _default_ servers:
*:80                   is a NameVirtualHost
         default server 192.168.1.1 (/etc/apache2/sites-enabled/000-default:1)
         port 80 namevhost 192.168.1.1 (/etc/apache2/sites-enabled/000-default:1)
Syntax OK

Divers

ErrorDocument 404

C'est la page qui s'affiche par défaut lorsqu'on demande au serveur web une page qu'il ne trouve pas. Pour afficher une autre page à la place, modifier votre .htaccess en rajoutant cette ligne :

ErrorDocument 404 /new_404_page.php

Cela marche aussi pour les autres codes d'erreurs.

ServerTokens

ServerTokens Full | OS | Minor | Minimal | Major | Prod

Pour cacher certaines informations sur la version et les extensions d'Apache. Par défaut c'est Full (ça affiche tout) mais on peut être prudent et n'afficher que certaine informations (les valeurs sont dans l'ordre décroissant) ; voici un exemple d'affichage avec mon serveur :

Full

Apache/2.2.9 (Debian) PHP/5.2.6-1+lenny3 with Suhosin-Patch mod_python/3.3.1 Python/2.5.2 mod_ssl/2.2.9 OpenSSL/0.9.8g mod_perl/2.0.4 Perl/v5.10.0

OS

Apache/2.2.9 (Debian) Server at ymir.rv Port 80

Minimal

Apache/2.2.9 Server at ymir.rv Port 80

Minor

Apache/2.2 Server at ymir.rv Port 80

Major

Apache/2 Server at ymir.rv Port 80

Prod

Apache Server at ymir.rv Port 80

ServerSignature

ServerSignature On | Off | EMail

Pour afficher la signature d'Apache (paramétrée avec la directive ServerTokens)en bas d'une page d'erreur (par exemple), ou juste l'email de l'administrateur.

ScriptAlias

Aujourd'hui j'ai décidé de déposer une page HTML (valide) dans un de mes répertoires disponibles sous Apache. Surprise elle me génère une vilaine erreur 500 :

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator, webmaster@localhost and inform them of the time the error occurred, and anything you might have done that may have caused the error.

More information about this error may be available in the server error log.

D'après les logs ça viendrait du fait que Apache veuille exécuter la page, comme s'il s'agissait de CGI !

[Mon Jun 24 21:05:03 2013] [error] [client 192.168.1.1] (13)Permission denied: exec of '/var/www/foo/toto.html' failed
[Mon Jun 24 21:05:03 2013] [error] [client 192.168.1.1] Premature end of script headers: toto.html

Après avoir tourné en rond quelques minutes en regardant si son extension (html) n'était pas préemptée par un module du genre php, le problème était devant le clavier : j'ai vilainement copier/coller le paragraphe des cgi-bin pour déclarer mon nouveau répertoire qui contient mon fichier toto.html :

ScriptAlias /foo "/var/www/foo/"
<Directory "/var/www/foo">
   Options FollowSymLinks
   AllowOverride All
   Order allow,deny
   Allow from 192.168.1
</Directory>

Et oui c'est bien ce fâcheux ScriptAlias (au lieu de Alias tout court) qui indique, à tord, à Apache que le dossier contient des exécutables et non des pages html. Solved.

Liens