Klientas skambina OpenVPN serveriui Compute Engine VM, būsenos lange rašoma prisijungta, o ping į VPC viduje esantį mazgą vis tiek niekur nenueina. Instinktas yra pridėti dar vieną push eilutę, ir tai niekada neišsprendžia. Compute Engine nusprendžia, kur keliauja paketai, pagal savo maršrutų lentelę ir pagal adresus, kuriuos VM sąsaja iš tikrųjų turi, todėl tunelio pool, kurio VM neturi, yra pool, į kurį niekas nepristato.

Sekite nepavykusį paketą, o ne konfigūracijos failą, ir trūkstamos dalys pasirodys iš eilės.

Pradėkite nuo mirštančio paketo

SYN išeina iš kliento, patenka į tunelį ir pasiekia VM kaip inkapsuliuotas paketas VPC viduje esančiai paskirties vietai. OpenVPN jį dekapsuliuoja ir bando persiųsti per eth0, kur fabric užduoda vieną klausimą prieš viską kita: ar ši instancija valdo paskirties adresą. Tunelio pool, iškirptas iš kito žmogaus potinklio, nepraeina šio klausimo, ir paketas išmetamas prieš tai, kai tikrinama bet kokia maršruto ar ugniasienės taisyklė.

Taigi kryptis nuo kliento iki VPC turi du atskirus reikalavimus, ir nė vienas jų nėra push direktyva. VM reikia alias diapazono, kuris apima tunelio pool, ir būtent tai daro jį teisėtu šių adresų savininku. VPC reikia maršruto, kuris nurodo VM kaip next hop kiekvienam apsaugotam prefiksui. Jei trūksta vieno, paketas miršta kitoje vietoje, o klientas mato tą pačią tylą.

Skaitome gedimą ta tvarka, nes iš kliento pusės abi sąlygos atrodo identiškai. Tunelis, kuris praneša prisijungęs, o niekas neatsako, yra topologijos problemos požymis, o ne blogo šifravimo.

Ar instancija valdo tunelio pool

Suteikite VM antrinį diapazoną savo potinklyje, tada leiskite OpenVPN išduoti adresus būtent iš to diapazono. Instancijoje, kurios pagrindinis adresas yra 10.156.0.10/20, /28 alias atskiria pool nuo adresų, kuriuos kitos instancijos jau turi:

gcloud compute instances network-interfaces update openvpn-vm \
  --zone=europe-west1-b \
  --aliases=eth0:10.156.1.0/28

Tada server direktyva turi aprašyti tą patį bloką. Pirmasis jos adresas tampa tunelio gateway, o likę adresai išduodami klientams. Čia du skaičiai aprašo vieną bloką, tinklą ir tinklo kaukę, ir tai yra pool sintaksė, kurios OpenVPN vis dar tikisi.

server 10.156.1.0 255.255.255.240

Patvirtinkite, kad adresas tikrai pateko į sąsają, o ne tik į OpenVPN konfigūraciją. Fabric persiunčia tai, ką praneša NIC, o ne tai, ką tiki daemonas. Viena komanda tai išsprendžia:

ip -4 addr show dev eth0

Antrinis adresas, kuris niekada nepasiekia eth0, arba pool, kuris persidengia su kitu potinkliu, vėliau pasireiškia kaip protarpiniai nuostoliai, o ne kaip paleidimo klaida. Daemonas paleidžiamas, klientai prisijungia, ir tik kai kurios paskirties vietos elgiasi netinkamai. Laikykite alias diapazoną mažą, kad pool būtų lengva atpažinti maršrutų lentelėje. Niekada neiškirpkite jo iš potinklio, kurį kita instancija jau naudoja.

Suteikite grįžtamajam srautui next hop

Atsakymas iš VPC mazgo adresuojamas kliento adresui tunelio pool, kuris nepriklauso jokiam VPC žinomam potinkliui. Be maršruto tam pool, atsakymas sustoja pirmame hop, kuris neturi atitikmens, o užklausa gali būti sėkmingai įvykdyta kitame gale.

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

Tas pats maršrutas reikalingas kiekvienam prefiksui, kuris yra už kliento, o ne VPC viduje. Tiems prefiksams taip pat reikia iroute įrašo to kliento ccd faile. Tas įrašas yra serverio pusės apskaita: jis pasako serveriui, kuris klientas valdo prefiksą, ir jis nieko neįdiegia pačiame kliente.

Laikykite push sąrašą pokalbio kliento pusei, nes jis tik prideda maršrutus prie prisijungiančios mašinos. Push eilutė VPC potinkliui ir VPC maršrutas atgal į pool yra dvi to paties kelio pusės, ir kiekviena pusė atskirai sukuria tunelį, kuris neša užklausas, bet ne atsakymus.

Ugniasienės, persiuntimas ir tarpiniai hopai

VPC ugniasienė vertina dekapsuliuotą paketą, todėl ingress taisyklė turi praleisti tunelio pool ir bet kurį svetainės prefiksą, kuris taip pasiekia VM. Default-deny laikysena čia nepasteimai žlunga: paketas išmetamas po dekapsuliavimo, o OpenVPN žurnalas rodo sveiką sesiją.

Bet kuriame Linux mazge, kuris persiunčia, o ne užbaigia, patikrinkite, ar net.ipv4.ip_forward įjungtas. Nuosavybės taisyklė galioja ir ten: mašina, kuri persiunčia potinkliui, kurio neturi, išmeta paketą taip pat kaip VM. Perskaitykite reikšmę prieš kaltindami tunelį.

Kai nepavyksta tiksliai vienas prefiksas

Dalinis gedimas yra lengviausiai skaitomas atvejis, nes visa kita kelyje jau įrodyta. Pradėkite nuo maršrutų sąrašo ir perskaitykite įrašo, kuris turėtų apimti prefiksą, paskirties diapazoną ir next hop, tada perskaitykite instancijos aprašą ir palyginkite jos alias diapazoną su pool, kurį dalija serveris.

gcloud compute routes list --filter=destination-range~10.164.0.0
 gcloud compute instances describe openvpn-vm --format=get(networkInterfaces[0].aliasIpRanges)

Trūkstamas maršrutas pasireiškia kaip next hop nebuvimas prefiksui, o trūkstamas alias pasireiškia kaip paketas, išmestas sąsajoje; iš kliento pusės abu atrodo panašiai, o tuose dviejuose išvedimuose jie visiškai skiriasi. Jei yra abu, likęs įtariamasis yra to kliento ccd iroute, kuris pretenduoja į prefiksą.

Užrašykite keturias reikšmes šalia tunelio: alias diapazonas, serverio pool, stumiami prefiksai, VPC maršrutai. Pasenęs alias sugadina kiekvieną pool adresą, pasenęs maršrutas sugadina vieną kryptį, trūkstamas push paslepia prefiksą nuo kliento, o neteisingas iroute nusiunčia prefiksą ne tam peer. Kitam žmogui, kuris pridės potinklį, reikia visų keturių vienoje vietoje, o užrašas pigesnis nei vakaras.

Susiję straipsniai