OpenVPN pe GCE: adaugă un IP alias înainte de a împinge rute
O rută împinsă nu face VM-ul next hop. Adaugă intervalul de IP alias, aliniază-l cu pool-ul serverului și creează ruta de întoarcere în VPC înainte de a testa clienții.
Un client se conectează la serverul OpenVPN de pe o VM Compute Engine, fereastra de stare spune conectat, iar un ping către un host din VPC tot nu ajunge nicăieri. Instinctul este să adaugi încă o linie push, iar asta nu repară niciodată problema. Compute Engine decide unde merg pachetele pe baza propriului tabel de rute și a adreselor pe care o interfață a VM-ului le deține efectiv, așa că un pool de tunel pe care VM-ul nu îl posedă este un pool către care nimeni nu livrează.
Urmărește pachetul care eșuează în locul fișierului de configurare, iar piesele lipsă apar în ordine.
Începe cu pachetul care moare
SYN-ul pleacă de la client, intră în tunel și ajunge la VM ca un pachet încapsulat către o destinație din VPC. OpenVPN îl decapsulează și încearcă să îl trimită mai departe pe eth0, unde fabric-ul pune o întrebare înainte de orice altceva: deține această instanță adresa de destinație. Un pool de tunel decupat din subrețeaua altcuiva eșuează acea întrebare, iar pachetul este aruncat înainte de a fi consultată vreo rută sau regulă de firewall.
Deci direcția de la client la VPC are două cerințe separate, iar niciuna nu este o directivă push. VM-ul are nevoie de un interval alias care acoperă pool-ul de tunel, iar asta este ce îl face proprietar legitim al acelor adrese. VPC-ul are nevoie de o rută care numește VM-ul ca next hop pentru fiecare prefix protejat. Dacă lipsește una, pachetul moare în alt loc, în timp ce clientul vede aceeași tăcere.
Citește defecțiunea în această ordine, pentru că din partea clientului cele două condiții arată identic. Un tunel care raportează conectat în timp ce nimic nu răspunde este semnătura unei probleme de topologie, nu a unei criptări proaste.
Deține instanța pool-ul de tunel
Dă VM-ului un interval secundar în interiorul propriei subrețele, apoi fă OpenVPN să distribuie adrese exact din acel interval. Pe o instanță a cărei adresă primară este 10.156.0.10/20, un alias /28 ține pool-ul separat de adresele pe care alte instanțe le au deja:
gcloud compute instances network-interfaces update openvpn-vm \
--zone=europe-west1-b \
--aliases=eth0:10.156.1.0/28Directiva server trebuie atunci să descrie același bloc. Prima sa adresă devine gateway-ul tunelului, iar adresele rămase sunt distribuite clienților. Aici două numere descriu un bloc, o rețea și o mască, iar aceasta este sintaxa de pool pe care OpenVPN încă o așteaptă.
server 10.156.1.0 255.255.255.240Confirmă că adresa a ajuns într-adevăr pe interfață și nu doar în configurația OpenVPN. Fabric-ul transmite ce raportează NIC-ul, nu ce crede daemonul. O singură comandă lămurește:
ip -4 addr show dev eth0O adresă secundară care nu ajunge niciodată la eth0, sau un pool care se suprapune cu altă subrețea, apare mai târziu ca pierderi intermitente în loc de eroare la pornire. Daemonul pornește, clienții se conectează, iar doar unele destinații se comportă greșit. Ține intervalul alias mic ca pool-ul să fie ușor de recunoscut într-un tabel de rute. Nu îl decupa niciodată dintr-o subrețea pe care o altă instanță o folosește deja.
Dă un next hop traficului de întoarcere
Un răspuns de la un host din VPC este adresat unei adrese de client din pool-ul de tunel, care nu aparține niciunei subrețele cunoscute de VPC. Fără o rută pentru acel pool, răspunsul se oprește la primul hop fără potrivire, iar cererea poate foarte bine să fi reușit la celălalt capăt.
gcloud compute routes create openvpn-return \
--network=prod-vpc \
--destination-range=192.168.127.0/24 \
--next-hop-instance=openvpn-vm \
--next-hop-instance-zone=europe-west1-b \
--priority=800Aceeași rută este necesară pentru orice prefix care se află în spatele unui client în loc de interiorul VPC-ului. Acele prefixe au nevoie și de o intrare iroute în fișierul ccd al acelui client. Acea intrare este evidență contabilă pe partea serverului: îi spune serverului ce client deține prefixul și nu instalează nimic pe clientul însuși.
Păstrează lista push pentru partea client a conversației, pentru că adaugă doar rute pe mașina care se conectează. O linie push pentru o subrețea din VPC și o rută VPC înapoi către pool sunt două jumătăți ale aceleiași căi, iar fiecare jumătate singură produce un tunel care duce cereri dar nu și răspunsuri.
Firewall-uri, forwarding și hopurile dintre ele
Firewall-ul VPC evaluează pachetul decapsulat, deci o regulă de intrare trebuie să admită pool-ul de tunel și orice prefix de site care ajunge la VM pe acea cale. O poziție de tip default-deny eșuează silențios aici: pachetul este aruncat după decapsulare, iar jurnalul OpenVPN arată o sesiune sănătoasă.
Pe orice gazdă Linux care face forwarding în loc să termine, verifică dacă net.ipv4.ip_forward este activat. Regula de proprietate se aplică și acolo: o mașină care face forwarding pentru o subrețea pe care nu o deține aruncă pachetul exact cum ar face-o VM-ul. Citește valoarea înainte de a da vina pe tunel.
Când eșuează exact un prefix
Defecțiunea parțială este cazul cel mai ușor de citit, pentru că tot restul căii a fost deja dovedit. Începe cu lista de rute și citește intervalul de destinație și next hop-ul intrării care ar trebui să acopere prefixul, apoi citește descrierea instanței și compară intervalul ei alias cu pool-ul pe care serverul îl distribuie.
gcloud compute routes list --filter=destination-range~10.164.0.0
gcloud compute instances describe openvpn-vm --format=get(networkInterfaces[0].aliasIpRanges)O rută lipsă se arată ca absența unui next hop pentru prefix, în timp ce un alias lipsă se arată ca un pachet aruncat la interfață; din partea clientului cele două seamănă, iar în cele două ieșiri sunt complet diferite. Dacă ambele există, suspectul rămas este iroute-ul ccd pentru clientul care revendică prefixul.
Notează cele patru valori lângă tunel: interval alias, pool-ul serverului, prefixele împinse, rutele VPC. Un alias învechit rupe fiecare adresă din pool, o rută învechită rupe o direcție, un push lipsă ascunde prefixul de client, iar un iroute greșit trimite prefixul către peer-ul greșit. Următoarea persoană care adaugă o subrețea are nevoie de toate patru într-un singur loc, iar notița este mai ieftină decât seara.