Pull to refresh

Mikrotik: настройка IPsec на автоматическое обновление адреса VPN сервера

Reading time 3 min
Views 38K
При настройке IPSec рано или поздно все сталкиваются с тем, что можно задать только IP-адреса удаленного VPN-сервера. Указание DNS-записей в настройках IPsec Policies и IPsec Peers не поддерживается.

Это может вызывать определенные неудобства в случаях, если на VPN-сервере:
  • сменили одного провайдера на другого;
  • решили изменить используемый статический IP-адрес;
  • используется динамический (серый) IP-адрес.


Взяв даже простейшую схему, становится видно, что нам придется менять настройки трех роутеров-клиентов VPN-сервера:



И в каждом из трех роутеров сменить значения:
  • IpSec/Policy/dst-address
  • IpSec/Policy/sa-dst-address
  • IpSec/Peer/address


В реальности, когда клиентов десятки и сотни, автоматизация этого процесса становится необходимостью. Рассмотрим, как это реализовать, используя стандартные возможности Microtik: DDNS, Scripts и Scheduler.

Для интереса немного усложним схему. Пусть центральными VPN-серверами у нас будут два роутера, к которым подключаются наши клиенты.



Включаем на обоих VPN-серверах DDNS, предоставляемый компанией. Mikrotik предоставляет DDNS как бесплатный сервис покупателям RouterOS.

ip cloud set ddns-enabled=yes

Другие поставщики DDNS
Я использую платный сервис DynECT от DynDNS, но схема работы от этого не меняется.

Можем увидеть результат: полученные A-записи в домене sn.mynetname.net, указывающие на наши VPN-серверы.

 > ip cloud print 
    ddns-enabled: yes
  public-address: 1.1.1.1
        dns-name: 111111111111.sn.mynetname.net
          status: updated


Переходим к роутерам, которые выступают клиентами.

В настройках IpSec/Policy и IpSec/Peer в комментарии к каждой строке подпишем DNS-имена VPN-серверов:





Далее добавляем скрипт SetIpSecDstAddrFromDns, который будет получать DNS-имена наших VPN-серверов из комментария и сравнивать их со значениями в настройках:

:if ([:len [/system script job find script=SetIpSecDstAddrFromDns]]>1) do={
  :error
}

:local DnsNameFromComment
:local ResolvedIpFromComment
:local ResolvedIpWithMaskFromComment

:local IpDstAddr
:local IpSaDstAddr


:foreach IpSecPolicyCount in=[/ip ipsec policy find] do={
  :set DnsNameFromComment [/ip ipsec policy get $IpSecPolicyCount comment]
  :if ($DnsNameFromComment!="") do={
    :do {
      :set ResolvedIpFromComment ([:resolve $DnsNameFromComment])
      :set ResolvedIpWithMaskFromComment ($ResolvedIpFromComment . "/32")
      :set IpDstAddr [/ip ipsec policy get $IpSecPolicyCount dst-address]
      :set IpSaDstAddr [/ip ipsec policy get $IpSecPolicyCount sa-dst-address]
      :if ($ResolvedIpWithMaskFromComment!=$IpDstAddr or $ResolvedIpFromComment!=$IpSaDstAddr) do={
        :log warning ("[SetIpSecDstAddrFromDns] Change IpSec policy dst-addr from " . $IpSaDstAddr . " to " . $ResolvedIpFromComment)
        /ip ipsec policy set $IpSecPolicyCount dst-address=$ResolvedIpWithMaskFromComment sa-dst-address=$ResolvedIpFromComment
      }
    } on-error={
      :set ResolvedIpFromComment "unknown"
      :log error ("[SetIpSecDstAddrFromDns] Cant resolve name " . $DnsNameFromComment)
    }
  }
}

:local IpPeerAddr
:foreach IpSecPeerCount in=[/ip ipsec peer find] do={
  :set DnsNameFromComment [/ip ipsec peer get $IpSecPeerCount comment]
  :if ($DnsNameFromComment!="") do={
    :do {
      :set ResolvedIpFromComment [:resolve $DnsNameFromComment]
      :set ResolvedIpWithMaskFromComment ($ResolvedIpFromComment . "/32")
      :set IpPeerAddr [/ip ipsec peer get $IpSecPeerCount address]
      :if ($ResolvedIpWithMaskFromComment!=$IpPeerAddr) do={
        :log warning ("[SetIpSecDstAddrFromDns] Change IpSec peer addr from " . $IpPeerAddr . " to " . $ResolvedIpFromComment)
        /ip ipsec peer set $IpSecPeerCount address=$ResolvedIpWithMaskFromComment
      }
    } on-error={
      :set ResolvedIpFromComment "unknown"
      :log error ("[SetIpSecDstAddrFromDns] Cant resolve name " . $DnsNameFromComment)
    }
  }
}

Добавляем задание в планировщик, которое будет каждые 30 секунд запускать скрипт и проверять, актуальны ли адреса наших VPN-серверов и обновлять их при необходимости.

Спасибо за внимание.

P. S. Статья не рассчитана на новичков, поэтому простейшие вещи, такие как настройка VPN-туннеля или описание скриптового языка Mikrotik, я опустил.
Tags:
Hubs:
+13
Comments 27
Comments Comments 27

Articles