Нехта просіць, каб браўзер выкарыстоўваў тунель, і ў адказ прыходзіць правіла міжсеткавага экрана, якое супадае з партамі прызначэння 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 зламаў унутраную сетку», розніца паміж задуманай і рэалізаванай мяжой будзе бачная ў гэтым запісе, і выпраўленне будзе зменай правіла, а не спрэчкай.

Падобныя артыкулы