Come gestire correttamente gli URL relativi con un proxy inverso


51

Ho una configurazione proxy inversa come segue in Apache:

Il server A con indirizzo www.example.com/folder è il server proxy inverso.

Si associa a: Server B con indirizzo test.madeupurl.com

Questo tipo di opere. Ma il problema che ho è, su www.example.com/folder, tutti i collegamenti relativi sono delle forme www.example.com/css/examplefilename.css piuttosto che www.example.com/folder/css/examplefilename. css

Come posso risolvere questo problema?

Finora il mio proxy inverso ha questo sul Server A (www.esempio.com):

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

Quale delle seguenti soluzioni ha funzionato per te nella risposta di HBruijn, se ricordi?
Kimberly W,

Risposte:


81

Apache ProxyPassRewrite non riscrive i corpi di risposta ricevuti da http://test.example.com , solo le intestazioni (come i reindirizzamenti a una pagina 404 e simili).

Una serie di alternative:

Uno ) Riscrivi l'app interna per utilizzare percorsi relativi anziché assoluti. cioè ../css/style.cssinvece di/css/style.css

Due ) Ridistribuire l'app interna nella stessa sottodirectory /folderanziché nella radice di test.example.com.

Tre ) È improbabile che accada uno e due ... Se sei fortunato, l'app interna utilizza solo due o tre sottodirectory e quelle non sono utilizzate sul tuo sito principale , scrivi semplicemente un mucchio di righe 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/

Quattro ) Crea un sottodominio separato per l'app interna e inverti semplicemente il proxy:

<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>

Cinque ) A volte gli sviluppatori sono completamente incapaci e hanno le loro applicazioni non solo generano URL assoluto, ma comprendono anche la parte hostname nella loro URL e le conseguenti sguardi di codice HTML come questo: <img src=http://test.example.com/icons/logo.png>.

A ) È possibile utilizzare la soluzione combinata di un DNS split horizon e dello scenario 4. Sia gli utenti interni che quelli esterni utilizzano test.example.com, ma il DNS interno punta direttamente all'indirizzo IP del server test.example.com. Per gli utenti esterni il record pubblico per test.example.com punta all'indirizzo IP del server Web pubblico www.example.com e quindi è possibile utilizzare la soluzione 4.

B ) Puoi effettivamente ottenere apache per non solo inviare richieste proxy a test.example.com, ma anche riscrivere il corpo della risposta prima che venga trasmesso ai tuoi utenti. (Normalmente un proxy riscrive solo le intestazioni / le risposte HTTP). mod_substitute in apache 2.2. Non ho testato se si impila bene con mod_proxy, ma forse le seguenti funzioni:

<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>

4
Buona mucca santa risposta. Non ho nemmeno provato nessuno di questi, ma volevo solo ringraziarvi per la scrittura! Aiuta un milione. Andando a testare alcune di queste idee ora e riporteremo presto :)
Lavoratore duro

Domanda veloce per favore, per il punto 2 se ti capisco correttamente, signore, stai suggerendo di ridistribuire l'adpp a test.madeupurl.com/folder? Ciò richiederebbe eventuali modifiche al mio file di configurazione di Apache? Questa sembra la soluzione più rapida
Gran lavoratore il

Inoltre, mi dispiace disturbarla, ma con il punto 1 quando provo ciò che suggerisce il problema che descrivo nella mia domanda persiste ancora. Per esempio qui ho usato: <link rel = "stylesheet" type = "text / css" href = "../ css / custom.css" /> e per l'indirizzo del link nel browser sta producendo test.madeupurl.com /css/bootstrap.css anziché test.madeupurl.com/folder/css/bootstrap.css . Avresti qualche suggerimento su questo sarebbe di grande aiuto
Gran lavoratore il

Spesso quando si ridistribuisce un'applicazione che è ora installata in DocumentRoot in una sottodirectory come / cartella i fogli di stile, le icone ecc. Verranno distribuiti in / cartella / css e / cartella / icone ecc. Quindi i collegamenti nell'output HTML diventeranno come quelli <img src=/folder/icons/button.png>in il turno sarà preso dalla ProxyPass /folder/ http://test.madeupurl.com/folder/direttiva.
HBruijn,

La pagina test.madeupurl.com/content/index.html vuole includere test.madeupurl.com/css/custom.css. In quella posizione dovresti usare l'URL relativo href="../css/custom.css"e non href="/css/custom.css". Quando l'utente di Internet recupera la pagina, l'URL sarà www.example.com/folder/content/index.html. L'URL per il CSS sarà quindi: www.example.com/folder/content/../css/custom.cssche è in realtà a www.example.com/folder/css/custom.csscui verrà inoltrato test.madeupurl.com/css/custom.css.
HBruijn,

8

A complemento della risposta di HBruijn , se si opta per la soluzione (3) "ProxyPass", potrebbe essere necessario utilizzare anche mod_proxy_html per riscrivere alcuni URL nelle pagine HTML.

cf. Come gestire correttamente gli URL relativi con un proxy inverso per alcuni esempi.

A titolo di esempio applicata, ecco come è possibile configurare Apache utilizzando la ProxyHTMLURLMapregola per inoltrare tutto a your-domain-name.com/pad al Etherpad istanza in esecuzione in locale sulla porta 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]


2
Ricorda però che mod_proxy_html è incluso solo da Apache 2.4 e versioni successive, dove la domanda originale sopra è per Apache 2.2
HBruijn,

La tua risposta è impeccabile. Tuttavia, ho incontrato un caso in cui il contenuto non è html, è piuttosto pdf. L'uso di ProxyHTMLURLMap non ha funzionato per me. Altri suggerimenti?
Mohamed Ennahdi El Idrissi,

2
Se il tuo contenuto è un PDF, non è necessario riscrivere gli URL al suo interno! A meno che tu non voglia che i tuoi utenti facciano clic sui collegamenti nel PDF per accedere ad altre pagine del tuo sito Web, ma questo sembra complicato. Per disabilitare la riscrittura degli URL, è sufficiente omettere le ultime 2 direttive: SetOutputFilter& ProxyHTMLURLMap.
Lucas Cimon,

Potrebbe essere necessario aggiungere RequestHeader unset Accept-Encoding per evitare errori di codifica
zar3bski

5

È possibile utilizzare il seguente modo per creare un proxy inverso:
1. Installare mod_proxy_html

    yum install mod_proxy_html
  1. Carica il modulo mod_proxy_html

    LoadModule proxy_html_module modules/mod_proxy_html.so
    
  2. E utilizzare le seguenti impostazioni

    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>  
    

Spero che questo aiuto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.