Client VPN ger klienten en adress, handskakningen slutförs, och anslutningen leder fortfarande ingenstans. Innan du rör certifikat eller klientversioner, titta på slutpunktens egen rutttabell. En AWS Client VPN-slutpunkt vidarebefordrar bara ett paket när en av dess rutter täcker destinationsprefixet; om inget matchar slängs paketet vid slutpunkten och målvärden ser aldrig ett SYN.

Det är ett vidarebefordringsbeslut, inte ett autentiseringsbeslut. Det fattas efter att tunneln är uppe och efter att auktoriseringsreglerna utvärderats, därför kan ett giltigt certifikat och en giltig grupp ändå ge en död anslutning.

Slutpunkten vidarebefordrar bara det rutttabellen täcker

Varje rutt är ett destinations-CIDR plus subnätet som ska ta emot trafiken. Slutpunkten jämför klientens destination med listan, väljer den matchande posten och skickar paketet till det associerade subnätet. Ingen post betyder inget nästa hopp.

Lägg märke till vad rutten inte är. Den är inte en post i VPC:ns rutttabell, och den auktoriserar ingenting. Auktoriseringsregler avgör om en grupp får nå en destination; rutter avgör om slutpunkten har någonstans att skicka paketet. Båda måste stämma, och de misslyckas med olika symtom, så att gissa vilken som är trasig kostar en eftermiddag.

Den klassiska missanpassningen är en peerad VPC. Någon lägger till en rutt för 10.20.0.0/24 medan värden bor i 10.20.4.0/24, så adressen hamnar utanför varje post. En inspelning på klientsidan visar upprepade SYN utan svar, och målets loggar visar ingenting alls.

Läs ruttlistan före certifikatet

Slutpunktens rutter är ett eget objekt, så fråga dem direkt i stället för att läsa VPC-tabellen:

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

Ta den exakta adressen och prefixlängden från klienten som misslyckas, och kontrollera sedan täckningen tecken för tecken. Längsta prefix gäller, så en bredare rutt räddar dig inte när en smalare pekar någon annanstans.

En resurs per destination med for_each

Handskrivna ruttblock driver i samma ögonblick som någon lägger till ett prefix i konsolen. Håll destinationerna i en map och skapa en resurs per nyckel, så att varje tillägg eller borttagning förblir isolerad.

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]
}

Behåll beroendet av nätverksassociationen. En rutt behöver ett associerat subnät, så ett apply som skapar båda måste ordna associationen först, och utan den referensen står Terraform fritt att prova rutten först. Läs sedan planen: antalet ruttillägg ska motsvara prefixen du lade till. Om planen också ersätter slutpunkten är slutpunktsresursen felaktigt skriven, och att tillämpa den kopplar från varje ansluten klient.

Att ta över en slutpunkt du inte skapade

De flesta team ärver en slutpunkt byggd i konsolen, och därför finns ingen ruttkod. Res inte en extra slutpunkt bara för att få in rutter i Terraform.

Importera i stället, eller skicka in id:na som variabler och låt de ärvda objekten vara ohanterade. Import kräver det id-format som leverantören dokumenterar för varje resurstyp; det kodar slutpunkten, destinationsprefixet och målsubnätet. Kopiera den strängen från resursdokumentationen i stället för att sätta ihop den ur minnet, kör en plan och förvänta dig inga ändringar innan du lägger till något nytt.

Följ paketet i den ordning det färdas

När rutten finns och anslutningen fortfarande misslyckas, gå vägen i ordning i stället för att gissa på det översta lagret.

  1. Rutt: ett prefix täcker destinationen och pekar på ett subnät som är associerat med slutpunkten.
  2. Auktorisering: en auktoriseringsregel tillåter den destinationen för användarens grupp. En rutt ensam ger aldrig åtkomst.
  3. Returväg: målsubnätets rutttabell skickar svar tillbaka mot slutpunkten, och säkerhetsgruppen tillåter porten från klientens adresspool.
  4. Applikation: öppna en riktig TCP-anslutning från klienten, och bekräfta sedan att målets loggar visar den förväntade källadressen från poolen.

Ändra ett prefix per apply, läs ruttlistan igen efteråt, och notera destinationen, den auktoriserande regeln och returvägen tillsammans. Nästa person som felsöker en nekad anslutning bör börja från den inventeringen, inte från en certifikatteori.

Relaterade artiklar