Wednesday, December 26, 2018

Настройка IPsec L2TP сервера на Ubiquiti EdgeRouter

В этой публикации мы расскажем, как настроить EdgeRouter L2TP (протокол туннелирования уровня 2), используя локальную аутентификацию. Этот пример основан на проверке «до совместного использования» и не фокусируется на аутентификации на основе сертификата.
Важно! Применимо к прошивке EdgeOS 1.9.1+ во всех моделях EdgeRouter. Требуется знание интерфейса командной строки (CLI) и базовых сетевых знаний.

Что используем?

  • EdgeRouter-X (ER-X)
  • Тестовый клиент (Host1 and Server1)

Что делаем?

  • Топология сети
  • L2TP сервер
  • Правила Firewall
  • Windows-клиент
  • Тестирование и результат

Топология сети

Сетевая топология представлена ниже. IP адреса и интерфейсы, использованные Host1 и клиентским роутером не соответствуют этому примеру. Используя L2TP терминологию, ER-X является "L2TP-сервером", в то время как Host1 является "L2TP-клиентом".
Для ER используются следующие интерфейсы:
  • eth0 (WAN) - 203.0.113.1
  • eth1 (LAN) - 192.168.1.1/24

L2TP-сервер

В этом примере ER был предварительно настроен с помощью "Мастера базовой установки" (Basic setup wizard). Мы предположим, что хосты локальной сети могут быть связаны с хостами в Интернете.
UDP порты и протоколы, относящиеся к L2TP:
  • UDP 1701 (L2TP)
  • UDP 500 (IKE)
  • ESP (Protocol 50)
  • UDP 4500 (NAT-T) 
CLI STEPS: Получите доступ к интерфейсу командной строки (CLI). Вы можете сделать это, используя CLI-кнопку в GUI или используя программу PuTTY.
1. Запустите режим конфигурации.
configure
2. Измените настройки аутентификации сервера (замените своим паролем).
set vpn l2tp remote-access ipsec-settings authentication mode pre-shared-secret
set vpn l2tp remote-access ipsec-settings authentication pre-shared-secret <secret>
Примечание: Если Вы определяете предварительно представленный пароль используя кавычки, убедитесь что пароль на стороне клиента не включает эти самые кавычки. Для примера, set vpn l2tp remote-access ipsec-settings authentication pre-shared-secret пароль 'sup3rSecure' должен выглядеть как 'sup3rSecure' на клиенте.
3.Создайте IP-адрес для использования VPN-клиентами.
set vpn l2tp remote-access client-ip-pool start 192.168.100.240
set vpn l2tp remote-access client-ip-pool stop 192.168.100.249
Примечание: Вы можете также выдавать IP адреса локальной субсети (192.168.1.0/24 в этом случае), но убедитесь, что они не пересекаются с IP адресами, которые выдает Ваш DHCP-сервер, или не используются другими устройствами Вашей сети. Определение адресов в том же радиусе, что и локальная субсеть, не рекомендуется, потому что оно может привести к проблемам с приложениями, которые полагаются на мультикаст (discovery).
4. Определите DNS серверы, которые будут использовать VPN клиенты.
set vpn l2tp remote-access dns-servers server-1 8.8.8.8
set vpn l2tp remote-access dns-servers server-2 8.8.4.4 
Вы также можете настроить DNS-сервер как внутренний IP-адрес самого маршрутизатора. В этом случае Вам также понадобится включить DNS пересылку (если она еще не включена) и установить адрес ожидания сети на тот же внутренний IP-адрес.
set vpn l2tp remote-access dns-servers server-1 192.168.1.1
set service dns forwarding options "listen-address=192.168.1.1"
set service dns forwarding cache-size 150
set service dns forwarding listen-on eth1 
5. Определите интерфейс WAN, который будете получать L2TP-запросы от клиентов.
Настройте только одно из следующих действий. Определите, какая команда лучше всего подходит для Вашей ситуации, используя следующие параметры:
(A) Ваш интерфейс WAN получает адрес через DHCP.
set vpn l2tp remote-access dhcp-interface eth0
(B) Ваш WAN-интерфейс настроен на статический адрес (замените значение на внешний адрес).
set vpn l2tp remote-access outside-address 203.0.113.1
(C) Ваш WAN-интерфейс получает адрес через PPPoE, или вы используете Dual WAN Load-Balancing.
set vpn l2tp remote-access outside-address 0.0.0.0
Примечание: Когда используются несколько восходящих линий (Dual WAN Load-Balancing), применяйте опцию C. Если Вы используете вариант A или B, Ваш сервер L2TP будет доступен только на одном адресе WAN.
6. Настройте локальную аутентификацию (замените на нужные Вам пользовательские пароли):
set vpn l2tp remote-access authentication mode local
set vpn l2tp remote-access authentication local-users username user1 password <password>
set vpn l2tp remote-access authentication local-users username user2 password <password>
7. (Необязательно) Определите интерфейсы IPsec, которые будут использоваться для L2TP.
Этот шаг зависит от используемой версии прошивки. Официальное использование этой команды устарело в версии 1.8.5.
set vpn ipsec ipsec-interfaces interface eth0
8. (Необязательно) Понизьте MTU для трафика L2TP.
Экспериментируйте с понижением значения MTU, если производительность L2TP низкая. Это может произойти, к примеру, когда внешний интерфейс WAN использует PPPoE (1492 байт MTU).
set vpn l2tp remote-access mtu <mtu-value>
9. (Необязательно) Включите требование от VPN-клиентов использовать определенный протокол аутентификации при подключении.
set vpn l2tp remote-access authentication require [ pap | chap | mschap | mschap-v2 ]
  • PAP - Require Password Authentication Protocol 
  • CHAP - Require Challenge Handshake Authentication Protocol 
  • MS-CHAP - Require Microsoft Challenge Handshake Authentication Protocol
  • MS-CHAP-V2 - Require Microsoft Challenge Handshake Authentication Protocol Version 2
10. Зафиксируйте изменения.
commit
11. Сохраните конфигурацию.
save

Правила Firewall

Правило WAN_LOCAL, созданное Мастером базовой установки (Basic Setup wizard), не разрешает входящие подключения по умолчанию. Для принятия VPN-трафика необходимо создать правила брандмауэра для L2TP, ESP и IKE.
1. Запустите режим конфигурации.
configure
2. Добавьте дополнительные правила L2TP, IKE, NAT-T и ESP для WAN интерфейсов.
set firewall name WAN_LOCAL rule 30 action accept
set firewall name WAN_LOCAL rule 30 description IKE
set firewall name WAN_LOCAL rule 30 destination port 500
set firewall name WAN_LOCAL rule 30 log disable
set firewall name WAN_LOCAL rule 30 protocol udp

set firewall name WAN_LOCAL rule 40 action accept
set firewall name WAN_LOCAL rule 40 description L2TP
set firewall name WAN_LOCAL rule 40 destination port 1701
set firewall name WAN_LOCAL rule 40 log disable
set firewall name WAN_LOCAL rule 40 protocol udp

set firewall name WAN_LOCAL rule 50 action accept
set firewall name WAN_LOCAL rule 50 description ESP
set firewall name WAN_LOCAL rule 50 log disable
set firewall name WAN_LOCAL rule 50 protocol esp

set firewall name WAN_LOCAL rule 60 action accept
set firewall name WAN_LOCAL rule 60 description NAT-T
set firewall name WAN_LOCAL rule 60 destination port 4500
set firewall name WAN_LOCAL rule 60 log disable
set firewall name WAN_LOCAL rule 60 protocol udp
Примечание. Имя локального правила брандмауэра, применяемого к интерфейсу WAN, может отличаться в Вашей среде. Независимо от схемы, убедитесь, что верное правило брандмауэра применяется в интерфейсе WAN или вручную применяйте его set interfaces ethernet eth0 firewall local name .
3. Зафиксируйте изменения.
commit
4. Сохраните конфигурацию.
save

Windows-клиент

Существуют различные способы подключения к серверу L2TP с использованием множества приложений и операционных систем. В этой статье мы сосредоточимся только на одном, встроенном VPN-клиенте Windows 10. Причиной выбора этого метода является то, что он обычно используется, и он также имеет важный момент, который стоит обсудить.
1. Перейдите к настройкам Windows 10 (WIN + I)> Сеть и Интернет> Добавить VPN-соединение:
  • VPN Провайдер: Windows (встроенный)
  • Название соединения: ER-L2TP
  • Название сервера: WAN IP-адрес сервера ER
  • VPN тип: L2TP/IPsec с предварительно представленным ключом или сертификатом.
2. Перейдите к свойствам сетевого адаптера Windows 10 (WIN + X)> ER-L2TP
Security > Allow these protocols > Microsoft CHAP Version 2 (MS-CHAP v2)
Примечание: Если ваш EdgeRouter находится вне NAT и Вы не можете подключиться к вашему серверу L2TP, это может быть связано с операционной системой Windows и тем, как она обрабатывает трафик IPsec на серверах/маршрутизаторах, расположенных вне устройства NAT. В этом случае примените хотфикс (шаг 3).
3. (Хотфикс) Перейдите в реестр Windows 10 (WIN + R)> regedit
Найдите следующее поддерево реестра:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PolicyAgent
Создайте новое DWORD (32-разрядное) значение в этом поддереве:
AssumeUDPEncapsulationContextOnSendRule
Измените вновь созданное значение DWORD, дайте ему значение 2 (по умолчанию 0) и перезагрузите компьютер.

Тестирование и результат

Последний шаг - протестировать и подтвердить прибытие трафика L2TP на внешний интерфейс и проверить журналы. Если есть проблемы с L2TP VPN, проверьте файлы журнала, чтобы определить проблему. После запуска сеанса L2TP проверьте соединение, используя следующие команды:
1. Проверить состояние IPsec в ER:
sudo ipsec statusall
Status of IKE charon daemon (strongSwan 5.2.2, Linux 3.10.14-UBNT, mips):
 uptime: 49 seconds, since Jul 17 14:01:59 2017
 malloc: sbrk 376832, mmap 0, used 272072, free 104760
 worker threads: 11 of 16 idle, 5/0/0/0 working, job queue: 0/0/0/0, scheduled: 0
 Listening IP addresses:
 192.168.1.1
 203.0.113.1
 10.255.255.0
Connections:
remote-access: 203.0.113.1...%any IKEv1, dpddelay=15s
remote-access: local: [203.0.113.1] uses pre-shared key authentication
remote-access: remote: uses pre-shared key authentication
remote-access: child: dynamic[udp/l2f] === dynamic[udp] TRANSPORT, dpdaction=clear
Security Associations (1 up, 0 connecting):
remote-access[1]: ESTABLISHED 30 seconds ago, 203.0.113.1[203.0.113.1]...192.0.2.1[172.16.1.10]
remote-access[1]: IKEv1 SPIs: 7ef8fd033bea7f4c_i 27eaafddd951c8dc_r*, rekeying disabled
remote-access[1]: IKE proposal: AES_CBC_256/HMAC_SHA1_96/PRF_HMAC_SHA1/ECP_384
remote-access{1}: INSTALLED, TRANSPORT, ESP in UDP SPIs: c009fce1_i cd73f1b4_o
remote-access{1}: AES_CBC_128/HMAC_SHA1_96, 3594 bytes_i (36 pkts, 18s ago), 675 bytes_o (17 pkts, 27s ago)
remote-access{1}: 203.0.113.1/32[udp/l2f] === 192.0.2.1/32[udp/l2f] 
2. Убедитесь, что трафик увеличивает счетчики на соответствующих правилах Firewall.
show firewall name WAN_LOCAL statistics 
------------------------------------------
IPv4 Firewall "WAN_LOCAL" [WAN to router]
 Active on (eth0,LOCAL) 

rule   packets  bytes   action   description
----   -------  -----   ------   -----------
10     2926     271414  ACCEPT   Allow established/related
20     0        0 DROP  Drop     invalid state
30     19       5512    ACCEPT   IKE
40     5        655     ACCEPT   L2TP
50     0        0       ACCEPT   ESP
60     8        1088    ACCEPT   NAT-T
10000  69       9516    DROP     DEFAULT ACTION
3. Захватите приход трафика L2TP на внешний интерфейс глобальной сети ER:
3. Захватить приход трафика L2TP на внешний интерфейс глобальной сети ER:
4. Захватите журналы ER IPsec VPN:
sudo swanctl --log
[NET] received packet: from 192.0.2.1[500] to 203.0.113.1[500] (408 bytes)
[IKE] 192.0.2.1 is initiating a Main Mode IKE_SA
[IKE] remote host is behind NAT
[CFG] looking for pre-shared key peer configs matching 203.0.113.1...192.0.2.1[172.16.0.10]
[CFG] selected peer config "remote-access"
[IKE] IKE_SA remote-access[15] established between ...
[IKE] CHILD_SA remote-access{5} established with SPIs ...
[KNL] 10.255.255.0 appeared on ppp0
5. IPsec Security Associations (SAs):
show vpn ipsec sa
remote-access: #545, ESTABLISHED, IKEv1, b0a8c5df5ff1b225:a251946b15ebaaae
 local '203.0.113.1' @ 203.0.113.1
 remote '172.16.0.10' @ 192.0.2.1
 AES_CBC-256/HMAC_SHA1_96/PRF_HMAC_SHA1/ECP_384
 established 351s ago
 remote-access: #17, INSTALLED, TRANSPORT-in-UDP, ESP:AES_CBC-128/HMAC_SHA1_96
 installed 8 ago
 in cd49a319, 0 bytes, 0 packets
 out 47a8a786, 0 bytes, 0 packets
 local 76.237.8.193/32[udp/l2f]
 remote 192.0.2.1/32[udp/l2f]
6. Пользователи и интерфейсы удаленного доступа:
show vpn remote-access 
Active remote access VPN sessions:

User       Time      Proto Iface Remote IP       TX pkt/byte   RX pkt/byte 
---------- --------- ----- ----- --------------- ------ ------ ------ ------
ubnt       00h01m22s L2TP  l2tp0 192.168.100.240     4     58     86   7.4K

show interfaces 
Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
Interface   IP Address    S/L   Description 
---------   ----------    ---   ----------- 
l2tp0       10.255.255.0  u/u   User: ubnt (192.168.100.240)
7. Отправить трафик через туннель от Host1 до Server1 и наоборот:
ping 192.168.1.10
PING 192.168.1.10 (192.168.1.10) 56(84) bytes of data.
64 bytes from 192.168.1.10: icmp_seq=1 ttl=63 time=45.9 ms
64 bytes from 192.168.1.10: icmp_seq=2 ttl=63 time=45.2 ms
64 bytes from 192.168.1.10: icmp_seq=3 ttl=63 time=45.5 ms

ping 172.16.1.10
PING 172.16.1.10 (172.16.1.10) 56(84) bytes of data.
64 bytes from 172.16.1.10: icmp_seq=1 ttl=63 time=43.9 ms
64 bytes from 172.16.1.10: icmp_seq=2 ttl=63 time=44.1 ms
64 bytes from 172.16.1.10: icmp_seq=3 ttl=63 time=44.4 ms

Аутентификация пользователей при помощи профиля в социальных сетях

В этой статье приведены шаги, позволяющие включить аутентификацию гостя через Facebook и Google+.
Примечания и требования: Применимо к UniFi Controller 5.4.2.1 и версиям выше. Чтобы использовать стороннюю аутентификацию гостя, у Вас должно быть общедоступное имя хоста, указывающее на Ваш контроллер. Если Ваша компания уже использует общедоступное доменное имя, например example.com, Вы можете настроить субдомен, такой как portal.example.com. Существует множество провайдеров динамических DNS, в которых Вы можете зарегистрировать имя хоста, а затем обновить USG для своего IP-адреса WAN

Содержание

  • Введение
  • Настройка приложения Facebook
  • Настройка API Google+
  • Настройка контроллера UniFi

Введение

Гостевая аутентификации через аккаунт в социальных сетях может быть включена для разрешения клиентам входить в гостевую сеть, используя свои учетные данные в Facebook или Google+. Начните с создания приложения facebook, входа в Google + API или обоих.

Настройка приложения Facebook

1. Зарегистрируйте приложение Facebook

Используйте ЭТО руководство, чтобы зарегистрировать приложение для аутентификации через Facebook, оставляя эту статью открытой для чтения.
Шаг 3 предлагает Вам выбрать отображаемое имя для Вашего приложения. Выберите имя, которое будет представлять ваш портал WiFi. Пользователи будут видеть его при аутентификации. В этом примере я буду использовать имя "CMurphy Hotspot Login" и электронную почту по умолчанию, которая связана с моей учетной записью Facebook. Для категории я использую "Communication". Категория здесь не критично важна, поэтому не стесняйтесь использовать другую категорию, если она лучше отражает Ваш бизнес.
Register a Facebook App
Вам будет предложено либо пройти к руководству по быстрой настройке, либо вернуться. Если Вы нажмете кнопку "Назад", Вы попадете на панель инструментов, нажав "My Apps" в верхнем правом углу. Выберите "Choose Platform > Website", чтобы начать быструю настройку.

2. Завершите быструю наастройку веб-сайта Facebook.

Complete Facebook Website Quick Start.
Выберите "Website".
В разделе "Tell us about your website", введите доменное имя вашего контроллера в качестве URL-адреса сайта. Затем нажмите "Developer Dashboard", чтобы перейти к панели разработчика.

3. Настройка приложения

Перейдите в раздел "Settings" на боковой панели, чтобы открыть основные настройки приложения.
App Settings
"App ID" и "App Secret" будут автоматически назначены Вашему приложению. Выберите имя и псевдо для Вашего приложения - они могут быть кикими угодно, но именно их пользователи будут видеть при аутентификации.
В разделе "App Domains" и "Site URL" введите домен или субдомен Вашего контроллера.
Если Вы хотите, можете добавить URL-адреса для политики конфиденциальности и условий обслуживания, а также значок приложения. Они не влияют на работу приложения, но улучшат профессиональное восприятие портала входа в систему.
Если вы хотите, можете добавить URL-адреса для политики конфиденциальности и условий обслуживания, а также значок приложения. Они не требуются для правильной работы, но улучшат профессиональное восприятие портала входа в систему.

4. Добавьте приложение

Затем нажмите "Add Product", затем "Facebook Login", чтобы создать страницу входа в систему.
Add Product

5. Добавьте субдомен контроллера и порт

В настройках входа в Facebook укажите домен контроллера или субдомен вместе с портами 8880 и 8843. Используйте параметры переключения в приведенном ниже изображении.
  • http://domain.com:8880/
  • https://domain.com:8843/
Add Controller Subdomain and Port
Сохраните изменения перед продолжением.

6. Опубликуйте приложение

Наконец, опубликуйте приложение с помощью "App Review > Make [App Name] Public" и нажмите "Confirm".
Publish App
Если Вы настраиваете и аутентификацию Google тоже, продолжайте чтение. Если нет - перейдите к настройке контроллера.

Настройка API Google+

1. Включите вход через Google

Используйте «Руководство по включению Google+ API», чтобы включить вход через Google.
Шаг 6а в этом руководстве предлагает администратору добавить свое приложения. В этом случае это будет субдомен, за которым следует порт 8880. Обратите внимание на "Client ID" и "Client Secret", которые будут использоваться позже в настройке контроллера.
Enable Google Login
Примечание: Если после установки клиентское устройство получает ошибку переадресации, добавьте URI-переадресацию ниже в разделе «Authorized redirect URIs» на предыдущем шаге:
Enable Google Login

Настройка контроллера UniFi

1. Активируйте гостевые политики

После того, как Вы настроили приложение Facebook или Google, зайдите на свой контроллер. Начните с активации гостевой политики.
Activate Guest Policies

2. Настройте гостевой портал

Затем откройте вкладку "Guest Control ", чтобы настроить гостевой портал. Выберите "Hotspot authentication". Если хотите, введите рекламный URL-адрес для пересылки клиентов на свой веб-сайт после их аутентификации. Выберите "Promotional URL" с использованием имени хоста и введите субдомен контроллера. Выберите "Enable HTTPS Redirection".
Configure the Guest Portal

3. Активируйте метод аутентификации сторонних поставщиков

В разделе "Hotspot", выберите сторонние методы аутентификации, которые Вы хотите активировать. Введите "ID" и "Secret" для выбранных приложений.
Activate Third Party Authentication Method

4. Добавить общедоступные IP-адреса Facebook

В разделе "Access Control" добавьте следующий список общедоступных IP-адресов, которые использует Facebook:
31.13.24.0/21
31.13.64.0/18
45.64.40.0/22
66.220.144.0/20
69.63.176.0/20
69.171.224.0/19
74.119.76.0/22
103.4.96.0/22
129.134.0.0/16
157.240.0.0/16
173.252.64.0/18
179.60.192.0/22
185.60.216.0/22
204.15.20.0/22
Add Facebook's Public IPs

5. Протестируйте гостевую сеть

Наконец, используйте устройство для подключения к гостевой сети и убедитесь, что гостевой портал работает правильно.

Dual Wan и особенности реализации NetWatch в MikroTik

Как работают вместе failover и netwatch. Взгляд изнутри.
Почти каждой более-менее подросшей компании начинает хотеться качества коммуникаций. Среди прочего, заказчику часто хочется отказоустойчивый «Dual WAN» и VoIP телефонию. Тоже отказоустойчивую, разумеется. Руководств и статей по каждой теме в отдельности написано много, но внезапно оказалось, что совместить первое и второе получается не у всех.
Уже есть статья «Mikrotik. Failover. Load Balancing» от vdemchuk. Как оказалось, она послужила для многих источником копипасты кода в маршрутизаторы.
Хорошее, рабочее решение, но SIP-клиенты из LAN, подключающиеся к внешней IP-АТС посредством NAT, при переключении теряли связь. Проблема известная. Связана она с работой Connection tracker, который запоминает имеющиеся соединения вовне, и сохраняет их состояние независимо от других условий.
Понять почему так происходит можно посмотрев на диаграмму packet flow:
Реализация NetWatch в MikroTik
Для транзитного трафика процедура обработки connection tracker выполняется всего в одной цепочке — prerouting, (т.е. до роутинга), до выбора маршрута и исходящего интерфейса. На этой стадии еще неизвестно, через какой интерфейс пакет пойдет в Интернет, и отследить src-ip при нескольких Wan-интерфейсах невозможно. Механизм фиксирует установленные соединения уже пост-фактум. Фиксирует и запоминает на время пока через соединение идут пакеты или пока не истечет заданный таймаут.

Описанное поведение характерно не только для маршрутизаторов MikroTik, но и для большинства Linux-based систем выполняющих NAT.

В результате, при обрыве связи через WAN1, поток данных послушно направляется через WAN2, только SOURCE IP прошедших через NAT пакетов остается неизменный — от интерфейса WAN1, т.к. в connection tracker уже есть соответствующая запись. Естественно, ответы на такие пакеты идут на интерфейс WAN1 уже потерявший связь с внешним миром. В итоге, связь как будто есть, но на самом деле её нет. При этом все новые соединения устанавливаются корректно.
Hint: увидеть с каких и на какие адреса делается NAT можно в колонках «Reply Src. Address» и «Reply Dst. Address». Отображение этих колонок включается в таблице «connections» с помощью правой кнопки мыши.
Реализация NetWatch в MikroTik
На первый взгляд выход выглядит довольно простым — при переключении сбросить ранее установленные SIP-соединения, чтобы они установились заново, уже с новым SRC-IP. Благо простой скрипт по просторам интернета бродит.
Cкрипт
:foreach i in=[/ip firewall connection find dst-address~":5060"] do={ /ip firewall connection remove $i }

Три шага к фейлу

Шаг первый. Копипастеры добросовестно переносят конфиг для Failover recursive routing:
Настройка роутинг из статьи «Mikrotik. Failover. Load Balancing»
# Настроим сети провайдеров:
/ip address add address=10.100.1.1/24 interface=ISP1
/ip address add address=10.200.1.1/24 interface=ISP2
# Настроим локальный интерфейс 
/ip address add address=10.1.1.1/24 interface=LAN
# скроем за NAT все что выходит из локальной сети
/ip firewall nat add src-address=10.1.1.0/24 action=masquerade chain=srcnat
###Обеспечение failover c более глубоким анализом канала###
#с помощью параметра scope укажем рекурсивные пути к узлам 8.8.8.8 и 8.8.4.4
/ip route add dst-address=8.8.8.8 gateway=10.100.1.254 scope=10
/ip route add dst-address=8.8.4.4 gateway=10.200.1.254 scope=10
# укажем 2 default gateway через узлы путь к которым указан рекурсивно
/ip route add dst-address=0.0.0.0/0 gateway=8.8.8.8 distance=1 check-gateway=ping
/ip route add dst-address=0.0.0.0/0 gateway=8.8.4.4 distance=2 check-gateway=ping
Шаг второй. Отследить событие переключения. Чем? "/tool netwatch", естественно! Попытка отследить падение шлюза WAN1 обычно выглядит так:
Netwatch config
/tool netwatch
add comment=«Check Main Link via 8.8.8.8» host=8.8.8.8 timeout=500ms /
down-script=":log warning («WAN1 DOWN»)
:foreach i in=[/ip firewall connection find dst-address~":5060"] do={
:log warning («clear-SIP-connections: clearing connection src-address:$[/ip firewall connection get $i src-address] dst-address:$[/ip firewall connection get $i dst-address]»)
/ip firewall connection remove $i}" 
up-script=":log warning («WAN1 UP»)
:foreach i in=[/ip firewall connection find dst-address~":5060"] do={
:log warning («clear-SIP-connections: clearing connection src-address:$[/ip firewall connection get $i src-address] dst-address:$[/ip firewall connection get $i dst-address]»)
/ip firewall connection remove $i}"
Шаг третий. Проверка.
Админ гасит первый аплинк WAN1 и вручную запускает скрипт. SIP-клиенты переподключились. Работает? Работает! Админ включает обратно WAN1 и вручную запускает скрипт. SIP-клиенты переподключились. Работает? Работает!

Fail

В реальной обстановке такой конфиг работать отказывается. Неоднократное повторение шага №3 приводит админа в состояние озлобления и мы слышим «Не работает ваш микротик!».

Разбор полётов

Всё дело в непонимании того, как происходит работа утилиты Netwatch. Применительно в отношении именно рекурсивного роутинга, утилита просто пингует заданный хост согласно основной таблице маршрутизации, используя активные маршруты.
Проведем эксперимент. Отключим основной канал WAN1 и посмотрим и интерфейс /tool netwatch. Мы увидим, что хост 8.8.8.8 по-прежнему имеет состояние UP.
Для сравнения опция check-gateway=ping, работает для каждого маршрута в отдельности в т.ч. рекурсивно, и делает сам маршрут активным либо НЕактивным.
Netwatch использует уже активные на данный момент маршруты. Когда что-либо происходит на линке до шлюза провайдера ISP1 (WAN1), маршрут до 8.8.8.8 через WAN1 становится неактивным, и netwatch игнорирует его, отправляя пакеты в новый default route. Failover играет злую шутку, и netwatch считает, что всё в порядке.
Второй вариант поведения netwatch, это двойное срабатывание. Механизм его таков: если пинги от netwatch попадут в таймаут check-gateway, то на один цикл проверки хост будет признан DOWN. Сработает скрипт переключения канала. SIP-соединения корректно перейдут на новый линк. Работает? Не совсем.
Скоро таблица маршрутизации перестроится, хост 8.8.8.8 получит статус UP, вновь сработает скрипт сброса SIP-соединений. Соединения второй раз переустановятся через WAN2.
В результате, при возвращении в строй ISP1 и переходе рабочего трафика на WAN1, SIP-соединения так и останутся висеть через ISP2 (WAN2). Чревато это тем, что при проблемах у на запасном канале система этого не заметит и телефонной связи не станет.

Решение

Для того, чтобы трафик на используемый для мониторинга хост 8.8.8.8 не заворачивался на ISP2, нам нужно иметь запасной маршрут до 8.8.8.8. На случай падения ISP1, создаем резервный маршрут с большим значением distance, например distance=10 и type=blackhole. Он и станет активным при пропадании линка до WAN1 Gateway:
/ip route add distance=10 dst-address=8.8.8.8 type=blackhole
В итоге имеем дополнение конфига всего лишь одной строкой:
Исправленный роутинг
# Настроим сети провайдеров:
/ip address add address=10.100.1.1/24 interface=ISP1
/ip address add address=10.200.1.1/24 interface=ISP2
# Настроим локальный интерфейс 
/ip address add address=10.1.1.1/24 interface=LAN
# скроем за NAT все что выходит из локальной сети
/ip firewall nat add src-address=10.1.1.0/24 action=masquerade chain=srcnat
###Обеспечение failover c более глубоким анализом канала###
#с помощью параметра scope укажем рекурсивные пути к узлам 8.8.8.8 и 8.8.4.4
/ip route add dst-address=8.8.8.8 gateway=10.100.1.254 scope=10
/ip route add distance=10 dst-address=8.8.8.8 type=blackhole
/ip route add dst-address=8.8.4.4 gateway=10.200.1.254 scope=10
# укажем 2 default gateway через узлы путь к которым указан рекурсивно
/ip route add dst-address=0.0.0.0/0 gateway=8.8.8.8 distance=1 check-gateway=ping
/ip route add dst-address=0.0.0.0/0 gateway=8.8.4.4 distance=2 check-gateway=ping
Данная ситуация характерна именно при падении последней мили, когда шлюз ISP1 становится недоступным. Либо при использовании туннелей, которые более подвержены падениям в силу цепной зависимости.

Monday, December 10, 2018

MikroTik ACCESS LAN --> WAN --> LAN Hairpin NAT

Hairpin NAT

In the below network topology a web server behind a router is on private IP address space, and the router performs NAT to forward traffic to its public IP address to the web server behind it.
Hairpin nat 1.png
The NAT configuration would look like below:
/ip firewall nat
add chain=dstnat dst-address=1.1.1.1 protocol=tcp dst-port=80 \
  action=dst-nat to-address=192.168.1.2
add chain=srcnat out-interface=WAN action=masquerade
When a client out on the Internet with IP address 2.2.2.2 establishes a connection to the web server, the router performs NAT as configured.
Hairpin nat 2 new.png
  1. the client sends a packet with a source IP address of 2.2.2.2 to a destination IP address of 1.1.1.1 on port tcp/80 to request some web resource.
  2. the router destination NATs the packet to 192.168.1.2 and replaces the destination IP address in the packet accordingly. The source IP address stays the same: 2.2.2.2.
  3. the server replies to the client's request and the reply packet has a source IP address of 192.168.1.2 and a destination IP address of 2.2.2.2.
  4. the router determines that the packet is part of a previous connection and undoes the destination NAT, and puts the original destination IP address into the source IP address field. The destination IP address is 2.2.2.2, and the source IP address is 1.1.1.1.
The client receives the reply packet it expects, and the connection is established.
When a client on the same internal network as the web server requests a connection to the web server's public IP address, the connection breaks.
Hairpin nat 3.png
  1. the client sends a packet with a source IP address of 192.168.1.10 to a destination IP address of 1.1.1.1 on port tcp/80 to request some web resource.
  2. the router destination NATs the packet to 192.168.1.2 and replaces the destination IP address in the packet accordingly. The source IP address stays the same: 192.168.1.10.
  3. the server replies to the client's request. However, the source IP address of the request is on the same subnet as the web server. The web server does not send the reply back to the router, but sends it back directly to 192.168.1.10 with a source IP address in the reply of 192.168.1.2.
The client receives the reply packet, but it discards it because it expects a packet back from 1.1.1.1, and not from 192.168.1.2. As far as the client is concerned the packet is invalid and not related to any connection the client previously attempted to establish.
To fix the issue, an additional NAT rule needs to be introduced on the router to enforce that all reply traffic flows through the router, despite the client and server being on the same subnet. The rule below is very specific to only apply to the traffic that the issue could occur with - if there are many servers the issue occurs with, the rule could be made broader to save having one such exception per forwarded service.
/ip firewall nat
add chain=srcnat src-address=192.168.1.0/24 \
  dst-address=192.168.1.2 protocol=tcp dst-port=80 \
  out-interface=LAN action=masquerade
Hairpin nat 4.png
With that additional rule, the flow now changes:
  1. the client sends a packet with a source IP address of 192.168.1.10 to a destination IP address of 1.1.1.1 on port tcp/80 to request some web resource.
  2. the router destination NATs the packet to 192.168.1.2 and replaces the destination IP address in the packet accordingly. It also source NATs the packet and replaces the source IP address in the packet with the IP address on its LAN interface. The destination IP address is 192.168.1.2, and the source IP address is 192.168.1.1.
  3. the web server replies to the request and sends the reply with a source IP address of 192.168.1.2 back to the router's LAN interface IP address of 192.168.1.1.
  4. the router determines that the packet is part of a previous connection and undoes both the source and destination NAT, and puts the original destination IP address of 1.1.1.1 into the source IP address field, and the original source IP address of 192.168.1.10 into the destination IP address field.
The client receives the reply packet it expects, and the connection is established.
However, the web server only ever sees a source IP address of 192.168.1.1 for all requests from internal clients regardless of the internal client's real IP address. There is no way to avoid this without either using a router that can do application level DNS inspection and can rewrite A records accordingly, or a split DNS server that serves the internal clients the internal server IP address and external clients the external server IP address.

Dynamic DNS Update Script for No-IP DNS

This script is a solution made of others solutions (nothing new). Much of this was adapted from the deprecated version of Dynamic DNS Update Script for behind NAT.
The goal is to update your account on DNSoMatic.com. The main advantage of this solution is that DNSoMatic offers the possibility of propagating DNS updates to thirth party DNSlike systems like OpenDNS, DynDNS, Change IP and other 27 more.
Note: The script below is RouterOS 5.14 & 6.6 Tested!
The following permissions are required for this script to run:
  • write
  • test
  • read
  • policy (for ROS 6.0+)
# DNSoMatic automatic DNS updates

#--------------- Change Values in this section to match your setup ------------------

# User account info of DNSoMatic

:local maticuser "dnsomatic-username"
:local maticpass "dnsomatic-password"

# Set the hostname or label of network to be updated. This is the part after the double colon (::) on the DNSoMatic services page.
# Hostnames with spaces are unsupported. Replace the value in the quotations below with your host names.
# To specify multiple hosts, separate them with commas. 
# Use "all.dnsomatic.com" for the matichost to update all items in dnsomatic with this IP.

:local matichost "hostname1,hostname2"

# Change to the name of interface that gets the changing IP address

:local inetinterface "ether1-gateway"

#------------------------------------------------------------------------------------

# No more changes need

:global previousIP;

:if ([/interface get $inetinterface value-name=running]) do={
# Get the current IP on the interface
    :local currentIP [/ip address get [find interface="$inetinterface" disabled=no] address];
    
# Strip the net mask off the IP address
    :for i from=( [:len $currentIP] - 1) to=0 do={
        :if ( [:pick $currentIP $i] = "/") do={ 
            :set currentIP [:pick $currentIP 0 $i]
        } 
    }
    
    :if ($currentIP != $previousIP) do={
        :log info "DNSoMatic: Update needed"
        :set previousIP $currentIP
        
# The update URL. Note the "\3F" is hex for question mark (?). Required since ? is a special character in commands.
        :local url "http://updates.dnsomatic.com/nic/update\3Fmyip=$currentIP&wildcard=NOCHG&mx=NOCHG&backmx=NOCHG"
        :local matichostarray;
        :set matichostarray [:toarray $matichost];
        :foreach host in=$matichostarray do={
            :log info "DNSoMatic: Sending update for $host"
            /tool fetch url=($url . "&hostname=$host") user=$maticuser password=$maticpass mode=http dst-path=("dnsomaticupdate-" . $host . ".txt")
            :log info "DNSoMatic: Host $host updated on DNSoMatic with IP $currentIP"
        }
    }  else={
        :log info "DNSoMatic: Previous IP $previousIP and current IP equal, no update need"
    }
} else={
    :log info "DNSoMatic: $inetinterface is not currently running, so therefore will not update."
}
This will also need you to configure scheduler entry for periodical runs (maybe every minute or so). You will probably want a second scheduler event run this script upon RouterOS startup.
If for whatever reason the update fails, the script will not update DNSoMatic until the IP address changes again. This is rare, but could happen. It would be recommended to set up a third scheduler with longer intervals (maybe 1 hour) to run a script with the following code:
:global previousIP;
:set previousIP ""

:log info "Cleared previousIP to force DNS-O-Matic update on next run."
The following permissions are required for this script to run:
  • write
  • test (for ROS 6.0+)
  • read (for ROS 6.0+)
  • policy (for ROS 6.0+)
It will silently fail if it doesn't have this permission.