Aș dori să încep prin a spune că știu că există literalmente sute de subiecte despre asta, pe care le-am urmărit înainte pentru ca lucrurile să funcționeze. Cu toate acestea, această configurație, pe care am funcționat-o luni de zile, nu funcționează într-un mediu diferit.
Cerințele sunt destul de simple: duceți utilizatorii de pe site-ul de pe portul 80 pe același site de pe portul 443.
Am spus site-ul, cu Apache în față și cu instanțe Tomcat pentru serviciile noastre reale. Aceste servicii sunt găzduite pe două mașini diferite, una virtuală pe GCP Compute Engine și alta baremetal de care în cele din urmă ne vom îndepărta.
Avem domeniul nostru, example.com, care conține un index al serviciilor. Este servit static de Apache 2.4. Îl putem accesa fie cu Http, cât și cu Https. Din acest index, redirecționăm folosind proxy_mod către app1, app2 și app3. App2 și App3 sunt în serverul baremetal. Utilizăm DNS pentru a duce utilizatorii la ei prin subdomeniile lor app2.example.com/app2 și app3.example.com/app3. Voi aborda concedierea în viitor. Deoarece anumite limitări și faptul că app2 și app3 nu sunt încă disponibile publicului, le accesăm doar prin Http.
App1 are același certificat SSL ca și serverul Apache, deoarece sunt găzduite în aceeași VM. Din nou, putem accesa atât example.com, cât și example.com/app1 cu Http și Https.
Acum problemele:
După cum se spune în titlu, am probleme cu erorile 502s ori de câte ori folosesc o configurație pe care am încercat-o deja și care funcționează într-un mediu diferit. Configurația menționată este aproximativ după cum urmează:
<VirtualHost *:80>
Redirect permanent / https://bar.com/
</VirtualHost>
<VirtualHost *:443>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
#SSL stuff
SSLEngine On
SSLCertificateFile /file.pem
SSLCertificateKeyFile /file.key
SSLVerifyClient none
#Proxies
ProxyRequests Off
SSLProxyEngine on
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
ProxyPass /api/ https://localhost:8443/api/
ProxyPassReverse /api/ https://localhost:8443/api/
</VirtualHost>
bar.com a fost mediul meu de testare. Am luat această configurație și am modificat-o după cum urmează, de exemplu.com
<VirtualHost *:80>
Redirect permanent / https://example.com/
</VirtualHost>
<VirtualHost *:443>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
#SSL stuff
SSLEngine On
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
SSLVerifyClient none
#Proxies
SSLProxyEngine on
SSLProxyVerify none
SSLProxyCheckPeerCN on
SSLProxyCheckPeerExpire on
Redirect permanent /app2 http://app2.example.com/app2
Redirect permanent /app3 http://app3.example.com/app3
<Location /app1>
ProxyPass https://localhost:8443/app1
ProxyPassReverse https://localhost:8443/app1
</Location>
</VirtualHost>
Dar acest lucru duce la erori 502. Din nou, înțeleg că vhost-ul de pe portul 80 este ok. Am citit chiar că acesta este modul recomandat (în prezent, caut unde am citit asta). Nu am încercat cu mod_rewrite, deoarece cred că eroarea nu este configurația în sine, ci un amestec între SSL și mod-urile Proxy cu GCP.
Pe partea GCP, avem regulile de bază pentru firewall și din moment ce putem accesa fie Https, fie Http cu configurația de bază (Adică vhost-ul pe care îl am pentru 443 dar ascult pe portul 80, fără primul vhost). Am configurat un echilibrator de încărcare, dar mai ales pentru a folosi CDN-ul Google. Are un grup de backend cu VM unde sunt găzduite Apache și app1. Pentru front-end, am reguli atât pentru portul 80, cât și pentru 443, ceea ce înseamnă că am un alt certificat SSL special pentru echilibrarea încărcăturii, care este gestionat de Google. Am configurat verificări de sănătate pentru ambele porturi, dezactivarea și activarea front-end-urilor pentru a fi sigur că nu este ceva cu porturile în sine și, până acum, aceasta nu pare să fie problema.
Încă mă aflu în jurul întregului ecosistem GCP, așa că cea mai bună presupunere este că îmi lipsește ceva din acea parte a ecuației, deoarece configurația Apache în sine mi se pare ok.
Ce mai am de incercat:
- Am scos echilibrul, setați VM-ul fără IP static și încercați acolo.
- Utilizați același certificat în frontend și în VM.
- Dezactivați portul 80 din frontend și configurați Apache pentru a asculta portul 443 (nu vreau să fac asta, deoarece este mai mult un hack; configurația în sine ar funcționa ca și cum ar fi http)
De ce nu am încercat încă aceste lucruri? Ei bine, după cum s-ar putea să ghiciți, să aruncați o privire în configurația din serverul live nu este cu adevărat o opțiune. Nu am acces la bar.com, așa că nu pot încerca lucruri așa cum mi-aș dori, iar utilizarea WSL, deși utilă, nu s-a dovedit a fi la fel de aproape de lucrul real (Acesta ar putea fi, de asemenea, ceva pe mașina mea .). Din moment ce nu pot lucra decât aproape de miezul nopții, nu pot să încerc multe lucruri atât de bine pe cât mi-aș dori.
Știe cineva ce ar putea fi aruncarea erorilor 502?
Dacă înțelegeți ideea, dar aveți nevoie de mai multe informații, vă rugăm să continuați și să întrebați. Voi fi cât pot de detaliat, dar rețineți că încă învăț cum funcționează IaaS.
EDITAȚI | ×:
După un timp, pot lucra în continuare la asta. Folosesc aceeași configurație ca și al doilea cod de bloc pe care l-am postat inițial.
Ca răspuns la @John Hanley (Vă rugăm să rețineți că am schimbat domeniul și IP-urile în valori „generice”):
Folosind curl -l -v
la domeniu, primesc următoarele:
* Încerc 1.1.1.1:80...
* TCP_NODELAY setat
* Conectat la portul 80 example.com (1.1.1.1) (#0)
> GET / HTTP/1.1
> Gazdă: exapole.com
> User-Agent: curl/7.68.0
> Accept: */*
>
* Marcați pachetul ca nu acceptă mai multe utilizări
< HTTP/1.1 502 Gateway greșit
< Content-Type: text/html; set de caractere=UTF-8
< Politică referitor: fără referitor
< Lungimea conținutului: 332
< Data: Duminică, 21 noiembrie 2021 08:57:31 GMT
<
<html><head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>Eroare server 502</title>
</cap>
<body text=#000000 bgcolor=#ffffff>
<h1>Eroare: Eroare server</h1>
<h2>Serverul a întâmpinat o eroare temporară și nu a putut finaliza solicitarea dvs.<p>Încercați din nou în 30 de secunde.</h2>
<h2></h2>
</body></html>
* Conexiunea #0 cu host example.com a rămas intactă
și
* Încercați 1.1.1.1:443...
* TCP_NODELAY setat
* Conectat la example.com (1.1.1.1) portul 443 (#0)
* ALPN, oferind h2
* ALPN, oferind http/1.1
* setați cu succes locațiile de verificare a certificatelor:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* TLSv1.3 (OUT), strângere de mână TLS, salut client (1):
* TLSv1.3 (IN), strângere de mână TLS, salut server (2):
* TLSv1.3 (IN), strângere de mână TLS, extensii criptate (8):
* TLSv1.3 (IN), strângere de mână TLS, Certificat (11):
* TLSv1.3 (IN), strângere de mână TLS, verificare CERT (15):
* TLSv1.3 (IN), strângere de mână TLS, Terminat (20):
* TLSv1.3 (OUT), TLS schimbă cifra, Schimbă specificația cifrului (1):
* TLSv1.3 (OUT), TLS handshake, Terminat (20):
* Conexiune SSL folosind TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server acceptat să utilizeze h2
* Certificat de server:
* subiect: CN=example.com
* data începerii: 4 octombrie 13:25:53 2021 GMT
* data expirării: 2 ianuarie 13:25:52 2022 GMT
* subjectAltName: gazda „example.com” a corespuns certificatului „example.com”
* emitent: C=US; O=Google Trust Services LLC; CN=GTS CA 1D4
* Verificare certificat SSL ok.
* Utilizând HTTP2, serverul acceptă utilizarea multiplă
* Starea conexiunii a fost schimbată (HTTP/2 confirmat)
* Copierea datelor HTTP/2 din bufferul de flux în bufferul de conexiune după actualizare: len=0
* Folosind ID-ul fluxului: 1 (easy handle 0x55b622463820)
> GET / HTTP/2
> Gazdă: example.com
> user-agent: curl/7.68.0
> accept: */*
>
* TLSv1.3 (IN), strângere de mână TLS, bilet pentru sesiune de știri (4):
* TLSv1.3 (IN), strângere de mână TLS, bilet pentru sesiune de știri (4):
* vechiul ID de sesiune SSL este învechit, se elimină
* Starea conexiunii a fost schimbată (MAX_CONCURRENT_STREAMS == 100)!
< HTTP/2 502
< tipul de conținut: text/html; set de caractere=UTF-8
< referrer-policy: no-referrer
< lungimea conținutului: 332
< data: duminica, 21 noiembrie 2021 08:57:56 GMT
< alt-svc: clar
<
<html><head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>Eroare server 502</title>
</cap>
<body text=#000000 bgcolor=#ffffff>
<h1>Eroare: Eroare server</h1>
<h2>Serverul a întâmpinat o eroare temporară și nu a putut finaliza solicitarea dvs.<p>Încercați din nou în 30 de secunde.</h2>
<h2></h2>
</body></html>
* Conexiunea #0 cu host example.com a rămas intactă
Cred că solicitarea https nu reușește aici din cauza antetelor lipsă, deoarece pot accesa site-ul din browserul meu.
Din aceasta văd că cererea este procesată corect de către LoadBalancer (sau cel puțin asta înțeleg), dar asta Etapa de conectare a fost schimbată
mesajul mă deranjează, mai ales că durează câteva secunde acolo, ca și cum ar aștepta un răspuns.
Din apachectl -S
Configurare VirtualHost:
*:80 vm-name.region.gcp-project.internal (/etc/apache2/sites-enabled/0080-default.conf:1)
*:443 example.com (/etc/apache2/sites-enabled/0443-secured.conf:6)
ServerRoot: „/etc/apache2”
DocumentRoot principal: „/var/www/html”
ErrorLog principal: „/var/log/apache2/error.log”
Mutex watchdog-callback: using_defaults
Mutex ssl-stapling-refresh: using_defaults
Mutex ssl-stapling: using_defaults
Mutex proxy: using_defaults
Mutex ssl-cache: using_defaults
Mutex implicit: dir="/var/run/apache2/" mecanism=default
Fișier Pid: „/var/run/apache2/apache2.pid”
Definiți: DUMP_VHOSTS
Definiți: DUMP_RUN_CFG
Utilizator: name="www-data" id=33
Grup: name="www-data" id=33
Acesta este interesant. În timp ce Vhost pentru portul 80 face referire la instanța VM a GCP în sine, VHost pentru portul 443 nu. Nu sunt sigur ce să iau din asta... Am încercat să accesez VM-ul prin IP-ul extern cu curl. Http arată starea corectă pentru redirecționarea permanentă, în timp ce HTTP-urile aruncă o eroare din cauza nepotrivirii CN și SAN (ceea ce are sens, deoarece certificatul este pentru un domeniu, nu pentru un IP). Cu aceasta, sunt oarecum sigur că schimbarea IP-ului VM cu IP-ul static pe care îl avem și lăsând Apache să facă echilibrarea încărcării îmi va îndeplini cerințele, dar mai adăugăm cel puțin o VM într-un viitor destul de apropiat, așa că făcând asta la acest punct pare... rău. Încă cred că CDN-ul este o caracteristică bună și ar trebui să o folosească până la urmă.
Despre Load Balancer:
Acesta este oarecum greu de explicat, așa că voi încerca să fiu cât mai detaliat, dar direct posibil (Există ceva în GCP CLI pentru a afișa această configurație? Nu te-ai gândit încă la CLI):
Echilibratorul de sarcină în sine:
Frontend-uri:
Protocol |
Port |
Certificat |
Politica SSL |
HTTP |
80 |
- |
- |
HTTPS |
443 |
de exemplu.com, gestionat GCP |
Valori implicite |
Backend-uri
|Protocol endpoint|Port numit|Timeout|verificare de stare|
|-|-|-|-|
|HTTP|http|30 secunde| hc-1 (Eșec)|
|HTTP/2|https|30 secunde| hc-2 (Trecere)|
*Ambele backend indică același grup, dar porturi diferite. Acest grup conține singurul nostru VM.
Reguli gazde/Cale:
Toate neimaginate merg la backend HTTP.Solicitați /* să accesați backend HTTPS.
În timp ce hc-1 eșuează, de fapt se rezolvă la pagina principală. Dar când încerc să accesez app1, nu reușește (ceea ce are sens, deoarece acel VHost nu conține o mapare proxy la app1 pentru început). Pe de alta parte, hc-2 trece, dar accesand site-ul ca https://example.com
aruncă erorile 502.
În cele din urmă, în ceea ce privește modul în care am activat site-urile, am folosit a2ensite pentru 0080-default.conf și 0443-secured.conf.
A, și, de asemenea, în această săptămână site-ul nostru nu a funcționat. Cred că a fost marți, în aceeași zi în care Spotify a avut probleme. A trebuit să deschid echilibrul de încărcare, să fac orice modificare, să salvez, să anulez modificarea menționată și să salvez din nou pentru a-l face să funcționeze din nou, dar hc-1 eșuează de atunci.
Am încercat multe permutări ale configurației mele, pornind de la cea despre care știu că funcționează (adică doar un echilibrator de încărcare pentru HTTP și cel VHost pe portul 80).