Je kunt een subnet achter een tunnel-eindpunt op drie manieren bereiken, en een minuut feiten verzamelen sluit meestal twee opties uit. De feiten zijn of de servers daarginds gebruikers moeten onderscheiden, of iemand daar ooit naar jouw bereik zal bellen, en wie de router aan de andere kant mag bewerken. Beantwoord die drie en het ontwerp kiest zichzelf. De rest gaat ervan uit dat jij het eindpunt beheert en de firewall mag bewerken.

Drie opties, en wat elk ervan werkelijk verandert

Prefix-mapping, DNAT per host en een gerouteerde prefix verplaatsen allemaal pakketten tussen dezelfde twee bereiken, maar ze veranderen verschillende dingen. Mapping verzint een alias-bereik en herschrijft adressen onderweg rekenkundig. Regels per host herschrijven ook, behalve dat elke bestemming met de hand wordt benoemd. Een gerouteerde prefix herschrijft niets: pakketten behouden de echte adressen en beide uiteinden zijn het eens over waar die adressen wonen.

What the far side needsPrefix mappingPer-host DNATRouted prefix
Users visible to its logsOnly without source NATSame conditionYes, unchanged
To start a connection toward youNo, alias is localNo, same reasonYes, both ends route
To absorb a new hostYes, arithmetic onlyNo, one rule per addressYes, it simply routes
To require no config changeYes, with source NATYes, same conditionNo, it needs a route back

Begin de eliminatie aan de andere kant, waar de beperkingen het moeilijkst te veranderen zijn. Als een server daar clientadressen in logs schrijft, ze tegen een allowlist controleert of ze aan een ander systeem geeft, vernietigt het vertalen van de bron zijn enige identificatie. Als de andere kant ook moet inbellen, valt vertaling volledig af, omdat niemand daar weet dat de alias bestaat. Alleen wanneer de andere kant louter verzoeken beantwoordt, worden de goedkopere opties veilig.

Prefix-paren, en waarom de groottes moeten kloppen

NETMAP is een doel in de nat-tabel dat op een paar prefixen van gelijke lengte werkt. Het heeft er geen tabel per adres in: het stript de prefix, houdt de host-bits en hangt ze weer aan de nieuwe prefix, daarom wordt een /24 op een /24 gemapt en nooit op een /25. De positie bepaalt de richting: een bestemmingsmatch in PREROUTING herschrijft waar een pakket heen gaat, en een bronmatch in POSTROUTING herschrijft waar het vandaan kwam.

Een host op 192.168.2.17 verschijnt bij je clients als 10.50.1.17, en de laatste octet is geen decoratie — het is aan beide kanten hetzelfde getal. Voeg morgen een host op 192.168.2.40 toe en zijn alias is 10.50.1.40, zonder regel om te bewerken.

Clients hebben nog steeds een route voor het alias-bereik nodig die naar jouw doos wijst, tenzij de alias binnen een subnet valt dat ze al bereiken. De gateway heeft geen route voor de alias nodig, omdat de bestemmingsvertaling in PREROUTING draait, vóór de route-opzoeking. Doorsturen moet ook aan staan, anders laat de kernel het pakket na het herschrijven vallen. De drie commando's hieronder zijn de hele opzet op een Debian-achtige gateway met clients op br0, de alias op 10.50.1.0/24 en de tunnel op tun0.

sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A PREROUTING -i br0 -d 10.50.1.0/24 -j NETMAP --to 192.168.2.0/24
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE

Het antwoord moet zelf de weg terug vinden

Het herschrijven van de bestemming bepaalt alleen waar een pakket wordt afgeleverd. De server aan de andere kant moet nog steeds antwoorden op een adres dat hij bereikt, en dat kan op twee manieren. Vertaal de bron zodat antwoorden naar jouw doos terugkeren, of laat de bron staan en geef de andere kant een route voor het clientbereik.

Masqueraden op de uitgaande weg is de kortere route: één regel in POSTROUTING en de andere kant ziet jouw tunneladres, dus heeft hij geen eigen route nodig. De prijs is dat elke gebruiker in één adres samenvalt, en logs per gebruiker niets meer betekenen. De bron intact laten behoudt die informatie, maar dan moet de externe site antwoorden voor het clientbereik terugsturen door de tunnel.OpenVPN server is dat een gepushte push "route 10.50.9.0 255.255.255.0", plus een route 192.168.2.0 255.255.255.0 regel.

De dure fout is van elk de helft doen. Als je een deel van het verkeer masqueradet terwijl de andere kant ook een terugroute voor ander verkeer draagt, komen antwoorden binnen op een interface waar de connection-tracking-entry nooit is gezien. De client meldt een time-out voor een verzoek dat de server als bediend logde. Beide richtingen van een flow moeten dezelfde netfilter-instantie passeren: één gateway die vertaalt, niet twee firewalls in serie.

conntrack -L -d 10.50.1.17
iptables -t nat -L PREROUTING -v -n

Lees de entry in beide richtingen: de oorspronkelijke tuple houdt je alias op de bestemming, terwijl de antwoord-tuple het echte adres draagt. Als de antwoord-tuple ontbreekt, is het terugpad het probleem, niet de regel. Als de PREROUTING-tellers nooit zijn bewogen, heeft het pakket die hook nooit bereikt.

Botsingen en de opzoeking die eerst loopt

Twee verschillende bereiken kunnen botsen, en beide storingen lijken op een kapotte tunnel in plaats van een slechte regel. De alias die je verzint moet over het hele pad ongebruikt zijn, en het echte externe bereik mag nog niet op je netwerk bestaan. Een duplicaat veroorzaakt intermittent verkeer naar de verkeerde host, wat moeilijker te diagnosticeren is dan een geweigerde verbinding. Vraag de routingtabel voordat je een regel toevoegt.

Op de gateway, ip route get 192.168.2.17 moet het tunnelapparaat noemen; een lokale bridge betekent dat het externe bereik is overschaduwd en geen nat-regel het repareert. Als je netwerk al 192.168.2.0/24 gebruikt, hernummer de externe site in plaats van een mapping op de botsing te stapelen.

Testen vanaf een echte client, en daarna behouden

Test vanaf een machine die de alias echt gebruikt, niet vanaf de gateway, omdat lokaal gegenereerd verkeer PREROUTING nooit op dezelfde manier passeert. Open een verbinding naar één host met alias en kijk hoe de tellers en de conntrack-entry samen verschijnen, sluit hem dan en bevestig dat de entry weggaat. Een verouderde entry wijst op een halfopen verbinding, wat meestal betekent dat het antwoord nooit terugkwam.

curl -sv http://10.50.1.17/ -o /dev/null
ss -tn dst 10.50.1.17
conntrack -L -d 10.50.1.17

Twee of drie geslaagde verbindingen bewijzen de rekenkunde, maar zeggen niets over persistentie of over de volgende engineer. Bewaar de regels waar het bootproces ze leest, wat op Debian en Ubuntu betekent iptables-save > /etc/iptables/rules.v4 met netfilter-persistent ingeschakeld. Een mapping die bij herstart verdwijnt is erger dan geen, omdat de storing komt zonder recente wijziging om de schuld te geven.

Laat een notitie naast de regels: het alias-bereik, het echte bereik, de reden voor het paar en welke kant mag initiëren. Die notitie scheidt een ontwerp van een stapel regels die niemand durft te verwijderen. Ze beslecht ook de latere vraag, wanneer de externe site een host toevoegt en een adres dat niemand configureerde al antwoordt. Als de notitie zegt dat de andere kant een terugroute nodig heeft, weet de volgende persoon dat het verwijderen van de masquerade-regel de connectiviteit breekt. Documentatie is hier goedkoop; een NAT-afhankelijkheid om drie uur 's nachts herontdekken is dat niet.

Gerelateerde artikelen