Napraw DNS gościa libvirt blokowany przez firewall VPN oparty na znacznikach
Firewall VPN oparty na znacznikach porzuca DNS gościa, zanim zobaczy go łańcuch filtrów. Jedna reguła o priorytecie mangle oznacza zapytanie i odpowiedź, nie otwierając twojej sieci LAN.
Goście w domyślnej sieci libvirt rozwiązują nazwy bezbłędnie, dopóki nie pojawi się interfejs WireGuard, a wtedy każde wyszukiwanie zatrzymuje się w tym samym miejscu. dnsmasq nadal nasłuchuje na 192.168.122.1:53, gość nadal ma ten adres jako resolver, a zapytanie nadal dociera. Zmieniło się to, że własne zapytanie hosta do serwera nadrzędnego, albo odpowiedź na nie, jest teraz odrzucane przez regułę ocenianą przed jakimkolwiek łańcuchem filtrów, który przyszłoby ci do głowy edytować. Wyjściem jest znacznik nałożony wystarczająco wcześnie, na połączeniu, które dziedziczy odpowiedź.
Goście tracą DNS w chwili, gdy tunel się podnosi
Potwierdź kształt, zanim cokolwiek zmienisz. Opuść tunel, uruchom dig @192.168.122.1 example.com z gościa i zobacz, że odpowiada. Podnieś tunel, powtórz i zobacz, że kończy się przekroczeniem czasu. Ta para wyników wyklucza zepsutą sieć libvirt, zły adres resolvera i martwy dnsmasq w jednym kroku.
Potem spójrz na stronę hosta. Jeśli dnsmasq loguje zapytanie i jego przekazanie na zewnątrz, pakiet dotarł, a awaria leży na wyjściu. Jeśli dnsmasq nie loguje niczego, zapytanie gościa jest odrzucane na wejściu, a wyjątek należy do innego hooka niż ten, który oznacza ten artykuł.
Dlaczego reguła accept w późniejszym łańcuchu nigdy nie zadziała
Firewall VPN oparty na znacznikach decyduje, patrząc na znacznik pakietu albo znacznik połączenia, a nie na twój adres źródłowy. Wszystko, co przychodzi na interfejs fizyczny bez oczekiwanego znacznika, jest odrzucane, a to odrzucenie dzieje się w zestawie reguł, który jest właścicielem testu znacznika. ip saddr 192.168.122.0/24 accept wiersz dodany do jakiegoś późniejszego łańcucha po prostu nigdy nie jest brany pod uwagę dla tego pakietu, dlatego oczywista reguła wygląda poprawnie i niczego nie zmienia.
Rozszerzanie jej, aż coś zadziała, to druga pułapka. Akceptowanie całej podsieci libvirt na ścieżce wejściowej hosta otwiera każdą usługę hosta dla gości, podczas gdy realna potrzeba dotyczy jednego portu.
Mechanizmem, który umożliwia wąski wyjątek, jest śledzenie połączeń. Gdy ustawisz ct mark na pakiecie, wartość jest zapisywana we wpisie conntrack, a nie tylko na pakiecie, więc każdy pakiet tego połączenia nosi ją potem, łącznie z odpowiedzią z hosta z powrotem do gościa. Na tym polega cały trik: oznacz żądanie raz, a ścieżka powrotna jest już oznaczona.
Oznacz zapytanie, zanim zobaczy je tablica VPN
Umieść wyjątek we własnej tablicy, żeby późniejszy czytelnik mógł go znaleźć bez parsowania reguł VPN:
table inet allowedLocal {
chain guest_dns {
type filter hook input priority mangle; policy accept;
ip saddr 192.168.122.0/24 meta l4proto { tcp, udp } \
th dport 53 ct mark set 0x00000f41
}
}
priority mangle jest ujemna, co stawia ten łańcuch przed zwykłymi łańcuchami filtrów, które pakiet VPN instaluje na priorytecie zero. To kolejność hooków czyni regułę skuteczną; ta sama reguła w łańcuchu sortowanym po łańcuchu VPN jest tylko dekoracją.
Sam numer znacznika nie jest przenośny. Weź wartość, którą zainstalowane reguły VPN akceptują dla własnego ruchu, odczytaj ją z działającego zestawu reguł i tę wartość zastosuj. Zły znacznik daje regułę, która ładuje się czysto, pasuje do każdego zapytania i niczego nie wpuszcza.
Trzymaj dziurę na szerokość portu 53
Jak zapisano, pozwala to na DNS z podsieci libvirt do hosta po TCP lub UDP na porcie 53 i nic więcej. Nie pozwala gościom sięgnąć internetu poza tunelem i nie pozwala hostowi otwierać połączeń w stronę gości. Jeśli gość będzie później potrzebował innej usługi hosta, dodaj osobną regułę wskazującą ten port docelowy, zamiast poluzowywać tę.
Bądź szczery co do tego, na co się wymieniasz. Gość, który może sięgnąć resolvera, może też tunelować dowolne dane przez zapytania DNS, a ten wyjątek jest świadomą dziurą w granicy VPN, a nie stwierdzeniem, że sieć lokalna jest zaufana. Ograniczenie źródła do 192.168.122.0/24 trzyma tę dziurę z dala od każdej innej podsieci lokalnej, a liczenie zapytań z tego źródła jest tanie, jeśli zagrożenie ma dla ciebie znaczenie.
Zrób tak, żeby przetrwało restart, i udowodnij obie połowy
Reguła wpisana w wierszu poleceń znika przy następnym rozruchu, a reguła wczytana po tym, jak interfejs VPN już przepuszcza ruch, przegrywa wyścig przy pierwszym połączeniu. Umieść tablicę w trwałej konfiguracji nftables hosta albo w jednostce uporządkowanej przed usługą VPN, i sprawdź kolejność, zamiast ją zakładać.
Weryfikacja wymaga trzech osobnych odpowiedzi. Potwierdź, że łańcuch jest wczytany i uporządkowany pierwszy, potwierdź, że wpis conntrack pokazuje znacznik w obu kierunkach, i potwierdź, że wyszukiwanie z gościa zwraca adres. Potem potwierdź drugą połowę: zwykły ruch webowy gościa do publicznego hosta nadal zawodzi, gdy tunel jest opuszczony albo blokuje. Jeśli DNS działa, a wszystko inne przecieka, twoja reguła jest szersza niż ta powyżej.
Jeśli wyszukiwania nadal zawodzą po założeniu znacznika, powstrzymaj pokusę rozszerzenia źródła. Sprawdź, do czego przekazuje dnsmasq, czy resolver gościa wskazuje na 192.168.122.1 czy na publiczny adres, który ktoś wpisał, i czy zapytanie w ogóle dociera do hosta. Oznaczanie wpuszcza pakiet i nic więcej, więc złe źródło nadrzędne albo zepsuta sieć wirtualna pozostaną zepsute, ile byś nie dodał reguł.