blob: d68294f2e96c7eefb82da3035b3a48a7cbe52f5c [file]
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE manualpage SYSTEM "../style/manualpage.dtd">
<?xml-stylesheet type="text/xsl" href="../style/manual.fr.xsl"?>
<!-- English Revision: 1938110:1939369 (outdated) -->
<!-- French translation : Lucien GENTIS -->
<!-- Reviewed by : Vincent Deffontaines -->
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<manualpage metafile="avoid.xml.meta">
<parentdocument href="./">Rewrite</parentdocument>
<title>Quand ne pas utiliser mod_rewrite</title>
<summary>
<p>Ce document est un complément à la <a
href="../mod/mod_rewrite.html">Documentation de référence</a> de
<module>mod_rewrite</module>. Il décrit peut-être un des concepts les
plus importants à propos de <module>mod_rewrite</module> - à savoir, quand doit-on éviter
de l'utiliser.</p>
<p><module>mod_rewrite</module> doit être considéré comme un dernier recours,
lorsqu'aucune alternative n'est possible. Utiliser mod_rewrite lorsqu'il
existe des alternatives plus simples conduit à des configurations
confuses, fragiles, et difficiles à maintenir. La compréhension des
autres alternatives disponibles est une étape très importante sur le
chemin de la maîtrise de <module>mod_rewrite</module>.</p>
<p>Vous devez vous attacher à comprendre le
fonctionnement des exemples, car la plupart d'entre eux ne
fonctionneront pas sur votre système si vous vous contentez de les
copier/coller dans vos fichiers de configuration.</p>
<p>Le cas le plus courant dans lequel <module>mod_rewrite</module> est
l'outil approprié est la situation où la seule solution envisageable
nécessite l'accès aux fichiers de configuration du serveur, alors que
cet accès ne vous est pas accordé. Certaines directives de configuration
ne sont disponibles que dans le fichier de configuration du serveur. Si
vous ne pouvez agir que sur les fichiers .htaccess, vous devrez donc
vous tourner vers <module>mod_rewrite</module>.</p>
</summary>
<seealso><a href="../mod/mod_rewrite.html">Documentation du module mod_rewrite</a></seealso>
<seealso><a href="intro.html">Introduction à mod_rewrite</a></seealso>
<seealso><a href="remapping.html">Redirection et remise en
correspondance</a></seealso>
<seealso><a href="htaccess.html">Réécritures par répertoire</a></seealso>
<seealso><a href="flags.html">Drapeaux de RewriteRule</a></seealso>
<seealso><a href="vhosts.html">Serveurs virtuels</a></seealso>
<seealso><a href="rewritemap.html">Utilisation de RewriteMap</a></seealso>
<seealso><a href="tech.html">Détails techniques</a></seealso>
<section id="redirect">
<title>Redirection simple</title>
<p><module>mod_alias</module> fournit les directives <directive
module="mod_alias">Redirect</directive> et <directive
module="mod_alias">RedirectMatch</directive> qui permettent de
rediriger une URL vers une autre. Plutôt que d'utiliser la directive
<directive module="mod_rewrite">RewriteRule</directive> pour ce genre de
redirection simple d'une URL ou d'une classe d'URLs vers une autre, on
préfèrera l'utilisation de ces directives. En outre, avec
<code>RedirectMatch</code>, vous pouvez inclure une expression
rationnelle dans votre critère de redirection, ce qui vous permet de
bénéficier de nombreux avantages de la directive
<code>RewriteRule</code>.</p>
<p>Une utilisation courante de la directive <code>RewriteRule</code> est
la redirection de toute une classe d'URLs. Par exemple, toutes les URLs
faisant référence au répertoire <code>/un</code> doivent être
redirigées vers <code>http://un.example.com/</code>, ou toutes les
requêtes <code>http</code> doivent être redirigées vers
<code>https</code>.</p>
<p>Pour ce faire, il est préférable d'utiliser la directive
<code>Redirect</code>. Souvenez-vous que la directive
<code>Redirect</code> conserve les informations relatives au chemin. En
d'autres termes, la redirection d'une URL <code>/un</code> va aussi
rediriger toutes les URLs de niveaux inférieurs comme
<code>/un/deux.html</code> et <code>/un/trois/quatre.html</code>.</p>
<p>Pour rediriger les URLs sous <code>/un</code> vers
<code>http://un.example.com/</code>, utilisez cette définition :</p>
<highlight language="config">
Redirect "/one/" "http://one.example.com/"
</highlight>
<p>Pour rediriger un nom d'hôte vers un autre nom d'hôte, par exemple
<code>example.com</code> vers <code>www.example.com</code>, voir la
méthode <a href="remapping.html#canonicalhost">Noms d'hôtes canoniques</a>.</p>
<p>Pour rediriger les URLs <code>http</code> vers <code>https</code>, une
directive <directive module="mod_alias">Redirect</directive> dans un serveur
virtuel HTTP dédié est l’approche la plus propre. Voir la recette <a
href="remapping.html#https-redirect">Forcer HTTPS</a> pour la configuration
recommandée et l’alternative de <module>mod_rewrite</module> pour l’utilisation
des fichiers <code>.htaccess</code>.</p>
<note><title>Ordre de traitement</title>
<p>Si vous mélangez des directives <directive
module="mod_alias">Redirect</directive> et <directive
module="mod_rewrite">RewriteRule</directive> dans le même contexte, sachez
que leur ordre d’exécution dépend de l’emplacement où elles apparaissent.
Dans un contexte de serveur virtuel ou global, c’est
<module>mod_rewrite</module> qui agit en premier, alors que dans un contexte
de répertoire (fichiers <code>.htaccess</code>), c’est
<module>mod_alias</module>. Voir <a href="tech.html#order">Ordre de
traitement des modules</a> pour les détails.</p>
</note>
</section>
<section id="alias"><title>Alias d'URL</title>
<p>La directive <directive module="mod_alias">Alias</directive> permet de mettre
en correspondance un chemin d’URL avec un répertoire, ce dernier étant en
général situé en dehors de l'arborescence définie par la directive <directive
module="core">DocumentRoot</directive>. Bien qu'il soit possible d'effectuer
cette mise en correspondance avec <module>mod_rewrite</module>, il est
préférable d'utiliser la directive <directive
module="mod_alias">Alias</directive> pour des raisons de simplicité et de
performances.</p>
<example><title>Utilisation de la directive Alias</title>
<highlight language="config">
Alias "/cats" "/var/www/virtualhosts/felines/htdocs"
</highlight>
</example>
<p>
Pour effectuer cette mise en correspondance, <module>mod_rewrite</module>
s'impose si vous n'avez pas accès aux fichiers de configuration du
serveur. En effet, la directive Alias ne peut pas être utilisée dans un
fichier <code>.htaccess</code>, mais seulement dans un contexte de
serveur principal ou de serveur virtuel.
</p>
<p>En outre, vous pouvez arriver au même résultat avec les liens
symboliques, pourvu que <code>Options FollowSymLinks</code> soit activé
sur votre serveur.</p>
</section>
<section id="proxy"><title>Mandat simple</title>
<p>La directive <directive module="mod_rewrite">RewriteRule</directive> fournit
le drapeau <a
href="flags.html#flag_p">[P]</a> qui permet de faire passer les URIs
réécrits par <module>mod_proxy</module>.</p>
<highlight language="config">
RewriteRule "^/?images(.*)" "http://serveur-images.local/images$1" [P]
</highlight>
<p>Cependant, dans les nombreux cas où aucune correspondance au modèle
n'est vraiment nécessaire, comme dans l'exemple ci-dessus, il est
préférable d'utiliser la directive <directive
module="mod_proxy">ProxyPass</directive>. L'exemple précédent pourrait
être remplacé par :</p>
<highlight language="config">
ProxyPass "/images/" "http://serveur-images.local/images/"
</highlight>
<p>Que vous utilisiez <directive
module="mod_rewrite">RewriteRule</directive> ou <directive
module="mod_proxy">ProxyPass</directive>, vous devrez dans tous les cas
utiliser aussi la directive <directive
module="mod_proxy">ProxyPassReverse</directive> pour intercepter les
redirections en provenance du serveur d'arrière-plan :</p>
<highlight language="config">
ProxyPassReverse "/images/" "http://serveur-images.local/images/"
</highlight>
<p>Vous devrez cependant tout de même utiliser <code>RewriteRule</code>
lorsque d'autres <code>RewriteRule</code>s se trouvent dans la même portée,
car elles agissent en général avant les directives
<code>ProxyPass</code>, et peuvent ainsi les court-circuiter.</p>
<p><directive module="mod_rewrite">RewriteRule</directive> s’avère vraiment
utile pour ne mandater les requêtes que si le contenu n’existe pas localement
— par exemple, lors de la migration d’un serveur vers un autre :</p>
<highlight language="config">
RewriteCond "%{REQUEST_FILENAME}" !-f
RewriteCond "%{REQUEST_FILENAME}" !-d
RewriteRule "^/(.*)" "http://old.example.com/$1" [P]
ProxyPassReverse "/" "http://old.example.com/"
</highlight>
<p>Dans cet exemple, les requêtes pour des ressources qui n’ont pas encore été
migrées sont mandatées silencieusement vers l’ancien serveur. Lors de la
migration du contenu, les fichiers locaux ont la priorité. N’oubliez pas de
toujours inclure une directive <directive
module="mod_proxy">ProxyPassReverse</directive> pour être sûr que toute
redirection effectuée par le serveur dorsal est correctement transmise au
client.</p>
</section>
<section id="setenv"><title>Test de variables d'environnement</title>
<p><module>mod_rewrite</module> est souvent utilisé pour effectuer une
action en fonction de la présence ou de l'absence d'une variable
d'environnement particulière ou d'un en-tête de requête, ce qui peut
être accompli de manière plus efficace via la directive <directive
module="core" type="section">If</directive>.</p>
<p>Considérons par exemple le scénario courant où la directive
<directive>RewriteRule</directive> est utilisée pour forcer un nom
d'hôte canonique, tel que <code>www.example.com</code> au lieu de
<code>example.com</code>. Il est possible d'utiliser à la place la
directive <directive module="core" type="section">If</directive> comme
suit :</p>
<highlight language="config">
&lt;If "req('Host') != 'www.example.com'"&gt;
Redirect "/" "http://www.example.com/"
&lt;/If&gt;
</highlight>
<p>On peut utiliser cette technique dans de nombreux scénarios courant
pour remplacer <module>mod_rewrite</module> pour effectuer des actions
en fonction d'en-têtes de requêtes ou de réponses, ou de variables
d'environnement.</p>
<p>Voir en particulier la <a href="../expr.html">documentation sur
l'évaluation des expressions</a> pour une vue d'ensemble des types
d'expressions que vous pouvez utiliser dans les sections <directive
module="core" type="section">If</directive>,
ainsi que dans certaines directives.</p>
</section>
<section id="fallback-resource"><title>Contrôleur frontal / Routage des
ressources</title>
<p>Une utilisation très courante de <module>mod_rewrite</module> consiste à
router toutes les requêtes pour des ressources non existantes vers un seul
script de contrôle frontal (par exemple <code>index.php</code>). Il s’agit de la
base du routage dans le cadre de la plus grande partie du web moderne.</p>
<p>L’approche typique avec <module>mod_rewrite</module> est :</p>
<highlight language="config">
RewriteEngine On
RewriteCond "%{REQUEST_FILENAME}" !-f
RewriteCond "%{REQUEST_FILENAME}" !-d
RewriteRule "^(.*)$" "/index.php" [L]
</highlight>
<p>Cette opération peut être effectuée beaucoup plus simplement avec la
directive <directive module="mod_dir">FallbackResource</directive> :</p>
<highlight language="config">
FallbackResource /index.php
</highlight>
<p>La directive <directive module="mod_dir">FallbackResource</directive> fait la
même chose — les requêtes pour des fichiers et répertoires existants sont
traitées normalement, toutes les autres étant routées vers la ressource
spécifiée — mais sans la surcharge de travail et la complexité du moteur de
réécriture. Elle fonctionne dans les deux contextes de configuration globale du
serveur et des fichiers <code>.htaccess</code>.</p>
<p>Pour désactiver une <code>FallbackResource</code> définie dans un répertoire
parent :</p>
<highlight language="config">
FallbackResource disabled
</highlight>
</section>
<section id="ifexpr"><title>Configuration conditionnelle avec des
expressions rationnelles</title>
<p>Dans de nombreux cas, l’utilisation de <directive
module="mod_rewrite">RewriteCond</directive> peut être remplacée par la
directive <directive module="core" type="section">If</directive> qui prend en
charge une <a href="../expr.html">syntaxe des expressions</a> riche et s’intègre
parfaitement avec les autres directives de httpd.</p>
<p>Redirection basée sur un élément de la chaîne de paramètres :</p>
<highlight language="config">
&lt;If "%{QUERY_STRING} =~ /lang=fr/"&gt;
Redirect "/welcome" "/bienvenue"
&lt;/If&gt;
</highlight>
<p>Restriction d’accès en fonction de la méthode de la requête :</p>
<highlight language="config">
&lt;If "%{REQUEST_METHOD} IN {'DELETE', 'PUT', 'PATCH'}"&gt;
Require ip 10.0.0.0/8
&lt;/If&gt;
</highlight>
<p>Blocage des requêtes qui ne comportent pas d’en-tête Host (clients
HTTP/1.0) :</p>
<highlight language="config">
&lt;If "-z req('Host')"&gt;
Require all denied
&lt;/If&gt;
</highlight>
<p>Voir la <a href="../expr.html">documentation sur l’évaluation des
expressions</a> pour une description complète de la syntaxe disponible dans les
blocs <directive module="core" type="section">If</directive>.</p>
</section>
<section id="blocked-inline-images">
<title>Blocage du référencement à chaud (Hotlinking) d'images</title>
<dl>
<dt>Description :</dt>
<dd>
<p>Le référencement à chaud consiste pour les autres sites à inclure
directement vos images dans leurs pages en utilisant votre bande
passante pour servir des contenus pour le site de quelqu'un d'autre.
Vous pouvez empêcher cela sans utiliser
<module>mod_rewrite</module>.</p>
</dd>
<dt>Solution :</dt>
<dd>
<p>Utilisez la directive <directive
module="mod_setenvif">SetEnvIf</directive> avec la directive <directive
module="mod_authz_core">Require</directive> :</p>
<highlight language="config">
SetEnvIf Referer example\.com localreferer
&lt;FilesMatch "\.(jpg|png|gif)$"&gt;
Require env localreferer
&lt;/FilesMatch&gt;
</highlight>
</dd>
<dt>Discussion :</dt>
<dd>
<p>Si vous avez besoin d’une logique plus complexe — comme servir une
autre image aux référenceurs à chaud au lieu de rejeter la requête — vous
aurez peut-être besoin de <module>mod_rewrite</module>. Les exemples
suivants s’appuient sur l’en-tête <code>HTTP_REFERER</code> qui est
facultatif et peut être usurpé. La condition <code>!^$</code> autorise les
requêtes qui ne comportent aucun en-tête Referer, de sorte que les
utilisateurs qui saisissent l’URL directement, ou dont les navigateurs
suppriment cet en-tête ne soient pas bloqués.</p>
<p>Rejeter purement et simplement la requête :</p>
<highlight language="config">
RewriteCond "%{HTTP_REFERER}" "!^$"
RewriteCond "%{HTTP_REFERER}" "!www.example.com" [NC]
RewriteRule "\.(gif|jpg|png)$" "-" [F,NC]
</highlight>
<p>Servir une image alternative :</p>
<highlight language="config">
RewriteCond "%{HTTP_REFERER}" "!^$"
RewriteCond "%{HTTP_REFERER}" "!www.example.com" [NC]
RewriteRule "\.(gif|jpg|png)$" "/images/go-away.png" [R,NC]
</highlight>
</dd>
</dl>
</section>
<section id="blocking-of-robots">
<title>Blocage des robots</title>
<dl>
<dt>Description :</dt>
<dd>
<p>Vous voulez bloquer les requêtes persistantes d’un robot particulier ou
d’un agent utilisateur qui ignore votre <code>/robots.txt</code>.</p>
</dd>
<dt>Solution :</dt>
<dd>
<p>Utilisez la directive <directive
module="mod_setenvif">SetEnvIfNoCase</directive> avec la directive
<directive module="mod_authz_core">Require</directive> :</p>
<highlight language="config">
SetEnvIfNoCase User-Agent ^NameOfBadRobot goaway
&lt;Location "/secret/files"&gt;
&lt;RequireAll&gt;
Require all granted
Require not env goaway
&lt;/RequireAll&gt;
&lt;/Location&gt;
</highlight>
</dd>
<dt>Discussion :</dt>
<dd>
<p>Toute technique qui s’appuie sur la chaîne <code>USER_AGENT</code> peut
être facilement contournée, car cette chaîne peut être modifiée par le
client. Si vous subissez une attaque soutenue, vous devez la traiter à un
niveau supérieur, par exemple au niveau de votre pare-feu.</p>
<p>Si vous devez combiner la recherche de correspondance par agent
utilisateur et par adresse IP, <module>mod_rewrite</module> peut être
utilisé en remplacement :</p>
<highlight language="config">
RewriteCond "%{HTTP_USER_AGENT}" "^NameOfBadRobot"
RewriteCond "%{REMOTE_ADDR}" "=123\.45\.67\.[8-9]"
RewriteRule "^/secret/files/" "-" [F]
</highlight>
</dd>
</dl>
</section>
<section id="host-deny">
<title>Interdire des hôtes dans une liste de rejets</title>
<dl>
<dt>Description :</dt>
<dd>
<p>Nous souhaitons établir une liste des hôtes auxquels nous voulons
interdire l’accès à notre serveur.</p>
</dd>
<dt>Solution :</dt>
<dd>
<p>Pour un simple blocage basé sur l’adresse IP, utilisez la directive
<directive module="mod_authz_host">Require</directive> directement :</p>
<highlight language="config">
&lt;Location "/"&gt;
&lt;RequireAll&gt;
Require all granted
Require not ip 193.102.180.41
Require not ip 192.76.162.40
&lt;/RequireAll&gt;
&lt;/Location&gt;
</highlight>
</dd>
<dt>Discussion :</dt>
<dd>
<p>Si vous avez besoin d’une liste d’interdiction dynamique basée sur un
fichier (plutôt que d’énumérer des adresses IP dans la configuration),
vous pouvez utiliser <module>mod_rewrite</module> et sa directive
<directive module="mod_rewrite">RewriteMap</directive> :</p>
<highlight language="config">
RewriteEngine on
RewriteMap hosts-deny "txt:/path/to/hosts.deny"
RewriteCond "${hosts-deny:%{REMOTE_ADDR}|NOT-FOUND}" "!=NOT-FOUND" [OR]
RewriteCond "${hosts-deny:%{REMOTE_HOST}|NOT-FOUND}" "!=NOT-FOUND"
RewriteRule "^" "-" [F]
</highlight>
<p>Le fichier de mappage contient une entrée par ligne, avec une adresse
IP ou un nom d’hôte comme clé et une valeur factice (parce que la
directive <directive module="mod_rewrite">RewriteMap</directive> requiert
des paires clé/valeur) :</p>
<example>
## hosts.deny<br />
193.102.180.41 -<br />
192.76.162.40 -<br />
</example>
<p>La seconde directive <directive
module="mod_rewrite">RewriteCond</directive> présuppose que
<code>HostnameLookups</code> est activé. Dans le cas contraire,
supprimer-la, ainsi que le drapeau <code>[OR]</code> de la première
condition.</p>
</dd>
</dl>
</section>
<section id="vhosts"><title>Serveurs virtuels</title>
<p>Bien qu’il soit possible de gérer les <a href="vhosts.html">serveurs virtuels
avec mod_rewrite</a>, il s’agit rarement de la bonne méthode. Le bon choix
consiste pratiquement toujours à créer des blocs <directive module="core"
type="section">VirtualHost</directive> individuels. Si vous devez gérer un très
grand nombre de serveurs virtuels, choisissez plutôt d’utiliser
<module>mod_vhost_alias</module> pour créer ces hôtes automatiquement.</p>
<p>Des modules tels que <module>mod_macro</module> permettent aussi de créer un
grand nombre de serveurs virtuels dynamiquement.</p>
<p>Utiliser <module>mod_rewrite</module> pour la création de serveurs virtuels
peut convenir si vous utilisez un service d’hébergement qui ne vous permet pas
d’accéder aux fichiers de configuration du serveur, et que vous soyez par
conséquent contraint d’utiliser des fichiers <code>.htaccess</code>.</p>
<p>Voir le document <a href="vhosts.html">les serveurs virtuels avec
mod_rewrite</a> pour plus de détails sur la manière de procéder si cette
approche vous semble encore être la bonne.</p>
</section>
<section id="load-balancing">
<title>Répartition de charge</title>
<dl>
<dt>Description :</dt>
<dd>
<p>Nous souhaitons répartir la charge entre plusieurs serveurs dorsaux.</p>
</dd>
<dt>Solution :</dt>
<dd>
<p>Utilisez le module <module>mod_proxy_balancer</module> qui fournit une
solution de répartition de charge flexible et totalement fonctionnelle. Il
prend en charge plusieurs algorithmes de répartition, la persistance de
session, les contrôles de bon fonctionnement et une configuration
dynamique avec le gestionnaire de répartition de charge (Balancer Manager)
— toutes choses impossibles avec l’approche de
<module>mod_rewrite</module>.</p>
<highlight language="config">
&lt;Proxy "balancer://mycluster"&gt;
BalancerMember "http://one.example.com"
BalancerMember "http://two.example.com"
BalancerMember "http://three.example.com"
&lt;/Proxy&gt;
ProxyPass "/" "balancer://mycluster/"
ProxyPassReverse "/" "balancer://mycluster/"
</highlight>
</dd>
<dt>Discussion :</dt>
<dd>
<p>Il est possible de mettre en œuvre une répartition de charge aléatoire
rudimentaire en utilisant <module>mod_rewrite</module> et une directive
<directive module="mod_rewrite">RewriteMap</directive> de type
<code>rnd</code> :</p>
<highlight language="config">
RewriteEngine on
RewriteMap lb "rnd:/path/to/serverlist.txt"
RewriteRule "^/(.*)" "http://${lb:servers}/$1" [P,L]
</highlight>
<p><module>mod_proxy_balancer</module> est cependant beaucoup plus flexible et
fonctionnel que tout ce que vous pourrez « bricoler » en utilisant
<module>mod_rewrite</module>, et correspond à l’approche recommandée.</p>
</dd>
</dl>
</section>
</manualpage>