Puncte:2

Apache în spatele proxy-ului invers nginx, setând antetul gazdă corect

drapel nl

Îmi rulez aplicația folosind Apache într-un container Docker. Am nginx care acționează ca un proxy invers care rulează într-un alt container Docker care are Apache în amonte. Eu folosesc proxy_pass directivă pentru aceasta.

Apache rulează în URL https://example-8gnm1aqrns-lz.a.run.app Nginx rulează în adresa URL http://example.com

Totul rulează pe Google Cloud Run și problema este că Google Cloud Run atribuie fiecărui serviciu o adresă URL și folosește Gazdă antet pentru a face diferența între aplicații, așa că sunt obligat să trimit antetul Gazdă: exemplu-8gnm1aqrns-lz.a.run.app atunci când vă conectați la upstream folosind nginx, astfel încât cererea să fie direcționată corect.

Acest lucru cauzează o problemă cu aplicația mea, deoarece crede că rulează în adresa URL https://example-8gnm1aqrns-lz.a.run.app si nu http://example.com.

Este posibil să folosiți o configurație Apache .htaccess pentru a suprascrie Gazdă antet bazat pe X-Redirecționat-Gazdă trimis de nginx?

Puncte:2
drapel co

În loc să-l solicite pe Apache să facă acest lucru, solicitați-l pe NGINX să o facă înainte chiar să predea datele către Apache, setând antetul Host pe care Apache îl așteaptă ca parte a transferului proxy_pass cu o opțiune de configurare suplimentară.

NGINX are următoarea variabilă pentru proxy_set_header pentru a crește ceea ce este transmis proxy-ului în backend. Deci ai avea ceva de genul asta:

...

Locație / {
    proxy_pass http://10.20.30.40;
    proxy_set_header Gazdă example.com;
}
...

în configurația dvs. NGINX pentru proxy invers. Apoi, lui Apache nu-i va păsa de X-Forwarded-Host, deoarece ați seta antetul Host în locul căruia Apache ar trebui să prioritizează servirea.

Acest ar trebui să remediez lucrurile - folosesc mai multe sisteme NGINX în acest fel când domeniul la care a ajuns browser-ul este diferit de gazda care răspunde a backend-ului - și până acum funcționează cu backend-uri Django, backend-uri PHP, Apache, chiar și un server HTTP Python pe care îl folosesc pentru a testa lucrurile . Și înțelegerea mea despre Apache este că va acorda prioritate antetului Host față de X-Forwarded-Host.

John Hanley avatar
drapel cn
E posibil sa ma insel. Dacă faceți o solicitare de la un serviciu Cloud Run la altul, antetul Host trebuie să se potrivească cu serviciul apelat, în caz contrar, veți obține un 404. Acesta este un exemplu în care Cloud Run Custom Domains plus soluția dvs. poate rezolva problema.
drapel co
@JohnHanley Ahh, da, probabil că ai dreptate, totuși, dacă OP se așteaptă ca punctul final să servească example.com și să obțină alte adrese URL, au nevoie de un ascultător generic care să se potrivească cu toate domeniile potențiale de aici. Cloud Run Custom Domains Cred că va funcționa mai bine pentru OP (suna ca acesta ar trebui să fie un răspuns unic)
John Hanley avatar
drapel cn
Cred că soluția ta este jumătatea corectă pentru început. Apoi, OP poate revizui Cloud Run Custom Domains etc., astfel încât logica domeniului său să funcționeze. Nu înțeleg dependența lui de numele de domenii pentru un backend.
drapel co
@JohnHanley Ei bine, dacă serverul $BACKEND rulează 50 de domenii separate și servește conținut pe baza antetului Host (care este modul în care funcționează VirtualHosts și câmpurile lor ServerName / ServerAlias ​​în Apache), atunci antetul Host este necesar pentru a specifica cum să se conecteze și cu ce Gazdă de transmis, astfel încât conținutul să fie difuzat corect. Așa este, întâmplător, modul în care NGINX determină ce zone să servească - câmpul server_name (regex, wildcard etc.) potrivirea determină ce configurație server/site să servească pentru o anumită cerere.
John Hanley avatar
drapel cn
Cu toate acestea, nu așa funcționează Cloud Run. Antetul gazdă determină la ce serviciu Google Cloud GFE direcționează solicitarea. Dacă backend-ul gestionează 50 de domenii, atunci serviciul Cloud Run ar avea nevoie de 50 de domenii personalizate.Având în vedere că fiecare domeniu personalizat va necesita o mapare a domeniului, nu sunt sigur că aceasta este nici măcar acceptată (limite de cotă). Backend-ul va avea nevoie de o altă metodă pentru a sprijini acest tip de identificare. Un antet personalizat va funcționa probabil. Cu toate acestea, acesta este un exemplu de transformare a unui design într-un serviciu care ar putea să nu fie potrivit pentru arhitectură.
drapel co
@JohnHanley Cred că tot ce trebuie să știu este unde se află NGINX. Dacă citesc corect OP, example.com -> NGINX -> Google Cloud Run. Deci, antetul Host pentru blocul de locație și proxy_pass trebuie doar să seteze Host la adresa URL unică GCR pentru cerere. Presupunând că NGINX se află de fapt la example.com.
fairport avatar
drapel nl
Din păcate, acest răspuns nu va funcționa, deoarece nu mă pot conecta la containerul Apache folosind adresa IP, trebuie să folosesc domeniul cu antetul Gazdă, astfel încât Google să știe cum să direcționeze cererea către serverul potrivit. Aș dori să repar antetul gazdă în Apache, astfel încât aplicația să își construiască rutele corect. Antetul gazdă corect este în X-Forwarded-Host sau aș putea folosi o variabilă de mediu pentru a o defini și eu.
drapel co
@fairport Nu sunt sigur că există funcționalitate în Apache pentru a rescrie antetul X-Forwarded-Host. Am căutat, dar nu am văzut o astfel de funcționalitate. Cred că, dacă aplicația dvs. nu va funcționa așa cum se așteaptă Google, trebuie să vă reconstruiți/restructurați aplicația ținând cont de cerințele Google, în loc să încercați să o piratați. Ceea ce are sens în ceea ce privește GCR, deoarece îl structurează într-un mod foarte specific. (Poate să-mi șterg răspunsul la un moment dat după ce ai citit acest comentariu)
fairport avatar
drapel nl
Da, în prezent mă uit la documentația directivei Apache RequestHeader și văd dacă pot înlocui antetul Host folosind o variabilă de mediu. O altă modalitate de a remedia acest lucru ar putea fi configurarea unei rețele VPC, în acest fel serviciul Cloud Run ar trebui să aibă o adresă IP statică pe care o pot folosi în loc de o adresă URL. Ultimul mod în care mă pot gândi dacă modific aplicația în sine, astfel încât să înlocuiască antetul gazdă folosind X-Forwarded-Host sau o variabilă de mediu, dar acest lucru pare un hacker.Îmi voi răspunde la propria întrebare dacă găsesc o modalitate bună de a rezolva această problemă.
Puncte:1
drapel nl

Am rezolvat această problemă definind o nouă variabilă de mediu numită APP_HOST în panoul de control Google Cloud Run și setați-l la exemplu.com.

Apoi am adăugat următoarea configurație la .htaccess fișier în rădăcina documentului:

<IfModule mod_env.c>
    PassEnv APP_HOST
</IfModule>

<IfModule mod_headers.c>
    RequestHeader set Host %{APP_HOST}e env=APP_HOST
</IfModule>

Acest lucru mi-a permis să trec peste Gazdă antet de la exemplu-8gnm1aqrns-lz.a.run.app la exemplu.com pe baza variabilei de mediu APP_HOST.

Desigur, aș fi putut codifica numele de gazdă, dar cred că utilizarea unei variabile de mediu vă oferă mai multă flexibilitate dacă doriți să utilizați același .htaccess fișier în contexte diferite, cum ar fi pe un server provizoriu.

Editați | ×

Iată cum puteți rezolva acest lucru folosind X-Redirecționat-Gazdă, de exemplu, dacă rulați gazde virtuale și aveți nevoie ca site-ul să fie accesibil din mai multe domenii

<IfModule mod_setenvif.c>
    SetEnvIf X-Forwarded-Host (.*) REAL_HOST_HEADER=$1
    <IfModule mod_headers.c>
        RequestHeader set Host "%{REAL_HOST_HEADER}e"
    </IfModule>
</IfModule>

Aceasta va prelua antetul de la X-Redirecționat-Gazdă și setați Gazdă antet bazat pe valoare.

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.