Przejdź do głównej treści

OpenWrt, mwan3 i domyślna trasa dla tunelu IPsec

OpenWrt mwan3 i failover IPsec: rozwiązywanie problemów z domyślną trasą dla płynnej redundancji Internetu i VPN. Dowiedz się, jak skonfigurować mwan3.user do automatycznych korekt metryk i przełączania tuneli IPsec.
Zawartość

Ostatnio miałem problem z mwan3, pakietem na routerach OpenWrt, który został zaprojektowany do zarządzania wieloma połączeniami internetowymi, albo do równoważenia obciążenia, albo do przełączania awaryjnego.

W pracy mamy dwa łącza światłowodowe, z których główne jest używane jako podstawowe, a drugie jest online, ale aktywowane tylko wtedy, gdy pierwsze przestanie działać – typowe podejście do przełączania awaryjnego (failover).

Pierwsze połączenie (nazwijmy je fibre) jest z metryką 10, podczas gdy drugie połączenie (fibre2) jest z metryką 20.

Dla osób zajmujących się technologią, pierwsze połączenie jest bezsporne (uncontended) ze statycznym adresem IP, podczas gdy nasze zapasowe połączenie jest sporne (contended) przez PPPoE.

Moją główną polityką w mwan3 jest fibre_fibre2.

Polityka fibre_fibre2 zawiera członka fibre_m1_w3 (Metryka 1, Waga 3) i fibre2_m2_w2 (Metryka 2, Waga 2).

Gdy fibre nie działa, fibre2 przejmuje kontrolę i cały ruch przepływa płynnie, prawie.

Powiedziałem prawie, ponieważ zdarzają się przypadki, w których ruch jest przesyłany przez niewłaściwy interfejs, nawet jeśli interfejs jest niedostępny.

Mam również serwer WireGuard ustawiony na moim routerze, więc gdy jedno połączenie zostaje zerwane, WireGuard zaczyna akceptować połączenia na drugim IP.

To znany problem, gdy używasz mwan3, że nie jest możliwe, aby WireGuard akceptował połączenia na obu połączeniach jednocześnie, gdy mwan3 jest aktywny.

Wadą mwan3, która nie jest tak łatwa do rozwiązania, jak się wydaje, jest to, że jeśli główne połączenie jest niedostępne, a zapasowe jest aktywowane, wszystkie połączenia zainicjowane przez elementy działające na samym routerze nadal próbują połączyć się przez domyślną trasę.

Jeśli uruchomisz polecenie:

ip route show

Otrzymasz coś takiego:

default via 1.2.3.4 dev wan metric 10 
default via 4.5.6.7 dev wan2 metric 20 

Podczas gdy wan jest fibre, a wan2 jest fibre2. 1.2.3.4 to teoretyczny adres IP bramy dla interfejsu wan, a 4.5.6.7 to teoretyczny adres IP bramy dla interfejsu wan2.

Gdy główne połączenie zostaje przerwane, cały ruch LAN jest starannie przekierowywany przez drugie połączenie. Ruch lokalny i telefony VoIP w firmach nadal działają.

Jednak lokalnie prowadzone usługi mogą nadal chcieć próbować wysyłać ruch przez domyślną trasę.

Problem polega na tym, że gdy główne połączenie zostaje przerwane, domyślna trasa z najniższą metryką jest nadal wyświetlana w tabeli trasowania; w związku z tym lokalnie prowadzone usługi nadal uważają, że jest to domyślna trasa, przez którą ruch będzie wysyłany i odbierany.

Problem polega na tym, że mwan3 nie może bezpośrednio zmienić tych domyślnych tras; w związku z tym część ruchu routera nadal będzie przesyłana przez trasę o najniższej metryce, nawet jeśli połączenie jest zerwane.

Ten problem dotyczy usług, takich jak tunele IPsec, które zaimplementowałem na routerze, aby umożliwić całej sieci LAN dostęp do określonych usług używanych w firmie za pośrednictwem RemoteApp.

Ustawiłem dwa tunele IPsec. Jeden dla połączenia głównego (left=1.2.3.5), a drugi dla kopii zapasowej (left=4.5.6.8).

1.2.3.5 to teoretyczny adres IP interfejsu WAN (fibre), a 4.5.6.8 to teoretyczny adres IP interfejsu WAN2 (fibre2).

Te tunele nie mogą pracować jednocześnie, ponieważ współdzielą tę samą lewą podsieć (leftsubnet=192.168.1.0/24).

Pierwszy tunel IPsec jest aktywowany (ipsec up tunnel1), gdy główne połączenie jest włączone. Drugi tunel (ipsec up tunnel2) jest aktywowany, gdy główne połączenie przestaje działać, a fibre2 przejmuje kontrolę (po… ipsec down tunnel1) – teoretycznie.

Gdy moje główne połączenie przestaje działać i mwan3 przekierowuje cały ruch przez fibre2, połączenie ipsec jest nadal wysyłane przez domyślną trasę, mimo że lewy adres IP określa, którego adresu IP należy użyć.

Błędem jest domyślna trasa i najniższa metryka interfejsu.

Przypomnijmy sobie nasze polecenie:

ip route show

I spójrz na to jeszcze raz:

default via 1.2.3.4 dev wan metric 10 
default via 4.5.6.7 dev wan2 metric 20 

Mimo że mwan3 ładnie przekierowuje cały ruch, a drugi tunel IPsec ładnie łączy się przez drugie połączenie (left=4.5.6.8), ruch pochodzący z samego tunelu IPsec, taki jak ping do IP po drugiej stronie tunelu IPsec, nadal wykorzystuje domyślną trasę z najniższą metryką (przechodząc przez niewłaściwy interfejs).

Wykonujesz ping 10.1.2.3… który jest wysyłany przez aktualnie aktywne połączenie światłowodowe (fibre2/WAN2), ale odpowiedź ping jest kierowana przez domyślną trasę z najniższą metryką, która należy do połączenia światłowodowego (fibre/WAN), które jest obecnie niedostępne.

Pewnego dnia było to dla mnie trochę trudne do zrozumienia. Próbowałem zrozumieć, co się dzieje, ponieważ drugi tunel IPsec był prawidłowo podłączony, oba końce go widziały, ale ruch LAN przez tunel nie płynął.

Postanowiłem wyłączyć główny interfejs, który obecnie jest oznaczony jako niedostępny, za pomocą polecenia ifdown wan.

Po wykonaniu tej czynności lokalny ruch przez tunel IPsec zaczął płynąć, a ping zaczął odpowiadać poprawnie.

Kiedy spojrzałem na ip route show zauważyłem, że po odłączeniu interfejsu, domyślna trasa, która miała metrykę 10 dla WAN, została usunięta, a tylko domyślna trasa, z metryką 20, była dla WAN2.

Dzięki temu rozumiem problem i ograniczenie mwan3, jeśli chodzi o domyślną trasę.

Muszę to rozwiązać i po chwili lektury udało mi się to zrobić przy użyciu alertów/powiadomień mwan3 za pośrednictwem mwan3.user znajdujących się w pliku /etc/mwan3.user, który można edytować w terminalu lub przez interfejs internetowy (Network > MultiWAN Manager > Notify zakładka).

Podejście teoretyczne

Pomysł był taki, że gdy fibre przestaje działać (kontrolowane i powiadamiane przez mwan3), metryka tego połączenia ulega zmianie, więc fibre2 (drugie połączenie, które przejmie mwan3) staje się najniższą metryką.

Umożliwi to przepływ ruchu przez połączenie o najniższej metryce, które w tym przypadku będzie połączeniem, które jest obecnie aktywne jako zapasowe (fibre2).

Praktyczne rozwiązanie

Aby zmienić metrykę interfejsu, musisz najpierw usunąć domyślną trasę dla pierwszego połączenia.

Niestety, nie można po prostu zmienić metryki, co byłoby idealne w takim przypadku.

W takim przypadku, gdy główne połączenie (fibre) zostanie zerwane, a ruch zostanie przekierowany (przez mwan3) do połączenia zapasowego, muszę zmienić metrykę z 10 na wyższą niż 20.

Postanowiłem po prostu dodać zero do bieżącej metryki.

Robię to, wykonując następujące polecenia.

ip route del default via 1.2.3.4
ip route add default via 1.2.3.4 metric 100

Spowoduje to również przekierowanie domyślnej odpowiedzi serwera Wireguard w celu przejścia przez połączenie o najniższej metryce.

Przełączanie awaryjne IPsec

W pliku /etc/ipsec.conf określiłem dwa tunele, po jednym dla każdego adresu IP każdego połączenia.

Tunel conn tunnel1 dla left=1.2.3.5 (główny, fibre) i conn tunnel2 dla left=4.5.6.8 (zapasowy, fibre2).

Ponieważ oba tunele współdzielą tę samą podsieć (leftsubnet=192.168.1.0/24), nie mogą działać jednocześnie (w tym samym czasie). Muszę ustawić tunnel1 za pomocą auto=start i tunnel2 za pomocą auto=add.

W takim scenariuszu, gdy z jakiegoś powodu tunnel1 ulegnie awarii lub się rozłączy, IPsec spróbuje ponownie połączyć się z nim od razu. Drugi tunel będzie mógł się połączyć tylko ręcznie, poprzez ipsec down tunnel1 i wykonanie ipsec up tunnel2.

To nie jest idealne rozwiązanie, ponieważ gdy moje główne połączenie zostanie przerwane, będę musiał przejść do routera i ręcznie uruchomić drugi tunel.

Problem polega na tym, że czasami musi upłynąć trochę czasu, zanim druga strona zauważy, że pierwszy tunel jest faktycznie przerwany. Gdybym próbował połączyć się z drugim tunelem, gdy druga strona nadal widzi aktywny pierwszy tunel, wystąpi błąd podczas uruchamiania z powodu błędu uwierzytelniania (nawet gdy oba tunele współdzielą różne hasła dostępu zapisane w… /etc/ipsec.secrets).

Postanowiłem umieścić oba tunele w oddzielnych plikach.

/etc/ipsec.conf.tunnel1
/etc/ipsec.conf.tunnel2

Ustawiłem to w obu plikach auto=start. Kiedy drugi tunel ma być uruchomiony, ale zawiedzie z powodu przedwczesnego połączenia i błędu uwierzytelniania, będzie ponawiał próby, aż się powiedzie.

Oczywiście umieszczenie tuneli w oddzielnych plikach konfiguracyjnych nie sprawi, że będą działać, ponieważ usługa IPsec zawsze będzie używała pliku konfiguracyjnego z /etc/ipsec.conf.

W takim przypadku, tak jak wykonałem zmianę metryki dla pierwszego połączenia, gdy zostanie ono przerwane, będę musiał powiedzieć, który tunel IPSec ma zostać użyty, kopiując plik ipsec.conf.tunnel2 do pliku ipsec.conf, gdy fibre2 stanie się aktywnym połączeniem. Gdy główne fibre powróci do trybu online, będę musiał skopiować ipsec.conf.tunnel1 do ipsec.conf, aby ustawić tunnel1 jako połączenie domyślne.

Oczywiście za każdym razem po kopiowaniu muszę ponownie uruchomić usługę IPsec poleceniem ipsec restart.

Teraz muszę połączyć wszystkie powyższe elementy, aby wykonać to automatycznie za pomocą funkcji alertów/powiadomień MWAN3

Skrypt mwan3.user

Umieśćmy poniższy skrypt w pliku /etc/mwan3.user, edytując go w Terminalu lub wklejając zawartość przez interfejs sieciowy (Network > MultiWAN Manager > Notify zakładka).

Wszystkie adresy IP tutaj są fałszywe i należy je dostosować do tego, czego używasz. Dla Twojej informacji, wszystkie moje połączenia używają statycznego zewnętrznego adresu IP w zakresie IPv4.

#!/bin/sh
if [ "${ACTION}" = "disconnected" ] && [ "${INTERFACE}" = "fibre" ] ; then
    # When FIBRE down - set FIBRE2 as primary
    ip route del default via 1.2.3.4 2>/dev/null
    ip route add default via 1.2.3.4 metric 100 2>/dev/null
    cp /etc/ipsec.conf.tunnel2 /etc/ipsec.conf; ipsec restart 2>/dev/null
fi

if [ "${ACTION}" = "connected" ] && [ "${INTERFACE}" = "fibre" ] ; then
    # When FIBRE up - remove FIBRE2 priority route
    ip route del default via 1.2.3.4 2>/dev/null
    ip route add default via 1.2.3.4 metric 10 2>/dev/null
    cp /etc/ipsec.conf.tunnel1 /etc/ipsec.conf; ipsec restart 2>/dev/null
fi

if [ "${ACTION}" = "disconnected" ] && [ "${INTERFACE}" = "fibre2" ] ; then
    # When FIBRE2 down - set FIBRE as primary
    ip route del default via 4.5.6.7 2>/dev/null
    ip route add default via 4.5.6.7 metric 200 2>/dev/null
fi

if [ "${ACTION}" = "connected" ] && [ "${INTERFACE}" = "fibre2" ] ; then
    # When FIBRE2 up - remove FIBRE priority route
    ip route del default via 4.5.6.7 2>/dev/null
    ip route add default via 4.5.6.7 metric 20 2>/dev/null
fi

Jak widać, są tu cztery reguły.

  1. Gdy główne połączenie ulegnie awarii, dzieją się następujące rzeczy: a. Usuń domyślną trasę dla głównego połączenia b. Dodaj ponownie domyślną trasę z wysoką metryką 100 c. Skopiuj ipsec.conf.tunnel2 do ipsec.conf (aby użyć drugiego tunelu, zaprojektowanego do pracy z połączeniem fibre2) i uruchom ponownie usługę IPsec.

  2. Gdy główne połączenie powróci do trybu online, dzieją się następujące rzeczy: a. Usuń domyślną trasę dla głównego połączenia o wysokiej metryce 100 b. Ponownie dodaj domyślną trasę o oryginalnej metryce 10 c. Skopiuj ipsec.conf.tunnel1 do ipsec.conf i uruchom ponownie usługę IPsec

Trzecia i czwarta reguła są opcjonalne i służą do zwiększenia domyślnej wartości metryki z 20 do 200, gdy połączenie zostanie zerwane, na wszelki wypadek, aby nawet niezamierzony ruch nie został przesłany przez niedziałający interfejs.

Domyślne metryki dla każdego połączenia ustawia się w Network > Interfaces, edytując każdy interfejs i w Advanced Settings określając metrykę w pozycji Use gateway metric.

W ten sposób mam działający mwan3 do zarządzania połączeniami internetowymi i odpowiedniego przekierowywania ruchu oraz zabezpieczenie dla tuneli IPsec, aby używać właściwego tunelu dla właściwego “aktywnego” połączenia, kierując ruch przez właściwą trasę (domyślną) połączenia, które jest obecnie w użyciu.

Problem z mwan3 i wysyłaniem ruchu przez niewłaściwy interfejs nie jest nowy, a jego naprawienie nie jest tak proste, jak się wydaje, ponieważ zależy od wielu różnych scenariuszy. Dlatego jeśli nie możemy mieć jednego rozwiązania, które pasuje do wszystkich, musimy zbudować własne rozwiązanie, które pasuje do tego, czego potrzebujemy, dzięki mwan3.user.

Pozdrawiam.

Udostępnij na Threads
Udostępnij na Bluesky
Udostępnij na Linkedin
Udostępnij przez WhatsApp
Udostępnij przez Email

Komentarze i Reakcje

Kategorie