Неко затражи да прегледач користи тунел, а одговор се врати као правило заштитног зида које се подудара са одредишним портовима 80 и 443. Изгледа прецизно и није. Подударање порта бира пакете по њиховом заглављу транспорта, а не по томе који је програм отворио сокет, а савремено прегледање није ограничено на та два порта на TCP-у. Правило ће пропустити део саобраћаја који сте хтели да укључите и ухватити саобраћај који никада нисте намеравали да дотакнете. Пре него што га напишете, одлучите коју од три различите границе заиста желите.

Правило описује транспортну класу, а не апликацију

На Linux-у подударање одредишног порта прегледа TCP заглавље и ништа изнад њега. Означавање тих пакета и усмеравање политичком рутом ради тачно како је документовано, и ниједан од тих механизама не зна шта носиви терет значи ни који га је процес послао. Ознака је број придружен пакету, а не идентитет придружен апликацији.

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

Одмах следе две последице. Програм за ажурирање софтвера који контактира TCP 443 добија исти третман као прегледач, што може бити у реду или може бити испад који чека следећи циклус ажурирања. А веб услуга намерно објављена на другом порту, рецимо 8443, потпуно излази из правила иако је то још увек веб саобраћај до којег је кориснику било стало.

Бројеви су легитимни селектори када се захтев заиста односи на те портове. Постају фикција када у тикету пише „прегледач“, а у скупу правила се имплементира распон портова. Тај јаз није документациона ситница. То је разлика између правила које можете да браните на прегледу и оног које нико не може да тестира.

HTTP/3 тихо напушта ваше TCP правило

HTTP/3 ради преко QUIC-а, а QUIC се преноси у UDP-у. Правило које се подудара само са TCP-ом не може да га види, па исти прегледач који прође вашу тест страницу може да пошаље каснији захтев преко UDP-а и заобиђе тунел, а да нико не промени поставку. RFC 9114 описује HTTP/3 као протокол заснован на QUIC-у, а QUIC користи UDP са подразумеваним портом 443 у уобичајеном распоређивању.

Да ли ће дати прегледач покушати HTTP/3 зависи од његове конфигурације, од сајта и од тога да ли је претходни покушај успео. Зато је лоше о томе расуђивати по сећању. Питајте алат уместо тога:

curl --http3 -sS -o /dev/null -w '%{http_version} %{time_total}\n' https://example.com
ss -tunp | grep -E ':443\b'

Линија curl исписује договорену верзију, па 3 потврђује да је коришћен пут преко UDP-а. Списак сокета затим показује да ли је та веза везана за интерфејс тунела или за физички. Ако HTTP/3 није доступан у вашој изградњи curl-а, заставица гласно пада уместо да тихо одступи, што је њена сопствена мала милост.

DNS је одвојена одлука коју морате да донесете

Правило порта за веб саобраћај не каже ништа о разрешавању имена. Прегледач може да користи системски резолвер, резолвер конфигурисан унутар прегледача или онај који је гурнула последња веза. Сваки од њих може да шаље упите другим путем од оног који бира ваше правило, што ствара класичан расцеп: страница се учита, име се разреши негде где нисте очекивали, а интерни сајт се разреши на јавну адресу или никако.

Одлучите то експлицитно. Ако интерна имена морају да се разрешавају кроз тунел, резолвер мора да буде унутра, а скуп правила мора да дозволи DNS ка том резолверу држећи остале упите напољу. Ако прегледач користи DNS over HTTPS ка јавном провајдеру, упит потпуно заобилази ваш резолвер и правило порта не може да помогне. Упишите избор у исти запис о измени као правило рутирања, јер обоје заједно чита онај ко буде отклањао следећи квар.

Затим потврдите резолвером, а не страницом:

resolvectl query intranet.example.internal
resolvectl status | grep -A3 'Current DNS Server'

Недостајући одговор је проблем разрешавања чак и када порука о грешци прегледача окривљује мрежу. Ова два квара изгледају идентично кориснику и потпуно су различити тикети.

Три границе, три различита механизма

Највећи део забуне нестаје чим именујете границу коју желите. Оне нису заменљиве и свака има другачији начин отказа током прекида тунела.

What you actually wantMechanism that fitsWhat it does not cover
These transport ports use this exitFirewall mark plus policy routeApplications, HTTP/3 over UDP, DNS
This browsing session stays separateApplication-aware VPN, or a separate network namespace plus a proxyOther applications in the same session
Only these private sites are reachableDestination-based routes with private DNSPublic sites on the same address family

Одвојен профил прегледача је замка у средњем реду. Он раздваја колачиће и историју и ништа не мења у табели рутирања домаћина, па оба профила иду истим путем. Изолација захтева нешто што језгро намеће, то јест именски простор, контејнер или апликацију која поседује сопствени интерфејс тунела.

Који год ред да важи, запишите шта треба да се догоди када тунел падне. Рута заснована на ознаци која нестане са интерфејсом обично се враћа на физичку подразумевану руту, што је понашање fail-open. То може бити прихватљиво за прегледање и неприхватљиво за све друго, и то је одлука, а не детаљ имплементације.

Тестирајте токове за које тврдите да их покривате

Пријемни тест мора да следи границу коју сте записали, а не бројеве портова који су били згодни. Изаберите један ток који мора да иде кроз тунел, један који не сме и један који користи транспорт о ком нисте размишљали:

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'

Претрага руте каже који интерфејс одредиште заиста користи, и то је чињеница коју већина извештаја погрешно наводи. Линија curl потврђује договорену верзију и породицу адреса. Испис скупа правила хвата правило које сте додали током тестирања и заборавили да ограничите, и тако привремена ознака постаје трајно fail-open рутирање.

Забележите сва три излаза са временском ознаком и чувајте их уз измену. Када касније неко пријави да је „VPN покварио интранет“, разлика између замишљене и имплементиране границе биће видљива у том запису, а исправка ће бити измена правила, не расправа.

Повезани чланци