RouterOS API делаем DMVPN

Сразу оговоримся, это будет не полноценный dmvpn, а мы с помощью API организуем fullmesh связь между всеми маршрутизаторами.

Всё началось с того, что к нам пришёл клиент, у которого 30 маршрутизаторов (30 офисов), и ему нужно было настроить VPN до центрального офиса, и настроить маршрутизацию, что бы клиенты могли спокойно ходить между филиалами. Сразу обговорили детали. Подняли IPsec между Loopback, подняли IPIP между loopback, организовали ospf и всё заработало. Выдали документацию, все наработки, пожали друг другу руки и подписали акты. И благополучно забыли про друг друга.

Некоторое время спустя клиент возвращается, с со словами "удивительно, но если маршрутизаторы соединить напрямую, то скорость возрастает", естественно подумали мы, так как задержки на каждом хопе свои, если надо, что бы офис из Владивостока подключился к Новосибирску, его трафик надо сначала доставить до Москвы, далее в Новосибирск, потом обратно до Москвы и снова во Владивосток, общая задержка 100ms против 30ms напрямую. Но вся идея была в том, что файрвол в Москве использовался для ограничения доступа, а если делать fullmesh, то в любой момент трафик может пойти по непонятному маршруту, то какой cost будет лучше.

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

Подитожим, заказчику нужен простой инструмент который позволит сделать fullmesh допустим ipip тунель шифрованные с помощью IPSEC и поднять OSPF на них, и правильно определить косты. Проблема естественно появилась в последней формулировке "правильно определить косты".

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

И так вроде всё понятно. Начнём с малого

Конфиг

В чём хранить конфигурационные данные.

База данных, mysql или mssql да очень удобно, но ещё одна точка отказа, да и как-то громоздко, также мы рассматривали sqlite, но пришли к такому выводу если мы когда-нибудь переделаем на БД, то необходимо писать отдельно систему администрирования так как добавить в БД данные руками не самая простая реализация.

Начали размышлять над типом данных, которые необходимо хранить в конфиге, нам необходимо хранить массивы, поэтому INI файл отпал сразу. Из вариантов осталось json, yaml и xml.

Yaml - хорош, но совершенно не приспособлен к ручной правке, уж очень не удобен синтаксис отступов, определяющий шаг вложения.

Json - всем хорош, но опять же, неудобна ручная правка.

XML - избыточен, большой объём данных. Но удобен и читабелен для человека. Но у него есть отдельный одни большой плюс, это нативная поддержка практически в любом ЯП.

И мы пришли к выводу, на первых порах мы реализуем на XML, а если дело пойдёт подумаем о хранении либо в БД либо в json.

Структура

Общая структура

<?xml version="1.0" encoding="UTF-8"?>
<vpn>
</vpn>

Global

Прежде чем начать, нам надо продумать общие параметры.

Реализуем объект Global где опишем, общие настройки для всех маршрутизаторов, которые будут настроенны.

<?xml version="1.0" encoding="UTF-8"?>
<vpn>
    <global>
        <ospfareaname>vpn</ospfareaname>
        <ospfareaid>0.0.0.55</ospfareaid>
        <defaultcostinterface>100</defaultcostinterface>
        <loopbackprefixforid>172.31.255.0/24</loopbackprefixforid>
        <interfaceprefix>ipip-dmvpn-</interfaceprefix>
        <addresesfortunnel>172.30.0.0/16</addresesfortunnel>
        <salt>dsao87dmagsoiudhmnlIJGIUYKGNVKMILHL(Jmdlisad</salt>
    </global>
</vpn>

ospfareaname - имя area в настройках RouterOS

ospfareaid - area id в настройках RouterOS

defaultcostinterface - цена интерфейса при создании

loopbackprefixforid - Создадим loopback интерфейс и назначим адрес из данного префикса. Также установим routerid в настройках ospf.

interfaceprefix - уникальный прификс для всех имён интерфейсов, так чтобы оно точно не пересекалось с существующими.

salt - соль которая будет использоваться для генерации уникального пароля аутентификации IPSEC.

addresesfortunnel - префикс из которого будут назначаться адреса на туннели.

routers

<?xml version="1.0" encoding="UTF-8"?>
<vpn>
    <global>
        <ospfareaname>vpn</ospfareaname>
        <ospfareaid>0.0.0.55</ospfareaid>
        <defaultcostinterface>100</defaultcostinterface>
        <loopbackprefixforid>172.31.255.0/24</loopbackprefixforid>
        <interfaceprefix>ipip-dmvpn-</interfaceprefix>
        <addresesfortunnel>172.30.0.0/16</addresesfortunnel>
        <salt>dsao87dmagsoiudhmnlIJGIUYKGNVKMILHL(Jmdlisad</salt>
    </global>
  <routers>
    <router>
        <id>0</id>
        <addreses>
            <address>4.4.4.4</address>
        </addreses>
    </router>
    <router>
        <id>1</id>
        <addreses>
            <address>1.1.1.1</address>
        </addreses>
    </router>
    <router>
        <id>2</id>
        <addreses>
            <address>2.2.2.2</address>
            <address>3.3.3.3</address>
            <address>4.4.4.4</address>
        </addreses>
    </router>
  </routers>
</vpn>

Пока на первых порах, этого будет достаточно.

Id - маршрутизатора, должен быть уникальным, для всего конфига.

адреса, с которых и на которые будут строиться туннели.

Если у вас есть предложения по улучшению или хотите обсудить можете писать в группу в телеграмме или в группу в ВК https://vk.com/mikrotikrus

Рассказать друзьям

Чатик телеграм

@mikrotikme