AWS VPN GCP Cloud VPN IPsec IKE networking

AWS Site-to-Site VPN tunel DOWN: diagnoza błędu negocjacji IKE Phase 1/2 z GCP Cloud VPN

Diagnoza i naprawa tunelu AWS Site-to-Site VPN w stanie DOWN spowodowanego błędem negocjacji IKE Phase 1/2 przy połączeniu z GCP Cloud VPN.

·
Twój tunel AWS Site-to-Site VPN jest w stanie DOWN, a GCP Cloud VPN pokazuje "Waiting for peer" lub "First handshake". Ruch między chmurami przestał przepływać. Poniższy runbook opisuje każdą niezgodność negocjacji IKE, która powoduje tę awarię, i jak ją naprawić.

Objawy

Konsola AWS VPN pokazuje tunel w stanie DOWN:

Tunnel 1: DOWN
  Status message: IPSEC IS DOWN
  IKE Status: Phase 1 negotiation failed

Konsola GCP Cloud VPN pokazuje jeden z komunikatów:

VPN tunnel status: Waiting for peer
VPN tunnel status: First handshake

Cloud Logging po stronie GCP pokazuje powtarzające się próby negocjacji:

IKE SA negotiation failed: no proposal chosen

Ruch między AWS VPC a GCP VPC jest całkowicie odrzucany. Sesja BGP (jeśli skonfigurowana) nigdy się nie zestawia, ponieważ tunel IPsec nie może się podnieść.

Po stronie AWS metryki tunelu VPN w CloudWatch potwierdzają problem:

aws cloudwatch get-metric-statistics \
  --namespace "AWS/VPN" \
  --metric-name TunnelState \
  --dimensions Name=VpnId,Value=vpn-0abc123def456 \
  --start-time $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%S) \
  --end-time $(date -u +%Y-%m-%dT%H:%M:%S) \
  --period 300 \
  --statistics Average

VPN zwraca konsekwentnie 0.0 (tunel down).

Przyczyna

Błąd negocjacji IKE Phase 1/2 między AWS a GCP jest zwykle spowodowany jedną lub kilkoma niezgodnościami:

  1. Niezgodność wersji IKE. AWS Site-to-Site VPN domyślnie używa IKEv2. Jeśli tunel GCP Cloud VPN został utworzony z IKEv1 (lub odwrotnie), początkowy handshake nie zestawia połączenia, ponieważ format nagłówka IKE różni się między wersjami.

  2. Różnice w kodowaniu klucza PSK. Znaki specjalne w kluczu PSK (takie jak !, @, #, $) mogą być interpretowane inaczej przez każdą platformę. AWS przechowuje PSK bez modyfikacji, ale niektóre konfiguracje GCP mogą kodować lub escapować znaki podczas wprowadzania.

  3. Niezgodność propozycji SA Phase 2 (IPsec). AWS i GCP muszą uzgodnić identyczne algorytmy szyfrowania i integralności. AWS może zaproponować AES-256-CBC z SHA-256, podczas gdy GCP domyślnie używa AES-256-GCM (który łączy szyfrowanie i integralność). Jeśli nie ma wspólnych propozycji, Phase 2 nie łączy nawet po udanym Phase 1.

  4. Zbyt agresywny timeout DPD (Dead Peer Detection). Jeśli jedna strona ma bardzo krótki timeout DPD (np. 10 sekund na AWS), a druga dłuższy interwał, agresywna strona zrywa tunel zanim peer odpowie na sondę DPD.

  5. Kolizja okna rekeying. Obie strony inicjują rekeying w tym samym momencie. Gdy AWS i GCP jednocześnie próbują odnowić klucz (z powodu zbliżonych wartości SA lifetime), kolizja powoduje odrzucenie istniejącego SA bez udanej negocjacji nowego.

Rozwiązanie

Krok 1: Pobranie aktualnej konfiguracji tunelu AWS VPN

aws ec2 describe-vpn-connections \
  --vpn-connection-ids vpn-0abc123def456 \
  --query 'VpnConnections[0].Options.TunnelOptions' \
  --output json

Zanotuj wartości IkeVersions, Phase1EncryptionAlgorithms, Phase2EncryptionAlgorithms, DPDTimeoutSeconds i PreSharedKey.

Krok 2: Pobranie konfiguracji tunelu GCP Cloud VPN

gcloud compute vpn-tunnels describe my-vpn-tunnel \
  --region us-central1 \
  --format="yaml(ikeVersion, sharedSecret, status, detailedStatus)"

Krok 3: Wyrównanie wersji IKE

Obie strony muszą używać tej samej wersji IKE. Wymuszenie IKEv2 po obu stronach:

Na AWS - modyfikacja opcji tunelu VPN:

aws ec2 modify-vpn-tunnel-options \
  --vpn-connection-id vpn-0abc123def456 \
  --vpn-tunnel-outside-ip-address 203.0.113.1 \
  --tunnel-options "IkeVersions=[{Value=ikev2}]"

Na GCP - odtworzenie tunelu z IKEv2 (GCP nie wspiera zmiany wersji IKE bez tworzenia tunelu na nowo):

gcloud compute vpn-tunnels delete my-vpn-tunnel --region us-central1 --quiet

gcloud compute vpn-tunnels create my-vpn-tunnel \
  --region us-central1 \
  --peer-address 203.0.113.1 \
  --shared-secret "YOUR_PSK_HERE" \
  --ike-version 2 \
  --vpn-gateway my-vpn-gateway \
  --interface 0 \
  --router my-cloud-router

Krok 4: Weryfikacja zgodności klucza PSK

Eksport PSK z AWS:

aws ec2 describe-vpn-connections \
  --vpn-connection-ids vpn-0abc123def456 \
  --query 'VpnConnections[0].Options.TunnelOptions[0].PreSharedKey' \
  --output text

Porównanie bajt po bajcie ze stroną GCP:

gcloud compute vpn-tunnels describe my-vpn-tunnel \
  --region us-central1 \
  --format="value(sharedSecret)"

Jeśli klucze zawierają znaki specjalne, zamień je na czysto alfanumeryczny PSK po obu stronach. AWS zaleca 8-64 znaki używając wyłącznie liter, cyfr, kropek i podkreślników.

Aktualizacja na AWS:

aws ec2 modify-vpn-tunnel-options \
  --vpn-connection-id vpn-0abc123def456 \
  --vpn-tunnel-outside-ip-address 203.0.113.1 \
  --tunnel-options "PreSharedKey=MySecurePsk2024.tunnel1"

Aktualizacja na GCP (wymaga odtworzenia lub aktualizacji tunelu):

gcloud compute vpn-tunnels update my-vpn-tunnel \
  --region us-central1 \
  --shared-secret "MySecurePsk2024.tunnel1"

Krok 5: Wyrównanie algorytmów szyfrowania Phase 2

Ustawienie obu stron na AES-256-GCM (zalecany ze względu na wydajność i bezpieczeństwo):

Na AWS:

aws ec2 modify-vpn-tunnel-options \
  --vpn-connection-id vpn-0abc123def456 \
  --vpn-tunnel-outside-ip-address 203.0.113.1 \
  --tunnel-options '{
    "Phase1EncryptionAlgorithms": [{"Value": "AES256"}],
    "Phase1IntegrityAlgorithms": [{"Value": "SHA2-256"}],
    "Phase1DHGroupNumbers": [{"Value": 20}],
    "Phase2EncryptionAlgorithms": [{"Value": "AES256-GCM-16"}],
    "Phase2IntegrityAlgorithms": [{"Value": "SHA2-256"}],
    "Phase2DHGroupNumbers": [{"Value": 20}]
  }'

GCP Cloud VPN HA automatycznie negocjuje kompatybilne algorytmy przy użyciu IKEv2, ale warto zweryfikować w logach:

gcloud logging read 'resource.type="vpn_gateway" AND textPayload:"proposal"' \
  --project my-project \
  --limit 20 \
  --format="table(timestamp, textPayload)"

Krok 6: Dostosowanie timeout DPD

Ustawienie rozsądnego timeout DPD na AWS (30 sekund to bezpieczna wartość domyślna):

aws ec2 modify-vpn-tunnel-options \
  --vpn-connection-id vpn-0abc123def456 \
  --vpn-tunnel-outside-ip-address 203.0.113.1 \
  --tunnel-options "DPDTimeoutSeconds=30,DPDTimeoutAction=restart"

GCP Cloud VPN używa stałego interwału DPD wewnętrznie. Ustawienie 30 sekund na AWS z akcją restart zapewnia automatyczne odtworzenie tunelu po krótkotrwałych problemach sieciowych bez nadmiernej agresywności.

Krok 7: Zapobieganie kolizjom rekeying

Przesunięcie wartości SA lifetime między stronami. Na AWS ustawienie Phase 1 lifetime na 28800 sekund (8 godzin) i Phase 2 na 3600 sekund (1 godzina):

aws ec2 modify-vpn-tunnel-options \
  --vpn-connection-id vpn-0abc123def456 \
  --vpn-tunnel-outside-ip-address 203.0.113.1 \
  --tunnel-options '{
    "Phase1LifetimeSeconds": 28800,
    "Phase2LifetimeSeconds": 3600,
    "RekeyMarginTimeSeconds": 540,
    "RekeyFuzzPercentage": 100
  }'

Wartość RekeyFuzzPercentage ustawiona na 100 dodaje losowość do okna rekeying, zmniejszając prawdopodobieństwo jednoczesnego odnawiania kluczy z obu stron.

Krok 8: Sprawdzenie logów GCP Cloud VPN pod kątem pozostałych błędów

gcloud logging read '
  resource.type="vpn_gateway"
  AND severity>=WARNING
  AND timestamp>="2026-07-14T00:00:00Z"
' --project my-project --limit 50 --format="table(timestamp, severity, textPayload)"

Szukaj komunikatów typu “no proposal chosen”, “invalid ke payload” lub “auth failed”, aby zidentyfikować ewentualne pozostałe niezgodności.

Walidacja

Potwierdzenie, że oba tunele pokazują UP na AWS:

aws ec2 describe-vpn-connections \
  --vpn-connection-ids vpn-0abc123def456 \
  --query 'VpnConnections[0].VgwTelemetry[*].{OutsideIP:OutsideIpAddress,Status:Status,StatusMessage:StatusMessage}' \
  --output table

Oczekiwany wynik:

------------------------------------------------------
|                  VgwTelemetry                       |
+----------------+--------+--------------------------+
|   OutsideIP    | Status |     StatusMessage        |
+----------------+--------+--------------------------+
|  203.0.113.1   |  UP    |  2 BGP ROUTES            |
|  203.0.113.2   |  UP    |  2 BGP ROUTES            |
+----------------+--------+--------------------------+

Potwierdzenie statusu tunelu GCP:

gcloud compute vpn-tunnels describe my-vpn-tunnel \
  --region us-central1 \
  --format="value(status, detailedStatus)"

Oczekiwany wynik: ESTABLISHED Tunnel is up and running.

Weryfikacja sesji BGP na Cloud Router:

gcloud compute routers get-status my-cloud-router \
  --region us-central1 \
  --format="yaml(result.bgpPeerStatus)"

Test łączności end-to-end z instancji w AWS VPC do GCP VPC:

# From AWS EC2 instance
ping -c 5 10.128.0.2

# Full path test
traceroute 10.128.0.2

Monitoring stabilności tunelu przez następną godzinę:

aws cloudwatch get-metric-statistics \
  --namespace "AWS/VPN" \
  --metric-name TunnelState \
  --dimensions Name=VpnId,Value=vpn-0abc123def456 \
  --start-time $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%S) \
  --end-time $(date -u +%Y-%m-%dT%H:%M:%S) \
  --period 60 \
  --statistics Average

Wszystkie punkty danych powinny zwracać 1.0 (tunel aktywny).

Jerzy Kopaczewski

Potrzebujesz pomocy z łącznością multi-cloud?

Umów darmową 30-minutową rozmowę. Zdiagnozujemy problem z połączeniem i zarekomendujemy właściwe rozwiązanie.