Поднимаем VPN через L2TP IPSec на Mikrotik
Долгое время не подходил к настройке VPN на Микротик, т.к. и нужды в реализации этой функции не было, и времени разбираться с настройкой - тоже. Но вот клюнул жареный петух и пришлось. Как выяснилось, сама по себе черновая настройка VPN-сервера посредством L2TP и шифрованием IPSec задача вполне себе тривиальная и решаемая за 10-15 минут.
Итак, начнем мы с определений.
Протокол L2TP - инструмент для обеспечения канала передачи данных, т.н. туннеля. В конечном итоге средство для создания VPN.
IPSec - набор средств для шифрования-дешифрования данных при их прохождении по туннелю.
При настройке мы по большей части будем пользоваться средой приложения Winbox, в нем работать несколько нагляднее, т.к. именно конфигурирование ВПНок подразумевает под собой огромное количество ключей в командах, которые будут хуже восприниматься в портянке текста.
В примере мы возьмем Mikrotik RB2011UAS-2HnD с версией прошивки 6.42.6 (stable) от Jul/06/2018 11:56:50, являющейся для него самой актуальной на момент написания статьи. Пул IP для локалки 192.168.88.0/24, WAN-интерфейс sfp1, локальный бридж зовется просто bridge.
1. Создаем пул IP-адресов для наших будущих VPN-клиентов. IP > Pool
Name: vpn_pool - имя для нового диапазона IP.
Addresses: 192.168.87.0/24 - сам диапазон, также можно указать что-то вроде 192.168.87.10-192.168.87.25, без применения маски.
Next pool: none
2. Идем в PPP > Profiles и создаем профиль для нашего туннеля.
Нас интересуют несколько вкладок.
General:
Name: l2tp_test_profile - название профиля
Local address: vpn_pool (здесь можно указать и шлюз нашего роутера, т.е. 192.168.88.1)
Remote address: vpn_pool - пул раздаваемых IP.
Change TCP MSS: yes
Protocols:
Тут всё выставляем по-умолчанию.
Use MPLS: default
Use compression: default
Use Encription: default
Limits:
Only one: default
3. Заходим в PPP > Secrets, а в этом месте мы настраиваем будущих клиентов нашего VPN-сервера.
Name: vpn_test_user - имя пользователя при подключении к VPN
Password: тут уж сами решайте, это пароль для подключения
Service: l2tp
Profile: l2tp_test_profile
4. PPP > Interface и кликаем на кнопку L2TP Server. Тут мы и включим сервер.
Enabled - yes, это и включает L2TP-сервер
MTU / MRU - 1450, выставляем максимальный размер кадра (фрейма) информации. Без надобности не меняем.
Keepalive Timeout - 30, таймаут в течение которого туннель считается живым и не требует подтверждения в виде соответсвующего фрейма.
Default profile - l2tp_test_profile, указываем созданный ранее профиль.
Authentication - mschap2, метод аутентификации, достаточно оставить только этот.
Use IPSec - yes, использовать ли шифрование? Конечно, указываем - да.
IPSec Secret: придумайте секретку (не путайте с паролем, т.к. секрет - это дополнительный параметр, указываемый на клиентской стороне).
Выше мы подняли L2TP-сервер и включили функцию IPSec, теперь время её настроить.
5. IP > IPSec > Groups
Может быть досадный баг при соединении к серверу с дефолтной группой политик. Создайте свою, у меня это policy_group1.
6. IP > IPSec > Peers, настройка общения пиров IPSec, алгоритма шифрования.
Основные настройки.
Address: 0.0.0.0/0, адрес, оставляем такой.
Port: 500
Auth method: pre shared key, метод аутентификации.
Exchange mode: main l2tp, режим обмена ключами.
Passive: yes, ставим галочку, да.
Secret: да, это всё та же секретка для IPSec, та же, что в пункте 4.
Расширенные настройки.
Policy template group: policy_group1, тот самый шаблон, который мы создали взамен дефолтного.
Send Initial Contact: yes, здесь да.
NAT Traversal: yes, и здесь.
My ID Type: auto
Generate policy: port override
Lifitime: 1d 00:00:00
DPD Interval: 120
DPD Maximum failures: 5
Proposal check: obey
Настройки шифрования.
Hash algorithm: sha1
Encryption Algorithm: 3des aes-128 aes-256
DH Group: modp 1024
7. IP > IPSec > Proposals, так называемы "Предложения".
Как бы объяснить этот момент? Скажем так, это то, какие варианты/опции подключения сможет предложить наш сервер подключающимся клиентам.
Никто не мешает создать другой сет предложений, но смысла я не вижу, пройдемся по дефолтному.
Name: default, в случае с сетапом по-умолчанию, имя останется неизменным, попытаетесь поменять - вылетит ошибка.
Auth algorithms: sha1, алгоритм аутентификации.
Enrc. algorithms: 3des, aes-256 cbc, aes-256 ctr, алгоритмы шифрования.
Life time: 00:30:00, время жизни. Как я это понимаю, время между сменами алгоритмов.
PFS Group: mod 1024
Нельзя не отметить, что пункты 6 и 7 частично повторяют друг друга. Вам не показалось. В пунктах 4 и 6 мы ведь тоже дублируем Secret. Зачем? То ли это баг, то ли фича, но при подключении различных клиентов (разные ОС) словно бы учитываются разные части конфига IPSec, так что не ленимся и настраиваем всё. Например, параметр PFS Group, который выставлен на 1024 в одном месте работает для Windows, в другом к примеру для iOS.
Чтобы всё работало как надо требуется настроить пару фильтрующих правил:
Скорее всего у вас по дефолту для политики forward стоит действие drop - chain=forward action=drop, так что потребуется разрешить форвардиться с IP нашего VPN-пула в локалку:
Ура, наш сервер настроен!
Примечание. Вы подняли туннель, узлы за VPN-сервером пингуются с клиентской железки и вроде бы всё должно быть хорошо и прекрасно, но... Если клиентская железка - это Микротик, то просто так хосты за ним ту сетку не увидят:
То есть какой-нибудь ПК с IP 192.168.30.28 не достучится до удаленного сервера/принтера с IP 192.168.31.11
Почему?
Идем в IP > Firewall > NAT:
Если правила настроены так, то всё заработает. Во всем виноват пресловутый маскарадинг. По-умолчанию masquerade настроен для физического WAN-интерфейса, которым может выступать sfp1/ether1/etc., но нам-то нужно, чтобы пользователи могли ходить в интернеты и через L2TP-подключение! Поэтому нужно создать следующее правило:
Chain=srcnat
Out. Interface=l2tp_client
Action=masquerade
Ну, теперь уж точно всё.
Эта часть статьи будет периодически дополняться различными нюансами, с которыми я столкнулся при настройке туннелей.
Настройка маршрутизации.
Довольно очевидный момент, если у вас две разнесенные сетки, то пакетам нужно знать, что для них будет шлюзом. Настройка простая и логичная, вот у нас имеются две подсети - 192.168.30.0/24 и 192.168.31.0/24, которые очень хотят общаться друг с другом, но не могут. Идем в IP > Route и тыкаем на плюсик, чтобы создать новый маршрут. В качестве Dst.Address укажем сеть, в которую нам нужно отправлять трафик, а Gateway - это будет l2tp-интерфейс.
Попробуйте пингануть хост за одним роутером с хоста за другим. Вам это вряд ли удастся, т.к. отсутствует обратный маршрут для ICMP-пакетов, нужно создать похожий route на другом маршрутизаторе, но с указанием второй сети.
В общем создание masquerade в NAT будет недостаточно.
Проблема NAT
Точнее это даже не проблема, а следствие настройки. Создавая правило с действием masquerade для out-interface L2TP мы сталкиваемся с тем, что уходящие с него пакеты меняют свой родной src.address из пулов 192.168.30.0/24 и 192.168.31.0/24 на IP, который присвоен L2TP-соединению.
Допустим, L2TP соединениям присваиваются IP из пула 192.168.29.0/24, и вот поднятому виртуальному интерфейсу выдан IP 192.168.29.252. Пакеты по велению раут-таблицы лезут на него и теряют свои уникальные src.address 192.168.31.51...52...251...etc., они заменятся адресом интерфейса из VPN-пула. Здесь и возникает проблема. Устройство на другой стороне будет пытаться адресовать ответный трафик не оригинальному IP, а всё тому же адресу L2TP-интерфейса. Всему виной правило NAT превратившее всё многообразие хостов 192.168.31.0/24 в скромный 192.168.29.252:
Просто отключить правило? Но тогда для хостов вообще упадет железный занавес. Нужно разрешить пакетам ходить туда, но продиктовать более удобные условия визы. Разберемся во всех вариантах натирования трафика мы в следующий раз, а пока по нашему вопросу.
Вместо masquerade нужно использовать просто action=accept. В чем разница? Маскарад заменяет адрес отправителя на первый адрес out-interface, который в нашем случае является айпишником туннеля. А вот действие accept, говорит, что пакеты обрабатывать не нужно, как раз таки это является залогом правильной работы IPSec. Вот и всё, в итоге правило должно выглядеть так:
Proxy ARP на локальном бридже
Вот настроили вы свою уютную впнку, и прекрасно пингуете с хоста в сетке 192.168.30.0/24 шлюз 192.168.31.1, но больше ничего из удаленной сети вам недоступно. С чем это связано? С дефолтными настройками роутеров может не взлететь по причине неверной настройки параметра ARP на локальном бридже. Открываем раздел меню Bridge и выбираем мост, объединяющий локальные интерфейсы. В окне его настройки ищем строчку ARP и ставим параметр proxy-arp.
Баг с политикой default
Выше уже говорилось об этом, но стоит еще раз заострить внимание на данном моменте. Характерным признаком данной ошибки будут сообщения в логе Микротика "failed to pre-process ph2 packet", а клиент Windows при этом будет выдавать ошибку 789 запуска VPN-сессии, гласящую, что "попытка L2TP-подключения не удалась из-за ошибки, произошедшей на уровне безопасности".
Что делаем?
Идем в IP > IPSec > Groups и там создаем новую политику, которую после указываем в IP > IPSec > Peers вместо дефолтной в поле Policy Template Group.
Также вариантом лечения является данный фокус:
Данный баг является рудиментом со старых билдов прошивки и проявляется не всегда.
Разного рода ошибки Firewall
И здесь речь не только о самом Микротике, но и о настройках брандмауэра/антивируса у хоста, шлюза клиента или прокси провайдера. Говоря о правилах firewall самого микротика, создать проблемы могут не только правила из цепочки input, но и из цепочки forward... Вы же, очевидно, настроили файрволл так, чтобы быть за ним как за каменной стеной? Ну, и о NAT тоже не стоит забывать. Дебажить всё это хозяйство поможет встроенный инструмент сниффинга трафика, а развернуть дамп можно в Wireshark.
Проблема при реконнекте VPN-сессии
Казалось бы, что страшного, ну отвалился туннель - поднимется же? Поднимется, конечно, но на стороне сервера каждый раз будет создаваться новый динамический интерфейс (с тем же самым названием, но не обманывайтесь). Ведет это к печальным последствиям - все правила и маршруты завязанные на l2tp-интерфейсе нафиг отваливаются, потому что он становится unreachable. А потом восстав из пепла новый интерфейс со старым названием чудесным образом во все эти правила и маршруты не попадает - всё приходится делать вручную.
А склады стоят и местные админы вам названивают. Что делать? Вариантов тут два. Либо настраивать OSPF на роутерах, чтобы все нужные нам маршруты вываливались на соседей автоматически при поднятии туннеля. Но это несколько более сложный вариант. Куда как проще запилить вместо динамического интерфейса постоянный созданный руками.
Для этого заходим на Микротик со стороны сервера и тыкаем в PPP. Далее жмем плюсик и выбирает L2TP Server Binding, после чего вбиваем туда данные из вкладки Secrets (оттуда нам потребуется имя пользователя). Ну, и название интерфейсу нужно будет дать.
Всё, это победа. Остается пройтись по правилам и маршрутам, чтобы подставить везде новый интерфейс.
Итак, начнем мы с определений.
Протокол L2TP - инструмент для обеспечения канала передачи данных, т.н. туннеля. В конечном итоге средство для создания VPN.
IPSec - набор средств для шифрования-дешифрования данных при их прохождении по туннелю.
При настройке мы по большей части будем пользоваться средой приложения Winbox, в нем работать несколько нагляднее, т.к. именно конфигурирование ВПНок подразумевает под собой огромное количество ключей в командах, которые будут хуже восприниматься в портянке текста.
В примере мы возьмем Mikrotik RB2011UAS-2HnD с версией прошивки 6.42.6 (stable) от Jul/06/2018 11:56:50, являющейся для него самой актуальной на момент написания статьи. Пул IP для локалки 192.168.88.0/24, WAN-интерфейс sfp1, локальный бридж зовется просто bridge.
Настройка туннеля L2TP
1. Создаем пул IP-адресов для наших будущих VPN-клиентов. IP > Pool
Name: vpn_pool - имя для нового диапазона IP.
Addresses: 192.168.87.0/24 - сам диапазон, также можно указать что-то вроде 192.168.87.10-192.168.87.25, без применения маски.
Next pool: none
2. Идем в PPP > Profiles и создаем профиль для нашего туннеля.
Нас интересуют несколько вкладок.
General:
Name: l2tp_test_profile - название профиля
Local address: vpn_pool (здесь можно указать и шлюз нашего роутера, т.е. 192.168.88.1)
Remote address: vpn_pool - пул раздаваемых IP.
Change TCP MSS: yes
Protocols:
Тут всё выставляем по-умолчанию.
Use MPLS: default
Use compression: default
Use Encription: default
Limits:
Only one: default
3. Заходим в PPP > Secrets, а в этом месте мы настраиваем будущих клиентов нашего VPN-сервера.
Name: vpn_test_user - имя пользователя при подключении к VPN
Password: тут уж сами решайте, это пароль для подключения
Service: l2tp
Profile: l2tp_test_profile
4. PPP > Interface и кликаем на кнопку L2TP Server. Тут мы и включим сервер.
Enabled - yes, это и включает L2TP-сервер
MTU / MRU - 1450, выставляем максимальный размер кадра (фрейма) информации. Без надобности не меняем.
Keepalive Timeout - 30, таймаут в течение которого туннель считается живым и не требует подтверждения в виде соответсвующего фрейма.
Default profile - l2tp_test_profile, указываем созданный ранее профиль.
Authentication - mschap2, метод аутентификации, достаточно оставить только этот.
Use IPSec - yes, использовать ли шифрование? Конечно, указываем - да.
IPSec Secret: придумайте секретку (не путайте с паролем, т.к. секрет - это дополнительный параметр, указываемый на клиентской стороне).
Настройка шифрования данных, IPSec
Выше мы подняли L2TP-сервер и включили функцию IPSec, теперь время её настроить.
5. IP > IPSec > Groups
Может быть досадный баг при соединении к серверу с дефолтной группой политик. Создайте свою, у меня это policy_group1.
6. IP > IPSec > Peers, настройка общения пиров IPSec, алгоритма шифрования.
Основные настройки.
Address: 0.0.0.0/0, адрес, оставляем такой.
Port: 500
Auth method: pre shared key, метод аутентификации.
Exchange mode: main l2tp, режим обмена ключами.
Passive: yes, ставим галочку, да.
Secret: да, это всё та же секретка для IPSec, та же, что в пункте 4.
Расширенные настройки.
Policy template group: policy_group1, тот самый шаблон, который мы создали взамен дефолтного.
Send Initial Contact: yes, здесь да.
NAT Traversal: yes, и здесь.
My ID Type: auto
Generate policy: port override
Lifitime: 1d 00:00:00
DPD Interval: 120
DPD Maximum failures: 5
Proposal check: obey
Настройки шифрования.
Hash algorithm: sha1
Encryption Algorithm: 3des aes-128 aes-256
DH Group: modp 1024
7. IP > IPSec > Proposals, так называемы "Предложения".
Как бы объяснить этот момент? Скажем так, это то, какие варианты/опции подключения сможет предложить наш сервер подключающимся клиентам.
Никто не мешает создать другой сет предложений, но смысла я не вижу, пройдемся по дефолтному.
Name: default, в случае с сетапом по-умолчанию, имя останется неизменным, попытаетесь поменять - вылетит ошибка.
Auth algorithms: sha1, алгоритм аутентификации.
Enrc. algorithms: 3des, aes-256 cbc, aes-256 ctr, алгоритмы шифрования.
Life time: 00:30:00, время жизни. Как я это понимаю, время между сменами алгоритмов.
PFS Group: mod 1024
Нельзя не отметить, что пункты 6 и 7 частично повторяют друг друга. Вам не показалось. В пунктах 4 и 6 мы ведь тоже дублируем Secret. Зачем? То ли это баг, то ли фича, но при подключении различных клиентов (разные ОС) словно бы учитываются разные части конфига IPSec, так что не ленимся и настраиваем всё. Например, параметр PFS Group, который выставлен на 1024 в одном месте работает для Windows, в другом к примеру для iOS.
Дополнительная настройка Firewall
Чтобы всё работало как надо требуется настроить пару фильтрующих правил:
/ip firewall filter
add chain=input action=accept protocol=udp port=1701,500,4500
add chain=input action=accept protocol=ipsec-esp
Скорее всего у вас по дефолту для политики forward стоит действие drop - chain=forward action=drop, так что потребуется разрешить форвардиться с IP нашего VPN-пула в локалку:
/ip firewall filter
add chain=forward action=accept src-address=192.168.87.0/24 in-interface=!sfp1 out-interface=bridge comment="allow vpn to lan" log=no log-prefix=""
Ура, наш сервер настроен!
Примечание. Вы подняли туннель, узлы за VPN-сервером пингуются с клиентской железки и вроде бы всё должно быть хорошо и прекрасно, но... Если клиентская железка - это Микротик, то просто так хосты за ним ту сетку не увидят:
{192.168.30.0/24} <> L2TP Client <-tunnel-> L2TP Server <> {192.168.31.0/24}
То есть какой-нибудь ПК с IP 192.168.30.28 не достучится до удаленного сервера/принтера с IP 192.168.31.11
Почему?
Идем в IP > Firewall > NAT:
Если правила настроены так, то всё заработает. Во всем виноват пресловутый маскарадинг. По-умолчанию masquerade настроен для физического WAN-интерфейса, которым может выступать sfp1/ether1/etc., но нам-то нужно, чтобы пользователи могли ходить в интернеты и через L2TP-подключение! Поэтому нужно создать следующее правило:
Chain=srcnat
Out. Interface=l2tp_client
Action=masquerade
Ну, теперь уж точно всё.
Нюансы
В этом месте в качестве эпиграфа должен был
быть анекдот про Петьку и Василия Иваныча.
быть анекдот про Петьку и Василия Иваныча.
Эта часть статьи будет периодически дополняться различными нюансами, с которыми я столкнулся при настройке туннелей.
Настройка маршрутизации.
Довольно очевидный момент, если у вас две разнесенные сетки, то пакетам нужно знать, что для них будет шлюзом. Настройка простая и логичная, вот у нас имеются две подсети - 192.168.30.0/24 и 192.168.31.0/24, которые очень хотят общаться друг с другом, но не могут. Идем в IP > Route и тыкаем на плюсик, чтобы создать новый маршрут. В качестве Dst.Address укажем сеть, в которую нам нужно отправлять трафик, а Gateway - это будет l2tp-интерфейс.
Попробуйте пингануть хост за одним роутером с хоста за другим. Вам это вряд ли удастся, т.к. отсутствует обратный маршрут для ICMP-пакетов, нужно создать похожий route на другом маршрутизаторе, но с указанием второй сети.
В общем создание masquerade в NAT будет недостаточно.
Проблема NAT
Точнее это даже не проблема, а следствие настройки. Создавая правило с действием masquerade для out-interface L2TP мы сталкиваемся с тем, что уходящие с него пакеты меняют свой родной src.address из пулов 192.168.30.0/24 и 192.168.31.0/24 на IP, который присвоен L2TP-соединению.
Допустим, L2TP соединениям присваиваются IP из пула 192.168.29.0/24, и вот поднятому виртуальному интерфейсу выдан IP 192.168.29.252. Пакеты по велению раут-таблицы лезут на него и теряют свои уникальные src.address 192.168.31.51...52...251...etc., они заменятся адресом интерфейса из VPN-пула. Здесь и возникает проблема. Устройство на другой стороне будет пытаться адресовать ответный трафик не оригинальному IP, а всё тому же адресу L2TP-интерфейса. Всему виной правило NAT превратившее всё многообразие хостов 192.168.31.0/24 в скромный 192.168.29.252:
[admin@MT1] > ip firewall nat
[admin@MT1] /ip firewall nat> add chain=srcnat out-interface=your_l2tp_connection action=masquerade
Просто отключить правило? Но тогда для хостов вообще упадет железный занавес. Нужно разрешить пакетам ходить туда, но продиктовать более удобные условия визы. Разберемся во всех вариантах натирования трафика мы в следующий раз, а пока по нашему вопросу.
Вместо masquerade нужно использовать просто action=accept. В чем разница? Маскарад заменяет адрес отправителя на первый адрес out-interface, который в нашем случае является айпишником туннеля. А вот действие accept, говорит, что пакеты обрабатывать не нужно, как раз таки это является залогом правильной работы IPSec. Вот и всё, в итоге правило должно выглядеть так:
[admin@MT1] > ip firewall nat
[admin@MT1] /ip firewall nat> add chain=srcnat out-interface=your_l2tp_connection action=accept
Proxy ARP на локальном бридже
Вот настроили вы свою уютную впнку, и прекрасно пингуете с хоста в сетке 192.168.30.0/24 шлюз 192.168.31.1, но больше ничего из удаленной сети вам недоступно. С чем это связано? С дефолтными настройками роутеров может не взлететь по причине неверной настройки параметра ARP на локальном бридже. Открываем раздел меню Bridge и выбираем мост, объединяющий локальные интерфейсы. В окне его настройки ищем строчку ARP и ставим параметр proxy-arp.
Баг с политикой default
Выше уже говорилось об этом, но стоит еще раз заострить внимание на данном моменте. Характерным признаком данной ошибки будут сообщения в логе Микротика "failed to pre-process ph2 packet", а клиент Windows при этом будет выдавать ошибку 789 запуска VPN-сессии, гласящую, что "попытка L2TP-подключения не удалась из-за ошибки, произошедшей на уровне безопасности".
Что делаем?
Идем в IP > IPSec > Groups и там создаем новую политику, которую после указываем в IP > IPSec > Peers вместо дефолтной в поле Policy Template Group.
Также вариантом лечения является данный фокус:
ip ipsec peer set 0 policy-template-group=*FFFFFFFF
Данный баг является рудиментом со старых билдов прошивки и проявляется не всегда.
Разного рода ошибки Firewall
И здесь речь не только о самом Микротике, но и о настройках брандмауэра/антивируса у хоста, шлюза клиента или прокси провайдера. Говоря о правилах firewall самого микротика, создать проблемы могут не только правила из цепочки input, но и из цепочки forward... Вы же, очевидно, настроили файрволл так, чтобы быть за ним как за каменной стеной? Ну, и о NAT тоже не стоит забывать. Дебажить всё это хозяйство поможет встроенный инструмент сниффинга трафика, а развернуть дамп можно в Wireshark.
Проблема при реконнекте VPN-сессии
Казалось бы, что страшного, ну отвалился туннель - поднимется же? Поднимется, конечно, но на стороне сервера каждый раз будет создаваться новый динамический интерфейс (с тем же самым названием, но не обманывайтесь). Ведет это к печальным последствиям - все правила и маршруты завязанные на l2tp-интерфейсе нафиг отваливаются, потому что он становится unreachable. А потом восстав из пепла новый интерфейс со старым названием чудесным образом во все эти правила и маршруты не попадает - всё приходится делать вручную.
А склады стоят и местные админы вам названивают. Что делать? Вариантов тут два. Либо настраивать OSPF на роутерах, чтобы все нужные нам маршруты вываливались на соседей автоматически при поднятии туннеля. Но это несколько более сложный вариант. Куда как проще запилить вместо динамического интерфейса постоянный созданный руками.
Для этого заходим на Микротик со стороны сервера и тыкаем в PPP. Далее жмем плюсик и выбирает L2TP Server Binding, после чего вбиваем туда данные из вкладки Secrets (оттуда нам потребуется имя пользователя). Ну, и название интерфейсу нужно будет дать.
Всё, это победа. Остается пройтись по правилам и маршрутам, чтобы подставить везде новый интерфейс.
Комментариев 3