Kæd to OpenVPN-klienter sammen på én Linux-vært med fwmark
Begge klienter vil have standardruten. Fastgør den indre server med en værtsrute, forhindr den anden klient i at omskrive tabeller, og styr derefter flows med fwmark.
At stable en anden OpenVPN-klient på én Linux-vært fejler på et af to steder. Enten kan den indre klient ikke nå sin egen server, fordi den ydre tunnel har overtaget den transport, eller den anden klient omskriver rutetabellen, og den første tunnel holder op med at virke. Begge problemer ligger i rutning, ikke i kryptering, og begge løses, før den nye tunnel bærer nogen applikationstrafik. Adresserne her er illustrerende: tun0 er den ydre tunnel, 203.0.113.9 er den indre server, og TCP 9999 er det flow, der skal bruge den indre vej.
To fejltilstande, én rutetabel
En indre klient åbner en UDP-socket mod sin server, og den socket følger den aktuelle rutetabel som enhver anden. Hvis den ydre tunnel allerede ejer standardruten, går håndtrykspakkerne ind i den ydre tunnel. Det virker kun, når den ydre server kan nå den indre server, og den anden side accepterer at bære flowet; ellers går håndtrykket i stå, og klienten prøver igen.
Den anden fejl kommer fra serverens push. Det sædvanlige push er redirect-gateway def1, som installerer 0.0.0.0/1 og 128.0.0.0/1 i stedet for at erstatte standardruten. To klienter, der hver installerer deres eget /1-par, kolliderer derfor, og det nyeste par vinder for næsten enhver destination. Kig efter de to præfikser i tabellen, når en tunnel dør, efter at den anden er forbundet, fordi selve standardruten måske aldrig er blevet ændret.
Markér flowet, og giv det en tabel
Styr den valgte trafik ved at markere den i mangle-tabellen og matche mærket i en politikregel. Reglen peger på en dedikeret tabel, hvis standardrute er den indre enhed, så kun markerede pakker tager den indre vej.
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 200De fleste fejl i dette regelsæt kommer fra to fejl. Den mærkeværdi, firewallen sætter, og den værdi, reglen matcher, skal være identiske, fordi en uoverensstemmelse hverken giver fejl eller effekt. Og PREROUTING ser kun pakker, der ankommer udefra, så en forbindelse, der startes på denne vært, har brug for en OUTPUT-regel med samme match, før den overhovedet markeres.
Fjern ruterejerskabet fra den anden klient
To muligheder forhindrer den anden klient i at redigere tabellen, og de virker på forskellige punkter. route-nopull ignorerer de push'ede ruteindstillinger, så intet installeres. route-noexec accepterer de push'ede indstillinger i klientens miljø, men overlader tabelændringen til et hook, hvilket er præcis, hvad du vil, når du skal se, hvad serveren tilbød.
Hooket kører med de push'ede værdier i sit miljø, og det bør kun tilføje de poster, du har godkendt. Gør det idempotent: ryd den tabel, det ejer, før det genopbygger, og antag ikke, at den forrige kørsel efterlod en ren tilstand. En genopkobling kalder hooket igen, og et hook, der tilføjer uden at rydde, vil akkumulere dublerede ruter.
Vælg én ejer, og skriv den ned. En profil, der sætter begge muligheder, eller et hook, der konkurrerer med et manuelt script, giver en tabel, som ingen senere kan forklare.
Fastgør begge serveradresser
Den indre server har brug for en værtsrute gennem den ydre enhed, før den indre klient forbinder. Den post er det, der holder den indre transport inde i den ydre tunnel i stedet for at lade den følge standardruten.
ip route add 203.0.113.9/32 dev tun0
ip route get 203.0.113.9Tilføj også en tilsvarende værtsrute for den ydre server i hovedtabellen, ellers kan en genopkobling rute den ydre klients egen transport ind i dens egen tunnel. Rækkefølgen er ikke valgfri: tilføj disse poster, efter at den relevante grænseflade findes, hvilket betyder et hook eller et script, der kører efter forbindelsen. En rute, der peger på en enhed, som er nede, fjernes eller ignoreres, så en post, der skrives ved opstart, overlever ikke det forløb, du antog.
Kontrollér opslaget i stedet for at læse hele tabellen. Ruteopslagets output angiver den enhed og kildeadresse, som kernen vil bruge, og det er præcis, hvad klienten får, når den åbner sin socket.
Test kæden, og gør fejlen synlig
Fang på den ydre grænseflade, mens den indre klient forbinder. Det indre håndtryk bør fremstå som krypteret nyttelast inde i den ydre tunnel; hvis det fremstår som almindelig UDP til 203.0.113.9, mangler værtsruten, og kæden blev aldrig bygget.
En kæde, der stille falder tilbage til det fysiske uplink, er det værste udfald, fordi grænsefladens tilstand ikke annoncerer noget, og den indre trafik forlader den forkerte kildeadresse. Hvis den anden klient kan genopkoble direkte, når den ydre tunnel falder, skal du deaktivere den vej eller binde den til den ydre grænseflade, så fejlen bliver synlig.
Afslut med to flows og et regeldump: en markeret forbindelse og en umarkeret bør tage forskellige veje, og ip rule show bør vise den prioritet, du havde tænkt. Hvis begge flows tager samme vej, anvendes mærket ikke der, hvor du tror.