MikroTik

MikroTik divan1 ср, 03 Май 2017 - 00:16

В этой подборке будут собраны заметки(исключительно из личного опыта) обо всем, что связано с маршрутизаторами MikroTik.

На понимание работы этого устройства потрачено столько времени, что было бы неправильно не облегчить другим этот путь,  и не поделиться своим опытом.

Здесь нет перепечаток по достаточно освещенным темам с других сайтов. Так же эта подборка не претендует на полноту описания работы с оборудованием Mikrotik.

Возможно пригодится кому-то кроме меня.

Программирование в RouterOS

Программирование в RouterOS divan1 пт, 25 янв 2019 - 19:05

Писать скрипты приходится не часто. И порой бывает подзабываешь че-каво, особенно после СИ-образных языков. Так что буду складывать в этом разделе особенности программирования под наш любимый роутер.

Mikrotik, вторые шаги

Mikrotik, вторые шаги admin вс, 09 апр 2017 - 23:51

Предисловие. Это можно не читать ))

Есть много хороших и не очень руководств по языку скриптов Mikrotik, но подробного описания как работать с функционалом(объектами) я не нашел. Пришлось собирать информацию по крупицам, разбираться по примерам. Как известно, что бы закрепить и систематизировать полученные знания, полезно их рассказать другим. Поэтому, рискну изложить то, что понял сам из разрозненных источников.

На первый взгляд может показаться, что очень много написанного не имеет отношения к написанию скриптов. Но это только на первый взгляд ;)

Подготовка

Хоть я и старался максимально подробно изложить материал, но перед началом работы имеет смысл ознакомиться с основами работы в терминале Mikrotik. Это и будут первые шаги. Вот достойный материал на эту тему: http://mikrotik.vetriks.ru/wiki/%D0%94%D0%BB%D1%8F_%D0%BD%D0%B0%D1%87%D…

Поехали

Для примера будем работать с DHCP сервером.

Окно выбора настроек DHCP сервера

Открываем терминал, пункт меню «New Terminal» и вводим команду: /ip dhcp-server  и жмем кнопку табуляции(далее <TAB>). Получим такой вывод:

/ip dhcp-server

Здесь мы видим доступные для продолжения ввода команды значения. То что подсвечено «синим» цветом, это подразделы. В WinBox их можно увидеть в виде вкладок. Нас же, более всего интересуют «фиолетовые» команды. Пробуем набирать print и <ENTER>. На выводе получим список всех(в примере один) настроенных DHCP серверов:

/ip dhcp-server print

Кстати, после print то же можно нажать <TAB>. Поиграйтесь с разными параметрами.

Усложняем задачу. Идем на вкладку Leases. В этом примере она выглядит так:

Окно настроек резервирования DHCP сервера

Отключим(не удалим(remove), а именно отключим(disable)) резервирование IP адреса для хоста, у которого текущий адрес 192.168.254.21. На скриншоте мы видим результат - команды, их вывод и отключенная запись резервирования. Разберем подробно.

Окно настроек резервирования DHCP сервера + терминал

Вводим: /ip dhcp-server lease <TAB> и наблюдаем список команд. По смыслу понимаем что нам подходит команда disable, но мы сделаем вид что ее нет, и в академических целях пойдем более сложным путем. Так же видна некая команда set, вероятно она устанавливает какие-то параметры. Посмотрим что она может.

Продолжаем вводить: set <TAB>. Теперь мы видим список «зеленых» параметров, которые мы можем использовать в команде set. Обратите внимание, что параметр numbers выделен жирным цветом — он обязательный. Следуя логике можно предположить, что это некий идентификатор(номер), однозначно указывающий на изменяемый командой set объект.

Так где же нам узнать этот номер? Например через команду print, вводим:
/ip dhcp-server lease print

Следует отметить, что номера выводимые командой print не постоянны, и могут измениться при следующей команде print.

Пробуем ввести: /ip dhcp-server lease set disabled=<TAB> и видим какие значения может принимать параметр, дописываем yes и <ENTER>. Упс, что за вопрос numbers? Да-да, тот самый номер, из первой колонки таблицы, команды print. В нашем случае вводим: 7<ENTER>.

Но все это можно сделать одной командой:
/ip dhcp-server lease set 7 disabled=yes

Забегая вперед, замечу, что при попытке получить значение disabled, командой:
:put [/ip dhcp-server lease get 7 disabled]
вы получите булево значение true или false. Это важно при использовании в скриптах, такая особенность вас может поджидать в самом неожиданном месте. О_о, а откуда взялся get, его ведь не было в списке доступных команд? Об этом то-же позже...

Чет какая-то фигня заметит пытливый читатель )) Верно, фигня. Теперь выполним задачу одной командой. Если помните, среди доступных команд есть find ее-то мы и будем использовать.

Обратите внимание на эти команды:

/ip dhcp-server lease

В первой строке: От корня иерархии объектов микротика мы двигаемся в раздел lease DHCP-сервера, где командой set изменяем значение параметра disabled у 7-го объекта.

Во второй и третьей строке проделывается то-же самое, только немного иначе. Сначала мы переходим в контекст - /ip dhcp-server lease, а затем в этом контексте выполняем команду с параметрами: set 7 disabled=yes

Теперь в нашей команде /ip dhcp-server lease set 7 disabled=yes сотрем цифру 7 и напишем [ find ]. После слова find нажмем <TAB> и увидим список параметров по которым мы можем выполнить поиск в списке объектов выделенных адресов.

Дописываем наш find, должно получиться так:
/ip dhcp-server lease set [find address=192.168.254.21] disabled=yes

Окно настроек резервирования DHCP сервера + терминал

Если кто заметил, в тексте IP-адрес экранирован кавычками, а на скриншоте нет. Можно использовать кавычки, можно не использовать — работает всяко.

Что такое find и как оно так произошло?

Команду find следует разобрать отдельно. Это одна из самых часто используемых команд в скриптах RouterOS. Она возвращает внутренний(это не тот номер, что возвращает print, но указывает на тот же объект) номер/номера объектов удовлетворяющих условию.

Окно настроек резервирования DHCP сервера + терминал

Если ввести команду(как в первой строке):
/ip dhcp-server lease find address=192.168.254.21
в надежде увидеть номер, то ничего не произойдет. Это как вызвать функцию, а возвращаемый ей результат не обработать.

Поэтому, используем :put для вывода возвращаемого значения(вторая строка). На выходе получаем шестнадцатеричное число DBB. Его можно использовать в качестве значения numbers(раньше мы брали номер из команды print).

Если вы внимательно посмотрите, то заметите что во второй строке :put [ip dhcp-server lease find address=192.168.254.21] перед ip нет символа /

Эта команда выполнится, так как мы и так находимся в корне иерархии объектов. Но если нам перейти в другой контекст, то тут-же получим ошибку.

/ip dhcp-server

 

Не много отвлеклись, но вернемся к нашей команде
/ip dhcp-server lease set [find address=192.168.254.21] disabled=yes

Что здесь происходит:

  1. Устанавливается контекст /ip dhcp-server lease

  2. Внутри контекста(пункт 1) выполняется find address=192.168.254.21 и возвращается значение *dbb, как если бы выполнили команду /ip dhcp-server lease find address=192.168.254.21

  3. Внутри контекста(пункт 1) выполняется set(со значением numbers равным *dbb), который присваевает параметру disabled значение yes

В развернутом виде это аналогично:

/ip dhcp-server lease set [/ip dhcp-server lease find address=192.168.254.21] disabled=yes

Таким образом мы видим, что квадратные скобки позволяют выполнять команды во время выполнения других команд и передавать результат «на верх».

Скрипт

На основе вышесказанного напишем скрипт получающий IP адреса клиентов DHCP сервера, отвечающих следующим условиям:

  1. Зарезервированы, т.е. IP-адрес закреплен за MAC

  2. В настоящее время в сети и имеют активную аренду адреса.

Полученные адреса поместить в список доступа(aclGrantIPs). Если клиент отключился, то удалить его IP из этого списка.

Скопируем скрипт и вставим его в терминал:

/ip dhcp-server lease
:foreach i in=[find] do={
    :local addrTMP [get $i address]
    :if ([get $i status]="bound" && ![get $i dynamic]) do={
        :do {/ip firewall address-list add address=$addrTMP list=aclGrantIPs} on-error={}
    } else={
        :do {/ip firewall address-list remove [find address=$addrTMP list=aclGrantIPs]} on-error={}
    }
}

Окно настроек резервирования DHCP сервера + терминал

Разберем построчно, что здесь происходит.

Устанавливаем контекст /ip dhcp-server lease

В цикле перебираем все выделенные адреса.

Если в терминале выполнить :put [/ip dhcp-server lease find] то будет выведен массив внутренних идентификаторов объектов/записей аренды адресов.

:put [/ip dhcp-server lease find]

Это и проделывается в строке

:foreach i in=[find] do={

что эквивалентно

:foreach i in=[/ip dhcp-server lease find] do={

или в рассматриваемом случае(со значениями)

:foreach i in=[*d;*26;*86;*141;*143;*1db;*1f3;*dbb;*dc1] do={

Создаем и инициализуем локальную переменную addrTMP значением содержащим IP адрес клиента. Обратите внимание, при создании переменной знак $ в начале не ставится, а при использовании ставится.

:local addrTMP [get $i address]

что эквивалентно

:local addrTMP [/ip dhcp-server lease get $i address]

где $i по порядку подставляется из массива [*d;*26;*86;*141;*143;*1db;*1f3;*dbb;*dc1] циклом :foreach

Аналогично предыдущему шагу, проверим значение параметров status и dynamic.

:if ([get $i status]="bound" && ![get $i dynamic]) do={

Наблюдая за поведением DHCP сервера, на вкладке Leases, можно предположить, что:

  • параметр status со значением bound говорит нам о том, что клиент недавно запросил/подтвердил свой адрес.
  • параметр dynamic определяет, что адрес динамический и возвращает булево значение true или false соответственно.

Если выполняются условия, что это DHCP клиент, со статической привязкой адресов и активен в настоящее время, то добавляем его в список доступа командой:
/ip firewall address-list add address=$addrTMP list=aclGrantIPs

Причем заметьте, что команда обернута в обработчик ошибок:
:do {} on-error={}

Это сделано, что-бы скрипт не останавливался «в тихую» с ошибкой, в случае если адрес уже есть в списке.

Если условие не выполняется, то удаляем запись с этим IP из списка. Например, наш клиент отключился, или у него администратор снял статическое резервирование адреса.

/ip firewall address-list remove [find address=$addrTMP list=aclGrantIPs]

Для удаления записи используется команда remove. Которая как get, set и еще некоторые другие команды, использует в качестве параметра numbers внутренний номер объекта. В этом случае, объект - это запись в IP - Firewall - Address List.

Команда find может искать по нескольким параметрам в одном запросе.

PS Теперь, когда многие вещи прояснились, можно ознакомиться с официальным описанием скриптового языка RouterOS или его переводом.

PSS Помнится я писал - "О_о, а откуда взялся get? Об этом позже...". Я сам не знаю почему так :) Возможно когда-нибудь узнаю и здесь напишу.

Работа с массивами в скриптах Mikrotik

Работа с массивами в скриптах Mikrotik divan1 пт, 25 янв 2019 - 03:01

Пока память свежа, напишу как работать с массивами в RouterOS. Все команды выполняются в терминале обычным копипастом.

Основы

В самом простом случае массив объявляется так:

:global array1 [:toarray "1,2,3"]
:global arrayNum {1;2;3}
:global arrayStr {"n1";"n2";"n3"}

Строковые значения без пробелов почти везде можно не закрывать кавычками. Но для повышения "читабельности" кода и этого маленького "почти", лучше все-таки использовать кавычки.

Количество элементов в массиве вычисляет функция :len:

# эта команда ничего не выведет в терминал
:len $arrayStr
# а вот эта выведет число 3, указывающее на количество элементов в массиве
:put [:len $arrayStr]

Далее будет использоваться команда :put для вывода значения в терминал. Но в скриптах эта команда обычно не используется, разве только для отладки.

Нумерация элементов массива начинается с нуля. Получить элемент из массива по его индексу можно командой :pick:

:put [:pick $arrayStr 1]
# или
:put ($arrayStr->1)
# в обоих случаях результатом будет: n2

Причем единицу можно заменить переменной, например $i. На всякий случай поясню, здесь и далее, текст "[admin@xxx] >" показывает приглашение терминала и его вводить не требуется. Следующие строки показывают результат выполнения команды.

[admin@xxx] > :for i from=0 to=([:len $arrayStr]-1) do={:put ($arrayStr->$i)}
n1
n2
n3

Ну и конечно есть оператор foreach: который перебирает все элементы массива.

[admin@xxx] > :foreach i in=$arrayStr do={:put $i}
n1
n2
n3

Установить значение элемента в массиве, даже если элемента с таким индексом не существует, можно следующим образом:

[admin@xxx] > :set ($arrayStr->4) "n5"

Теперь посмотрим что получилось в массиве. Выведем значения и тип хранимого значения:

[admin@xxx] > :foreach i in=$arrayStr do={:put "$i - type of item:$([:typeof $i])"}
n1 - type of item:str
n2 - type of item:str
n3 - type of item:str
 - type of item:nothing
n5 - type of item:str

Продвинутые методы

В моем скрипте быстрой настройки IPSEC есть такой код(лишь с той разницей, что там используется локальная переменная) объявляющий структуру предприятия:

  :global structNET {
    "Company Z: OfficeHQ"={ip=23.5.230.7 ; lan=192.168.11.0/24 ; rootnode=true} ;
    "Company Z: Office2"={ip=189.2.134.7 ; lan=192.168.12.0/24} ;
    "Company Z: Office3"={ip=95.36.71.7 ; lan=192.168.13.0/24} ;
    "Company Z: Office4"={ip=154.4.96.7 ; lan=192.168.14.0/24 ; initiator=true ; rootnode=true} ;
  }

Обращаться к элементам такого массива можно следующим образом:

[admin@xxx] > :put ($structNET->"Company Z: Office4")
initiator=true;ip=154.4.96.7;lan=192.168.14.0/24;rootnode=true

[admin@xxx] > :put ($structNET->"Company Z: Office4"->"ip")
154.4.96.7

Естественно, что вместо литералов могут использоваться переменные, как было показано в примере выше, где 1 заменялась на $i. А вот конструкция с :pick , может преподнести сюрприз:

[admin@xxx] > :put [:pick $structNET 0]
ip=189.2.134.7;lan=192.168.12.0/24

Подозреваю, это связано с сортировкой именованных элементов массива. И вывод foreach следующего примера это доказывает.

Перебор всех элементов при помощи :foreach:

[admin@xxx] > :foreach office,data in=$structNET do={ :put $office; :put $data;}
Company Z: Office2
ip=189.2.134.7;lan=192.168.12.0/24
Company Z: Office3
ip=95.36.71.7;lan=192.168.13.0/24
Company Z: Office4
initiator=true;ip=154.4.96.7;lan=192.168.14.0/24;rootnode=true
Company Z: OfficeHQ
ip=23.5.230.7;lan=192.168.11.0/24;rootnode=true

Скрипты для микротик

Скрипты для микротик divan1 пт, 25 янв 2019 - 01:29

Здесь я буду выкладывать только те скрипты, что написал сам. Как архив для быстрого поиска. Возможно кому-то пригодится.

Скрипт быстрой и наглядной настройки IPSEC

Скрипт быстрой и наглядной настройки IPSEC divan1 чт, 04 Май 2017 - 08:48

Настройка

Поменяйте значения локальных переменных, в начале скрипта, под свои нужды и всех делов. В целом, по имени переменных понятно их назначение. Приведу толкование назначения лишь некоторых переменных:

  • phase1pskIPSec - общий ключ.
  • modeUninstall - значение true, укажет скрипту удалить с маршрутизатора настройки попадающие под описание структуры сети в structNET.

Детально стоит рассмотреть structNET - это массив с описанием ваших подсетей. Каждая запись массива описывает одну  подсеть, и имеет вид:
"ID маршрутизатора"={ip=<внешний ip> ; lan=<адрес локальной сети/битмаска> }.

Так-же доступны необязательные параметры:

  • initiator=true  - определяет, что при работе с этим рутером, его пиры не могут иницировать с ним соединение. Указывать больше одного инициатора стоит только в том случае, если вы точно понимаете что делаете ;)
  • rootnode=true - условно необязательный параметр(хотя бы одна запись в массиве должна его иметь). Определяет штаб-квартиру/главный офис и т.д. и т.п. Если всем записям указать этот параметр, то будет настроена сеть типа "каждый с каждым".

ID маршрутизатора можно узнать командой: :put [/system identity get name]

Схема сети

На рисунке показана схема сети, которая описана в скрипте, в качестве примера. Стрелками указано направление установки IPSEC-туннелей.

Если у вас еще не настроены на firewall правила для хождения IPSec, то вот они:

### Общие правила для IPSEC & PPP  #####
/ip firewall filter 
add chain=input protocol=udp dst-port=1701,4500,500 action=accept place-before=1 comment="L2TP, IPSEC-NAT, IKE"
add chain=input protocol=ipsec-esp action=accept place-before=1 comment="Allow IPSec-ESP"
add chain=input protocol=ipsec-ah action=accept place-before=1 comment="Allow IPSec-AH"

Кто-то скажет - А не много-ли там лишнего, в правилах? Удалите лишнее, кому не нравится ;) Правила можно добавить в начало скрипта, или выполнить вручную на каждом маршрутизаторе.

Если никаких особых требований к шифрованию нет, остается только заполнить structNET, придумать phase1pskIPSec и можно начинать.

Просто копируете скрипт, включая {}, и вставляете его в терминал микротика.


{
# author: Ivan Dementev aka DiVAN1, 2017/04
# e-mail: ivan_div@mail.ru
# version: 1.2
# date: 2018/12/17

  :local modeUninstall false

  :local vpnName "zcomp"
  :local peerProfileName "profile-$vpnName"
  :local phase1AuthAlgorithms "sha1"
  :local phase1EncAlgorithms "aes-128,3des"
  :local phase1DHGroup "modp1024"
  :local phase1pskIPSec "SuperPassw0rd"
  :local phase1Lifetime "1d"

  :local phase2ProposalName "proposal-$vpnName"
  :local phase2Lifetime "30m"
  :local phase2AuthAlgorithms "sha1"
  :local phase2EncAlgorithms "aes-128-cbc,3des"
  :local phase2IPSecProtocols "esp"

  :local systemName [/system identity get name]
  :local structNET {
    "Company Z: OfficeHQ"={ip=23.5.230.7 ; lan=192.168.11.0/24 ; rootnode=true} ;
    "Company Z: Office2"={ip=189.2.134.7 ; lan=192.168.12.0/24} ;
    "Company Z: Office3"={ip=95.36.71.7 ; lan=192.168.13.0/24} ;
    "Company Z: Office4"={ip=154.4.96.7 ; lan=192.168.14.0/24 ; initiator=true ; rootnode=true} ;
  }

  /ip firewall nat print  count-only  
  :local extIP ($structNET->$systemName->"ip")
  :if ( $extIP = nil ) do={:put "Not found IPSEC settings for this router! Check /system identity name."} else={
    :local localNet ($structNET->$systemName->"lan")
    :local localRootNode [:tobool ($structNET->$systemName->"rootnode")]
    :put "-=< $systemName >=- Local root node:$localRootNode"
    /ip firewall nat add chain=srcnat disabled=yes place-before=0 log-prefix=#D1
    :local idFirstNATRule [:pick [/ip firewall nat find log-prefix=#D1] 0]

    /ip ipsec proposal 
      remove [find name=$phase2ProposalName]
      :if ( !$modeUninstall ) do={
        add auth-algorithms=$phase2AuthAlgorithms enc-algorithms=$phase2EncAlgorithms lifetime=$phase2Lifetime\
            name=$phase2ProposalName
      }
      
    /ip ipsec peer profile
      remove [find name=$peerProfileName]
      :if ( !$modeUninstall ) do={
        add dh-group=$phase1DHGroup enc-algorithm=$phase1EncAlgorithms hash-algorithm=$phase1AuthAlgorithms lifetime=$phase1Lifetime\
            name=$peerProfileName
      }
      
    :foreach office,data in=$structNET do={
      :if ( $systemName != $office && $idFirstNATRule != nil) do={
        :put "#####> $office"
        :local saDstAddress ($data->"ip")
        :local dstAddress ($data->"lan")
        :local dstAddress ($data->"lan")
        :local peerRootNode [:tobool ($data->"rootnode")]
        :local addData ($peerRootNode||$localRootNode)
        :put "peer root node:$peerRootNode"
        :local peerPassiveMode "no"
        :if ( [:tobool ($data->"initiator")] ) do={:set peerPassiveMode "yes"}
        
        /ip firewall nat
          remove [find action=accept chain=srcnat dst-address=$dstAddress src-address=$localNet]
          :if ( !$modeUninstall&&$addData ) do={
            :put "add firewall NAT rules..."
            add action=accept chain=srcnat dst-address=$dstAddress src-address=$localNet place-before=$idFirstNATRule\
                comment="over IPSEC: $systemName <->>> $office"
          }

        /ip ipsec peer
          remove [find address="$saDstAddress/32"]
          :if ( !$modeUninstall&&$addData ) do={
            :put "add firewall IPSEC peer..."
            add address="$saDstAddress/32" secret=$phase1pskIPSec profile=$peerProfileName passive=$peerPassiveMode comment=$office
          }
          
        /ip ipsec policy
          remove [find dst-address=$dstAddress sa-dst-address=$saDstAddress sa-src-address=$extIP src-address=$localNet]
          :if ( !$modeUninstall&&$addData ) do={
            :put "add IPSEC policies..."
            add dst-address=$dstAddress sa-dst-address=$saDstAddress sa-src-address=$extIP src-address=$localNet proposal=$phase2ProposalName\
            ipsec-protocols=$phase2IPSecProtocols tunnel=yes action=encrypt comment=$office
          }
        
#        If you have fasttrack enabled, packet bypasses ipsec policies. 
#        https://wiki.mikrotik.com/wiki/Manual:IP/IPsec#NAT_and_Fasttrack_Bypass
#
        /ip firewall raw
          remove [find action=notrack chain=prerouting src-address=$localNet dst-address=$dstAddress]
          remove [find action=notrack chain=prerouting src-address=$dstAddress dst-address=$localNet]
          :if ( !$modeUninstall&&$addData ) do={
            :put "add firewall raw prerouting rules..."
            add action=notrack chain=prerouting src-address=$localNet dst-address=$dstAddress comment=" $systemName <->>> $office"
            add action=notrack chain=prerouting src-address=$dstAddress dst-address=$localNet
          }
      }  
    }
    /ip firewall nat remove [find log-prefix=#D1]
  }
  :put "Done!"
}

Проблемы?

Скрипт проверен на RouterOS 6.39 на 750-х и 951-х моделях. Если вдруг у вас не работают ваши туннели, тому может быть множество причин. Например:

  • провайдер блокирует IP протоколы AH и ESP
  • в некоторых конфигурациях, в самом конце есть правило:
    action=drop chain=forward comment="default configuration" connection-nat-state=!dstnat connection-state=new in-interface=<ваш внешний интерфейс>
    включите у правила логирование и посмотрите, не оно ли блокирует ваши пакеты

В процессе выполнения скрипта вы можете получить ошибку: item referred by 'place-before' does not exist (11). Особенно если запускаете его несколько раз подряд.
Выполните в терминале: /ip firewall nat print это перестроит индекс элементов таблицы NAT.
Оффтоп: если вы попали на эту страницу через поиск по сообщению ошибки, то вам надо перестраивать индекс той таблицы, на запись которой ссылается ваш запрос.

Хотите понять как оно работает?

Читайте заметку Mikrotik, вторые шаги

Обновлено

2018/12/17: Учтены изменения в новых версиях RouteOS, где многие нстройки из "peer" перенесены в "peer profile"

Скрипт быстрой настройки CAPsMAN

Скрипт быстрой настройки CAPsMAN divan1 вт, 26 июн 2018 - 00:42

Правим в первых трех строках настройки под себя и вперед:


{
:local SSID myWiFi
:local PSK passphrase
:local BRIDGE bridgeLocal

/caps-man channel
    add band=2ghz-g/n name=channel-24G-auto
    add band=2ghz-g/n frequency=2412 name=channel-24G-01
    add band=2ghz-g/n frequency=2417 name=channel-24G-02
    add band=2ghz-g/n frequency=2422 name=channel-24G-03
    add band=2ghz-g/n frequency=2427 name=channel-24G-04
    add band=2ghz-g/n frequency=2432 name=channel-24G-05
    add band=2ghz-g/n frequency=2437 name=channel-24G-06
    add band=2ghz-g/n frequency=2442 name=channel-24G-07
    add band=2ghz-g/n frequency=2447 name=channel-24G-08
    add band=2ghz-g/n frequency=2452 name=channel-24G-09
    add band=2ghz-g/n frequency=2457 name=channel-24G-10
    add band=2ghz-g/n frequency=2462 name=channel-24G-11
    add band=5ghz-n/ac name=channel-50G-auto
    add band=5ghz-n/ac frequency=5180 name=channel-50G-36
    add band=5ghz-n/ac frequency=5200 name=channel-50G-40
    add band=5ghz-n/ac frequency=5220 name=channel-50G-44
    add band=5ghz-n/ac frequency=5240 name=channel-50G-48

/caps-man datapath
    add bridge=$BRIDGE client-to-client-forwarding=yes local-forwarding=yes name=datapath1

/caps-man security 
    add authentication-types=wpa-psk,wpa2-psk encryption=aes-ccm group-encryption=aes-ccm name=("security-".$SSID) passphrase=$PSK

/caps-man configuration
    add channel=channel-24G-auto country=russia datapath=datapath1 distance=indoors hw-protection-mode=rts-cts hw-retries=7 mode=ap name=cfg-24-lan \
        security=("security-".$SSID) ssid=$SSID
    add channel=channel-50G-auto country=russia datapath=datapath1 distance=indoors hw-protection-mode=rts-cts hw-retries=7 mode=ap name=cfg-50-lan \
        security=("security-".$SSID) ssid=$SSID

/caps-man provisioning
    add action=create-dynamic-enabled hw-supported-modes=gn master-configuration=cfg-24-lan name-format=prefix-identity
    add action=create-dynamic-enabled hw-supported-modes=ac,an master-configuration=cfg-50-lan name-format=prefix-identity

/caps-man manager
    set enabled=yes upgrade-policy=require-same-version
}    
 

Скрипт создания гостевой Wi-Fi сети

Скрипт создания гостевой Wi-Fi сети divan1 вт, 02 Май 2017 - 23:50

Кому нужно подробно разжевать что здесь сделано, ищите статьи в интернете, коих целый мильен. А мы без всяких подробностей, приступим к делу.

Правим значения переменных под себя. Копируем и вставляем в терминал микротика. Значения шейпера можно поправить в конце скрипта, или по выполнению скрипта через WinBox.

{
# имя основного wlan интерфейса
:local masterWLAN "wlan1"
# имя/SSID гостевой сети
:local guestSSID "free-wifi"
# локальная/частная сеть
:local privateSubNet 192.168.11.0/24
# адрес гостевой сети
:local guestSubNet   192.168.0.0
# адрес маршрутизатора в гостевой сети
:local guestSubNetIP 192.168.0.1
# битовая маска гостевой сети
:local guestSubNetBitMask "/24"
# пул адресов для гостевых хостов
:local guestDHCPPool 192.168.0.10-192.168.0.99

/interface bridge add arp=reply-only name=bridge-wifi-guests
/interface wireless security-profiles add authentication-types=wpa-psk,wpa2-psk eap-methods="" management-protection=allowed name=open supplicant-identity=""
/interface wireless add disabled=no master-interface=$masterWLAN name=wlan2-guest security-profile=open ssid=$guestSSID wps-mode=disabled
/interface bridge port add bridge=bridge-wifi-guests interface=wlan2-guest

/ip address add address="$guestSubNetIP$guestSubNetBitMask" interface=wlan2-guest network=$guestSubNet

/ip pool add name=dhcp-guest-pool ranges=$guestDHCPPool
/ip dhcp-server add name=server-4guest add-arp=yes address-pool=dhcp-guest-pool disabled=no interface=bridge-wifi-guests
/ip dhcp-server network add address="$guestSubNet$guestSubNetBitMask" comment="guest wifi network" dns-server=8.8.8.8 gateway=$guestSubNetIP

/ip route rule
add action=unreachable dst-address="$guestSubNet$guestSubNetBitMask" src-address=$privateSubNet
add action=unreachable dst-address=$privateSubNet src-address="$guestSubNet$guestSubNetBitMask"

# для работы шейпера необходимо отключить правило где action=fasttrack-connection
/ip firewall filter disable [find action=fasttrack-connection]
/queue simple add burst-limit=2M/5M burst-threshold=512k/2M burst-time=7s/7s max-limit=1M/3M name=queue-free-wifi target=bridge-wifi-guests
}

Если у вас несколько локальных подсетей(через IPSec или еще как), то необходимо поправить под себя политики маршрутизации или написать правила для firewall.

 

Смена канала на точке доступа Mikrotik cAP ac нажатием кнопки

Смена канала на точке доступа Mikrotik cAP ac нажатием кнопки divan1 пт, 25 янв 2019 - 00:54

Есть у Микротика точка доступа "cAP ac". Помимо отличных ТТХ и дизайна у нее есть кнопка, на которую можно "вешать скрипты". И эта кнопка также легко доступна пользователю как и прекрасна ))). На фото, небольшой круглый блин с индикатором по центру.

точка доступа "cAP ac"

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

Автоматический выбор канала проблему не решает никак. Все время подключаться и менять канал не по нашему. Вот и был написан скрипт переключения каналов.

Идем в System - Scripts. Создаем новый скрипт нажатием кнопки "+". В поле Name пишем имя скрипта - change_chanel_wifi24. В поле "Source" вставляем код:

{
# change name of wireless interface
:local wirelessInterface "wlan24"
:global channelList [:toarray "2412, 2427, 2442, 2457, 2417, 2432, 2447, 2462, 2422, 2437, 2452"]
:local channelListCount [:len $channelList]
:global currentChannelIndex
:put $channelListCount
:if ([:typeof $currentChannelIndex]!="num") do={
  :set $currentChannelIndex 0
} else={
  :set $currentChannelIndex ($currentChannelIndex+1)
  if ($currentChannelIndex>=$channelListCount) do={
    :set $currentChannelIndex 0
  }
}
:local strDATE [/system clock get date]
:local strTIME [/system clock get time]
:local freq [:pick $channelList $currentChannelIndex]
/interface wireless set [find name=$wirelessInterface]  comment="Channel changed by buttonClick $strDATE $strTIME" frequency=$freq
:log warning "Channel changed by buttonClick $strDATE $strTIME: interface=$wirelessInterface, channel=$freq"
}

Далее, раздел System - Routerboard. Жмем кнопку "Mode button". В открывшемся окне ставим галочку Enabled и в "On Event" пишем название нашего скрипта - change_chanel_wifi24. Жмем все ОКи.

Проверяем как работает.

LTE модем и Mikrotik. Stopped DHCP-клиента на lte1 интерфейсе.

LTE модем и Mikrotik. Stopped DHCP-клиента на lte1 интерфейсе. divan1 вт, 26 июн 2018 - 00:24

Проблема вылезла на E3372h-153 + RouterBOARD 962UiGS-5HacT2HnT. С разной периодичностью(от нескольких дней, до нескольких недель) происходит отвал/восстановление lte1 интерфейса. В какой-то момент, DHCP-клиент на интерфейсе lte1 перестает получать адрес, запись краснеет и переходит в состояние - "stopped...".

В качестве костыля был написан скрипт и помещен в планировщик:

  :local INTERFACE "lte1"
  :local ifID [/interface find name=$INTERFACE]
  :if ($ifID = "") do={
    :put "No interface"
  } else={
    /ip dhcp-client
    :local addDHCPClient true
    :set ifID [find interface=$INTERFACE]
    :if ($ifID = "") do={
        :put "No DHCP-client on interface"
    } else={
        :local ifADDR [get $ifID address ]
        :if ($ifADDR~"192.168.") do={
            :put $ifADDR
            :set addDHCPClient false
        } else={
            :put "addr invalid" 
            :log error "Invalid IP-address on $INTERFACE. DHCP-client remove."
            remove $ifID
        }
    }
    :if ($addDHCPClient) do={
      :local strDATE [/system clock get date]
      :local strTIME [/system clock get time]
      add interface=$INTERFACE dhcp-options=hostname,clientid disabled=no comment="Added by Script on $strDATE $strTIME"
      :log warning "DHCP-client created on $INTERFACE"
      :put "DHCP-client added to interface"
    }
  }

Mikrotik и L2TP интернет от Билайн

Mikrotik и L2TP интернет от Билайн divan1 вс, 08 дек 2019 - 23:34

Довелось столкнуться с проблемой: Микротик не может установить L2TP-соединение в сети Билайн(В.Пышма). При этом другие маршрутизаторы, например ASUS соединяются без проблем. Анализ показал, что DHCP клиент на интерфейсе ether1 получает помимо адреса/маски и DNS-серверов еще и несколько маршрутов к разным внутренним сетям/ресурсам. Но что самое интересное, среди этих маршрутов нет тех которые ведут к DNS серверам. Соответственно L2TP-клиент не может отрезольвить адрес tp.internet.beeline.ru о чем и пишет в логах.

Казалось бы, создай статические маршруты до DNS-серверов и всех делов. Но через пару недель опять нет интернета. Очередной разбор показал что сменился не только адрес на интерфейсе ether1, но и вообще вся подсеть.

Пришлось создать решение не зависящее от таких случаев. Создаем статические маршруты и устанавливаем у них комментарий - beeline_gw_set_by_script
В DHCP клиенте, на вкладке Advanced в раздел Script пишем следующий код:
{
# author: Ivan Dementev aka DiVAN1, 2019
# e-mail: ivan_div@mail.ru
# version: 1.0
# date: 2019/12/9
 :delay delay-time=3000ms
 :local gw [/ip route get [find dst-address =10.0.0.0/8] gateway]
 /ip route set [find comment =beeline_gw_set_by_script] gateway=$gw
}