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.
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:
-
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.
-
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. -
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.
-
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.
-
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).
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.