?

Log in

No account? Create an account
Previous Entry Поделиться Next Entry
Микротик: создание Address List по списку MAC-адресов
mr_welk
DHCP сервер в микротике не умеет выдавать адреса в зависимости от мак-адреса, хотя в винде DHCP можно это настроить с помощью встроенной политики.
В принципе, мне не очень важно было выдавать разным устройствам адреса из разных пулов, возможно, это понадобится позже.
Но вот добавить в Address List устройства с определенными маками понадобилось. Например, это удобно чтобы выпускать кассовые апапараты в интернет по отдельному правилу.

Сначала сделал скрипт который сравнивает MAC по маске, но маки надо запихнуть в тело скрипта. В принципе, оно нормально работает.

[Скрипт 1]

foreach i in=[/ip dhcp-server lease find] do={
:local macaddress [/ip dhcp-server lease get $i mac-address]
:if ($macaddress~"9C:28:40:*") do={
    :local ipaddr [/ip dhcp-server lease get $i address]
    /ip firewall address-list add address=$ipaddr list=Kassa_ timeout=600
    }
}



Этот скрипт можно запихнуть в DHCP сервер - там есть возможность при выдаче аренды выполнять скрипт.
Но мне захотелось сделать более универсальное решение: брать MAC-адреса из файла.
Соответственно, нужен парсинг файла, всегда было интересно это попробовать.
В результате родилось это.
Сначала скрипт с подробными комментариями и выводом кучи информации ы лог, потом сокращенный вариант.
Отладки скриптов в микротике, по сути, нет совсем, вывод тоже отсутствует, но можно писать в логи, даже разным цветом :)  warning - синим, error - красным.
Для Notepad ++ есть самописный синтаксис для микротиковских скриптов, немного подправил его под себя. Устанавливается через импорт синтаксиса.
Надо только его сохранить с расширением xml

[RouterOS NP++]




Скрипт предназначен для запуска вручную или через шедулер, можно его модифицировать для выполнения внутри DHCP, он при этом значительно уменьшится.
Комментарии на русском красного цвета надо удалить, скриптовый язык вообще не понимает русских букв.

[Сам скрипт с комментариями:]

# Script from Welk for getting mac-addresses from file MAC.txt and adding devices with this MAC in address list
# File name must begin from "MAC" and finish to "txt"
# recordings of mac-adresses in file can recognise regular expressions,
# last string must be empty, codepage must be UTF-8 without BOM
# Variables:                                                Задаём локальные переменные
# file with MAC-Addresses                          Имя файла с мак-адресами, задано не жёстко, можно иметь несколько файлов или поменять
:local filemac [/file find name~"MAC*.*txt"]
#on-error={                                                  пробовал вывод по ошибке, не заработало
# :log info ("File MAC.txt not found")}
# Ending string position                                последняя позиция анализируемой строки
:local EndString 0;
# one string of file (mac-address)                  содержимое одной строки файла
:local line "";
# Starting position of string                            первая (нулевая) позиция анализируемой строки
:local StartString 0;
# Contents of file                                          содержимое файла - оно загружается в эту переменную, поэтому ограничение на файл 4кБ
:local content [/file get $filemac contents]
# Lenght of file                                              длинна файла (количество символов)
:local contlen [:len $content]
# Quantity of added IP-addresses                количество адресов, добавленных в наш адреслист, используется только для информации
:local Quant 0 ;
:log warning "Script for add MAC address to address list started!" ;  запись в лог при запуске (синяя потому что warning)
:log info [/file get $filemac name]
#:log info "Content=" ;\:log info $content ;      выводил для тестов содержимое файла, тут выяснилось что кодировка должна быть UTF-8 без BOM, иначе лезут лишние символы
:log info "Contlen=" ;                                      выводим в лог длинну файла в символах
:log info $contlen ;
/ip firewall address-list remove [find list=Mac_Filtered]          чистим адрес лист
:do {
#                    find 1 2 3   ( 1 - where to search, 2 - what to search, 3 - position to search from)  описание аргументов команды find - что ищем, начальная позиция, конечная позиция
:set EndString [:find $content "\r\n" $StartString ] ;    находим начальную и конечную позицию в строке с маком, анализирую символы конца строки и возврата каретки
#               pick 1 2 3   ( 1 - where picking, 2 - starting position, 3 - ending position) описание аргументов команды "взять" :)  1 - где берем, 2 - начальная позиция, 3 - конечная
:set line [:pick $content $StartString $EndString] ;  записываем в переменную значение одной строки, то есть мак-адрес из текстового файла
:log info "StartString=" ;
:log info $StartString ;  вывод для тестов
:log info "EndString=" ;
:log info $EndString ;    вывод для тестов
:local lenline [:len $line]  подсчитываем количество символов в строке
:if ($lenline > 0) do={  пока количество символов в строке не нулевое, выполняем цикл
:foreach i in=[/ip dhcp-server lease find] do={
:local macaddress [/ip dhcp-server lease get $i mac-address]  берем мак-адрес из dhcp
:if ($macaddress~$line) do={    сравниваем с нашим адресом в текущей строке  (сравнение неточное, поэтому можно использовать знаки подстановки, задавать мак не целиком
:log info "Matched!" ;    вывод для тестов  - нашли совпадение
:set Quant ( $Quant + 1 ) ;  счетчик найденных мак-адресов увеличиваем
:log info $line ;    вывод для тестов
:log info $macaddress ;  вывод для тестов
:local ipaddr [/ip dhcp-server lease get $i address]    берем из dhcp соответствующий текущему маку IP адрес
:log info $ipaddr ; вывод для тестов
/ip firewall address-list add address=$ipaddr list=Mac_Filtered timeout=120 ;  заносим IP в адрес-лист (таймаут для тестов 2 минуты, надо подставить что нужно)
}
}
}
:set StartString ( $EndString + 2 ) ;  счетчик начала следующей строки увеличиваем на 2 символа (как раз это конец строки и возврат каретки)
} while ( $StartString < ($contlen-2) ) ;    смотрим не закончился ли файл
log warning "MAC file to Address list script done" ; вывод информации в лог об успешном завершении скрипта
log warning "Added in Access List IP addresses:"  вывод информации в лог о количестве добавленных адресов
log warning $Quant ;




Вот короткий вариант скрипта без комментариев:

[Открыть]




P.S.  Отладки скриптов в микротике нет, но проверить синтаксис можно командой в терминале:
/system script print from=имяфайла
неправильный синтаксис будет подсвечен

Метки: