En väg ut från den här arbetsstationen är en SOCKS-proxy, och OpenVPN bakom den rapporterar anslutningstimeout utan någon användbar information. Webbläsaren på samma maskin fungerar via den proxyn, uppgifterna stämmer och porten svarar. Tre saker skiljer sig tillräckligt ofta för att kontrolleras först: SOCKS-versionen som proxyn talar, transporten som klienten valde och platsen där namnmatchningen sker. Bekräfta var och en innan du skyller på brandväggen.

Matcha SOCKS-versionen före brandväggen

Community-OpenVPN talar SOCKS5 för socks-proxy. Peka den mot en proxy som bara erbjuder SOCKS4 och TCP-anslutningen öppnas, sedan stannar, eftersom klienten väntar på svar på en hälsning som andra sidan aldrig tolkar. Utifrån ser det stoppet precis ut som en filtrerad port, och därför kommer versionsfrågan före varje brandväggsregel. En hämtning med SOCKS-kunskap avgör det med ett enda kommando.

curl --socks5-hostname 127.0.0.1:9050 gw.lab.example

En slutförd begäran bevisar två saker på en gång: proxyn accepterade SOCKS-begäran och den löste namnet. Inget URL-schema behövs, eftersom curl behandlar en bar värd som HTTP, och det räcker för det här testet.

Den hämtningen utesluter också det fel som klientloggen döljer. En proxy kan tillåta webbläsaren och ändå neka VPN-destinationen, och då sker nekandet vid CONNECT, före all VPN-autentisering. OpenVPN rapporterar bara timeout, så proxyns eget svar är beviset du behöver.

Transporten måste vara TCP på båda sidor

SOCKS5 bär en TCP-ström här, så själva tunneln behöver proto tcp-client. En profil som fortfarande är inställd på UDP fungerar inte den här vägen, eftersom klienten inte använder protokollets UDP-associationsläge. Att vända profilen är en verklig ändring och inte en formalitet: fjärrsidan måste lyssna på TCP på samma port. Sedan blir nyttolasten TCP inuti TCP, där ett förlorat segment skickas om två gånger och takten försämras, vilket interaktiva sessioner märker mycket mer än stora överföringar.

proto tcp-client
remote gw.lab.example 8443
socks-proxy 127.0.0.1 9050

Direktivet tar proxyvärden, en valfri port och en valfri uppgiftsfil. Lägg dem i själva profilen så att en kopia beter sig likadant någon annanstans.

Stäng in hela kedjan i en container

Att göra kedjan på värden innebär att ta över dess standardrutt och lämna resolvern i ett tillstånd som ingen senare kan förklara. Ett namnutrymme eller en container avgränsar den i stället, så värden behåller sin egen väg medan SOCKS-hoppet och tunneln lever tillsammans. Ingenting reser sig inuti utan en tunnelanordning, rättigheter att konfigurera den och en nåbar proxy. En Compose-tjänst får det med cap_add: NET_ADMIN och en bind-monterad /dev/net/tun.

cap_add:
  - NET_ADMIN
devices:
  - /dev/net/tun:/dev/net/tun

Det paret är snävare än att köra containern privilegierad, och det är hela det enhetsåtkomst som behövs. En Tor-klient eller en separat proxycontainer kan stå för lyssnaren. Bind den i båda fallen till loopback och nå den från namnutrymmet via värden i stället för att exponera proxyn mot nätet.

Namnmatchningen är där isoleringen brister

En tunnel som bär paket men ändå frågar värdens resolver har inte isolerat något. Två saker gör isoleringen verklig: namnutrymmet har en egen resolver, och dess frågor går via proxyn eller tunneln, aldrig över det fysiska gränssnittet. Använd två namn i testet: ett som bara finns bakom tunneln och ett publikt som borde följa samma väg.

docker compose exec vpn cat /etc/resolv.conf
docker compose exec vpn getent hosts internal.lab.example

Om fjärrnamnet löses men det publika inte, är kedjan selektiv och inte trasig, och skillnaden säger vilken väg varje fråga tog. Om båda löses från värden men ingen inuti containern, lånar containern fortfarande värdens resolver. Skriv ned resolverfilen du hittade, för det är inställningen som måste ändras.

Bevisa varje hopp i ordning

Listan är kort. En SOCKS5-begäran får svar, tunneln når sin lyssnare via proxyn och paket som lämnar namnutrymmet bär den adress fjärrsidan förväntar sig. Bekräfta ett i taget i stället för att lägga på mer konfiguration. När klienten säger ansluten och inget rör sig, sitter brottet nästan alltid i det andra eller tredje faktumet.

curl --socks5-hostname 127.0.0.1:9050 gw.lab.example
docker compose exec vpn ip route get 203.0.113.10
docker compose exec vpn getent hosts internal.lab.example

Skriv ned kombinationen som fungerade: SOCKS-version, transport, resolver och namnutrymmesinställningar. Att lösa kedjan en andra gång ur minnet kostar mer än anteckningen. Ha de fyra fakta i ärendet och inte i chatten.

En kedja som rapporterar ansluten och inte passerar något har oftast brustit vid hoppet du ännu inte bevisat. Testa det hoppet innan du lägger till ett lager till.

Relaterade artiklar