Zacząłem od zewnątrz, tak jak zrobiłby to użytkownik: wpisałem nazwę w przeglądarce telefonu na danych komórkowych i patrzyłem, jak połączenie wisi, aż upłynął limit czasu. Nazwa się rozwiązywała, więc DNS był w porządku. Strona przekierowania portów routera domowego też była ślepą uliczką, bo jej adres WAN pokazywał 100.64.31.42, a to nie jest adres, do którego dostawca mnie routuje z internetu. Ten numer wyjaśnia całą awarię: łącze znajduje się za carrier-grade NAT, więc publiczny adres po mojej stronie tunelu należy do dostawcy. To, co następuje, to droga, którą przeszedłem od tej zawieszonej karty do usługi, która odpowiada.

Zacznij od klienta i idź do środka

Zanim zmienisz jakąkolwiek regułę, udowodnij, gdzie zatrzymuje się łańcuch. Na laptopie uruchomiłem dig +short files.example.net i dostałem adres VPS-a, co wykluczyło nieaktualny DNS na mojej maszynie. Potem curl -v --connect-timeout 5 files.example.net:5022 przekroczył limit czasu zamiast zostać odrzucony. Ta różnica ma znaczenie: przekroczenie limitu zwykle oznacza, że pakiety są wyrzucane po drodze, a odrzucenie oznacza, że coś odpowiedziało i powiedziało nie.

Następnym skokiem do środka był sam VPS. ss -ltnp nie pokazał niczego nasłuchującego na 5022, co było oczekiwane przed powstaniem reguły DNAT. Na tej samej maszynie wg show (lub ip -br a show tun0 dla OpenVPN) potwierdził, że peer domowy działa i ma świeży handshake. Jeśli peer nie działa, żadna reguła NAT nie pomoże, a zielone światło na stronie VPN routera domowego nic nie znaczy.

Potwierdź, że łącze domowe naprawdę jest za CGNAT

Porównaj adres, który router podaje na interfejsie WAN, z tym, co widzi zewnętrzna usługa. Wszystko w 100.64.0.0/10, czyli od 100.64.x.x do 100.127.x.x, to zakres adresów współdzielonych z RFC 6598 i nie da się go osiągnąć z internetu. Do tego samego wniosku dojdziesz, gdy router twierdzi, że ma zwykły adres prywatny, a publiczne sprawdzenie zwraca coś niezwiązanego. Łącze CGNAT może też mieć adres publiczny ważny tylko do następnego lease, więc przekierowanie portu wydaje się działać godzinę, a potem cicho umiera.

Niektórzy dostawcy rzeczywiście dają prawdziwy publiczny adres, ale blokują przychodzące porty 80 i 443 na kontach domowych. Jeśli Twoja usługa jest tylko webowa, a adres WAN jest naprawdę publiczny, zapytaj wsparcie, zanim zbudujesz przekaźnik. Jeśli nie jest, poniższy projekt dotyczy każdego portu tak samo, i warto zatrzymać eksperyment po stronie routera: translator w sieci dostawcy kończy połączenie, zanim dotrze ono do Twojego interfejsu WAN.

Skieruj nazwę na adres VPS-a

DNS nie przekazuje ruchu, więc rekord A usługi musi zawierać publiczny adres VPS-a. Rekord A wskazujący 192.168.1.20 rozwiązuje się użytecznie tylko dla klientów będących już w VPN; z internetu rozwiązuje się na adres, którego nikt nie może routować. Dla dostępu administracyjnego do samego VPS-a trzymam osobną nazwę, żeby nigdy nie mylić, do którego hosta odnosi się rekord.

Jeśli zarówno VPS, jak i maszyna domowa serwują HTTP, daj każdej własną nazwę i pozwól VPS-owi zdecydować, kto odpowiada. Złożenie ich w jedną nazwę i nadzieja, że proxy wybierze właściwy backend, to dokładnie sposób, w jaki spędzasz całe popołudnie na debugowaniu niewłaściwego hosta.

Jeden port przez DNAT, SSH zostaje na 22

Opcja bezpośrednia to NAT docelowy na VPS-ie. Włącz forwarding dla działającego jądra i trzymaj adres tunelowy serwera domowego w regule, a nie jego adres LAN:

sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A PREROUTING -p tcp -d 198.51.100.10 --dport 5022 -j DNAT --to-destination 10.8.0.2

Zostaw SSH do samego VPS-a na 22 i przekieruj inny port, na przykład 5022, do maszyny domowej. Przekierowanie 22 do wyłączonej maszyny oznacza utratę jedynej drogi, która mogłaby ją naprawić. Ta sama logika dotyczy proxy: trzymaj port zarządzania VPS-a poza regułami przekaźnika.

Utrwal reguły, gdy zaczną działać. W Debianie lub Ubuntu apt install iptables-persistent, a potem netfilter-persistent save zapisują je do /etc/iptables/rules.v4. Na hoście z firewalld odpowiednikiem jest trwałe przekierowanie portu w strefie, które wymaga firewall-cmd --reload przed zastosowaniem. Reguły żyjące tylko w pamięci znikają przy pierwszym restarcie serwisowym dostawcy, zwykle o złej godzinie.

Napraw trasę powrotną albo uniknij potrzeby jej posiadania

DNAT przepisuje tylko cel. Serwer domowy widzi połączenie z oryginalnego adresu klienta, a jeśli jego trasa domyślna wskazuje router domowy, odpowiedź wychodzi przez domowy WAN, gdzie translator dostawcy ją wyrzuca. Ta asymetria była drugą awarią, na którą trafiłem, po tym jak reguła DNAT wyglądała na całkowicie poprawną.

Dwie poprawki działają. Daj maszynie domowej trasę polityki, aby ruch z tunelu wracał przez tunel:

ip rule add from 10.8.0.2 table 100
ip route add default dev wg0 table 100

Albo pozwól VPS-owi przepisać źródło, aby odpowiedź miała adres, który może osiągnąć, i pozwól conntrackowi odwrócić ją na wyjściu:

iptables -t nat -A POSTROUTING -d 10.8.0.2 -p tcp --dport 5022 -j SNAT --to-source 10.8.0.1

Wersja SNAT ukrywa prawdziwy adres klienta przed serwerem domowym, więc logi aplikacji pokazują 10.8.0.1 jako peera. Przekaż oryginalny adres na poziomie aplikacji albo zaakceptuj utratę logowania na klienta, ale zdecyduj o tym świadomie, zamiast odkrywać to podczas incydentu.

Sprawdź całą drogę z zewnątrz

Sprawdź z sieci, która nie jest ani VPS-em, ani domem: telefonu na danych komórkowych albo taniej powłoki gdzie indziej. nc -vz files.example.net 5022 powinien zgłosić udane połączenie, a openssl s_client -connect files.example.net:443 -servername files.example.net powinien pokazać certyfikat dla publicznej nazwy. Potem sprawdź grupę zabezpieczeń lub zaporę chmurową dostawcy. Reguła DNAT, która nigdy nie widzi pakietu, jest zwykle blokowana jedną warstwę wyżej niż host.

Na koniec zdecyduj, co się dzieje, gdy tunel padnie. Reguła DNAT nadal przyjmuje połączenia i po cichu podaje je do martwego tunelu, co wygląda dokładnie jak zepsuta usługa. Kontrola kondycji na VPS-ie, która odrzuca port, gdy peer nie działa, kosztuje kilka linii i oszczędza godzinę zgadywania. Potem przestań edytować reguły i obserwuj to przez dzień, zanim jej zaufasz.

Powiązane artykuły