Regler for port 80 og 443 sender ikke nettleseren gjennom en VPN
En porttreff velger TCP-strømmer, ikke en nettleser. HTTP/3 kjører over UDP, DNS kan ta en annen vei, og en oppdatering treffer den samme regelen du skrev.
Noen ber om at nettleseren skal bruke tunnelen, og svaret kommer tilbake som en brannmurregel som treffer destinasjonsportene 80 og 443. Den ser presis ut og er det ikke. En porttreff velger pakker etter transportoverskriften, ikke etter hvilket program som åpnet sokkelen, og moderne nettsurfing begrenser seg ikke til de to portene på TCP. Regelen vil overse noe av trafikken du ville inkludere og fange trafikk du aldri mente å røre. Før du skriver den, må du bestemme hvilken av tre forskjellige grenser du egentlig vil ha.
Regelen beskriver en transportklasse, ikke en applikasjon
På Linux undersøker en destinasjonsporttreff TCP-overskriften og ingenting over den. Å merke disse pakkene og styre dem med en policyrute virker nøyaktig som dokumentert, og ingen av disse maskineriene vet hva nyttelasten betyr eller hvilken prosess som sendte den. Merket er et nummer festet til en pakke, ikke en identitet festet til en applikasjon.
nft add rule inet mangle output tcp dport { 80, 443 } meta mark set 0x1
ip rule add fwmark 0x1 table 100
ip route add default dev wg0 table 100
To konsekvenser følger umiddelbart. En programvareoppdatering som kontakter TCP 443 får samme behandling som nettleseren, noe som kan være greit eller kan være et avbrudd som venter på neste oppdateringssyklus. Og en webtjeneste som bevisst er publisert på en annen port, si 8443, faller helt utenfor regelen selv om det fortsatt er webtrafikken brukeren var opptatt av.
Tallene er legitime selektorer når kravet virkelig handler om de portene. De blir fiksjon når det står «nettleser» i saken og et portområde implementeres i regelsettet. Det gapet er ikke en dokumentasjonsdetalj. Det er forskjellen mellom en regel du kan forsvare i en gjennomgang og en ingen kan teste.
HTTP/3 forlater stille TCP-regelen din
HTTP/3 kjører over QUIC, og QUIC bæres i UDP. En regel som bare treffer TCP kan ikke se det, så den samme nettleseren som består testsiden din kan sende en senere forespørsel over UDP og omgå tunnelen uten at noen endrer en innstilling. RFC 9114 beskriver HTTP/3 som en QUIC-basert protokoll, og QUIC bruker UDP med standardport 443 i vanlig utrulling.
Om en gitt nettleser prøver HTTP/3 avhenger av konfigurasjonen, av nettstedet og av om et tidligere forsøk lyktes. Det gjør det dårlig egnet til å resonnere om fra hukommelsen. Spør verktøyet i stedet:
curl --http3 -sS -o /dev/null -w '%{http_version} %{time_total}\n' https://example.com
ss -tunp | grep -E ':443\b'
curl-linjen skriver ut den forhandlede versjonen, så en 3 bekrefter at UDP-veien ble brukt. Socketlisten viser deretter om forbindelsen er bundet til tunellens grensesnitt eller det fysiske. Hvis HTTP/3 ikke er tilgjengelig i curl-bygget ditt, feiler flagget høylytt i stedet for å falle stille tilbake, noe som er dens egen lille nåde.
DNS er en egen beslutning du må ta
En portregel for webtrafikk sier ingenting om navneoppslag. Nettleseren kan bruke systemets resolver, en resolver konfigurert inne i nettleseren eller en som den siste forbindelsen dyttet inn. Hver av dem kan sende spørringer via en annen vei enn den regelen din velger, noe som gir den klassiske splittelsen: siden lastes, navnet løses opp et sted du ikke forventet, og det interne nettstedet løses til en offentlig adresse eller ikke i det hele tatt.
Bestem det eksplisitt. Hvis interne navn må løses gjennom tunnelen, må resolveren være inne i den, og regelsettet må tillate DNS til den resolveren mens andre spørringer holdes ute. Hvis nettleseren bruker DNS over HTTPS til en offentlig leverandør, omgår spørringen resolveren din helt, og portregelen kan ikke hjelpe. Skriv valget i samme endringsrekord som rutingregelen, fordi de to leses sammen av den som feilsøker neste feil.
Bekreft det deretter med resolveren i stedet for med siden:
resolvectl query intranet.example.internal
resolvectl status | grep -A3 'Current DNS Server'
Et manglende svar er et oppslagsproblem selv når nettleserens feilmelding gir nettverket skylden. De to feilene ser identiske ut for en bruker og er helt forskjellige saker.
Tre grenser, tre forskjellige mekanismer
Det meste av forvirringen forsvinner når du navngir grensen du vil ha. De er ikke utskiftbare, og hver har en annen feilmodus under et tunnelutfall.
| What you actually want | Mechanism that fits | What it does not cover |
|---|---|---|
| These transport ports use this exit | Firewall mark plus policy route | Applications, HTTP/3 over UDP, DNS |
| This browsing session stays separate | Application-aware VPN, or a separate network namespace plus a proxy | Other applications in the same session |
| Only these private sites are reachable | Destination-based routes with private DNS | Public sites on the same address family |
En separat nettleserprofil er fellen i midterste rad. Den skiller informasjonskapsler og historikk og endrer ingenting i vertens rutingtabell, så begge profilene tar samme vei. Isolasjon krever noe kjernen håndhever, altså et navnerom, en container eller et program som eier sitt eget tunellgrensesnitt.
Uansett hvilken rad som gjelder, skriv ned hva som skal skje når tunnelen faller. En merkebasert rute som forsvinner med grensesnittet faller vanligvis tilbake til den fysiske standardruten, noe som er fail-open-atferd. Det kan være akseptabelt for surfing og uakseptabelt for alt annet, og det er en beslutning, ikke en implementasjonsdetalj.
Test strømmene du hevder å dekke
Akseptansetesten må følge grensen du skrev ned, ikke portnumrene som var praktiske. Velg én strøm som må gå gjennom tunnelen, én som ikke må, og én som bruker en transport du ikke tenkte på:
ip route get 203.0.113.40
curl -sS -o /dev/null -w 'v4 %{http_version} %{remote_ip}\n' https://example.com
nft list ruleset | grep -A2 'dport'
Ruteoppslaget forteller hvilket grensesnitt en destinasjon faktisk bruker, og det er det faktumet de fleste rapporter tar feil av. curl-linjen bekrefter den forhandlede versjonen og adressefamilien. Utskriften av regelsettet fanger regelen du la til under testingen og glemte å avgrense, og slik blir et midlertidig merke permanent fail-open-ruting.
Loggfør alle tre utdataene med tidsstempel og oppbevar dem sammen med endringen. Når noen senere rapporterer at «VPN-en ødela intranettet», vil forskjellen mellom den tiltenkte og den implementerte grensen være synlig i den loggen, og rettelsen blir en regelendring i stedet for en diskusjon.