Mijn laptop zei verbonden. De AWS Client VPN-client toonde zijn groene status, het endpoint registreerde een sessie, en toch kon ik geen MongoDB-poort openen op een EC2-instantie in een privésubnet. Niets was zichtbaar kapot: het certificaat was geldig, het profiel kwam uit de console en de tunnel vervoerde verkeer. De fout was van mij, omdat ik verbonden las als geautoriseerd.

Inloggen beantwoordt precies één vraag: mag deze identiteit een sessie opzetten? Alles daarna wordt beslist door aparte regels die je certificaat nooit zien. Een sessie die authenticeert en een pakket dat aankomt zijn twee verschillende successen, en de kloof daartussen is waar de meeste meldingen van het type de VPN staat aan maar de host is onbereikbaar leven.

De controles hieronder zijn de volgorde die ik nu gebruik.

Wat een verbonden sessie werkelijk bewijst

Tijdens de handshake valideert het endpoint het clientcertificaat tegen zijn trust store, of stuurt de browser naar je identiteitsprovider wanneer SAML is geconfigureerd. Als dat slaagt, krijgt de client een adres uit de client-CIDR van het endpoint en toont de console een actieve verbinding. Op geen enkel moment in die uitwisseling vraagt iets of je 10.0.4.17 op poort 27017 mag bereiken.

Toestemming voor een bestemming is een apart object op het endpoint. Elke flow wordt vergeleken met de autorisatieregels, en elk daarvan koppelt een bestemmings-CIDR aan de groep waaraan de regel is toegekend. Als geen regel de bestemming dekt, accepteert het endpoint de sessie en laat het verkeer vallen. Er is geen banner, geen herverbindingslus en niets in de clientinterface dat geweigerd zegt.

Vergelijk de autorisatieregel met de resource, niet met de VPC

Lijst de regels op en leg ze naast het adres dat de instantie werkelijk heeft:

aws ec2 describe-client-vpn-authorization-rules \
  --client-vpn-endpoint-id cvpn-endpoint-0a1b2c3d4e5f6a7b8

De uitvoer toont per regel een bestemmings-CIDR en een groeps-ID. Er schuilen twee fouten in. De regel kan 10.0.0.0/16 autoriseren terwijl de instantie in een gepeerde VPC op 10.1.0.0/16 zit; de peering-route bestaat, maar niemand schreef een autorisatieregel voor het tweede bereik. Of de regel wijst naar een directorygroep waar de gebruiker in de directory lid van is, maar niet in de groep die het endpoint evalueert.

Schrijf de smalste regel die de bestemming dekt, en voeg een tweede alleen toe wanneer een tweede CIDR echt nodig is. Een brede 0.0.0.0/0-regel uit een quickstart werkt, en daarom overleeft die tot in productie en verbergt het model.

Twee routetabellen bepalen of het pakket beweegt

Een endpoint-route koppelt een bestemmings-CIDR aan een van de subnetten waarmee het endpoint is geassocieerd. Dat is de helft van de weg. De eigen routetabel van het subnet moet nog steeds weten hoe het pakket door te sturen, en dat telt op het moment dat de bestemming achter een peering-verbinding, een transit gateway of een on-premises bereik ligt dat via een site-to-site-tunnel bereikbaar is.

aws ec2 describe-client-vpn-routes \
  --client-vpn-endpoint-id cvpn-endpoint-0a1b2c3d4e5f6a7b8

Zoek een route waarvan de bestemming overeenkomt met de CIDR van de resource en waarvan het doel een geassocieerd subnet is. Ontbreekt de route, voeg die toe. Is die er en blijft de host stil, dan zit de kloof aan de VPC-kant, dus vergelijk met de routetabel van het associatiesubnet.

Eén instelling aan de clientkant breekt de routing zonder de tunnel te breken: een profiel met route-nopull. De richtlijn zegt tegen een op OpenVPN gebaseerde client dat hij de routes moet negeren die de server pusht, zodat de interface alleen met het eigen adres van het endpoint opkomt en de bestemming simpelweg geen route heeft. Controleer met ip route show op Linux of netstat -rn op macOS of er een route via de tun-interface is. Is die er niet, verwijder dan route-nopull uit het geëxporteerde profiel en verbind opnieuw zodat de gepushte routes worden toegepast.

Beveiligingsgroepen zien jouw clientadres niet

Dit is het deel dat ik een hele middag verkeerd had. Voor een IPv4-endpoint dat aan een subnet is gekoppeld, vertaalt de dienst het bronadres van de client naar het adres van de netwerkinterface van het endpoint in dat subnet. Het pakket dat bij de instantie aankomt, draagt niet het adres dat jouw client toonde, dus een beveiligingsgroepregel die de clientpool toestaat, zeg 172.16.0.0/22, matcht helemaal niets.

Sta de poort toe vanuit de beveiligingsgroep van het endpoint, die aan de interface van de associatie hangt, en niet vanuit de client-CIDR. Naar de groep verwijzen is duurzamer dan een adres hardcoderen, omdat het interfaceadres niet van jou is om te beheren. Netwerk-ACL's zijn stateless, dus waar aangepaste vermeldingen bestaan, moeten zowel de inkomende als de uitgaande richting de flow toestaan.

Verbind ook met het privéadres van de instantie. Een openbaar IP haalt het pakket uit de VPC en brengt het via een andere weg met andere regels weer binnen, dus een test via het openbare adres zegt niets over de privéweg.

Een isolatievolgorde die bij de eerste fout stopt

Werk deze op volgorde af en stop waar er een faalt. Elke stap sluit één laag uit in plaats van alle.

  1. Bevestig welke identiteit de sessie gebruikte en welke groep het endpoint evalueert. Een certificaat uit één trust store is niet dezelfde principal als een SAML-bewering uit de directory.
  2. Bevestig dat een autorisatieregel de CIDR van de resource voor die groep dekt.
  3. Bevestig dat er een endpoint-route bestaat die op een geassocieerd subnet is gericht, en dan dat de routetabel van het subnet verder kan sturen.
  4. Bevestig dat de beveiligingsgroep de poort toestaat vanuit de endpointinterface en niet vanuit de clientpool.
  5. Test van binnen de VPC, met een SSM-sessie op een andere instantie in hetzelfde subnet, om een applicatieprobleem van een clientwegprobleem te scheiden.

Wanneer de stappen niet beslissend zijn, is deze tabel waarop ik terugval:

SymptomLayer to inspect
Client shows connected, host times out, no byte growth on the interfaceAuthorization rule, then security group
Ping fails but a TCP connect to the port succeedsICMP is blocked; not an access failure
Tunnel reconnects every few minutesTwo machines sharing one client certificate
Works on one laptop, fails on anotherLocal profile has route-nopull or stale pushed routes

Twee accountdetails veroorzaken symptomen die op rechtenfouten lijken. Elke gebruiker heeft een apart clientcertificaat nodig; er één delen tussen twee machines zorgt dat sessies elkaar verdringen, en het resultaat is een herverbindingslus in plaats van een weigering. Wanneer een nieuw endpoint wordt gemaakt, toont de console een DNS-naam die sommige clientversies alleen accepteren met het willekeurige voorvoegsel dat op de endpointpagina staat, dus kopieer de volledige naam in plaats van hem te reconstrueren.

Als de vijfde stap je vastzet, haal dan het verbindingslog van het endpoint op en lees de autorisatievermeldingen voordat je iets verandert. Het log noemt de bestemming die is gecontroleerd en de regel die wel of niet overeenkwam, en dat brengt de vraag met vier lagen terug tot één antwoord.

Gerelateerde artikelen