Итак, VRRP мы настроили, но что делать при изменении конфигурации на основном роутере? Делать то же самое на втором? А если забыть? Надо автоматизировать этот процесс!
Итак у нас есть два роутера mikrotik сконфигурированных в отказоустойчивой конфигурации при помощи VRRP. Необходимо синхронизировать конфигурацию Firewall с мастера на slave.
Решение
На мастере будет запускаться (через sheduler) скрипт, который будет делать экспорт конфигурации в файл и затем будет заливать его на slave по ftp.
На slave будет запускаться скрипт, который импортирует конфигурацию из залитого с мастера файла.
Для проверки синхронизации в разделе /ip firewall address-list будет создаваться фиктивный лист с названием sync_timestamp (в состоянии disabled). Во время экспорта в комментарий к указанному листу будет добавлена дата и время экспорта. Таким образом по этому листу можно сверять версии конфигурации.
Скрипт Export_config на мастере: (обновлено 17.04.2024, после подключения VPN и маршрутизацией части трафика через него, необходимо синхронизировать также настройки /routing/table и /ip/route)
P.S. У меня из теперь 3, 2 программных и железный RB4011iGS, поэтому передача конфига идет на оба слейва
:local ftpuser "ftp"
:local ftppassword "ftppass"
:local ftphost1 "192.168.xxx.xx1"
:local ftphost2 "192.168.xxx.xx2"
:local config "sync-master"
:local pool "pools"
:local routtab "routetab"
:local route "route"
# set timestamp for monitoring (if looking for entry)
:if ( [:len [/ip firewall address-list find where list=sync_timestamp address="0.0.0.0" disabled=yes]] = 0 ) do={
/ip firewall address-list add list=sync_timestamp address="0.0.0.0" disabled=yes
}
:local date [/system clock get date]
:local time [/system clock get time]
:local timestamp "$date_$time"
/ip firewall address-list set [/ip firewall address-list find where list=sync_timestamp address="0.0.0.0" disabled=yes] comment="timestamp: $timestamp"
#export config
/ip firewall
export file="$config"
/ip pool
export file="$pool"
/routing table
export file="$routtab"
/ip route
export file="$route"
# put config to slave
/
tool fetch address=$ftphost1 user=$ftpuser password=$ftppassword mode=ftp src-path=($config.".rsc") dst-path=($config.".rsc") upload=yes;
tool fetch address=$ftphost2 user=$ftpuser password=$ftppassword mode=ftp src-path=($config.".rsc") dst-path=($config.".rsc") upload=yes;
tool fetch address=$ftphost1 user=$ftpuser password=$ftppassword mode=ftp src-path=($pool.".rsc") dst-path=($pool.".rsc") upload=yes;
tool fetch address=$ftphost2 user=$ftpuser password=$ftppassword mode=ftp src-path=($pool.".rsc") dst-path=($pool.".rsc") upload=yes;
tool fetch address=$ftphost1 user=$ftpuser password=$ftppassword mode=ftp src-path=($routtab.".rsc") dst-path=($routtab.".rsc") upload=yes;
tool fetch address=$ftphost2 user=$ftpuser password=$ftppassword mode=ftp src-path=($routtab.".rsc") dst-path=($routtab.".rsc") upload=yes;
tool fetch address=$ftphost1 user=$ftpuser password=$ftppassword mode=ftp src-path=($route.".rsc") dst-path=($route.".rsc") upload=yes;
tool fetch address=$ftphost2 user=$ftpuser password=$ftppassword mode=ftp src-path=($route.".rsc") dst-path=($route.".rsc") upload=yes;
Скрипт apply_master_config на slave:
# Varables
:local config "sync-master.rsc"
:local pool "pools.rsc"
:local routtab "routetab.rsc"
:local route "route.rsc"
#Import Route Table
:if ([:len [/file find name=$routtab]] > 0) do={
:put "Found Route Table config from master"
/routing table remove [/routing table find name!="main"]
/import $routtab
/file remove $routtab
} else { :put "Route Table config ($routtab) from master not found"}
#Import firewall
:if ([:len [/file find name=$config]] > 0) do={
:put "Found config from master!"
/ip firewall filter remove [/ip firewall filter find dynamic=no]
/ip firewall nat remove [/ip firewall nat find dynamic=no]
/ip firewall raw remove [/ip firewall raw find dynamic=no]
/ip firewall mangle remove [/ip firewall mangle find dynamic=no]
/ip firewall address-list remove [/ip firewall address-list find dynamic=no]
/ip firewall layer7-protocol remove [/ip firewall layer7-protocol find]
/import $config
/file remove $config
} else { :put "Config form master ($config) not found" }
# Import pool config
:if ([:len [/file find name=$pool]] > 0) do={
:put "Found pool config from master"
/ip pool remove [/ip pool find]
/import $pool
/file remove $pool
} else { :put "Pool config ($pool) from master not found"}
#Import routes
:if ([:len [/file find name=$route]] > 0) do={
:put "Found Route config from master"
/ip route remove [/ip route find dynamic=no]
/import $route
/file remove $route
} else { :put "Route config ($route) from master not found"}
*Обратите внимание, на то как сделано удаление таблицы маршрутизации. Поиск по dynamic=no не работает, я это обнаружил на следующий день, когда у меня оказались задублированы эти таблицы. Но я нашел выход)
На slave нужно создать пользователя с разрешением на ftp, и добавить скрипты в sheduler (на мастер можно раз в сутки, на slave раз в час). Если на мастере что-то изменили, не забываем запустить экспорт:
sys scr run Export_config
P.S.Если кто-то знает, как экспортировать несколько настроек в один файл, пишите в комментах, буду благодарен. Ну или как отправить по ftp сразу несколько файлов.
Эта инструкция была найдена на просторах интернета
Ну и как обычно, скрипт приема пришлось дорабатывать. Я выложил уже доработанную версию, в оригинале не очищало 2 таблицы, и импорт падал с ошибкой параметр существует. При этом остальные правила оказывались удаленными, что привело бы к проблемам при переходе на резерв.
Обсудить статью на форуме
No responses yet