Apilar un segon client OpenVPN en un sol amfitrió Linux falla en un de dos punts. O el client intern no pot arribar al seu servidor perquè el túnel extern ha capturat aquest transport, o el segon client reescriu la taula de rutes i el primer túnel deixa de funcionar. Tots dos problemes són d'encaminament, no de xifratge, i tots dos es resolen abans que el túnel nou porti cap tràfic d'aplicació. Les adreces d'aquí són il·lustratives: tun0 és el túnel extern, 203.0.113.9 és el servidor intern i TCP 9999 és el flux que ha d'usar el camí intern.

Dos modes de fallada, una taula d'encaminament

Un client intern obre un sòcol UDP cap al seu servidor, i aquest sòcol segueix la taula de rutes actual com qualsevol altre. Si el túnel extern ja posseeix la ruta per defecte, els paquets de l'apretada de mans entren al túnel extern. Això només funciona quan el servidor extern pot arribar al servidor intern i l'altre costat accepta portar el flux; si no, l'apretada de mans s'atura i el client torna a intentar-ho.

La segona fallada ve del push del servidor. El push habitual és redirect-gateway def1, que instal·la 0.0.0.0/1 i 128.0.0.0/1 en lloc de substituir la ruta per defecte. Per tant, dos clients que instal·len cadascun la seva parella /1 xoquen, i la parella més nova guanya per a gairebé qualsevol destinació. Busqueu aquests dos prefixos a la taula quan un túnel mor després de connectar-se el segon, perquè potser la ruta per defecte no ha canviat mai.

Marqueu el flux i doneu-li una taula

Dirigiu el tràfic seleccionat marcant-lo a la taula mangle i fent coincidir la marca en una regla de política. La regla apunta a una taula dedicada la ruta per defecte de la qual és el dispositiu intern, així només els paquets marcats prenen el camí intern.

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

La majoria de fallades d'aquest conjunt de regles vénen de dos errors. El valor de la marca que posa el tallafoc i el valor que fa coincidir la regla han de ser idèntics, perquè una discrepància no produeix cap error ni cap efecte. I PREROUTING només veu paquets que arriben de fora, així que una connexió iniciada en aquest amfitrió necessita una regla OUTPUT amb la mateixa coincidència abans de ser marcada.

Treu la propietat de les rutes al segon client

Dues opcions impedeixen que el segon client editi la taula i actuen en punts diferents. route-nopull ignora les opcions de ruta empeses, així que no s'instal·la res. route-noexec accepta les opcions empeses a l'entorn del client però deixa el canvi de taula a un hook, que és el que voleu quan necessiteu veure què ha ofert el servidor.

El hook s'executa amb els valors empesos al seu entorn i hauria d'afegir només les entrades que heu aprovat. Feu-lo idempotent: buideu la taula que posseeix abans de reconstruir-la i no assumiu que l'execució anterior va deixar un estat net. Una reconnexió torna a invocar el hook, i un hook que afegeix sense netejar acumularà rutes duplicades.

Trieu un sol propietari i deixeu-lo per escrit. Un perfil que estableix les dues opcions, o un hook que competeix amb un script manual, produeix una taula que ningú no podrà explicar després.

Fixeu les dues adreces dels servidors

El servidor intern necessita una ruta d'amfitrió a través del dispositiu extern abans que el client intern es connecti. Aquesta entrada és la que manté el transport intern dins del túnel extern en lloc de deixar-lo seguir la ruta per defecte.

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

Afegiu també una ruta d'amfitrió corresponent per al servidor extern a la taula principal, o una reconnexió pot encaminar el transport del mateix client extern cap al seu propi túnel. L'ordre no és opcional: afegiu aquestes entrades després que existeixi la interfície pertinent, és a dir, amb un hook o un script que s'executi després de la connexió. Una ruta que apunta a un dispositiu aturat s'elimina o s'ignora, així que una entrada escrita a l'arrencada no sobreviu a la seqüència que heu suposat.

Comproveu la consulta en lloc de llegir tota la taula. La sortida de la consulta de ruta indica el dispositiu i l'adreça d'origen que el nucli farà servir, que és exactament el que obté el client quan obre el seu sòcol.

Proveu la cadena i feu visible la fallada

Captureu a la interfície externa mentre el client intern es connecta. L'apretada de mans interna hauria d'aparèixer com a càrrega xifrada dins del túnel extern; si apareix com a UDP pla cap a 203.0.113.9, falta la ruta d'amfitrió i la cadena no s'ha construït mai.

Una cadena que torna silenciosament a l'enllaç físic és el pitjor resultat, perquè l'estat de la interfície no anuncia res i el tràfic intern surt amb l'adreça d'origen equivocada. Si el segon client es pot reconnectar directament quan cau el túnel extern, desactiveu aquest camí o lligueu-lo a la interfície externa perquè la fallada sigui visible.

Acabeu amb dos fluxos i un bolcat de regles: una connexió marcada i una de no marcada haurien de prendre camins diferents, i ip rule show hauria de llistar la preferència que volíeu. Si tots dos fluxos prenen el mateix camí, la marca no s'aplica on penseu.

Articles relacionats