Правилата за портите 80 и 443 не го пуштаат прелистувачот низ VPN
Совпаѓањето на порта избира TCP текови, не прелистувач. HTTP/3 работи преку UDP, DNS може да тргне по друг пат, а ажурирањето удира на истото правило што сте го напишале.
Некој бара прелистувачот да го користи тунелот, а одговорот се враќа како правило на огнен ѕид што совпаѓа со одредишните порти 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 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 |
Одделен профил на прелистувач е стапицата во средниот ред. Тој ги одвојува колачињата и историјата и не менува ништо во табелата за насочување на домаќинот, па двата профила одат по истиот пат. Изолацијата бара нешто што јадрото го спроведува, значи именски простор, контејнер или апликација што поседува свој интерфејс за тунел.
Кој и ред да важи, запишете што треба да се случи кога тунелот ќе падне. Рута базирана на ознака што исчезнува со интерфејсот обично се враќа на физичката стандардна рута, што е однесување 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-от го расипа интранетот“, разликата меѓу предвидената и имплементираната граница ќе биде видлива во тој запис, а поправката ќе биде промена на правило, не расправија.