En applikation binder till VPN:ets adress, och anslutningen lämnar ändå via den vanliga standardvägen. Inget i bindningen misslyckades; den gjorde precis det en bindning gör. Att binda en socket till en lokal adress väljer den källadress som kärnan sätter i huvudet. Det installerar ingen väg och skapar ingen policyregel som skickar paket med den källan in i en viss tunnel.

Resten av den här handboken är den kontrollordning jag använder, tillsammans med kommandot som ger varje observation.

Vad en bindning faktiskt avgör

En bindning tilldelar socketen en lokal adress. Sedan kör kärnan samma vägsökning som den annars skulle ha kört, om inte en policyregel ändrar vilken tabell sökningen läser.

Därför kan ett paket gå ut med en VPN-källadress på ett fysiskt gränssnitt. På andra sidan kommer det från ett privat intervall som nätet aldrig väntade sig på den vägen, returtrafiken saknar väg tillbaka, och anslutningen hänger sig eller återställs.

Linux-referensen för IP-sockets dokumenterar bindningens semantik. Routinghalvan bor i ip-rule och ip-route, och det är separata manualer av en anledning.

Bekräfta att adressen tillhör den här namnrymden

En adress du kan binda till måste finnas på ett gränssnitt inne i den nätverksnamnrymd applikationen kör i. En peer-adress, en gateway-adress eller en adress som bara finns i en annan namnrymd går inte att binda till, och anropet misslyckas med EADDRNOTAVAIL.

ip -br addr show
ip netns identify <pid>
ss -tanp | grep <port>

Kör de tre i samma sammanhang som applikationen: samma namnrymd och, om du får tag i den, samma användare. Ett gammalt net30-diagram är inte bevis för vilken adress din nuvarande topologi tilldelade klienten. Läs gränssnittet som faktiskt är uppe.

Läs sökningen för den källan och destinationen

Ett enda kommando svarar på frågan som bindningen inte svarade på:

ip route get 203.0.113.10 from 10.8.0.2
ip rule show

Den första raden skriver ut den väg ett paket från den källan till den destinationen skulle ta, inklusive utgående gränssnitt och föredragen källa. Om den namnger det fysiska gränssnittet är bindningen och vägen oense, och paketet går ut med en källa som vägen inte kan komma tillbaka till.

Sedan berättar ip rule show om någon regel skulle ha valt en annan tabell. Prioriteringar spelar roll här, eftersom den första matchande regeln vinner, och en regel som fångar allt ovanför din gör din regel osynlig.

Installera bara en policyregel om det är designen

Källbaserad routing är en medveten design, inte en reparation för en enda applikation. Om policyägaren vill att trafik från tunnelns subnät ska använda tunneln, hör regeln hemma i den ägarens konfiguration och inte i ett engångskommando på din laptop.

En användbar form är en egen tabell med en standardväg genom tunneln, plus en regel som skickar VPN:s källintervall in i den tabellen. Lägg till de undantag designen behöver, eftersom en tabell som bara innehåller en tunnelstandard fångar destinationer som ska förbli lokala eller nås över den fysiska vägen.

ip route add default dev tun0 table 100
ip rule add from 10.8.0.2 table 100 priority 100
ip route get 203.0.113.10 from 10.8.0.2

Rulla tillbaka med ip rule del och ip route flush table 100. Allt som läggs till så försvinner vid omstart om inte en hanterare skriver det, vilket både är en säkerhetsegenskap och en anledning att inte ha den enda kopian i din shellhistorik.

Verifiera med tre observationer

Notera källan applikationen bad om, vägen sökningen valde och källan servern faktiskt såg.

Dessa tre kan vara oense, och varje oenighet pekar någon annanstans. En avlyssning på tunnelgränssnittet bevisar att paketet gick ut med rätt källa. En avlyssning på det fysiska gränssnittet bevisar att det gick ut fel väg. Servervyn är den enda som bevisar vägen hela vägen.

Om applikationen erbjuder ett alternativ för bindning till enhet eller ett routingläge per app, behandla det som en annan mekanism med andra begränsningar. Liknande inställningar leder inte alla till samma kärnbeslut.

Relaterade artiklar