Å stable en andre OpenVPN-klient på én Linux-vert feiler på ett av to steder. Enten når ikke den indre klienten sin egen server fordi den ytre tunnelen har tatt over den transporten, eller den andre klienten skriver om rutetabellen og den første tunnelen slutter å virke. Begge problemene ligger i rutingen, ikke i krypteringen, og begge løses før den nye tunnelen bærer noen applikasjonstrafikk. Adressene her er illustrative: tun0 er den ytre tunnelen, 203.0.113.9 er den indre serveren, og TCP 9999 er flyten som må bruke den indre veien.

To feilmoduser, én rutetabell

En indre klient åpner en UDP-socket mot serveren sin, og den socketen følger gjeldende rutetabell som enhver annen. Hvis den ytre tunnelen allerede eier standardruten, går håndtrykkspakningene inn i den ytre tunnelen. Det virker bare når den ytre serveren kan nå den indre serveren og den andre siden godtar å bære flyten; ellers stopper håndtrykket og klienten prøver på nytt.

Den andre feilen kommer fra serverens push. Den vanlige pushen er redirect-gateway def1, som installerer 0.0.0.0/1 og 128.0.0.0/1 i stedet for å erstatte standardruten. To klienter som hver installerer sitt eget /1-par kolliderer derfor, og det nyeste paret vinner for nesten alle mål. Se etter de to prefiksene i tabellen når en tunnel dør etter at den andre kobler til, fordi standardruten selv kanskje aldri har endret seg.

Merk flyten og gi den en tabell

Styr den valgte trafikken ved å merke den i mangle-tabellen og matche merket i en policyregel. Regelen peker på en egen tabell der standardruten er den indre enheten, slik at bare merkede pakker tar den indre veien.

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

De fleste feilene i dette regelsettet kommer fra to feilgrep. Merkeverdien som brannmuren setter, og verdien regelen matcher, må være identiske, fordi avvik ikke gir noen feil og ingen effekt. Og PREROUTING ser bare pakker som kommer utenfra, så en tilkobling som startes på denne verten trenger en OUTPUT-regel med samme match før den i det hele tatt merkes.

Ta ruteeierskapet fra den andre klienten

To alternativer hindrer den andre klienten i å redigere tabellen, og de virker på forskjellige steder. route-nopull ignorerer de pushede rutealternativene, så ingenting installeres. route-noexec godtar de pushede alternativene inn i klientens miljø, men lar tabellendringen være opp til en hook, og det er det du vil når du trenger å se hva serveren tilbød.

Hooken kjører med de pushede verdiene i miljøet sitt, og den bør bare legge til oppføringene du godkjente. Gjør den idempotent: tøm tabellen den eier før du bygger den opp igjen, og ikke anta at forrige kjøring etterlot en ren tilstand. En gjentilkobling kaller hooken på nytt, og en hook som legger til uten å tømme, samler dupliserte ruter.

Velg én eier og skriv den ned. En profil som setter begge alternativene, eller en hook som konkurrerer med et manuelt skript, gir en tabell ingen kan forklare senere.

Fest begge serveradressene

Den indre serveren trenger en vertsrute gjennom den ytre enheten før den indre klienten kobler til. Den oppføringen er det som holder den indre transporten inne i den ytre tunnelen i stedet for å la den følge standardruten.

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

Legg også til en tilsvarende vertsrute for den ytre serveren i hovedtabellen, ellers kan en gjentilkobling rute den ytre klientens egen transport inn i sin egen tunnel. Rekkefølgen er ikke valgfri: legg til disse oppføringene etter at det relevante grensesnittet finnes, altså en hook eller et skript som kjører etter tilkoblingen. En rute som peker på en enhet som er nede, fjernes eller ignoreres, så en oppføring skrevet ved oppstart overlever ikke sekvensen du antok.

Sjekk oppslaget i stedet for å lese hele tabellen. Utdataene fra ruteoppslaget navngir enheten og kildeadressen kjernen vil bruke, og det er nøyaktig det klienten får når den åpner socketen sin.

Test kjeden og gjør feilen synlig

Fang på det ytre grensesnittet mens den indre klienten kobler til. Det indre håndtrykket skal vises som kryptert nyttelast inne i den ytre tunnelen; hvis det vises som vanlig UDP til 203.0.113.9, mangler vertsruten og kjeden ble aldri bygget.

En kjede som stille faller tilbake til den fysiske uplinken er det verste utfallet, fordi grensesnittilstanden ikke kunngjør noe og den indre trafikken går ut fra feil kildeadresse. Hvis den andre klienten kan koble direkte til på nytt når den ytre tunnelen faller, deaktiver den veien eller bind den til det ytre grensesnittet slik at feilen blir synlig.

Avslutt med to flyter og én regelutskrift: en merket og en umerket tilkobling skal ta ulike veier, og ip rule show skal liste prioriteten du hadde tenkt. Hvis begge flytene tar samme vei, brukes ikke merket der du tror.

Relaterte artikler