SSH-dynamisk videresendelse som SOCKS-proxy over din VPN
En app, der kun taler SOCKS, har ingen proxy-endpoint på en almindelig VPN. To hop, én loopback-lytter og et navneopslag, som SSH-serveren selv må klare.
En applikation, der kun taler SOCKS, har intet at tale med på en almindelig VPN, fordi tunnelen bærer pakker, og appen vil have et proxy-endpoint. OpenSSH kan levere det endpoint, når adgangsejeren tillader det, fordi dynamisk videresendelse gør én SSH-session til en lokal proxy. Derefter er der to hop, som skal holdes adskilt: tunnelen, der når SSH-værten, og forbindelsen, som den vært åbner videre. At skille dem ad forklarer både, hvorfor ordningen virker, og hvad den aldrig vil gøre.
Hvad SSH-lytteren bliver, og hvad den ikke bliver
Dynamisk videresendelse får SSH-klienten til at lytte lokalt og tale SOCKS4 eller SOCKS5 med alt, der forbinder. Hver anmodning angiver en destination, og SSH-serveren åbner den videre forbindelse, og derfor kan destinationsopslaget ske på den anden side. Det er TCP-videresendelse på applikationsniveau, ikke en VPN for hele enheden. Det bærer ingen UDP-tilknytning, ingen ICMP og intet for applikationer, der helt ignorerer proxyindstillinger. Hoppingen fra SSH-serveren til applikationen er heller ikke inde i din tunnel, hvilket betyder noget, når destinationen kun accepterer trafik fra kendte netværk.
Forudsætningerne er reelle: en rute til SSH-værten, en autoriseret konto, en verificeret værtsnøgle til serveren og tilladelse til at videresende. Ingen af dem skabes af proxyen, og den sidste mangler normalt først. Bekræft alle fire, før du fejlfinder noget andet, fordi fejlen ser ens ud fra klienten, uanset hvilken der mangler.
Start det på loopback med en eksplicit port
Vælg en ubrugt lokal port, og bind den eksplicit til loopback i stedet for at udelade adressen. De tre muligheder nedenfor findes hver af én grund.
ssh -D 127.0.0.1:1080 -NT -o ControlPath=none -o ExitOnForwardFailure=yes \
[email protected]
-N springer den fjernkommando over, og -T springer pseudoterminalen over, så sessionen findes kun for at videresende. ExitOnForwardFailure får klienten til at afslutte, når lytteren ikke kan oprettes, i stedet for at køre uden den videresendelse, du bad om. ControlPath=none holder sessionen ude af en eksisterende multiplekset forbindelse, som måske tilføjer sine egne videresendelser. Loopback holder lytteren væk fra LAN'et, men på en delt maskine er det ikke en autorisationsgrænse, fordi andre lokale processer også kan nå den. OpenSSH-klientens reference dokumenterer alle disse flag, og loopback-advarslen følger af, hvad en lyttende socket er.
Send navne gennem proxyen, ikke uden om den
En SOCKS5-klient kan selv opløse destinationen eller bede proxyen gøre det, og det valg afgør, hvilken resolver der svarer. Med socks5h sender curl værtsnavnet gennem proxyen, så opslaget sker på SSH-serveren. Med almindelig socks5 opløser laptop'en først, og kun forbindelsen rejser, hvilket stille undergraver pointen, når navnet er internt. Anmodningen nedenfor rydder også listen uden proxy, så en nedarvet NO_PROXY-værdi ikke kan føre den uden om proxyen.
curl -sS --noproxy '' --proxy socks5h://127.0.0.1:1080 https://app.corp.example/health
Certifikatvalidering og applikationens eget login gælder stadig, fordi proxyen ikke erstatter nogen af dem. Der er to opslag tilbage: laptop'en skal nå SSH-værten gennem den tilladte VPN- og DNS-vej, og SSH-serveren skal selv opløse applikationsnavnet. Det andet kan testes alene, før nogen trafik sendes gennem proxyen.
ssh [email protected] getent hosts app.corp.example
Bevis én tilladt destination, og luk så sessionen
Test en destination, som politikken tillader, og en, den bør afvise, fordi en fungerende videresendelse kun beviser, at lytteren virker, og intet mere. Applikationen ser den kildeadresse, SSH-serveren vælger, og det er ikke din laptops tunneladresse. Hvor den anden ende logger forbindelser efter kilde, er den forskel det første, der skal tjekkes, når en anmodning afvises.
Stop sessionen gennem den proces, der ejer den, i stedet for at dræbe en uvedkommende shell. Bekræft derefter, at lytteren er væk, fordi en port, der stadig svarer, er en session, du ikke reelt har lukket. Fjern kun den proxyindstilling, som denne øvelse indførte, og lad resten af applikationens konfiguration være. En terminal uden opsyn med en videresendelsesregel er ikke en tjeneste, og en permanent proxy kræver et godkendt livsforløb, ikke et glemt vindue.
ss -ltn | grep 1080
Fejl, som denne ordning ikke kan rette
Nogle symptomer peger direkte på grænserne ovenfor, og at genkende dem tidligt sparer en eftermiddag med proxy-fejlfinding. Tabellen knytter det, du ser, til det, det normalt betyder. Alt i den sidste kolonne er et designspørgsmål, ikke en konfigurationsfejl.
| What you see | What it usually means | Where to look |
|---|---|---|
| The app connects and nothing follows | It ignores proxy settings entirely | Its own network settings, not the SSH session |
| A name resolution error for the destination | The SSH server cannot resolve it | Server resolver and search domains |
| A UDP-only application fails | Dynamic forwarding carries TCP only | This arrangement cannot serve it |
| curl works, the browser does not | The browser is not using the socks5h endpoint | Browser proxy configuration |
| The listener answers after the session ended | Another process owns port 1080 | The ss output, then the owning process |
De første tre rækker er dem, folk fejldiagnosticerer, fordi hver af dem giver et forbindelsesforsøg i stedet for en fejl om selve proxyen. Et navn, der opløses på laptop'en, siger intet om serverens resolver, og fejlen læses i stedet som et certifikat- eller timeoutproblem. Applikationer med kun UDP står uden for designet, ikke i stykker indeni, og ingen ekstra ssh-indstilling ændrer det. Browserrækken er den sædvanlige påmindelse om, at proxyindstillinger gælder for hver enkelt applikation. Den sidste række er grunden til, at nedlukningstjekket findes: en port, der stadig lytter, betyder, at nu ejer noget andet den.