Waarom een VPN-client op het kantoor-LAN elk antwoord verliest
Een laptop op het kantoor-LAN en op een tunnel in hetzelfde subnet antwoordt vanaf de verkeerde interface. Losse reverse-path-filtering verklaart de stilte.
Een laptop zit via Ethernet op de /24 van het kantoor en sluit zich ook aan bij een OpenVPN-server die in dezelfde /24 woont. Een collega pingt het tunneladres; het verzoek komt duidelijk aan, en er gaat niets terug. Het tunnellog is schoon en browsen werkt nog, dus de tunnel is de verkeerde verdachte. IPv4-bronvalidatie op de ontvangende machine gooit het pakket weg voordat iets het leest.
Het weggooien gebeurt voordat iets het pakket leest
Bronvalidatie stelt één vraag over elk inkomend pakket: als deze host dat bronadres zou beantwoorden, zou het antwoord dan via de interface naar buiten gaan waarop het pakket net aankwam? Als het antwoord nee is, gooit de kernel het pakket bij aankomst weg. Noch een socket noch een doorstuurpad ziet het ooit, en daarom registreert een opname op de tunnel nog steeds een verzoek dat de toepassing nooit ontvangt.
De client hier heeft 10.66.0.9 op zijn tunnel, en de OpenVPN-server antwoordt op 192.168.80.10 binnen de prefix van het kantoor. Een collega op 192.168.80.25 pingt het tunneladres, dus het verzoek doorkruist de LAN, de server routeert het de tunnel in, en het komt aan op de tunnelinterface van de client met een bronadres van het kantoor. In de routetabel van die machine hoort de prefix van het kantoor bij het Ethernet-apparaat, niet bij de tunnel. De validatie vergelijkt de aankomstinterface met de route, vindt een mismatch en verwerpt het pakket, dus de collega ziet totaal verlies terwijl beide kanten een gezonde tunnel melden.
De spiegelrichting heeft dezelfde vorm: wanneer de client richting kantoor begint, kunnen antwoorden aan de kantoorzijde om precies dezelfde reden worden verworpen. Een oplossing die maar in één richting is geverifieerd, komt meestal terug als een tweede ticket.
Bewijs de geldende modus voordat je een sysctl aanraakt
Lees de effectieve waarden in plaats van een distributiestandaard te vertrouwen, want de instelling per interface is maar de helft van de beslissing. De geldende modus is de hoogste van de interfacewaarde en de waarde van all, dus een nul op de tunnelinterface betekent niets zolang all één is. De beslissing van de strikte modus is een routingbeslissing, dus voer de opzoeking uit die de kernel uitvoert en vergelijk het antwoord met de interface waarop het pakket werkelijk aankwam.
tcpdump -ni tun0 icmp and host 192.168.80.25
ip route get 192.168.80.25
sysctl net.ipv4.conf.all.rp_filter net.ipv4.conf.tun0.rp_filter
Herhaal daarna de ping terwijl je de foutteller in de gaten houdt. Een stijgende teller naast een verzoek dat de opname al toont, is de signatuur van dit weggooien, niet van een ontbrekende route. Zet intussen marsmannetjes-logging aan, zodat de kernel de bron en de interface noemt die hij heeft geweigerd. Samen sluiten ze het cijfer, de firewall en een ontbrekende iroute als verklaringen uit.
Schrijf de basislijn op voordat je iets verandert: beide waarden, het apparaat dat de opzoeking koos, en de teller die je volgde. Dat record is wat je later vertelt of de wijziging deed wat je denkt.
Wat elke rp_filter-modus werkelijk accepteert
De kernel toont drie waarden per interface, en het zijn niet drie tinten van één regel. Nul schakelt de controle uit. Eén is strikt en eist dat de bron teruggerouteerd wordt via de aankomstinterface. Twee is los en eist alleen dat er een of andere route naar de bron in de tabel staat, waar die ook heen wijst.
| Value | Name | Accepts | Still rejects |
|---|---|---|---|
| 0 | off | any source at all | nothing on this check |
| 1 | strict | a source routed back out the arrival interface | a source whose route points elsewhere |
| 2 | loose | a source with any route in the table | a source with no route at all |
De rij die hier telt is de losse, en wat die blijft weigeren. Een vervalste bron die overal in je tabel routeerbaar is, komt erdoor, terwijl een bron zonder enige route nog steeds wordt geweigerd. Op een laptop is dat een smalle concessie; op een router die verkeer voor anderen doorstuurt is die breed. De modus hoort bij de host, dus hetzelfde getal draagt op de twee plekken een ander gewicht.
Welke rij deze topologie nodig heeft, volgt uit de tabel en niet uit gewoonte. Het pakket is legitiem en de bron is routeerbaar, dus de losse accepteert het en de strikte niet. Niets in de zaak vraagt om nul, en nul kiezen zou een controle weghalen die hier niets kost.
Kies de kleinste wijziging die de dubbelzinnigheid wegneemt
De losse modus is de kleinste wijziging die past, en het is een echte verlaging van de strengheid, geen onschuldige schakelaar. Een betere optie bestaat wanneer de topologie het toelaat: haal de overlap weg, en de dubbelzinnigheid verdwijnt.
Waar de prefix van het kantoor alleen via Ethernet nodig is, haal hem uit de routes die het profiel trekt, en het adres wordt via één pad bereikbaar. Als beide paden echt naast elkaar moeten bestaan, zet bron en apparaat vast met een beleidsregel in plaats van de validatie op elke interface los te draaien. Dat houdt strikte filtering voor al het overige op de machine en documenteert de uitzondering waar de volgende ingenieur hem zal zoeken.
Welk pad je ook kiest, leg het vast in een sysctl-drop-in en niet in een live commando. Zet de sleutels all en default samen, zodat een herverbinding de strikte modus niet stil kan terugzetten.
# /etc/sysctl.d/99-rp-filter.conf
net.ipv4.conf.default.rp_filter = 2
net.ipv4.conf.all.rp_filter = 2
sysctl --system
Wat de losse modus opgeeft, en waar
De losse modus weigert nog steeds een bron die geen route zou kunnen bereiken, en hij stopt met het weigeren van een vervalste bron die toevallig routeerbaar is. Op een laptop is dat een smalle concessie. Op een apparaat dat verkeer doorstuurt dat niet van hem is, is dezelfde keuze veel breder. Dezelfde instelling draagt daarom twee heel verschillende betekenissen, afhankelijk van waar hij draait.
De controle helemaal uitzetten op een host die verkeer voor anderen doorstuurt, is de enige reparatie die je moet vermijden. Nul gooit de validatie weg die de losse modus zorgvuldig bewaart. Als de host voor anderen doorstuurt, pleit dan in plaats daarvan voor de beleidsregeloptie uit de vorige sectie.
Laat een notitie achter die de twee interfaces, de overlappende prefix en de exacte test noemt die nu slaagt. Dat is nuttiger voor de volgende ingenieur dan een regel dat de filtering is aangepast.