Client VPN przydziela klientowi adres, uzgadnianie się kończy, a połączenie i tak donikąd nie prowadzi. Zanim dotkniesz certyfikatów lub wersji klienta, spójrz na własną tabelę tras punktu końcowego. Punkt końcowy AWS Client VPN przekazuje pakiet tylko wtedy, gdy jedna z jego tras obejmuje prefiks celu; jeśli nic nie pasuje, pakiet jest odrzucany w punkcie końcowym, a host docelowy nigdy nie widzi SYN.

To decyzja o przekazywaniu, nie o uwierzytelnianiu. Zapada po podniesieniu tunelu i po ocenie reguł autoryzacji, dlatego prawidłowy certyfikat i prawidłowa grupa wciąż mogą dać martwe połączenie.

Punkt końcowy przekazuje tylko to, co obejmuje jego tabela tras

Każda trasa to CIDR celu oraz podsieć, która ma odbierać ruch. Punkt końcowy porównuje cel klienta z tą listą, wybiera pasujący wpis i wysyła pakiet do powiązanej podsieci. Brak wpisu oznacza brak następnego skoku.

Zwróć uwagę, czym trasa nie jest. Nie jest wpisem w tabeli tras VPC i niczego nie autoryzuje. Reguły autoryzacji decydują, czy grupa może dotrzeć do celu; trasy decydują, czy punkt końcowy ma gdzie wysłać pakiet. Oba muszą się zgadzać, a zawierają się z różnymi objawami, więc zgadywanie, który jest zepsuty, kosztuje całe popołudnie.

Klasyczna niezgodność to VPC z peeringiem. Ktoś dodaje trasę dla 10.20.0.0/24, podczas gdy host mieszka w 10.20.4.0/24, więc adres wypada poza każdy wpis. Przechwycenie po stronie klienta pokazuje powtarzane SYN bez odpowiedzi, a logi celu nie pokazują absolutnie niczego.

Przeczytaj listę tras przed certyfikatem

Trasy punktu końcowego to osobny obiekt, więc pytaj o nie bezpośrednio, zamiast czytać tabelę VPC:

aws ec2 describe-client-vpn-routes --client-vpn-endpoint-id cvpn-endpoint-0123456789abcdef0 --query 'Routes[].{Dest:DestinationCidr,Target:TargetSubnet,Origin:Origin}'

Wróż dokładny adres i długość prefiksu od zawodzącego klienta, a następnie sprawdź pokrycie znak po znaku. Obowiązuje dopasowanie najdłuższego prefiksu, więc szersza trasa cię nie uratuje, gdy węższa wskazuje gdzie indziej.

Jeden zasób na cel z for_each

Ręcznie pisane bloki tras rozjeżdżają się w chwili, gdy ktoś doda prefiks w konsoli. Trzymaj cele w mapie i twórz jeden zasób na klucz, aby każde dodanie lub usunięcie pozostało odizolowane.

variable "client_vpn_routes" {
  type = map(string)
  default = {
    "10.20.0.0/16"  = "subnet-0aa11bb22cc33dd44"
    "172.31.0.0/20" = "subnet-0aa11bb22cc33dd44"
  }
}

resource "aws_ec2_client_vpn_route" "this" {
  for_each               = var.client_vpn_routes
  client_vpn_endpoint_id = var.client_vpn_endpoint_id
  destination_cidr_block = each.key
  target_vpc_subnet_id   = each.value
  depends_on             = [aws_ec2_client_vpn_network_association.this]
}

Zachowaj zależność od powiązania sieciowego. Trasa potrzebuje powiązanej podsieci, więc apply, który tworzy oba, musi ustawić powiązanie jako pierwsze, a bez tego odwołania Terraform może spróbować trasy najpierw. Potem przeczytaj plan: liczba dodanych tras powinna odpowiadać dodanym prefiksom. Jeśli plan zastępuje także punkt końcowy, zasób punktu końcowego jest napisany źle, a jego zastosowanie odłącza każdego połączonego klienta.

Przejmowanie punktu końcowego, którego nie utworzyłeś

Większość zespołów dziedziczy punkt końcowy zbudowany w konsoli, dlatego nie istnieje kod tras. Nie stawiaj drugiego punktu końcowego tylko po to, by wciągnąć trasy do Terraform.

Zamiast tego zaimportuj go albo przekaż identyfikatory jako zmienne i pozostaw odziedziczone obiekty niezarządzane. Import wymaga formatu identyfikatora, który dostawca dokumentuje dla każdego typu zasobu; koduje on punkt końcowy, prefiks celu i podsieć docelową. Skopiuj ten ciąg z dokumentacji zasobu, zamiast składać go z pamięci, uruchom plan i oczekuj braku zmian, zanim dodasz coś nowego.

Śledź pakiet w kolejności, w jakiej podróżuje

Gdy trasa istnieje, a połączenie nadal zawodzi, przejdź ścieżkę po kolei, zamiast zgadywać na najwyższej warstwie.

  1. Trasa: prefiks obejmuje cel i wskazuje podsieć powiązaną z punktem końcowym.
  2. Autoryzacja: reguła autoryzacji zezwala na ten cel grupie użytkownika. Sama trasa nigdy nie daje dostępu.
  3. Droga powrotna: tabela tras podsieci docelowej odsyła odpowiedzi w stronę punktu końcowego, a grupa zabezpieczeń zezwala na port z puli adresów klienta.
  4. Aplikacja: otwórz prawdziwe połączenie TCP z klienta, a potem potwierdź, że logi celu pokazują oczekiwany adres źródłowy z puli.

Zmieniaj jeden prefiks na apply, potem ponownie przeczytaj listę tras i zapisz razem cel, regułę autoryzującą oraz drogę powrotną. Następna osoba, która będzie debugować odrzucone połączenie, powinna zacząć od tego spisu, a nie od teorii o certyfikatach.

Powiązane artykuły