Klient łączy się z serwerem OpenVPN na maszynie Compute Engine, okno stanu pokazuje połączenie, a ping do hosta w VPC nadal nigdzie nie dociera. Odruch każe dodać kolejną linię push i to nigdy nie naprawia problemu. Compute Engine decyduje, dokąd trafiają pakiety, na podstawie własnej tabeli tras i adresów, które interfejs VM faktycznie posiada, więc pula tunelu, której VM nie posiada, jest pulą, do której nikt nie dostarcza.

Śledź ginący pakiet zamiast pliku konfiguracji, a brakujące elementy pojawią się po kolei.

Zacznij od pakietu, który ginie

SYN opuszcza klienta, trafia do tunelu i dociera do VM jako pakiet hermetyzowany do celu w VPC. OpenVPN go dehermetyzuje i próbuje przesłać przez eth0, gdzie fabric zadaje jedno pytanie przed wszystkim innym: czy ta instancja posiada adres docelowy. Pula tunelu wycięta z podsieci kogoś innego nie przechodzi tego pytania, a pakiet jest odrzucany, zanim sprawdzona zostanie jakakolwiek trasa czy reguła zapory.

Kierunek od klienta do VPC ma więc dwa odrębne wymagania i żadne z nich nie jest dyrektywą push. VM potrzebuje zakresu alias obejmującego pulę tunelu i to właśnie czyni ją prawowitym właścicielem tych adresów. VPC potrzebuje trasy, która wskazuje VM jako next hop dla każdego chronionego prefiksu. Brak jednego z nich i pakiet ginie w innym miejscu, a klient widzi tę samą ciszę.

Czytaj awarię w tej kolejności, bo z punktu widzenia klienta oba warunki wyglądają identycznie. Tunel, który zgłasza połączenie, gdy nic nie odpowiada, jest sygnaturą problemu topologii, a nie złego szyfrowania.

Czy instancja posiada pulę tunelu

Daj VM zakres pomocniczy w obrębie jej własnej podsieci, a następnie pozwól OpenVPN wydawać adresy dokładnie z tego zakresu. Na instancji, której adres podstawowy to 10.156.0.10/20, alias /28 oddziela pulę od adresów, które inne instancje już mają:

gcloud compute instances network-interfaces update openvpn-vm \
  --zone=europe-west1-b \
  --aliases=eth0:10.156.1.0/28

Dyrektywa server musi wtedy opisywać ten sam blok. Jej pierwszy adres staje się bramą tunelu, a pozostałe adresy trafiają do klientów. Dwie liczby opisują tutaj jeden blok, sieć i maskę, i to jest składnia puli, której OpenVPN nadal oczekuje.

server 10.156.1.0 255.255.255.240

Potwierdź, że adres naprawdę trafił na interfejs, a nie tylko do konfiguracji OpenVPN. Fabric przekazuje to, co zgłasza NIC, a nie to, w co wierzy demon. Jedno polecenie to rozstrzyga:

ip -4 addr show dev eth0

Adres pomocniczy, który nigdy nie dociera do eth0, albo pula nakładająca się na inną podsieć, objawia się później jako sporadyczne straty, a nie jako błąd startu. Demon startuje, klienci się łączą i tylko niektóre cele zachowują się źle. Trzymaj zakres alias mały, aby pulę łatwo było rozpoznać w tabeli tras. Nigdy nie wycinaj go z podsieci, której inna instancja już używa.

Daj ruchowi powrotnemu next hop

Odpowiedź z hosta w VPC jest adresowana do adresu klienta w puli tunelu, który nie należy do żadnej podsieci znanej VPC. Bez trasy do tej puli odpowiedź zatrzymuje się na pierwszym hopie bez dopasowania, a żądanie mogło spokojnie odnieść sukces na drugim końcu.

gcloud compute routes create openvpn-return \
  --network=prod-vpc \
  --destination-range=192.168.127.0/24 \
  --next-hop-instance=openvpn-vm \
  --next-hop-instance-zone=europe-west1-b \
  --priority=800

Ta sama trasa jest potrzebna dla każdego prefiksu, który leży za klientem, a nie wewnątrz VPC. Te prefiksy potrzebują też wpisu iroute w pliku ccd tego klienta. Ten wpis to księgowość po stronie serwera: mówi serwerowi, który klient posiada prefiks, i nie instaluje nic na samym kliencie.

Zostaw listę push dla strony klienta rozmowy, ponieważ dodaje ona trasy tylko do maszyny, która się łączy. Linia push dla podsieci VPC i trasa VPC z powrotem do puli to dwie połowy tej samej ścieżki, a każda połowa osobno daje tunel, który niesie żądania, ale nie odpowiedzi.

Zapory, przekazywanie i hopki pomiędzy

Zapora VPC ocenia pakiet po dehermetyzacji, więc reguła ingress musi wpuścić pulę tunelu i każdy prefiks witryny, który dociera do VM tą drogą. Postawa default-deny zawodzi tutaj po cichu: pakiet jest odrzucany po dehermetyzacji, a log OpenVPN pokazuje zdrową sesję.

Na każdym hoście Linux, który przekazuje, a nie kończy, sprawdź, czy net.ipv4.ip_forward jest włączone. Reguła własności obowiązuje także tam: maszyna, która przekazuje dla podsieci, której nie posiada, odrzuca pakiet tak samo jak VM. Przeczytaj wartość, zanim obwinisz tunel.

Gdy zawodzi dokładnie jeden prefiks

Częściowa awaria jest najłatwiejszym przypadkiem do odczytania, bo wszystko inne na ścieżce zostało już udowodnione. Zacznij od listy tras i odczytaj zakres docelowy oraz next hop wpisu, który powinien obejmować prefiks, potem odczytaj opis instancji i porównaj jej zakres alias z pulą, którą wydaje serwer.

gcloud compute routes list --filter=destination-range~10.164.0.0
 gcloud compute instances describe openvpn-vm --format=get(networkInterfaces[0].aliasIpRanges)

Brakująca trasa objawia się brakiem next hopu dla prefiksu, a brakujący alias objawia się pakietem odrzuconym na interfejsie; z perspektywy klienta oba wyglądają podobnie, a w tych dwóch wynikach są całkowicie różne. Jeśli są oba, pozostałym podejrzanym jest iroute ccd klienta, który rości sobie prefiks.

Zapisz cztery wartości obok tunelu: zakres alias, pula serwera, wypchnięte prefiksy, trasy VPC. Nieaktualny alias psuje każdy adres puli, nieaktualna trasa psuje jeden kierunek, brakujący push ukrywa prefiks przed klientem, a błędny iroute wysyła prefiks do niewłaściwego peera. Następna osoba, która doda podsieć, potrzebuje wszystkich czterech w jednym miejscu, a notatka jest tańsza niż wieczór.

Powiązane artykuły