Postawienie drugiego OpenVPN serwera daje ci drugie miejsce, do którego klienci mogą się łączyć, i nic więcej. Nie umieszcza tych klientów w sieci pierwszego serwera, a opcja o nazwie client-to-client zmienia tylko przekazywanie wewnątrz jednego procesu serwera. Obie pule stają się jedną siecią, gdy świadomie trasujesz między nimi, z właścicielem dla każdego kierunku. Wszystko poniżej zakłada tryb TUN w przestrzeni użytkownika z wyłączonym tym wewnętrznym przekazywaniem, więc decyzję podejmuje jądro.

Mit: jedna lista kont, jedna sieć

Uwierzytelnianie i osiągalność są mylone, bo oba mieszkają w konfiguracji serwera. Użytkownik, który może zalogować się do dowolnej z dwóch bram, wygląda z zewnątrz jak użytkownik jednego systemu z dwojgiem drzwi. W środku każdy serwer rozdaje adresy z własnej puli i instaluje trasy tylko dla klientów, których obsługuje. Więc klient na bramie A, który wysyła pakiet do klienta na bramie B, prosi o miejsce docelowe, o którym jego własny serwer nigdy nie słyszał. Pakiet trafia na trasę domyślną A, opuszcza tunel i dociera do firewalla, którego nigdy nie poproszono o jego przepuszczenie.

Dodanie drugiego serwera nie dodaje więc nadmiarowości, wykrywania ani wspólnej domeny rozgłoszeniowej. Dodaje sieć trasowaną, która wymaga planu, a plan zaczyna się od adresacji.

Daj każdej bramie własną pulę i adres tranzytowy

Dwa zakresy, które nie mogą kolidować z niczym innym, plus małe łącze tranzytowe między hostami, to cały plan adresacji. Trzymaj tranzyt w prywatnym segmencie, który kontrolujesz, i zapisz liczby, zanim którykolwiek serwer wyda dzierżawę.

GatewayClient poolTransit address
gateway-a10.64.10.0/24172.28.44.1/30
gateway-b10.64.20.0/24172.28.44.2/30

Oprzyj się pokusie, by dać obu serwerom tę samą pulę, aby profile pozostały identyczne. Trasa jądra nie potrafi powiedzieć, który z dwóch hostów aktualnie posiada dowolny adres w obrębie współdzielonego zakresu, więc tablica routingu wskazywałaby na jedną bramę, a klient może być podłączony do drugiej. Nazwy interfejsów to lokalne konwencje, nie współdzielony stan. Oba hosty nazywają tutaj urządzenie tunelu tun0, a łącze tranzytowe transit0, co jest w porządku, bo żaden pakiet nie niesie tych nazw.

Zainstaluj trasę po obu stronach

Każda brama potrzebuje trasy do puli drugiej przez adres tranzytowy, a przekazywanie musi być włączone, by któraś mogła działać jako hop. Najpierw potwierdź bieżącą tablicę, potem dodaj wpis i utrwal go przez menedżera sieci hosta, a nie przez hak ponownego połączenia.

sysctl net.ipv4.ip_forward
ip route add 10.64.20.0/24 via 172.28.44.2 dev transit0
ip route get 10.64.20.37

Odbij to na drugim hoście z zamienionymi pulami. Wielokrotne dodawanie tej samej trasy z niepowiązanego skryptu to sposób, w jaki host kończy z kilkoma kopiami i tajemniczą zmianą, gdy ktoś następnym razem czyta tablicę. Jeśli łącze tranzytowe samo jest tunelem, trasa wskazuje na topologię tego tunelu, a hop musi przetrwać jego ponowne połączenie. Adres tranzytowy, który znika na trzydzieści sekund, zabiera ze sobą ścieżkę między pulami, co jest właściwością projektu wartą ogłoszenia, a nie odkrycia.

Wypchnij trasę klienta bez udawania własności

Klienci potrzebują trasy do zdalnej puli, inaczej ich własny system operacyjny wyśle pakiet do domyślnej bramy i tunel nigdy go nie zobaczy. Konfiguracja serwera to naturalne miejsce, by ją dostarczyć.

push "route 10.64.20.0 255.255.255.0"

Umieść lustrzaną linię w konfiguracji drugiego serwera, następnie połącz ponownie klienta testowego i odczytaj jego tablicę. Klient, który ignoruje wypchnięte trasy, potrzebuje własnej zatwierdzonej konfiguracji, a trasa, która nigdy nie przychodzi, nie jest kontrolą dostępu. Nie dawaj klientowi iroute dla całej puli drugiej bramy. Ta dyrektywa istnieje dla podsieci za jednym połączonym klientem, a użycie jej do zakrycia brakującej trasy między bramami daje serwer, który wierzy, że posiada adresy, których nie może osiągnąć.

Udowodnij jedno żądanie i odmów drugiego

Wybierz realną operację, na przykład HTTPS od klienta na 10.64.10.21 do usługi na 10.64.20.37, i zezwól dokładnie na to na obu hostach. Każdy firewall przepuszcza żądanie po stronie wejściowej i śledzoną odpowiedź po stronie powrotnej; polityka samej usługi docelowej nadal musi je zaakceptować.

iptables -A FORWARD -i tun0 -o transit0 -s 10.64.10.21 -d 10.64.20.37 -p tcp --dport 443 -j ACCEPT
iptables -A FORWARD -i transit0 -o tun0 -d 10.64.10.21 -s 10.64.20.37 -p tcp --sport 443 -m conntrack --ctstate ESTABLISHED -j ACCEPT

Przy wzajemnych trasach źródłowy NAT jest tu niepotrzebny i wręcz szkodliwy: tłumaczenie źródła ukrywa, który klient wysłał żądanie, i niweczy politykę opartą na źródle po stronie celu. Sprawdź, czy istniejąca reguła masquerade dla wyjścia do internetu nie łapie także tej ścieżki. Potem przetestuj odmowę. Usługa, która powinna pozostać lokalna w puli B, musi pozostać nieosiągalna z puli A, a pary klientów na tej samej bramie też trzeba przetestować, bo właśnie zmieniona polityka przekazywania dotyczy także ich.

Jeszcze jedna korekta modelu mentalnego: łącze tranzytowe przenosi odszyfrowane pakiety wewnętrzne, więc jest granicą zaufania, a nie prywatną gwarancją. Jeśli przecina sieć, której nie kontrolujesz, chroń ten hop zatwierdzonym szyfrowanym tunelem i trasuj przez jego rzeczywistą topologię. TLS od końca do końca nadal sam uwierzytelnia aplikację, dlatego usługa wewnętrzna powinna go dalej używać.

Powiązane artykuły