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.
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.