MikroTik: Туннель GRE/IPsec (Site-to-Site)

MikroTik: Туннель GRE/IPsec (Site-to-Site)

Продолжаем серию статей по настройке туннеля между двумя маршрутизаторами. На этот раз создадим #GRE туннель.

На обоих маршрутизаторах у меня используются динамические WAN IP. #GRE предпочитает только статические IP-адреса. Чтобы обойти данное ограничение, я использую скрипт из статьи MikroTik и CloudFlare: Динамический IP для домена, который обновляет IP-адреса маршрутизаторов в суб-доменах, далее скриптом в конце статьи я забираю актуальные IP-адреса суб-доменов и обновляю их в настройках интерфейса #GRE.

Вводные данные

  • Маршрутизатор R1:
    • WAN IP: gw1.example.com.
    • LAN IP: 10.1.0.1.
    • Network: 10.1.0.0/16.
  • Маршрутизатор R2:
    • WAN IP: gw2.example.com.
    • LAN IP: 10.2.0.1.
    • Network: 10.2.0.0/16.

Настройка маршрутизаторов

Router #1

  • Создаём интерфейс #GRE:
    • Имя интерфейса: gre-sts.
    • Секретная фраза для IPsec: PassWord.
    • WAN IP-адрес локального маршрутизатора R1: 1.1.1.1.
    • WAN IP-адрес удалённого маршрутизатора R2: 2.2.2.2.
    • Комментарий: HOST: gw2.example.com.
1
2
/interface gre
add allow-fast-path=no ipsec-secret="PassWord" name="gre-sts" remote-address=2.2.2.2 comment="HOST: gw2.example.com"
  • Прописываем интерфейсу IP-адрес 10.255.255.1/24:
    • Адрес интерфейса: 10.255.255.1/24.
    • Интерфейс: gre-sts.
    • Комментарий: [GRE] GRE-STS.
1
2
/ip address
add address=10.255.255.1/24 interface="gre-sts" comment="[GRE] GRE-STS"
  • Указываем маршрут до удалённой сети R2:
    • Адрес удалённой сети R2: 10.2.0.0/16.
    • Шлюз R2: 10.255.255.2.
    • Комментарий: [GRE] GW2.
1
2
/ip route
add distance=1 dst-address=10.2.0.0/16 gateway=10.255.255.2 comment="[GRE] GW2"

Router #2

  • Создаём интерфейс #GRE:
    • Имя интерфейса: gre-sts.
    • Секретная фраза для IPsec: PassWord.
    • WAN IP-адрес локального маршрутизатора R2: 2.2.2.2.
    • WAN IP-адрес удалённого маршрутизатора R1: 1.1.1.1.
    • Комментарий: HOST: gw1.example.com.
1
2
/interface gre
add allow-fast-path=no ipsec-secret="PassWord" name="gre-sts" remote-address=1.1.1.1 comment="HOST: gw1.example.com"
  • Прописываем интерфейсу IP-адрес 10.255.255.2/24:
    • Адрес интерфейса: 10.255.255.2/24.
    • Интерфейс: gre-sts.
    • Комментарий: [GRE] GRE-STS.
1
2
/ip address
add address=10.255.255.2/24 interface="gre-sts" comment="[GRE] GRE-STS"
  • Указываем маршрут до удалённой сети R1:
    • Адрес удалённой сети R1: 10.1.0.0/16.
    • Шлюз R1: 10.255.255.1.
    • Комментарий: [GRE] GW1.
1
2
/ip route
add distance=1 dst-address=10.1.0.0/16 gateway=10.255.255.1 comment="[GRE] GW1"

Динамический IP

К сожалению, #MikroTik для интерфейса #GRE использует только IP-адреса, нельзя указать имя суб-домена. Но на форуме #MikroTik я нашёл скрипт, который парсит доменное имя удалённого маршрутизатора в специально составленном комментарии (HOST: sub.example.com) к интерфейсу и запрашивает IP-адрес этого домена. Данный IP-адрес автоматически вставляется в поле remote-address интерфейса #GRE. Но как быть, если у нас самих внешний динамический IP-адрес на локальном маршрутизаторе? Я переделал скрипт, чтобы он запрашивал внешний IP-адрес локального маршрутизатора и вставлял его поле local-address интерфейса #GRE.

Суть скрипта в решении проблем с внешними динамическими IP-адресами маршрутизатора.

ros.gre.dip.rsc
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# @package    MikroTik / RouterOS / GRE / Dynamic IP
# @author     Kai Kimera <mail@kai.kim>
# @copyright  2024 Library Online
# @license    MIT
# @version    0.1.0
# @link       https://lib.onl/ru/articles/2024/04/326618af-d950-5001-8114-57c66bb8a5af/
# -------------------------------------------------------------------------------------------------------------------- #

:local wanInterface "ether1"

# -------------------------------------------------------------------------------------------------------------------- #
# -----------------------------------------------------< SCRIPT >----------------------------------------------------- #
# -------------------------------------------------------------------------------------------------------------------- #

:local wanAddress
:local greComment
:local greCommentLen
:local greHost
:local greLocalAddress
:local greRemoteAddressNew
:local greRemoteAddressOld

:set wanAddress [/ip address get [/ip address find interface=$wanInterface] address]
:set wanAddress [:pick $wanAddress 0 [:find $wanAddress "/"]]

:foreach i in=[/interface gre find where comment~"^HOST: "] do={
  :set greComment [/interface gre get $i comment]
  :set greCommentLen [:len $greComment]
  :set greHost [:pick $greComment 6 $greCommentLen]
  :set greLocalAddress [/interface gre get $i local-address]
  :set greRemoteAddressOld [/interface gre get $i remote-address]
  :set greRemoteAddressNew [:resolve $greHost]

  :if ($greRemoteAddressNew != $greRemoteAddressOld) do={
    /interface gre set $i remote-address=$greRemoteAddressNew
    :log info ("Updating GRE remote address (" . $greComment . ") from " . $greRemoteAddressOld . " to " . $greRemoteAddressNew . ".")
  }

  # :if ($wanAddress != $greLocalAddress) do={
  #   /interface gre set $i local-address=$wanAddress
  #   :log info ("Updating GRE local address from " . $greLocalAddress . " to " . $wanAddress . ".")
  # }
}