Källrouting för två VPN-pooler: vad din regel missar
En regel av formen from matchar klientadressen innan SNAT skriver om den, och ett test från gatewayen matchar ingen av dem. Kör uppslaget per pool och läs i stället prioriteterna.
Två klientpooler, en gateway och planen ser trivial ut: en regel skickar den första poolen via den snabba upplänken, en annan skickar den andra poolen genom en partnertunnel. Sedan finns reglerna på plats och den andra poolen lämnar fortfarande via standardrutten. Regeln är inte trasig. Paketets källa är inte vad författaren förväntade sig i det ögonblick uppslaget sker, eftersom översättning och uppslag sker på olika punkter i samma pakets resa, och ordningen är det motsatta mot det mentala diagram som de flesta ritar.
Uppslaget sker innan källan skrivs om
För ett paket som vidarebefordras från en VPN-klient kör kärnan en fast sekvens. Det anländer på tunnelgränssnittet, passerar prerouting där conntrack och DNAT bor, därefter fattas routingbeslutet, därefter vidarebefordran, därefter postrouting där SNAT tillämpas sist. En regel av formen from konsulteras under det routingbeslutet, vilket betyder att den ser klientens ursprungliga adress, inte den översatta.
Att lägga till en masquerade-regel ändrar alltså inte vilken policy som matchar det utgående flödet. Det som ändras är vad den bortre änden ser, och därmed vilken returväg som finns. Det är två olika konsekvenser, och ändringsgranskningar blandar ihop dem ständigt. Separera dem och designen blir oftast tydlig inom en minut.
Det är i svarsriktningen den översatta adressen dyker upp i reglerna. Ett paket som kommer tillbaka till gatewayen är adresserat till den översatta adressen, och om du har policyregler baserade på destinationen eller på gränssnittet det kom in på, är det värdet du matchar. Samma anslutning, olika källa till sanning i varje riktning.
| Stage | Source the kernel sees | What it means for your rule |
|---|---|---|
| Prerouting | Client address, 172.31.7.42 | Where marks and DNAT are applied |
| Routing decision | Still 172.31.7.42 | This is where from rules match |
| Postrouting | Becomes 198.51.100.9 | What the far end and its return route see |
Två pooler med olika källor behöver alltså verkligen olika tabeller, och designen är sund. Det tabellen ovan utesluter är genvägen att felsöka genom att titta på vad fjärrsidan tog emot och härleda regeln från det.
Ett test från gatewayen är inte ett test av poolen
Trafik som gatewayen själv genererar passerar aldrig prerouting, eftersom den inte anlände på ett gränssnitt. Den routas i utdatavägen, med gatewayens egen adress som källa, och en from-regel baserad på ett klientområde matchar inte. Varje ärende i det här området som säger att det fungerar från burken men inte från klienten är samma faktum upprepat.
Simulera klienten i stället för att approximera den. Routinguppslaget kan frågas direkt, med en källa och ett ingångsgränssnitt angivet:
ip route get 198.51.100.9 from 172.31.7.42 iif tun0
ip route get 198.51.100.9 from 172.31.8.42 iif tun0
ip route show table 201
Kör det en gång per pool. Om de två kommandona returnerar samma gränssnitt skiljer reglerna inte poolerna, och orsaken är antingen en saknad regel eller en regel med högre prioritet som matchar båda. Om de returnerar olika gränssnitt men klienten fortfarande misslyckas ligger felet efter uppslaget och du kan sluta titta på regler.
Prioritet, inte placering i filen
Regler utvärderas i stigande prioritetsordning, och det är talet som räknas, inte ordningen du skrev dem i. local-tabellen ligger på prioritet 0, main-tabellen på 32766 och standardregeln på 32767, därför hamnar en regel som lagts till med standardprioritet nära slutet av listan och förlorar mot nästan allt.
ip rule show
ip rule add from 172.31.8.0/24 lookup 201 priority 1000
ip -4 route show table 201
En explicit prioritet gör den avsedda ordningen synlig i filen och i granskningen. Den hindrar också ett senare tillägg från att tyst hoppa före en befintlig regel, vilket är den vanligaste orsaken till att en fungerande policy slutar fungera efter en orelaterad ändring.
En matchande regel som pekar på en ofullständig tabell är den andra fällan. Om tabell 201 innehåller en standardrutt men ingen rutt till destinationen släpps paketet eller skickas till fel ställe, och regeln ser helt korrekt ut isolerad. Läs tabellen, inte bara regeln. En regel är en pekare, och en tom tabell är en pekare till ingenting.
Returvägen måste fortfarande finnas
Källpolicy väljer en utgång. Den skapar inte en returväg. Om den andra poolen går ut genom en partnertunnel måste partnern veta hur den når 172.31.8.0/24, antingen via en rutt tillbaka till gatewayen eller genom att ta emot översatta adresser som den redan känner till.
Att välja mellan dem är ett designbeslut med synliga konsekvenser. Att routa klientområdet tillbaka bevarar varje klients identitet hos partnern och kräver att den accepterar ditt prefix. Översättning döljer poolen bakom en enda adress och kräver att partnern bara accepterar den adressen, till priset att dina och deras loggar inte längre är överens om vem som anslöt.
Vad du än väljer, skriv ner det bredvid pooldefinitionen. En returrutt som bara finns i någons minne är precis den sortens sak som överlever tills partnern byter en brandvägg, och som sedan tar en dag att återskapa.
Fånga inte gatewayens egen tunnel i policyn
Reglerna du skriver för klienter gäller också trafik som gatewayen genererar, om du inte utesluter den. En bred regel baserad på en markering eller på utgångsgränssnittet kan fånga gatewayens egen anslutning till partnern, och då routas tunneln som bär policyn av policyn. Det ger en slinga eller ett avbrott som ser ut som ett leverantörsfel.
Begränsa varje regel så snävt som designen tillåter: källprefix, ingångsgränssnitt och, där det stöds, en markering som bara klientpaket bär. Testa sedan gatewayens egen anslutning efter varje regeländring, eftersom felet är självrefererande och inte syns i ett klienttest.
Manualsidan för ip-rule dokumenterar semantiken för väljaren och prioriteten. Kombinera den med ett uppslagstest per pool och designen blir kontrollerbar, vilket är skillnaden mellan policyrouting som håller ett år och den som alla är rädda för att röra.