Jeden klient na Twoim serwerze OpenVPN musi stracić dostęp do LAN, podczas gdy wszystkie pozostałe tunele pozostają aktywne. Jeśli tego poszukasz, najlepsza odpowiedź zwykle mówi, że demon tego nie potrafi, co jest tylko w połowie prawdą: OpenVPN nie ma zapory na klienta, ale host kończący tunel już filtruje pakiety. Dwie decyzje, które się liczą, to tożsamość, którą blokujesz, i pozycja reguły. Zrób to dobrze, a zmiana stanie się jedną linią, którą możesz przetestować i usunąć.

Przypnij klienta, zanim napiszesz regułę

OpenVPN dzierżawi adresy tunelu z puli, więc 10.8.0.6 to miejsce, a nie osoba. Gdy sesja się kończy, dzierżawa wraca i może trafić do następnego połączenia, co oznacza, że reguła napisana wobec tego adresu podąża za miejscem, a nie za użytkownikiem. Najpierw zdecyduj, co naprawdę blokujesz: adres do krótkiego eksperymentu czy certyfikat kogoś, kogo chcesz trzymać na zewnątrz.

Aby powiązać adres z certyfikatem, utwórz plik w katalogu wskazanym przez client-config-dir i nadaj mu dokładnie common name certyfikatu. Wpisz do niego jedną dyrektywę, ifconfig-push 10.8.0.6 255.255.255.0, a ten klient zachowa ten sam adres tunelu przy ponownych połączeniach. Aby to działało, muszą istnieć dwa ustawienia: client-config-dir musi być zadeklarowany w konfiguracji serwera, a wysyłany adres musi leżeć w podsieci, którą serwer potrafi routować. Brak jednego sprawia, że plik jest ignorowany bez błędu, co czyni następny test zapory mylącym.

Tymczasowa blokada może użyć adresu z puli, o ile bilet zapisuje, która sesja go wtedy miała.

Kolejność decyduje, czy odrzucenie zadziała

Na bramie Linux, która przekazuje między tunelem a LAN, pakiety przechodzą przez łańcuch FORWARD. Przeczytaj poniższe polecenie jak zdanie: wstaw na początek FORWARD, dopasuj ruch wchodzący z tun0, od tego jednego hosta, adresowany do podsieci LAN, i odrzuć go.

iptables -I FORWARD -i tun0 -s 10.8.0.6/32 -d 192.168.1.0/24 -j DROP

To -I sprawia, że reguła działa. Dodana przez -A ląduje poniżej każdego szerokiego zezwolenia dla podsieci tunelu i nigdy nie widzi pakietu. Sprawdź pozycję przez iptables -vnL FORWARD --line-numbers i przeczytaj też liczniki: odrzucenie na górze, które nic nie liczy, oznacza, że ruch przychodzi inną drogą.

Własny adres LAN bramy to inna droga. Pakiety wysyłane do samego urządzenia idą do INPUT, nie do FORWARD, więc klient może stracić hosta LAN, a mimo to otworzyć stronę administracyjną routera. Dodaj pasującą regułę INPUT, gdy to ma znaczenie.

Czego filtr nie widzi

Filtrowanie odbywa się przy ocenie pakietu, więc ustanowiona sesja TCP może trwać, aż zostanie zamknięta lub zresetowana. Jeśli blokada ma zadziałać natychmiast, wyczyść śledzone przepływy dla tego źródła przez conntrack -D -s 10.8.0.6 po wstawieniu reguły. Jeśli kilka sekund nakładania jest akceptowalne, zapisz ten wybór, zamiast zostawiać go domyślnym. Tak czy inaczej, następna osoba musi wiedzieć, czy reguła zatrzymuje żywy ruch, czy tylko nowe połączenia.

Ruch między peerami nigdy nie dotyka zapory hosta. Przy włączonym client-to-client OpenVPN przekazuje te pakiety wewnątrz demona, więc ani FORWARD, ani INPUT ich nie widzi. Jedyne rozwiązania to wyłączenie client-to-client albo zaakceptowanie, że peery mogą się wzajemnie osiągać; reguła iptables tego ruchu nie zobaczy.

IPv6, firmware i przetrwanie restartu

Reguła IPv4 nie mówi nic o IPv6. Jeśli tunel i LAN niosą obie rodziny, równoważna reguła musi istnieć w ip6tables albo w zestawie reguł nftables, który posiada politykę na tym hoście. Firmware routera często ukrywa netfilter za własną abstrakcją, więc składnia i nazwy tabel skopiowane z forum mogą nie działać.

Na OpenWrt udokumentowaną drogą jest wpis konfiguracji zapory, a nie ręcznie napisana linia iptables, a ręcznie napisana linia może zniknąć przy przeładowaniu zapory. Inne dystrybucje przywracają reguły przez netfilter-persistent, jednostkę startową lub magazyn dostawcy, a te mechanizmy nie są wymienne. Udowodnij wybrany restartem, bo przeładowanie ćwiczy inną drogę.

Sprawdź po kolei każdą drogę, potem wycofaj czysto

Testuj każdą drogę osobno, bo jedno udane sprawdzenie ukrywa pozostałe. Zablokowany klient powinien nadal docierać do internetu przez tunel, ale ponosić porażkę wobec hosta LAN, drugi klient powinien docierać do tego samego hosta, a adres bramy i droga do peera wymagają każda własnej obserwacji. Zapisz wyniki obok reguły, aby następna zmiana miała punkt odniesienia. Tabela poniżej to zestaw, który warto zachować w bilecie.

DrogaOczekiwane z regułąGdy zawiedzie
Zablokowany klient do hosta LANBrak odpowiedziReguła jest poniżej zezwolenia albo źródło nie pasuje
Zablokowany klient do internetuDziała przez tun0Reguła jest zbyt szeroka, bez dopasowania celu
Drugi klient do tego samego hosta LANDziałaReguła dopasowała więcej niż zamierzony host
Zablokowany klient do adresu LAN bramyZablokowane tylko z pasującą regułą INPUTBrak reguły INPUT
Zablokowany klient do adresu tunelu peeraNadal działaclient-to-client jest włączone i poza zasięgiem zapory

Wycofanie to usunięcie według specyfikacji, a nie flush: iptables -D FORWARD -i tun0 -s 10.8.0.6/32 -d 192.168.1.0/24 -j DROP usuwa dokładnie ten wpis i pozostawia resztę łańcucha nietkniętą. Usuń tę samą linię z pliku, który przywraca reguły przy starcie, przeładuj go i potwierdź, że klient znów dociera do hosta LAN. Flush FORWARD cofnąłby też reguły, których nie napisałeś, co zamienia wycofanie w drugi incydent.

Przed zamknięciem biletu potwierdź trzy rzeczy: przypięty adres pasuje do certyfikatu, reguła stoi powyżej zezwoleń z licznikiem różnym od zera, a plik trwałości zawiera tę samą regułę, którą testowałeś. Jeśli czegoś brakuje, blokada jest iluzją w sesji shell.

Powiązane artykuły