четверг, 8 декабря 2016 г.

Переносим динамический адрес-лист на другой Mikrotik.

  Обратился человек по имени Serg и попросил помочь с написанием скрипта. Суть скрипта такова, есть некий динамически список (dynamic address list) в Mikrotik - его нужно сохранить. А после перезагрузки маршрутизатора - восстановить с тем же таймаутом (address-list timeout). Проблема эта возникла из-за того, что после перезагрузки маршрутизатора динамические адрес-листы очищаются. Попутно было бы не плохо переносить эти адрес-листы на другие Микротики.
  Начнем с того, что командой экспорта динамические листы экспортировать не получиться, она сохраняет только статические листы:



  Поэтому для экспорта динамического листа можно использовать команду print. Для адрес-листа 3333 команда будет такая:

/ip firewall address-list print file=list where list="3333"
Файл list.txt имеет такой вид:


  После сохранения этого файла мы можем его импортировать на другой маршрутизатор, или на этот же, но после перезагрузки. Скрипт импорта:
if ( [/file get [/file find name=list.txt] size] > 0 ) do={
:global content [/file get [/file find name=list.txt] contents] ;
:global contentLen [ :len $content ] ;
:global lineEnd 0;
:global line "";
:global lastEnd 0;
:global addrip "";
:global list "";
:global timeout "";
:global end 0;
:do {
:set lineEnd [:find $content "\n" $lastEnd ] ;
:set line [:pick $content $lastEnd $lineEnd] ;
:set lastEnd ( $lineEnd + 1 ) ;
:if ( [:pick $line 0 1] != "#" and [:pick $line 0 1] != "F" and [:pick $line 0 2] != " #" and [:len $line ] > 40) do={
:set end [:find $line " " 27] ;
:set addrip [:pick $line 27 $end] ;
:set end [:find $line " " 5] ;
:set list [:pick $line 5 $end] ;
:set end [:find $line " " 59] ;
:set timeout [:pick $line 59 $end] ;
:put "IP: $addrip, list: $list, timeout: $timeout"
/ip firewall address-list add address=$addrip list=$list timeout=$timeout comment="imported"
}
} while ($lineEnd < $contentLen)
}
 Этот скрипт возвращает наш динамический лист на место со всеми количествами записей которые в нем есть. Так же сохраняется таймаут записей на момент создания файла list.txt. 

Импортированные записи с комментарием "imported".

  Есть еще один путь, это скриптом сделать файл импорта:
{
:local lists {"3333"}
:local export "list"
:local file "/ip firewall address-list\n"
:foreach i in=$lists do={
:set $file ($file . "remove [find list=\"" . $i . "\"]\n")
:foreach j in=[/ip firewall address-list print as-value where list=$i] do={
:set $file ($file . "add list=\"" . ($j->"list") . "\" address=\"" . ($j->"address") . "\" timeout=\"" . ($j->"timeout") . "\"\n")
}
}
:if ([/file print count-only where name=$export] = 0) do={
/file print file=$export
:delay 2
}
/file set $export contents=$file
delay 2
/tool fetch address=1.1.1.1 port=21 src-path=list.txt upload=yes user=admin mode=ftp password=admin dst-path=list.rsc
delay 2
/file remove list.txt
}
  Для отработки скрипта нужно создать ftp-аккаунт и дать права на загрузку файлов для этого пользователя. Загружать будем с себя на себя. Это нужно из-за того, что напрямую (кроме как командой export) создать файл .rsc нельзя - тут подробнее. После этого скрипта создается файл list.rsc.


   С таким содержанием:


  Который можно импортировать командой:
/import list.rsc
  Или загрузить по ftp с другого Микротика:
#Filename of export (must match receiving router import filename)
:local importFile "list.rsc"
#IP Address of router with existing address list(s)
:local hostIP 1.1.1.1
#FTP Username and Password
:local ftpUser admin
:local ftpPassword admin
tool fetch address=$hostIP src-path=$importFile dst-path=$importFile mode=ftp user=$ftpUser password=$ftpPassword
/import $importFile
  Стоит обратить внимание, что записи в нашем адрес-листе должны обязательно содержать поле "timeout" и не содержать комментариев. В противном случае - нужно будет подправлять скрипт. Скрипты проверены на версии RouterOS 6.37.3 (stable).
  Так же, нельзя забывать о том, что при таком исполнении мы упираемся в ограничение 4K размера буфера (переменных и другого). Это всегда активно обсуждается на офф. форуме, но ограничение как было - так и есть. Из-за этого адрес-лист большого размера может просто не экспортироваться. Ну и в v6.38rc микротиковцы поломали колонку timeout при команде "ip firewall address-list print file=" - в файле ее просто нет, из-за этого, естественно, скрипт уходит в ошибку (хотя команда "print detail" это поле имеет). Будем надеяться - пофиксят.
  Если вы знаете другой путь, как можно сохранить динамический список, например, в файл, без использования переменных (а соответственно и ограничения в 4096 = 4k) - пишите в комментариях.

UPD 15.12.16
  В теме на офф форуме нашли путь сохранения динамических листов в файлы большого обьема.



Используемые материалы:

Подписаться на новые статьи.

2 комментария:

  1. День добрый!
    Кстати команда Import проглатывает и обычные текстовы файлы (/import *.txt) и можно не заморачиваться с ftp.

    Serg.

    ОтветитьУдалить