Eén client op je OpenVPN-server moet LAN-toegang verliezen terwijl alle andere tunnels blijven draaien. Zoek je dit op, dan zegt het beste antwoord meestal dat de daemon dat niet kan, wat maar half waar is: OpenVPN heeft geen firewall per client, maar de host die de tunnel beëindigt, filtert al pakketten. De twee beslissingen die tellen zijn de identiteit die je blokkeert en de positie van de regel. Doe die twee goed en de wijziging wordt één regel die je kunt testen en verwijderen.

Koppel de client voordat je de regel schrijft

OpenVPN leaset tunneladressen uit een pool, dus 10.8.0.6 is een plek, geen persoon. Als de sessie eindigt, komt de lease terug en kan die aan de volgende verbinding worden gegeven, wat betekent dat een regel tegen dat adres de plek volgt, niet de gebruiker. Bepaal dus eerst wat je werkelijk blokkeert: een adres voor een kort experiment, of een certificaat voor iemand die je buiten wilt houden.

Om het adres aan het certificaat te binden, maak je een bestand in de map die client-config-dir noemt en geef je het bestand precies de common name van het certificaat. Zet er één richtlijn in, ifconfig-push 10.8.0.6 255.255.255.0, en die client houdt hetzelfde tunneladres bij herverbindingen. Twee instellingen moeten bestaan wil dit werken: client-config-dir moet in de serverconfiguratie zijn gedeclareerd, en het gepushte adres moet in een subnet liggen dat de server kan routeren. Ontbreekt één, dan wordt het bestand zonder fout genegeerd, wat de volgende firewallsest misleidend maakt.

Een tijdelijke blokkade mag een pooladres gebruiken, zolang de ticket vastlegt welke sessie het toen had.

De volgorde bepaalt of de drop loopt

Op een Linux-gateway die tussen de tunnel en het LAN doorstuurt, passeren pakketten de keten FORWARD. Lees het commando hieronder als een zin: voeg bovenaan FORWARD in, match verkeer dat binnenkomt vanaf tun0, van die ene host, gericht aan het LAN-subnet, en gooi het weg.

iptables -I FORWARD -i tun0 -s 10.8.0.6/32 -d 192.168.1.0/24 -j DROP

Het is -I dat de regel laat lopen. Toegevoegd met -A, belandt hij onder elke brede acceptatie voor het tunnelsubnet en ziet nooit een pakket. Controleer de positie met iptables -vnL FORWARD --line-numbers, en lees ook de tellers: een drop bovenaan die niets telt, betekent dat het verkeer via een andere weg binnenkomt.

Het eigen LAN-adres van de gateway is een andere weg. Pakketten naar de doos zelf gaan naar INPUT, niet naar FORWARD, dus een client kan een LAN-host verliezen en toch de beheerpagina van de router openen. Voeg de bijbehorende INPUT-regel toe wanneer dat telt.

Wat het filter niet kan zien

Filteren gebeurt wanneer een pakket wordt beoordeeld, dus een bestaande TCP-sessie kan doorgaan tot die sluit of wordt gereset. Moet de blokkade meteen werken, wis dan de gevolgde stromen voor die bron met conntrack -D -s 10.8.0.6 nadat de regel erin staat. Zijn een paar seconden overlap acceptabel, leg die keuze dan vast in plaats van hem impliciet te laten. Hoe dan ook moet de volgende persoon weten of de regel levend verkeer stopt of alleen nieuwe verbindingen.

Verkeer tussen peers raakt nooit de firewall van de host. Met client-to-client aan stuurt OpenVPN die pakketten binnen de daemon door, dus noch FORWARD noch INPUT ziet ze. De enige oplossingen zijn client-to-client uitzetten of accepteren dat peers elkaar kunnen bereiken; een iptables-regel ziet dat verkeer niet.

IPv6, firmware en overleving na een herstart

Een IPv4-regel zegt niets over IPv6. Als de tunnel en het LAN beide families dragen, moet de gelijkwaardige regel bestaan in ip6tables, of in de nftables-regelset die het beleid op die host bezit. Router-firmware verbergt netfilter vaak achter zijn eigen abstractie, dus syntaxis en tabelnamen van een forum gelden misschien niet.

Op OpenWrt is het gedocumenteerde pad een firewallconfiguratie-item en geen handgeschreven iptables-regel, en een handgeschreven regel kan verdwijnen wanneer de firewall opnieuw laadt. Andere distributies herstellen regels via netfilter-persistent, een opstarteenheid of een leveranciersopslag, en die mechanismen zijn niet uitwisselbaar. Bewijs degene die je koos met een herstart, want een herlaad oefent een andere weg.

Verifieer per weg en rol daarna schoon terug

Test elke weg apart, want één geslaagde controle verbergt de andere. Een geblokkeerde client moet nog steeds via de tunnel het internet bereiken maar falen tegen een LAN-host, een tweede client moet diezelfde host bereiken, en het gatewayadres en de peer-weg hebben elk hun eigen observatie nodig. Schrijf de resultaten naast de regel zodat de volgende wijziging een basis heeft. De tabel hieronder is de set die de moeite waard is om in de ticket te houden.

WegVerwacht met de regelWanneer het faalt
Geblokkeerde client naar een LAN-hostGeen antwoordRegel staat onder een acceptatie, of de bron komt niet overeen
Geblokkeerde client naar het internetWerkt via tun0Regel is te breed, zonder bestemmingsmatch
Tweede client naar dezelfde LAN-hostWerktRegel matchte meer dan de bedoelde host
Geblokkeerde client naar het LAN-adres van de gatewayAlleen geblokkeerd met de bijbehorende INPUT-regelINPUT-regel ontbreekt
Geblokkeerde client naar een peertunneladresWerkt nog steedsclient-to-client is ingeschakeld en buiten het bereik van de firewall

Terugdraaien is een verwijdering volgens specificatie, geen flush: iptables -D FORWARD -i tun0 -s 10.8.0.6/32 -d 192.168.1.0/24 -j DROP verwijdert precies die regel en laat de rest van de keten intact. Verwijder dezelfde regel uit het bestand dat de regels bij het opstarten herstelt, laad het opnieuw en bevestig dat de client de LAN-host weer bereikt. Een flush van FORWARD zou ook regels ongedaan maken die je niet hebt geschreven, wat een terugdraaiing tot een tweede incident maakt.

Voordat je de ticket sluit, bevestig drie dingen: het vastgezette adres komt overeen met het certificaat, de regel staat boven de acceptaties met een teller die niet nul is, en het persistentiebestand bevat dezelfde regel die je hebt getest. Ontbreekt een van deze, dan is de blokkade een illusie in een shell-sessie.

Gerelateerde artikelen