Přepínání mezi hlavní a záložní konektivitou pomocí démona ifstated

28. 3. 2012
Doba čtení: 4 minuty

Sdílet

Především ve firemním prostředí se zvyšuje tlak na dostupnost služeb, firmy si pořizují záložní konektivitu pro případ výpadku a je tedy potřeba nakonfigurovat rozložení zátěže mezi připojení nebo přepínání ve chvíli výpadku. Ukážeme si, jak takové přepínání realizovat. Použijeme k tomu démona ifstated.

V našem příkladu budeme mít dvě sítě, každá z nich má dvě konektivity a sítě jsou propojené dvěma vpn tunely. Budeme řešit dostupnost sítí při výpadku konektivity. To znamená testování stavu připojení a reakce na změnu – v našem případě úpravu routování. Další použití může být pro jednoduchý multihoming. V případě výpadku hlavní konektivity se na internet dostaneme přes záložní linku.

Takovou věc je možné řešit několika způsoby, třeba i shell skripty, které budou periodicky pingat a dle výsledku změní routovací tabulky. Další možnost je použití nějakého dynamického routovacího protokolu, např. OSPF. Ale proč brát kanón (OSPF + quagga) na vrabce? Postačí nám jeden malý démon.

                tunel main               _________          tunel main
_________           10.1.0.1       _____/         \          10.1.0.2          __________
         |     ______________    /                 \__    ________________    |
         |     ______________   |    internet         \   ________________    |
FreeBSD  |                      |                    /                        | FreeBSD
   1     |     ______________    \_______           /     ________________    |    2
         |     ______________            \_________/      ________________    |
_________|                                                                    |__________
sit               tunel back                                tunel back        sit 2
192.168.60.0      10.1.0.5                                   10.1.0.6         192.168.70.0
255.255.255.0                                                                 255.255.255.0

Ifstatet pochazi z OpenBSD a je portován i do dalších systémů. Je to démon, který reaguje na změny sítě a dle těchto změn spouští námi definované příkazy. Démon se často používá v kombinaci s carp (Common Address Redundancy Protocol, viz man carp), tedy více strojů a sdílení adres. Dnes si ukážeme řešení bez něj, někdy příště se podíváme i na carp.

Změny v síti je schopen testovat dvěma metodami:
 – stav síťových rozhraní – up, down a unknown
 – externí testy – jsou spouštěné periodicky, nejčastěji se jedná o ping

Dále definujeme stavy, které mají dvě části:
 – init blok – příkazy, které se vykonají při aktivaci stavu
 – tělo – podmínky (if, if not), které se testují při změně stavů a na jejich vyhodnocení se přepne příslušný stav

Asi lépe si to ukázat na příkladu, zde je uvedena část konfiguračního souboru  ifstated.conf.

# co a jak testovat - v kazdem testu dva pingy
# ukoncit po uspesnem prichodu prvniho a timeout jednu sekundu
tun_main = '( "ping -q -c 2 -o -W1000 10.1.0.2 > /dev/null" every 10)'
tun_back = '( "ping -q -c 2 -o -W1000 10.1.0.6 > /dev/null" every 10)'

# definice stavu primary
state primary {
    init {    # toto se spusti pri aktivaci tohoto stavu
      run "route delete 192.168.70.0/24"
      run "route add 192.168.70.0/24 10.1.0.2"
    }
# telo
    # pokud nebezi ani jeden z tunelu, prepni se do stavu nic
    if ! $tun_back && ! $tun_main
       set-state nic
    # kdyz nefunguje hlavni tunel, ale jde zalozni, prepni na backup
    if ! $tun_main && $tun_back
       set-state backup
}state backup {
init {
...

A teď praktická ukázka. Ta předpokládá funkční L3 tunely mezi lokalitami. To je nad rámec článku, já jsem použil OpenVPN.

Instalace démona ve FreeBSD je jednoduchá:

# cd /usr/ports/net/ifstated
# make install

Automatické spouštění zajistíme v rc.conf:
  ifstated_enable="YES"

Konfigurační soubor si uložíme do /usr/local/etc/ifstated.conf.
Konfigurace pro LAN 1:

init-state primary
tun_main = '( "ping -q -c 2 -o -W1000 10.1.0.2 > /dev/null" every 10)'
tun_back = '( "ping -q -c 2 -o -W1000 10.1.0.6 > /dev/null" every 10)'

state primary {
    init {
        run "route delete 192.168.70.0/24"
        run "route add 192.168.70.0/24 10.1.0.2"
    }
    if ! $tun_back && ! $tun_main
            set-state nic
    if ! $tun_main && $tun_back
        set-state backup
}

state backup {
    init {
        run "route delete 192.168.70.0/24"
        run "route add 192.168.70.0/24 10.1.0.6"
    }
    if ! $tun_back && ! $tun_main
            set-state nic
    if ! $tun_back && $tun_main
            set-state primary
}

state nic   {
    init    {
        run "echo vypadek | mail -s vypadek admin@nekde.cz"
    }
    if $tun_main
        set-state primary
    if ! $tun_main && $tun_back
        set-state backup
}

Konfigurace pro LAN 2:

init-state primary
# init-state backup
tun_main = '( "ping -q -c 2 -o -W1000  10.1.0.1 > /dev/null" every 10)'
tun_back = '( "ping -q -c 2 -o -W1000 10.1.0.5 > /dev/null" every 10)'

state primary {
    init {
        run "route delete 192.168.60.0/24"
        run "route add 192.168.60.0/24 10.1.0.1"
    }
    if ! $tun_back && ! $tun_main
            set-state nic
    if ! $tun_main && $tun_back
        set-state backup
}

state backup {
    init {
        run "route delete 192.168.60.0/24"
        run "route add 192.168.60.0/24 10.1.0.5"
    }
    if ! $tun_back && ! $tun_main
            set-state nic
    if ! $tun_back && $tun_main
            set-state primary
}

state nic   {
    init    {
        run " echo vypadek | mail -s vypadek admin@nekde.cz"
    }
    if $tun_main
            set-state primary
    if ! $tun_main && $tun_back
            set-state backup
}

V sekci init nemusí být jen routování, můžeme si například zalogovat změnu nebo si poslat e-mail/SMS o stavu.

Pokud pingáte dost rychle, přepnutí bude rychlejší než u defaultně nastaveného OSPF. Pozor ale na timeout u pingu. Pokud nevhodně nastavíte počet pingů a jejich timeout, může se stát, že test nestihne doběhnout a je násilně ukončen dalším testem, a tím nedostáváme správný stav. Např. timeout pingu je tři sekundy, spouštíte test každých pět sekund a nastane stav, že ze tří testovacích pingů první dva vyprší a už jsme na šesti sekundách a test je ukončen. Parametry u pingu je nutné si také upravit dle vašeho systému.

bitcoin_skoleni

Ping testů může být víc, lze snadno detekovat chybu u poskytovatele, když například dopingneme výchozí bránu, ale zařízení za touto branou již ne. Jen vzniknou trošku složitější podmínky v jednotlivých stavech.

Pokud nechceme řešit podobné hrátky s VPN, ale jen jednu lokalitu a dvě konektivity, stačí nastavit správně ping testy a měnit si výchozí bránu, případně nastavení firewallu. Jak jsem uváděl – podobné řešení je možné postavit třeba jen na shell skriptu, i to má své kouzlo. Záměrem bylo, ukázat podobné řešení elegantněji. Toto řešení nedokáže vše, při přepnutí konektivity samozřejmě přijdete o navázaná TCP spojení, to IPv4 neumí řešit.

Autor článku

Petr Macek studoval aplikovanou informatiku na Jihočeské univerzitě, pracuje jako síťový specialista ve firmě Kostax, s. r. o. Baví ho především FreeBSD, sítě a monitoring Cacti.