Toisen OpenVPN-asiakkaan pinoaminen yhdelle Linux-isännälle epäonnistuu toisessa kahdesta kohdasta. Joko sisempi asiakas ei tavoita omaa palvelintaan, koska ulompi tunneli on vallannut sen siirron, tai toinen asiakas kirjoittaa reititystaulukon uudelleen ja ensimmäinen tunneli lakkaa toimimasta. Molemmat ongelmat ovat reitityksessä, eivät salauksessa, ja molemmat ratkaistaan ennen kuin uusi tunneli kuljettaa sovellusliikennettä. Osoitteet ovat tässä havainnollisia: tun0 on ulompi tunneli, 203.0.113.9 on sisempi palvelin ja TCP 9999 on virta, jonka on käytettävä sisempää polkua.

Kaksi vikatilaa, yksi reititystaulukko

Sisempi asiakas avaa UDP-soketin palvelimeensa, ja se soketti noudattaa nykyistä reititystaulukkoa kuten mikä tahansa muu. Jos ulommalla tunnelilla on jo oletusreitti, kättelypaketit menevät ulompaan tunneliin. Se toimii vain, kun ulompi palvelin tavoittaa sisemmän palvelimen ja toinen puoli suostuu kuljettamaan virran; muuten kättely pysähtyy ja asiakas yrittää uudelleen.

Toinen vika tulee palvelimen pushista. Tavallinen push on redirect-gateway def1, joka asentaa 0.0.0.0/1 ja 128.0.0.0/1 oletusreitin korvaamisen sijaan. Siksi kaksi asiakasta, joista kumpikin asentaa oman /1-parinsa, törmäävät, ja uusin pari voittaa lähes jokaiseen kohteeseen. Etsi nuo kaksi etuliitettä taulukosta, kun tunneli kuolee toisen yhdistämisen jälkeen, koska itse oletusreitti ei ehkä ole koskaan muuttunut.

Merkitse virta ja anna sille taulukko

Ohjaa valittu liikenne merkitsemällä se mangle-taulukossa ja sovittamalla merkki käytäntösäännössä. Sääntö osoittaa omaan taulukkoon, jonka oletusreitti on sisempi laite, joten vain merkityt paketit kulkevat sisempää polkua.

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

Useimmat tämän sääntöjoukon viat tulevat kahdesta virheestä. Palomuurin asettama merkkiarvo ja säännön sovittama arvo on oltava identtiset, koska ero ei tuota virhettä eikä vaikutusta. Ja PREROUTING näkee vain ulkopuolelta saapuvat paketit, joten tällä isännällä aloitettu yhteys tarvitsee OUTPUT-säännön samalla sovituksella ennen kuin se ylipäätään merkitään.

Ota reittien omistajuus pois toiselta asiakkaalta

Kaksi vaihtoehtoa estää toista asiakasta muokkaamasta taulukkoa, ja ne vaikuttavat eri kohdissa. route-nopull jättää pushitut reittivaihtoehdot huomiotta, joten mitään ei asenneta. route-noexec hyväksyy pushitut vaihtoehdot asiakkaan ympäristöön mutta jättää taulukon muutoksen hookille, mikä on juuri se mitä haluat, kun sinun on nähtävä, mitä palvelin tarjosi.

Hook toimii pushituilla arvoilla ympäristössään, ja sen pitäisi lisätä vain ne merkinnät, jotka hyväksyit. Tee siitä idempotentti: tyhjennä taulukko, jonka se omistaa, ennen uudelleenrakentamista, äläkä oleta, että edellinen ajo jätti puhtaan tilan. Uudelleenyhdistäminen kutsuu hookin uudelleen, ja hook, joka lisää tyhjentämättä, kerää reittien kaksoiskappaleita.

Valitse yksi omistaja ja kirjoita se muistiin. Profiili, joka asettaa molemmat vaihtoehdot, tai hook, joka kilpailee käsikirjoitetun skriptin kanssa, tuottaa taulukon, jota kukaan ei voi myöhemmin selittää.

Kiinnitä molempien palvelinten osoitteet

Sisempi palvelin tarvitsee isäntäreitin ulomman laitteen kautta ennen kuin sisempi asiakas yhdistää. Juuri tämä merkintä pitää sisemmän siirron ulomman tunnelin sisällä sen sijaan, että se seuraisi oletusreittiä.

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

Lisää vastaava isäntäreitti myös ulommalle palvelimelle päätaukulkuun, muuten uudelleenyhdistäminen voi reitittää ulomman asiakkaan oman siirron sen omaan tunneliin. Järjestys ei ole valinnainen: lisää nämä merkinnät sen jälkeen, kun asianomainen liitäntä on olemassa, eli hookilla tai skriptillä, joka ajetaan yhdistämisen jälkeen. Alhaalla olevaan laitteeseen osoittava reitti poistetaan tai jätetään huomiotta, joten käynnistyksen yhteydessä kirjoitettu merkintä ei selviä oletetusta järjestyksestä.

Tarkista haku sen sijaan, että lukisit koko taulukon. Reittihaun tulos nimeää laitteen ja lähdeosoitteen, jota ydin käyttää, ja juuri sen asiakas saa avatessaan sokettinsa.

Testaa ketju ja tee viasta näkyvä

Kaappaa ulommalla liitännällä, kun sisempi asiakas yhdistää. Sisemmän kättelyn pitäisi näkyä salattuna hyötykuormana ulomman tunnelin sisällä; jos se näkyy tavallisena UDP:nä osoitteeseen 203.0.113.9, isäntäreitti puuttuu eikä ketjua koskaan rakennettu.

Ketju, joka palaa hiljaa fyysiseen ylälinkkiin, on huonoin tulos, koska liitännän tila ei ilmoita mitään ja sisempi liikenne lähtee väärästä lähdeosoitteesta. Jos toinen asiakas voi yhdistää suoraan uudelleen, kun ulompi tunneli kaatuu, poista se polku käytöstä tai sido se ulompaan liitäntään, jotta vika on näkyvissä.

Lopeta kahteen virtaan ja yhteen sääntövedokseen: merkityn ja merkitsemättömän yhteyden pitäisi kulkea eri polkuja, ja ip rule show'n pitäisi listata aiottu prioriteetti. Jos molemmat virrat kulkevat samaa polkua, merkkiä ei käytetä siellä, missä luulet sen olevan.

Aiheeseen liittyvät artikkelit