Reëls vir poort 80 en 443 stuur nie die blaaier deur 'n VPN nie
'n Poortpassing kies TCP-vloei, nie 'n blaaier nie. HTTP/3 loop oor UDP, DNS kan 'n ander pad neem, en 'n opdateringsprogram pas by dieselfde reel wat jy geskryf het.
Iemand vra dat die blaaier die tonnel moet gebruik, en die antwoord kom terug as 'n vuurmuurreel wat bestemmingspoorte 80 en 443 pas. Dit lyk presies en dit is nie. 'n Poortpassing kies pakkette volgens hulle vervoeropskrif, nie volgens watter program die sok oopgemaak het nie, en moderne blaai beperk hom nie tot daardie twee poorte op TCP nie. Die reel sal van die verkeer mis wat jy wou insluit en verkeer vang wat jy nooit wou raak nie. Voordat jy dit skryf, besluit watter van drie verskillende grense jy eintlik wil hê.
Die reël beskryf 'n vervoerklas, nie 'n toepassing nie
Op Linux ondersoek 'n bestemmingspoortpassing die TCP-opskrif en niks daarbo nie. Om daardie pakkette te merk en met 'n beleidsroete te stuur werk presies soos gedokumenteer, en niks van daardie masjinerie weet wat die vrag beteken of watter proses dit gestuur het nie. Die merk is 'n nommer wat aan 'n pakket geheg is, nie 'n identiteit wat aan 'n toepassing geheg is nie.
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
Twee gevolge volg onmiddellik. 'n Sagteware-opdatering wat TCP 443 kontak, kry dieselfde behandeling as die blaaier, wat dalk goed is of dalk 'n onderbreking is wat op die volgende opdateringsiklus wag. En 'n webdiens wat doelbewus op 'n ander poort gepubliseer is, sê 8443, val heeltemal buite die reel terwyl dit steeds die webverkeer is waaroor die gebruiker omgegee het.
Die nommers is wettige kiesers wanneer die vereiste werklik oor daardie poorte gaan. Hulle word 'n fiksie wanneer "blaaier" in die kaartjie geskryf word en 'n poortreeks in die reelstel geimplementeer word. Die gaping is nie 'n dokumentasie-nukkerigheid nie. Dit is die verskil tussen 'n reel wat jy in 'n hersiening kan verdedig en een wat niemand kan toets nie.
HTTP/3 verlaat jou TCP-reël stilweg
HTTP/3 loop oor QUIC, en QUIC word in UDP gedra. 'n Reel wat net TCP pas, kan dit nie sien nie, so dieselfde blaaier wat jou toetsblad slaag, kan 'n latere versoek oor UDP stuur en die tonnel omseil sonder dat iemand 'n instelling verander. RFC 9114 beskryf HTTP/3 as 'n QUIC-gebaseerde protokol, en QUIC gebruik UDP met 'n verstekpoort van 443 in die algemene ontplooiing.
Of 'n gegewe blaaier HTTP/3 probeer, hang af van sy opstelling, van die werf en van of 'n vorige poging geslaag het. Dit maak dit 'n swak ding om uit die geheue te beredeneer. Vra eerder die gereedskap:
curl --http3 -sS -o /dev/null -w '%{http_version} %{time_total}\n' https://example.com
ss -tunp | grep -E ':443\b'
Die curl-reel druk die bedingde weergawe, so 'n 3 bevestig dat die UDP-pad gebruik is. Die soklys wys dan of daardie verbinding aan die tonnelkoppelvlak of aan die fisiese een gekoppel is. As HTTP/3 nie in jou curl-bou beskikbaar is nie, misluk die vlag luidrugtig eerder as om stilweg terug te val, wat sy eie klein genade is.
DNS is 'n afsonderlike besluit wat jy moet neem
'n Poortreel vir webverkeer se niks oor naamresolusie nie. Die blaaier kan die stelseloplosser gebruik, 'n oplosser wat binne die blaaier opgestel is, of een wat deur die laaste verbinding gestoot is. Elkeen van die kan navrae oor 'n ander pad stuur as die een wat jou reel kies, wat die klassieke splitsing veroorsaak: die bladsy laai, die naam word erens opgelos waar jy dit nie verwag het nie, en die interne werf los op na 'n openbare adres of glad nie.
Besluit dit uitdruklik. As interne name deur die tonnel moet oplos, moet die oplosser binne-in dit wees, en die reelstel moet DNS na daardie oplosser toelaat terwyl ander navrae buite gehou word. As die blaaier DNS oor HTTPS na 'n openbare verskaffer gebruik, omseil die navraag jou oplosser heeltemal en die poortreel kan nie help nie. Skryf die keuse in dieselfde veranderingsrekord as die roetereel, want die twee word saam gelees deur wie ook al die volgende fout ontfout.
Verifieer dan met die oplosser eerder as met die bladsy:
resolvectl query intranet.example.internal
resolvectl status | grep -A3 'Current DNS Server'
'n Ontbrekende antwoord is 'n resolusieprobleem selfs wanneer die blaaier se foutboodskap die netwerk blameer. Daardie twee mislukkings lyk identies vir 'n gebruiker en is heeltemal verskillende kaartjies.
Drie grense, drie verskillende meganismes
Die meeste van die verwarring verdwyn sodra jy die grens noem wat jy wil hê. Hulle is nie uitruilbaar nie, en elkeen het 'n ander mislukkingsmodus tydens 'n tonnelonderbreking.
| 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 |
'n Afsonderlike blaaierprofiel is die lokval in die middelste ry. Dit skei koekies en geskiedenis, en dit verander niks aan die gasheer se roetertabel nie, so albei profiele neem dieselfde pad. Isolasie vereis iets wat die kern afdwing, wat beteken 'n naamruimte, 'n houer of 'n toepassing wat sy eie tonnelkoppelvlak besit.
Watter ry ook al geld, skryf neer wat moet gebeur wanneer die tonnel val. 'n Merkgebaseerde roete wat saam met die koppelvlak verdwyn, val gewoonlik terug na die fisiese verstekroete, wat fail-open-gedrag is. Dit mag aanvaarbaar wees vir blaai en onaanvaarbaar vir enigiets anders, en dit is 'n besluit, nie 'n implementeringsdetail nie.
Toets die vloei wat jy sê jy dek
Die aanvaardingstoets moet die grens volg wat jy neergeskryf het, nie die poortnommers wat gerieflik was nie. Kies een vloei wat deur die tonnel moet gaan, een wat nie moet nie, en een wat 'n vervoer gebruik waaraan jy nie gedink het nie:
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'
Die roete-opsoek vertel jou watter koppelvlak 'n bestemming werklik gebruik, wat die feit is wat die meeste verslae verkeerd kry. Die curl-reel bevestig die bedingde weergawe en die adresfamilie. Die reelstel-uitvoer vang die reel wat jy tydens toetsing bygevoeg het en vergeet het om te beperk, wat is hoe 'n tydelike merk permanente fail-open-roetering word.
Teken al drie uitsette met 'n tydstempel aan en hou hulle by die verandering. Wanneer iemand later rapporteer dat "die VPN die intranet gebreek het", sal die verskil tussen die beoogde grens en die geimplementeerde een in daardie rekord sigbaar wees, en die regstelling sal 'n reelverandering wees eerder as 'n argument.