AWS Client VPN är ansluten, men EC2 svarar fortfarande inte
Ansluten betyder bara att certifikatet eller SAML-inloggningen fungerade. Auktoriseringsregler, endpoint-rutter och säkerhetsgrupper vaktar var sin del av vägen till en privat värd.
Min laptop visade ansluten. AWS Client VPN-klienten visade sitt gröna tillstånd, endpointen loggade en session, och ändå kunde jag inte öppna en MongoDB-port på en EC2-instans i ett privat subnät. Inget var uppenbart trasigt: certifikatet var giltigt, profilen kom från konsolen och tunneln bar trafik. Felet var mitt, eftersom jag läste ansluten som auktoriserad.
Inloggningen svarar på exakt en fråga: får den här identiteten upprätta en session? Allt därefter avgörs av separata regler som aldrig ser ditt certifikat. En session som autentiserar och ett paket som anländer är två olika framgångar, och gapet mellan dem är där de flesta rapporterna av typen VPN:en är uppe men värden nås inte bor.
Kontrollerna nedan är den ordning jag använder nu.
Vad en ansluten session faktiskt bevisar
Under handskakningen validerar endpointen klientcertifikatet mot sitt trust store, eller omdirigerar webbläsaren till din identitetsleverantör när SAML är konfigurerat. Om det går igenom får klienten en adress från endpointens klient-CIDR och konsolen visar en aktiv anslutning. Vid ingen punkt i det utbytet frågar något om du får nå 10.0.4.17 på port 27017.
Tillstånd för en destination är ett separat objekt på endpointen. Varje flöde matchas mot auktoriseringsreglerna, och var och en parar ihop ett destinations-CIDR med den grupp regeln beviljas till. När ingen regel täcker destinationen accepterar endpointen sessionen och släpper trafiken. Det finns ingen banner, ingen återanslutningsloop och inget i klientgränssnittet som säger nekat.
Jämför auktoriseringsregeln med resursen, inte med VPC:n
Lista reglerna och lägg dem bredvid den adress instansen faktiskt har:
aws ec2 describe-client-vpn-authorization-rules \
--client-vpn-endpoint-id cvpn-endpoint-0a1b2c3d4e5f6a7b8Utdata visar ett destinations-CIDR och ett grupp-ID per regel. Två fel gömmer sig i dem. Regeln kan auktorisera 10.0.0.0/16 medan instansen ligger i en peerad VPC på 10.1.0.0/16; peering-rutten finns, men ingen skrev en auktoriseringsregel för det andra intervallet. Eller så pekar regeln på en kataloggrupp som användaren är med i i katalogen men inte i den grupp som endpointen utvärderar.
Skriv den smalaste regel som täcker destinationen, och lägg bara till en andra när ett andra CIDR verkligen behövs. En bred 0.0.0.0/0-regel från en snabbstart fungerar, och därför överlever den till produktion och döljer modellen.
Två rutttabeller avgör om paketet rör sig
En endpoint-rutt mappar ett destinations-CIDR till ett av de subnät som endpointen är kopplad till. Det är halva vägen. Subnätets egen rutttabell måste fortfarande veta hur paketet ska vidarebefordras, och det spelar roll i det ögonblick destinationen ligger bakom en peering-anslutning, en transit gateway eller ett lokalt intervall som nås via en site-to-site-tunnel.
aws ec2 describe-client-vpn-routes \
--client-vpn-endpoint-id cvpn-endpoint-0a1b2c3d4e5f6a7b8Leta efter en rutt vars destination matchar resursens CIDR och vars mål är ett kopplat subnät. Saknas rutten, lägg till den. Finns den och värden fortfarande är tyst, ligger gapet på VPC-sidan, så jämför med rutttabellen för kopplingssubnätet.
En klientinställning bryter routingen utan att bryta tunneln: en profil som innehåller route-nopull. Direktivet säger åt en OpenVPN-baserad klient att ignorera de rutter servern skjuter ut, så gränssnittet kommer upp bara med endpointens egen adress och destinationen har helt enkelt ingen rutt. Kontrollera med ip route show på Linux eller netstat -rn på macOS om det finns en rutt genom tun-gränssnittet. Om inte, ta bort route-nopull från den exporterade profilen och anslut igen så att de utskjutna rutterna tillämpas.
Säkerhetsgrupper ser inte din klientadress
Det här är delen jag hade fel på en hel eftermiddag. För en IPv4-endpoint kopplad till ett subnät översätter tjänsten klientens källadress till adressen för endpointens nätverksgränssnitt i det subnätet. Paketet som når instansen bär inte adressen din klient visade, så en säkerhetsgruppregel som tillåter klientpoolen, säg 172.16.0.0/22, matchar ingenting alls.
Tillåt porten från endpointens säkerhetsgrupp, som sitter på kopplingens gränssnitt, i stället för från klient-CIDR:et. Att referera gruppen är mer hållbart än att hårdkoda en adress, eftersom gränssnittsadressen inte är din att styra. Nätverks-ACL:er är tillståndslösa, så där egna poster finns måste både den inkommande och den utgående riktningen tillåta flödet.
Anslut också till instansens privata adress. En offentlig IP tar paketet ut ur VPC:n och tillbaka in via en annan väg med andra regler, så ett test mot den offentliga adressen säger ingenting om den privata vägen.
En isoleringsordning som stannar vid första felet
Gå igenom dessa i ordning och stanna där en fallerar. Varje steg utesluter ett lager i stället för alla.
- Bekräfta vilken identitet sessionen använde och vilken grupp endpointen utvärderar. Ett certifikat från ett trust store är inte samma principal som en SAML-assertion från katalogen.
- Bekräfta att en auktoriseringsregel täcker resursens CIDR för den gruppen.
- Bekräfta att en endpoint-rutt finns och pekar på ett kopplat subnät, och sedan att subnätets rutttabell kan skicka vidare.
- Bekräfta att säkerhetsgruppen tillåter porten från endpoint-gränssnittet och inte från klientpoolen.
- Testa inifrån VPC:n, med en SSM-session på en annan instans i samma subnät, för att skilja ett applikationsproblem från ett klientvägsproblem.
När stegen inte är avgörande är den här tabellen det jag faller tillbaka på:
| Symptom | Layer to inspect |
|---|---|
| Client shows connected, host times out, no byte growth on the interface | Authorization rule, then security group |
| Ping fails but a TCP connect to the port succeeds | ICMP is blocked; not an access failure |
| Tunnel reconnects every few minutes | Two machines sharing one client certificate |
| Works on one laptop, fails on another | Local profile has route-nopull or stale pushed routes |
Två kontodetaljer ger symtom som liknar behörighetsfel. Varje användare behöver ett eget klientcertifikat; delar man ett mellan två maskiner tränger sessionerna undan varandra, och resultatet blir en återanslutningsloop i stället för en avvisning. När en ny endpoint skapas visar konsolen ett DNS-namn som vissa klientversioner bara accepterar med det slumpmässiga prefix som visas på endpoint-sidan, så kopiera hela namnet i stället för att bygga upp det igen.
Om det femte steget låser dig, hämta endpointens anslutningslogg och läs auktoriseringsposterna innan du ändrar något. Loggen namnger destinationen som kontrollerades och regeln som matchade eller inte, och det krymper frågan med fyra lager till ett svar.