Git 403 cu VPN conectat: găsește cine răspunde
Un 403 este un răspuns, nu un verdict despre VPN. Identifică ce componentă a refuzat, apoi compară o singură variabilă pe rând între rețele și notează ce s-a schimbat.
Funcționează pe Wi-Fi-ul biroului și eșuează pe hotspotul telefonului, cu VPN-ul conectat în ambele cazuri. Git returnează 403 și eroarea are trei linii. Tentația este să tratezi hotspotul drept cauză și să schimbi setările de rețea până se mișcă ceva. HTTP 403 înseamnă că un server a înțeles cererea și a refuzat-o, deci întrebarea utilă este care server, iar pasul următor util este o comparație care schimbă un singur lucru pe rând.
Citește statusul înaintea rețelei
Un 403 nu este o căutare eșuată, un timeout TCP sau un handshake TLS care nu s-a terminat niciodată. Este o decizie, luată de ceva care ți-a parsat cererea.
Până nu știi ce a luat acea decizie, fiecare schimbare de rețea pe care o încerci este o presupunere cu o poveste plauzibilă atașată.
Cine poate răspunde cu 403?
Aplicația depozitului este doar un candidat. Un proxy, un gateway sau un serviciu de filtrare poate sta în fața ei și poate răspunde primul, iar clientul vede același status fie și așa. Păstrează statusul, antetele relevante și un corp al erorii curățat, apoi corelează-le cu jurnalele serviciului autorizat. URL-ul remote și endpointul atins efectiv pot diferi și ele prin DNS sau configurația proxy, așa că verifică adresa configurată și procesul care face cererea.
Dacă refuzul nu a ajuns niciodată la depozit, jurnalele lui vor fi mute, iar acea tăcere este dovadă.
Compară o singură variabilă pe rând
Comparația cu hotspotul este utilă pentru că îngustează problema, nu pentru că dovedește o cauză. Două rețele pot diferi în adresare, familie de IP, proxy, negociere TLS și politică de ieșire în același timp.
Schimbă un singur lucru pe încercare și notează restul. Tabelul de mai jos este minimul pe care îl țin într-o notă în timp ce fac asta:
| Keep constant | Record when it changes |
|---|---|
| Repository, operation and credentials | Resolved address and IP family |
| Git process and configuration | Proxy use and the responding component |
| Intended VPN profile | Actual route and exit seen by the service |
Un singur rând care diferă între rularea care funcționează și cea care eșuează este locul în care merge următoarea oră.
O soluție ocolitoare este dovadă, nu explicație
Forțarea unei alte familii de adrese poate schimba destinația, ruta sau intermediarul care este selectat, deci poate schimba rezultatul fără a dovedi că IPv6 este incompatibil cu depozitul. O altă versiune TLS negociată este o observație din aceeași categorie. Niciuna nu justifică dezactivarea verificării certificatelor sau slăbirea conexiunii. Urmează politica și jurnalele componentei care a refuzat până la decizia reală, în loc să te oprești la prima schimbare care funcționează.
O soluție ocolitoare pe care nu o poți explica va eșua din nou în altă parte.
Scrie un raport care va fi corectat
Dă proprietarului componentei care a răspuns aceeași operație, două căi și componenta care a spus nu. Elimină antetele de autorizare, acreditările încorporate și detaliile depozitului privat înainte de a partaja ceva.
Raportul util este scurt, reproductibil și numește stratul, nu simptomul.
Verificarea pe care o fac, în ordine
Confirmă URL-ul remote și endpointul rezolvat, apoi captează statusul și antetele dintr-o rulare care eșuează. Repetă aceeași operație pe o a doua rețea și compară cele două înregistrări.
Apoi du acea diferență la componenta care a răspuns:
- Configurația proxy pe client și în rețea.
- Politica de ieșire sau filtrarea din fața depozitului.
- Domeniul tokenului sau al contului, inclusiv expirarea și condițiile SSO.
- Permisiunea depozitului pentru identitatea pe care o reprezintă tokenul.
Semantica statusului în sine se află în RFC 9110, și merită citată atunci când scrii raportul.