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

Настройка

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

  • 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"