Prepojiť dvoch klientov OpenVPN na jednom hostiteľovi Linux s fwmark
Obaja klienti chcú predvolenú trasu. Ukotvite vnútorný server host-trasou, zabráňte druhému klientovi prepisovať tabuľky a potom smerujte toky pomocou fwmark.
Pridanie druhého klienta OpenVPN na jedného hostiteľa Linux zlyhá na jednom z dvoch miest. Buď vnútorný klient nedosiahne svoj vlastný server, pretože vonkajší tunel zachytil ten transport, alebo druhý klient prepíše tabuľku trás a prvý tunel prestane fungovať. Oba problémy sú v smerovaní, nie v šifrovaní, a oba sa riešia predtým, ako nový tunel prenesie akúkoľvek aplikačnú premávku. Adresy tu sú ilustratívne: tun0 je vonkajší tunel, 203.0.113.9 je vnútorný server a TCP 9999 je tok, ktorý musí použiť vnútornú cestu.
Dva režimy zlyhania, jedna tabuľka trás
Vnútorný klient otvorí UDP socket k svojmu serveru a tento socket nasleduje aktuálnu tabuľku trás ako každý iný. Ak vonkajší tunel už vlastní predvolenú trasu, pakety nadväzovania spojenia idú do vonkajšieho tunela. Funguje to len vtedy, keď vonkajší server dosiahne vnútorný a druhá strana súhlasí s prenosom toku; inak sa nadväzovanie zastaví a klient to skúsi znova.
Druhé zlyhanie prichádza z push správy servera. Zvyčajný push je redirect-gateway def1, ktorý nainštaluje 0.0.0.0/1 a 128.0.0.0/1 namiesto nahradenia predvolenej trasy. Preto sa dvaja klienti, z ktorých každý nainštaluje vlastnú dvojicu /1, zrážajú a najnovšia dvojica vyhráva pre takmer každý cieľ. Hľadajte tieto dva prefixy v tabuľke, keď tunel zomrie po pripojení druhého, pretože samotná predvolená trasa sa možno nikdy nezmenila.
Označte tok a dajte mu tabuľku
Smerujte vybranú premávku tak, že ju označíte v tabuľke mangle a zhodíte značku v pravidle politiky. Pravidlo ukazuje na vyhradenú tabuľku, ktorej predvolená trasa je vnútorné zariadenie, takže vnútornú cestu berú len označené pakety.
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 200Väčšina zlyhaní v tomto súbore pravidiel pochádza z dvoch chýb. Hodnota značky, ktorú nastaví firewall, a hodnota, ktorú pravidlo porovnáva, musia byť rovnaké, pretože nezhoda neprináša chybu ani účinok. A PREROUTING vidí len pakety prichádzajúce zvonku, takže spojenie začaté na tomto hostiteľovi potrebuje pravidlo OUTPUT s rovnakým porovnaním skôr, než sa vôbec označí.
Zoberte vlastníctvo trás druhému klientovi
Dve možnosti bránia druhému klientovi upravovať tabuľku a pôsobia v rôznych bodoch. route-nopull ignoruje odoslané možnosti trás, takže sa nič nenainštaluje. route-noexec prijme odoslané možnosti do prostredia klienta, ale zmenu tabuľky nechá na hook, a to je to, čo chcete, keď potrebujete vidieť, čo server ponúkol.
Hook beží s odoslanými hodnotami vo svojom prostredí a mal by pridať len záznamy, ktoré ste schválili. Urobte ho idempotentným: pred prestavbou vyprázdnite tabuľku, ktorú vlastní, a nepredpokladajte, že predchádzajúce spustenie zanechalo čistý stav. Opätovné pripojenie znovu vyvolá hook a hook, ktorý pridáva bez čistenia, hromadí duplicitné trasy.
Vyberte jedného vlastníka a zapíšte ho. Profil, ktorý nastaví obe možnosti, alebo hook, ktorý súťaží s ručným skriptom, vytvorí tabuľku, ktorú potom nikto nevie vysvetliť.
Ukotvite obe adresy serverov
Vnútorný server potrebuje host-trasu cez vonkajšie zariadenie skôr, než sa vnútorný klient pripojí. Práve tento záznam drží vnútorný transport vo vnútri vonkajšieho tunela namiesto toho, aby ho nechal nasledovať predvolenú trasu.
ip route add 203.0.113.9/32 dev tun0
ip route get 203.0.113.9Pridajte aj zodpovedajúcu host-trasu pre vonkajší server do hlavnej tabuľky, inak môže opätovné pripojenie nasmerovať transport samotného vonkajšieho klienta do jeho vlastného tunela. Poradie nie je voliteľné: pridajte tieto záznamy po tom, čo príslušné rozhranie existuje, teda v hooku alebo skripte, ktorý sa spustí po pripojení. Trasa ukazujúca na vypnuté zariadenie sa odstráni alebo ignoruje, takže záznam zapísaný pri štarte neprežije postupnosť, ktorú ste predpokladali.
Skontrolujte vyhľadávanie namiesto čítania celej tabuľky. Výstup vyhľadania trasy uvádza zariadenie a zdrojovú adresu, ktoré kernel použije, a to je presne to, čo klient dostane, keď otvorí svoj socket.
Otestujte reťaz a urobte zlyhanie viditeľným
Snímajte na vonkajšom rozhraní, kým sa vnútorný klient pripája. Vnútorné nadväzovanie spojenia sa má objaviť ako šifrovaný obsah vo vonkajšom tuneli; ak sa objaví ako obyčajný UDP na 203.0.113.9, chýba host-trasa a reťaz sa nikdy nevybudoval.
Reťaz, ktorá sa ticho vráti na fyzický uplink, je najhorší výsledok, pretože stav rozhrania nič neoznamuje a vnútorná premávka vychádza z nesprávnej zdrojovej adresy. Ak sa druhý klient dokáže pripojiť priamo, keď vonkajší tunel padne, vypnite tú cestu alebo ju pripnite k vonkajšiemu rozhraniu, aby bolo zlyhanie viditeľné.
Skončite dvoma tokmi a jedným výpisom pravidiel: označené a neoznačené spojenie by mali ísť rôznymi cestami a ip rule show by malo uviesť zamýšľanú prioritu. Ak oba toky idú tou istou cestou, značka sa neuplatňuje tam, kde si myslíte.