Laptopul meu afișa conectat. Clientul AWS Client VPN își afișa starea verde, endpointul înregistra o sesiune, și totuși nu puteam deschide un port MongoDB pe o instanță EC2 într-o subrețea privată. Nimic nu era vizibil stricat: certificatul era valid, profilul venea din consolă și tunelul transporta trafic. Greșeala era a mea, pentru că citeam conectat ca autorizat.

Autentificarea răspunde exact la o întrebare: poate această identitate să stabilească o sesiune? Tot ce urmează este decis de reguli separate care nu văd niciodată certificatul tău. O sesiune care se autentifică și un pachet care ajunge sunt două reușite diferite, iar golul dintre ele este locul unde trăiesc cele mai multe raportări de tipul VPN-ul e sus, dar gazda nu e accesibilă.

Verificările de mai jos sunt ordinea pe care o folosesc acum.

Ce demonstrează de fapt o sesiune conectată

În timpul handshake-ului, endpointul validează certificatul clientului față de trust store-ul propriu sau redirecționează browserul către furnizorul tău de identitate când SAML este configurat. Dacă trece, clientul primește o adresă din CIDR-ul de client al endpointului, iar consola arată o conexiune activă. În niciun moment al acelui schimb nu întreabă cineva dacă poți ajunge la 10.0.4.17 pe portul 27017.

Permisiunea pentru o destinație este un obiect separat pe endpoint. Fiecare flux este comparat cu regulile de autorizare, iar fiecare dintre ele asociază un CIDR de destinație cu grupul căruia i se acordă regula. Când nicio regulă nu acoperă destinația, endpointul acceptă sesiunea și aruncă traficul. Nu există banner, nu există buclă de reconectare și nimic în interfața clientului care să spună refuzat.

Compară regula de autorizare cu resursa, nu cu VPC-ul

Listează regulile și pune-le lângă adresa pe care instanța o are de fapt:

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

Ieșirea arată un CIDR de destinație și un ID de grup pe regulă. În ea se ascund două defecțiuni. Regula poate autoriza 10.0.0.0/16 în timp ce instanța stă într-un VPC împerecheat pe 10.1.0.0/16; ruta de peering există, dar nimeni nu a scris o regulă de autorizare pentru al doilea interval. Sau regula indică un grup din director în care utilizatorul este membru în director, dar nu și în grupul pe care endpointul îl evaluează.

Scrie cea mai îngustă regulă care acoperă destinația și adaugă una secundă doar când al doilea CIDR este cu adevărat necesar. O regulă largă 0.0.0.0/0 dintr-un start rapid funcționează și exact de aceea supraviețuiește în producție și ascunde modelul.

Două tabele de rute decid dacă pachetul se mișcă

O rută a endpointului asociază un CIDR de destinație cu una dintre subrețelele de care endpointul este legat. Aceasta este jumătate de drum. Tabelul de rute al subrețelei trebuie în continuare să știe cum să înainteze pachetul, iar asta contează în momentul în care destinația se află în spatele unei conexiuni de peering, al unui transit gateway sau al unui interval on-premises accesibil printr-un tunel site-to-site.

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

Caută o rută a cărei destinație se potrivește cu CIDR-ul resursei și al cărei target este o subrețea asociată. Dacă ruta lipsește, adaugă-o. Dacă există și gazda tace în continuare, golul este de partea VPC-ului, așa că compară cu tabelul de rute al subrețelei de asociere.

O singură setare de partea clientului strică rutarea fără să strice tunelul: un profil care conține route-nopull. Directiva îi spune unui client bazat pe OpenVPN să ignore rutele pe care le împinge serverul, așa că interfața urcă doar cu adresa endpointului însuși, iar destinația pur și simplu nu are rută. Verifică cu ip route show pe Linux sau netstat -rn pe macOS dacă există o rută prin interfața tun. Dacă nu există, scoate route-nopull din profilul exportat și reconectează-te pentru ca rutele împinse să fie aplicate.

Grupurile de securitate nu văd adresa clientului tău

Aceasta este partea pe care am greșit-o o după-amiază întreagă. Pentru un endpoint IPv4 asociat cu o subrețea, serviciul traduce adresa sursă a clientului în adresa interfeței de rețea a endpointului din acea subrețea. Pachetul care ajunge la instanță nu poartă adresa pe care o afișa clientul tău, așa că o regulă de grup de securitate care permite pool-ul de clienți, să zicem 172.16.0.0/22, nu se potrivește cu nimic.

Permite portul din grupul de securitate al endpointului, care este atașat interfeței asocierii, nu din CIDR-ul de client. Referirea grupului este mai durabilă decât codificarea unei adrese, pentru că adresa interfeței nu este a ta de controlat. ACL-urile de rețea sunt fără stare, așa că acolo unde există intrări personalizate, atât direcția de intrare cât și cea de ieșire trebuie să permită fluxul.

Conectează-te și la adresa privată a instanței. Un IP public scoate pachetul din VPC și îl readuce pe alt drum, cu alte reguli, deci un test pe adresa publică nu spune nimic despre drumul privat.

O ordine de izolare care se oprește la prima defecțiune

Parcurge aceste puncte în ordine și oprește-te unde unul eșuează. Fiecare pas exclude un strat, nu pe toate.

  1. Confirmă ce identitate a folosit sesiunea și ce grup evaluează endpointul. Un certificat dintr-un trust store nu este același principal ca o afirmație SAML din director.
  2. Confirmă că o regulă de autorizare acoperă CIDR-ul resursei pentru acel grup.
  3. Confirmă că există o rută a endpointului și că țintește o subrețea asociată, apoi că tabelul de rute al subrețelei poate înainta mai departe.
  4. Confirmă că grupul de securitate permite portul din interfața endpointului, nu din pool-ul de clienți.
  5. Testează din interiorul VPC-ului, cu o sesiune SSM pe altă instanță din aceeași subrețea, ca să separi o problemă a aplicației de o problemă a drumului clientului.

Când pașii nu sunt hotărâtori, acest tabel este pe ce mă sprijin:

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

Două detalii de cont produc simptome care arată ca eșecuri de permisiune. Fiecare utilizator are nevoie de un certificat de client separat; partajarea unuia între două mașini face sesiunile să se suprima reciproc, iar rezultatul este o buclă de reconectare, nu un refuz. Când se creează un endpoint nou, consola afișează un nume DNS pe care unele versiuni de client îl acceptă doar cu prefixul aleatoriu afișat în pagina endpointului, așa că copiază numele complet în loc să îl reconstruiești.

Dacă al cincilea pas te blochează, ia jurnalul de conexiuni al endpointului și citește intrările de autorizare înainte de a schimba ceva. Jurnalul numește destinația verificată și regula care s-a potrivit sau nu, iar asta reduce întrebarea cu patru straturi la un singur răspuns.

Articole similare