RouterOS в Mikrotik не запоминает динамические элементы списков адресов и в случае перезагрузки или пропажи питания, в списках останутся только статичные элементы. Например у вас есть правило, отлавливающее спамеров или сканеров портов и банящее их IP адреса на месяц. Обычно такие адреса сохраняются в виде динамических записей в списках, но они не сохраняются при перезагрузке, а значит легко потерять базу «редисок», собранную скажем за пару месяцев непрерывной работы шлюза.
Для работы этой схемы нужен FTP сервер (у меня он виндовый, но батник легко переделывается под никсы) с учетной записью, имеющей права на чтение–запись. Механизм строится на взаимодействии следующих элементов: на шлюзе зашедуленные скрипты BackupDynList_to_FTP и BackupDynListFromFTP, на FTP сервере зашедуленный скрипт convertmtik.bat. Сторонний сервер нужен для того, чтобы разгрузить внутреннюю память микротика (списки могут быть довольно большими, а энергонезависимая память не у всех большая) и для того, чтобы обработать файл более мощными средствами работы с текстом, чем имеет встроенный скриптовый язык mikrotik. Вызов функции DynListExport используется для того, чтобы обойти ограничение системы на размер списка. Необходимость конвертирования списка связана с тем, что если в базе уже присутствует такой же элемент (скажем, статическая запись), то при импорте возникает ошибка и происходит остановка выполнения импорта. Чтобы этого не происходило, при каждом добавлении статической записи, сбрасывается обработчик ошибок и в случае совпадения запись просто не добавляется, а процесс импорта идет дальше.
Скрипт BackupDynList_to_FTP выполняется каждый час (00:00), он собирает в файл iplist_dyn.src все данные о динамических записях (которым осталось жить не менее получаса) во всех списках и отправляет этот файл на ftp. На сервере каждый час со сдвигом в полчаса от первого скрипта (00:30) выполняется батник convertmtik.bat, который преобразует исходный скрипт, принятый от шлюза, в скрипт, защищенный от ошибок совпадений и сохраняет его под именем iplist_dyn_done.src
Теперь, в случае падения или перезагрузки шлюза, в момент запуска данные о динамических записях автоматически пропадают, но через 60 секунд после запуска скрипт BackupDynListFromFTP скачивает с FTP файл iplist_dyn_done.src и запускает его на выполнение, восстанавливая списки.
Активатор Hourly_Dynlist_Backup_on_FTP (/sys sheduler), выполняется в начале каждого часа:
Скрипт BackupDynList_to_FTP (не забудьте поменять адрес FTP, логин и пароль):
Активатор BackupDynList_from_FTP (/sys sheduler), выполняется в момент запуска шлюза (startup):
Скрипт BackupDynListFromFTP (не забудьте поменять адрес FTP, логин и пароль):
Серверный скрипт convertmtik.bat — для своей работы использует порт линуксовой утилиты SED, например из gnuwin32, которая должна быть прописана в path на сервере:
Для работы этой схемы нужен FTP сервер (у меня он виндовый, но батник легко переделывается под никсы) с учетной записью, имеющей права на чтение–запись. Механизм строится на взаимодействии следующих элементов: на шлюзе зашедуленные скрипты BackupDynList_to_FTP и BackupDynListFromFTP, на FTP сервере зашедуленный скрипт convertmtik.bat. Сторонний сервер нужен для того, чтобы разгрузить внутреннюю память микротика (списки могут быть довольно большими, а энергонезависимая память не у всех большая) и для того, чтобы обработать файл более мощными средствами работы с текстом, чем имеет встроенный скриптовый язык mikrotik. Вызов функции DynListExport используется для того, чтобы обойти ограничение системы на размер списка. Необходимость конвертирования списка связана с тем, что если в базе уже присутствует такой же элемент (скажем, статическая запись), то при импорте возникает ошибка и происходит остановка выполнения импорта. Чтобы этого не происходило, при каждом добавлении статической записи, сбрасывается обработчик ошибок и в случае совпадения запись просто не добавляется, а процесс импорта идет дальше.
Скрипт BackupDynList_to_FTP выполняется каждый час (00:00), он собирает в файл iplist_dyn.src все данные о динамических записях (которым осталось жить не менее получаса) во всех списках и отправляет этот файл на ftp. На сервере каждый час со сдвигом в полчаса от первого скрипта (00:30) выполняется батник convertmtik.bat, который преобразует исходный скрипт, принятый от шлюза, в скрипт, защищенный от ошибок совпадений и сохраняет его под именем iplist_dyn_done.src
Теперь, в случае падения или перезагрузки шлюза, в момент запуска данные о динамических записях автоматически пропадают, но через 60 секунд после запуска скрипт BackupDynListFromFTP скачивает с FTP файл iplist_dyn_done.src и запускает его на выполнение, восстанавливая списки.
Активатор Hourly_Dynlist_Backup_on_FTP (/sys sheduler), выполняется в начале каждого часа:
/system script run BackupDynList_to_FTP
Скрипт BackupDynList_to_FTP (не забудьте поменять адрес FTP, логин и пароль):
/system script environment remove [ find where name="DynListExport" ];
:global DynListExport do={
:foreach i in=[/ip firewall address–list find where dynamic=yes and timeout>0d00h30m] do={
:local list [/ip firewall address–list get $i list];
:local address [/ip firewall address–list get $i address];
:local timeout [/ip firewall address–list get $i timeout];
:local comment [/ip firewall address–list get $i comment];
:put "/ip firewall address–list add list=$list address=$address timeout=$timeout comment=\"$comment\";"};
}
:log info "Starting Backup to FTP Script..."
:global iplistfile ("iplist_dyn.rsc")
:if ([/file find name=$iplistfile]!= "") do={/file rem $iplistfile};
/execute script="\$DynListExport" file=$iplistfile
:delay 60s
/tool fetch address="Адрес_FTP_сервера" port=21 mode=ftp src–path="iplist_dyn.rsc.txt" user=Пользователь password=Пароль dst–path="iplist_dyn.src" upload=yes
:delay 20s
/file rem $iplistfile
:log info "Finished Backup to FTP!"
Активатор BackupDynList_from_FTP (/sys sheduler), выполняется в момент запуска шлюза (startup):
{:delay 60s};
/system script run BackupDynListFromFTP
Скрипт BackupDynListFromFTP (не забудьте поменять адрес FTP, логин и пароль):
:local BackupFile "iplist_dyn_done.src"
/file remove [find name=$BackupFile]
/tool fetch address="Адрес_FTP_сервера" port=21 mode=ftp src–path="$BackupFile" user=Пользователь password=Пароль
/import file–name=$BackupFile
{:delay 30s};
/file remove [find name=$BackupFile]
/log info "$BackupFile imported"
Серверный скрипт convertmtik.bat — для своей работы использует порт линуксовой утилиты SED, например из gnuwin32, которая должна быть прописана в path на сервере:
echo # ––––––––––––––––––––––––––––––––––––––––––––––––––––– — > iplist_dyn_done.src
echo # %date% %time% >> iplist_dyn_done.src
echo # ––––––––––––––––––––––––––––––––––––––––––––––––––––– — >> iplist_dyn_done.src
echo /ip firewall address–list > iplist_dyn_done.src
sed –e "s/;//" –e "s/\/ip firewall address–list //" –e "s/.*/:do { & } on–error={}/" iplist_dyn.src >> iplist_dyn_done.src
Lopar
А почему вы не храните это в файловой системе самого устройства? Команда экспорта может создать файл в файловой системе, а запуск этого файла развернёт всё назад. Минус одно стороннее устройство.
CheshirCa Автор
Хорошо, когда свободной энергонезависимой памяти в устройстве много, а списки занимают мало места. Однако чаще всего размер списков в районе 2-3 мегабайт, а свободного места в устройстве предательски мало. Второе — я так и не нашел способа отпарсить списки такого размера средствами скриптового языка RouterOS (тут еще примешивается проблема, что система не может нормально работать со списками большого размера, из-за этого приходится использовать DynListExport), а если список не подготовлен соответствующим образом, то при обнаружении дублирующихся записей импорт прервется. Ну и третье — желательно иметь бэкап всех настроек на стороннем устройстве, чтобы в случае аппаратной проблемы можно было легко поднять шлюз на аналогичном (или похожем) железе.