77 votes

Comment gérer correctement les urls relatives avec un reverse proxy ?

J'ai un proxy inverse configuré comme suit dans Apache :

Le serveur A avec l'adresse www.example.com/folder est le serveur proxy inverse.

Il se connecte à : Serveur B avec l'adresse test.madeupurl.com

Ça marche. Mais le problème que je rencontre est que, sur www.example.com/folder, tous les liens relatifs sont de la forme www.example.com/css/examplefilename.css plutôt que www.example.com/folder/css/examplefilename.css.

Comment puis-je réparer cela ?

Jusqu'à présent, mon proxy inverse a ceci sur le serveur A (www.example.com) :

<Location /folder>
    ProxyPass  http://test.madeupurl.com
    ProxyPassReverse http://test.madeupurl.com
</Location>

123voto

snowdude Points 2790

Apache ProxyPassRewrite ne réécrit pas les corps de réponse reçus de la part de http://test.example.com seulement les en-têtes (comme les redirections vers une page 404 et autres).

Un certain nombre d'alternatives :

Un ) Réécriture de l'application interne pour utiliser des chemins relatifs au lieu d'absolus, c'est-à-dire ../css/style.css 代わりに /css/style.css

Deux ) Redéployez l'application interne dans le même sous-répertoire. /folder plutôt que dans la racine de test.example.com.

Trois ) Le premier et le deuxième ont peu de chances de se produire... Si vous avez de la chance, l'application interne n'utilise que deux ou trois sous-répertoires... et ceux-ci sont inutilisés sur votre site principal il suffit d'écrire un tas de lignes ProxyPass :

# Expose Internal App to the internet.
ProxyPass /externalpath/  http://test.example.com/
ProxyPassReverse /externalpath/  http://test.example.com/
# Internal app uses a bunch of absolute paths. 
ProxyPass /css/  http://test.example.com/css/
ProxyPassReverse /css/  http://test.example.com/css/
ProxyPass /icons/  http://test.example.com/icons/
ProxyPassReverse /icons/  http://test.example.com/icons/

Quatre ) Créez un sous-domaine distinct pour l'application interne et utilisez simplement un proxy inverse pour tout :

<VirtualHost *:80>
   ServerName app.example.com/
   # Expose Internal App to the internet.
   ProxyPass /  http://test.internal.example.com/
   ProxyPassReverse /  http://test.internal.example.com/
</VirtualHost>

Cinq ) Parfois, les développeurs sont complètement désemparés et font en sorte que leurs applications ne génèrent pas seulement des URL absolus mais incluent même la partie nom d'hôte dans leurs URL et le code HTML qui en résulte ressemble à ceci : <img src=http://test.example.com/icons/logo.png> .

A ) Vous pouvez utiliser la solution combinée d'un DNS à horizon partagé et du scénario 4. Les utilisateurs internes et externes utilisent test.example.com, mais votre DNS interne pointe directement vers l'adresse IP du serveur de test.example.com. Pour les utilisateurs externes, l'enregistrement public de test.example.com pointe vers l'adresse IP de votre serveur web public www.example.com et vous pouvez alors utiliser la solution 4.

B ) En fait, vous pouvez faire en sorte qu'apache ne se contente pas d'envoyer des requêtes par proxy à test.example.com, mais aussi à réécrire le corps de la réponse avant qu'il ne soit transmis à vos utilisateurs. (Normalement, un proxy ne fait que réécrire les en-têtes/réponses HTTP). mod_substitute dans apache 2.2. Je n'ai pas testé s'il s'intègre bien avec mod_proxy, mais peut-être que ce qui suit fonctionne :

<Location /folder/>
  ProxyPass http://test.example.com/
  ProxyPassReverse http://test.example.com/ 
  AddOutputFilterByType SUBSTITUTE text/html
  Substitute "s|test.example.com/|www.example.com/folder/|i" 
</Location>

14voto

CodeChimp Points 243

En complément de HBruijn Si vous optez pour la solution (3) "ProxyPass", il se peut que vous deviez également utiliser mod_proxy_html pour réécrire certaines URL dans vos pages HTML.

cf. Comment gérer correctement les urls relatives avec un reverse proxy ? pour quelques exemples.

À titre d'exemple appliqué, voici comment vous pouvez configurer Apache à l'aide de la commande ProxyHTMLURLMap pour transmettre tout à votre-nom-de-domaine.com/pad à votre Etherpad qui fonctionne localement sur le port 9001 :

<Location /pad>
  ProxyPass http://localhost:9001 retry=0
  # retry=0 => avoid 503's when restarting etherpad-lite
  ProxyPassReverse http://localhost:9001
  SetOutputFilter proxy-html
  ProxyHTMLURLMap http://localhost:9001
</Location>
RewriteRule ^/pad$ /pad/ [R]

12voto

ThanhHH Points 201

Vous pouvez utiliser la méthode suivante pour créer un proxy inverse :
1. Installez mod_proxy_html

    yum install mod_proxy_html
  1. Chargement du module mod_proxy_html

    LoadModule proxy_html_module modules/mod_proxy_html.so
  2. Et utilisez le paramètre suivant

    ProxyRequests off  
    ProxyPass /folder/  http://test.madeupurl.com  
    ProxyHTMLURLMap http://test.madeupurl.com  /folder  
    
    <Location /folder/>  
        ProxyPassReverse /  
        ProxyHTMLEnable On  
        ProxyHTMLURLMap  /  /folder/  
        RequestHeader    unset  Accept-Encoding  
    </Location>  

J'espère que cela vous aidera.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X