Antro OpenVPN kliento pridėjimas viename Linux hoste žlunga vienoje iš dviejų vietų. Arba vidinis klientas negali pasiekti savo serverio, nes išorinis tunelis užgrobė tą transportą, arba antrasis klientas perrašo maršrutų lentelę ir pirmasis tunelis nustoja veikti. Abi problemos yra maršrutizavime, ne šifravime, ir abi išsprendžiamos prieš naujam tuneliui perduodant bet kokį programų srautą. Čia pateikti adresai yra iliustratyvūs: tun0 yra išorinis tunelis, 203.0.113.9 yra vidinis serveris, o TCP 9999 yra srautas, kuris turi naudoti vidinį kelią.

Du gedimo būdai, viena maršrutų lentelė

Vidinis klientas atidaro UDP lizdą į savo serverį, ir tas lizdas laikosi dabartinės maršrutų lentelės kaip ir bet kuris kitas. Jei išorinis tunelis jau turi numatytąjį maršrutą, rankos paspaudimo paketai patenka į išorinį tunelį. Tai veikia tik tada, kai išorinis serveris gali pasiekti vidinį serverį ir kita pusė sutinka perduoti srautą; kitaip rankos paspaudimas sustoja ir klientas bando dar kartą.

Antrasis gedimas kyla iš serverio push. Įprastas push yra redirect-gateway def1, kuris įdiegia 0.0.0.0/1 ir 128.0.0.0/1, o ne pakeičia numatytąjį maršrutą. Todėl du klientai, kurių kiekvienas įdiegia savo /1 porą, susiduria, ir naujausia pora laimi beveik kiekvienam tikslui. Kai tunelis miršta po to, kai prisijungia antrasis, ieškokite tų dviejų prefiksų lentelėje, nes pats numatytasis maršrutas galėjo niekada nepasikeisti.

Pažymėkite srautą ir duokite jam lentelę

Nukreipkite pasirinktą srautą pažymėdami jį mangle lentelėje ir suderindami žymę politikos taisyklėje. Taisyklė nurodo dedikuotą lentelę, kurios numatytasis maršrutas yra vidinis įrenginys, todėl tik pažymėti paketai eina vidiniu keliu.

iptables -t mangle -A PREROUTING -p tcp -m multiport --dport 9999 -j MARK --set-mark 0x9999
ip rule add fwmark 0x9999 table 200 pref 1000
ip route add default dev tun1 table 200

Dauguma šio taisyklių rinkinio gedimų kyla iš dviejų klaidų. Ugniasienės nustatyta žymės reikšmė ir taisyklės lyginama reikšmė turi būti identiškos, nes neatitikimas nesuteikia nei klaidos, nei efekto. O PREROUTING mato tik paketus, ateinančius iš išorės, todėl šiame hoste pradėtas ryšys prieš pažymint apskritai reikalauja OUTPUT taisyklės su ta pačia atitiktimi.

Atimkite maršrutų nuosavybę iš antrojo kliento

Dvi parinktys neleidžia antrajam klientui redaguoti lentelės, ir jos veikia skirtinguose taškuose. route-nopull ignoruoja push siunčiamas maršruto parinktis, todėl nieko neįdiegiama. route-noexec priima push siunčiamas parinktis į kliento aplinką, bet lentelės pakeitimą palieka hook, ir to norite tada, kai reikia pamatyti, ką pasiūlė serveris.

Hook veikia su push siunčiamomis reikšmėmis savo aplinkoje ir turėtų pridėti tik tuos įrašus, kuriuos patvirtinote. Padarykite jį idempotentišką: prieš perkurdami išvalykite lentelę, kurią jis valdo, ir nelaikykite, kad ankstesnis paleidimas paliko švarią būseną. Pakartotinis prisijungimas vėl iškviečia hook, o hook, kuris prideda neišvalęs, kaupia pasikartojančius maršrutus.

Pasirinkite vieną savininką ir užrašykite jį. Profilis, kuris nustato abi parinktis, arba hook, kuris konkuruoja su rankiniu scenarijumi, sukuria lentelę, kurios vėliau niekas negali paaiškinti.

Užfiksuokite abu serverių adresus

Vidinis serveris prieš vidiniam klientui prisijungiant turi turėti maršrutą į hostą per išorinį įrenginį. Būtent tas įrašas laiko vidinį transportą išoriniame tunelyje, o ne leidžia jam sekti numatytąjį maršrutą.

ip route add 203.0.113.9/32 dev tun0
ip route get 203.0.113.9

Taip pat pridėkite atitinkamą maršrutą į hostą išoriniam serveriui pagrindinėje lentelėje, kitaip pakartotinis prisijungimas gali nukreipti paties išorinio kliento transportą į jo paties tunelį. Tvarka nepasirenkama: pridėkite šiuos įrašus po to, kai egzistuoja atitinkama sąsaja, tai yra hook arba scenarijus, paleidžiamas po prisijungimo. Maršrutas, nurodantis į išjungtą įrenginį, pašalinamas arba ignoruojamas, todėl įkrovimo metu įrašytas įrašas neišgyvena jūsų numatytos sekos.

Tikrinkite paiešką, o ne skaitykite visą lentelę. Maršruto paieškos išvestis nurodo įrenginį ir šaltinio adresą, kuriuos naudos kernel, ir tai yra būtent tai, ką klientas gauna atidarydamas savo lizdą.

Išbandykite grandinę ir padarykite gedimą matomą

Fiksuokite išorinėje sąsajoje, kol vidinis klientas jungiasi. Vidinis rankos paspaudimas turėtų pasirodyti kaip šifruotas turinys išoriniame tunelyje; jei jis pasirodo kaip paprastas UDP į 203.0.113.9, maršruto į hostą įrašo trūksta ir grandinė niekada nebuvo sukurta.

Grandinė, kuri tyliai grįžta prie fizinio uplink, yra blogiausias rezultatas, nes sąsajos būsena nieko neskelbia ir vidinis srautas išeina iš neteisingo šaltinio adreso. Jei antrasis klientas gali tiesiogiai prisijungti iš naujo, kai išorinis tunelis nukrenta, išjunkite tą kelią arba pririškite jį prie išorinės sąsajos, kad gedimas būtų matomas.

Užbaikite su dviem srautais ir vienu taisyklių išvedimu: pažymėtas ir nepažymėtas ryšys turėtų eiti skirtingais keliais, o ip rule show turėtų išvardyti numatytą prioritetą. Jei abu srautai eina tuo pačiu keliu, žymė netaikoma ten, kur manote.

Susiję straipsniai