Pull to refresh

Comments 27

Еще бы найти красивое решение, что бы туннель не засыпал время от времени. А то пока приходится скриптом раз в пол часа туннель тушить/поднимать. Работает, но костыль страшный =)
если ipsec транспортный (а не туннельный), то можно во вложенном туннеле использовать keep alive
ЕМНИП, микротик не умеет транспортный ипсек
Изменяет. Умеет оба типа ipsec. Джун не умеет транспортный. У нас с ним туннельный, а с другими микротиками и цисками транспортный.
В Netwatch клиента ставите пинг любого хоста из подсети VPN-сервера (или внутренний адрес самого сервера), тогда туннель никогда не заснет. Но, как сказали выше, гораздо проще использовать IPsec в транспортном режиме.
Лично мой неполный список «хотелок» к роутерос включает в себя:
  • Открытые спеки на модули
  • IPSEC как интерфейс
  • LLDP
  • Вменяемое управление vlan
  • Переменные в правилах, туда же — dns-менеджер, как в Asterisk.
  • Группы интерфейсов (как вариант — переменная типа «массив» для использования в правилах фв)
  • Группы MAC-адресов
  • Триггеры на события, с лихим перепиливанием всей ныне кривой системы Scripting, размазанной по scheduler, netwatch и system scripts
  • Железку за $150, тянущую 100 мбит ipsec.


Всё это дело потихоньку сподвигает меня расковырять прошивку и допилить отсутствующее собственноручно, но пока тупо некогда.
А ещё очень сильно хочется создавать динамические объекты из скрипта. Перезагрузил роутер, или остановил скрипт — они хопа, и исчезли.
Допустим, скрипт по хттпс (с аутентификацией сертификатом, естественно) получает список next hop-ов, создаёт динамические правила фв, пиры и политики ipsec, загоняет сети в ospf, получает маршруты — и хопа, уже NHRP не нужен, всё вполне себе опенсорсненько, реализуемо в виде скрипта на баше под другие платформы и у циски чутка жим-жим за мелкобизнес.

Эх, я б к ним работать пошел, да климат в Латвии не очень =(
Управление Vlan'ами в последней версии на crs (может на других моделях тоже, не проверил ещё) вполне ок стало =) раньше был лютый костыль, а про железку, имхо, не реально за 150$ получить чип с аппаратной поддержкой шифрования.
Напишите фичреквест у них в вики, может запилят когда-нибудь. Вообще же эти ребята пока вполне окучивают свою нишу, и собственно даже их решения с 10G — это тот же пионернет, по сути. Просто сейчас даже пионеры уже потихоньку дорастают до 10G.

А вообще, список претензий к ним длинный. Причем даже во вполне тривиальных вещах
  • IPSEC как интерфейс

Используйте транспортный режим, вложенный туннель (GRE/IPIP/L2TP) и будет желаемым интерфейсом.

  • Группы интерфейсов (как вариант — переменная типа «массив» для использования в правилах фв)

Сам уже давно жду эту функцию, будет очень полезна.
Эх, научилось бы оно наконец OpenVPN по UDP :)
Openvpn хорош, чертяка. Но ipsec таки лучше, хотя бы распространенностью своей.
Но если очень нужно прям openvpn (была у меня одна точка — из вариантов доступа был только хттп-прокси, а людям нужен был внутренний впн) — пошаманьте с Метароутером, у меня с какой-то древней версией Openwrt openvpn вполне пристойно бегал, мегабит 20 снимал с железки на mipsbe.
Хорош, но микротик на него откровенно забил, и развивать больше не собирается, насколько я знаю.
Может не все так плохо.

What's new in 6.28rc13 (2015-Mar-13 16:06):

*) made metarouter work on boards with 802.11ac support or usb LTE;
Я не про metarouter скорее, а по openvpn =)
Немного поправил скрипт, что бы так же менялся sa-src-address при смене внешнего ip

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

:local DnsNameFromComment
:local ResolvedIpFromComment
:local ResolvedIpWithMaskFromComment

:local IpDstAddr
:local IpSaSrcAddr
:local IpSaDstAddr
:local IpPublic

: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 IpSaSrcAddr [/ip ipsec policy get $IpSecPolicyCount sa-src-address]
:set IpSaDstAddr [/ip ipsec policy get $IpSecPolicyCount sa-dst-address]
:set IpPublic [ /ip cloud get public-address]
:if ($ResolvedIpWithMaskFromComment!=$IpDstAddr or $ResolvedIpFromComment!=$IpSaDstAddr) do={
:log warning («Public ip router » .$IpPublic)
:log warning ("[SetIpSecSrcAddrFromDns] Change IpSec policy src-addr from ". $IpSaSrcAddr. " — to-- ". $IpPublic)
:log warning ("[SetIpSecDstAddrFromDns] Change IpSec policy dst-addr from ". $IpSaDstAddr. " — to-- ". $ResolvedIpFromComment)
/ip ipsec policy set $IpSecPolicyCount sa-src-address=$IpPublic 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)
}
}
}
: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)
}
}
}

автору респект
Пара замечаний:
  • Условие проверки (if) на смену IpSaSrcAddr необходимо скорректировать, а именно надо сравнивать IpSaSrcAddr и IpPublic
  • Данная корректировка будет верна только для роутеров с внешним адресом. Если ваш роутер находится за NAT, то в IpSaSrcAddr необходимо подставлять не внешний IP, а IP интерфейса, который идет к шлюзу. Я другим скриптом проверяю внешний IP роутера и адрес, который указан в маршруте по умолчанию, сравниваю их, если они не равны, делаю вывод, что роутер находится за NAT. Если тебя будет интересно, распишу подробнее.
Спасибо большое за статью и предложенный скрипт.
Поскольку активно пользуюсь туннельным режимом IPsec, внес небольшое изменение в скрипт, чтобы он не изменял dst-addr, для соответствующих правил.

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

:local DnsNameFromComment
:local ResolvedIpFromComment
:local ResolvedIpWithMaskFromComment

:local IpDstAddr
:local IpSaDstAddr
:local TunnelPolicy


: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]
      :set TunnelPolicy [/ip ipsec policy get $IpSecPolicyCount tunnel]
      :if ($ResolvedIpWithMaskFromComment!=$IpDstAddr or $ResolvedIpFromComment!=$IpSaDstAddr) do={
        :if ($TunnelPolicy=no) do={
          :log warning ("[SetIpSecDstAddrFromDns] Change IPsec policy dst-addr and sa-dst-addr from " . $IpSaDstAddr . " to " . $ResolvedIpFromComment . " for $DnsNameFromComment")
          /ip ipsec policy set $IpSecPolicyCount dst-address=$ResolvedIpWithMaskFromComment sa-dst-address=$ResolvedIpFromComment
        } else={
          :log warning ("[SetIpSecDstAddrFromDns] Change IPsec tunnel policy dst-addr from " . $IpSaDstAddr . " to " . $ResolvedIpFromComment . " for $DnsNameFromComment")
          /ip ipsec policy set $IpSecPolicyCount 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 . " for $DnsNameFromComment")
        /ip ipsec peer set $IpSecPeerCount address=$ResolvedIpWithMaskFromComment
      }
    } on-error={
      :set ResolvedIpFromComment "unknown"
      :log error ("[SetIpSecDstAddrFromDns] Cant resolve name " . $DnsNameFromComment)
    }
  }
}

Спасибо за статью! Однако в последней версии прошивки что-то не работает. Вижу, что не те адреса заменяет скрипт. Вы могли бы глянуть, т.к. в программировании Mikrotik не силен. P.S. Вижу исправления :-)
Игорь, разобрались уже?
Нет, что-то все равно не работает. SA Src. Address не хочет менять. Скрипт, предложенный пользователем AVP неполный, не вижу переменной :local IpSaSrcAddr

Был бы ОЧЕНЬ благодарен, если бы выложили последнюю полную версию скрипта для последней прошивки.
Друзья, вожно выложить актуальный работающий скрипт, который будет проверять и менять как Destination Address, так и Source Address? Большое спасибо.
Вернусь с праздников, свяжусь с вами.
Вопрос простейший, скрипт должен проверять как адрес источника, так и получателя и соответствующим образом корректировать правила.
Sign up to leave a comment.

Articles