Более-менее полный туториал, как сделать собственный VPN на базе Mikrotik
В какой-то момент устав от неработающих сайтов решил себе сделать собственный VPN. Так как дома давно трудятся маршрутизаторы Mikrotik, то было все сделано на них. Сам я не являюсь сетевым инженером, поэтому существующие в Интернет инструкции не позволили сделать все за один присест. Туториал ниже позволит кому-то получить рабочий инструмент и погрузиться в интересные мир настройки сетевых устройств.
Условия задачи
Сделать сетевое решение для дома, которое позволит домашним устройствам (телефоны, компьютеры, телевизоры и прочее) бесшовно пользоваться нужными вам интернет-ресурсами со всего мира.
В частности, данное решение одновременно используется дома и на даче. И дома и на даче стоят роутеры Mikrotik разных моделей.
И домашний и дачный роутер изначально были настроены в качестве домашних роутеров с несколькими подключениями по локальной сети и по Wi-Fi. Поэтому настройка локальных сетей не входит в этот материал.
Пусть для простоты сети имеют следующую нумерацию:
Домашняя локальная сеть 192.168.1.0/24
Дачная локальная сеть 192.168.2.0/24
Обе сети должны использовать разную адресацию.
Решение строится на использовании Mikrotik сервере, размещенном на зарубежном VDS, а также построении защищенного туннеля GRE over IPSec.
Шаг 1, создание сервера
Для создания использовался хостинг провайдер <рекламы не будет>. Подойдет любой другой с VDS серверами, который поддерживает развертывание RouterOS CHR.
После покупки сервера VDS необходимо установить на сервер RouterOS CHR (Cloud Hosted Router). Для установки лучше всего использовать готовую инструкцию. Я использовал следующую. И нет, я этим провайдером не пользуюсь, просто инструкция хорошая.
https://ruvds.com/ru/helpcenter/kak-ustanovit-mikrotik-routeros-na-vps/
Для подключения к серверу используем консоль хостера и подключение через KVM.
ВАЖНО. Хостинг провайдер предлагает разные операционные системы на выбор. Как ни странно, но не все операционные системы подходят для такой установки. Поэтому лучше использовать Ubuntu 20 как исходную операционку, с ней точно работает.
Шаг 2, начальная настройка сервера
После того, как прошли по инструкции по установке CHR необходимо подключиться к серверу и установить новый пароль администратора.
После установки пароля пришло время первичной настройки сетевых интерфейсов. Использую команды:
/ip address add address=<адрес от хостера> interface=<интерфейс от хостера>
/ip route add gateway=<гейт от хостера>
/ip dns set servers=8.8.8.8
В этот момент сервер становится доступен из сети Интернет и на него сразу начинают пытаться зайти зловредные боты. Поэтому сразу нужно заблокировать любые подключения извне.
/ip firewall filter add chain=input action=accept connection-state=related,established
/ip firewall filter add chain=forward action=accept connection-state=related,established
/ip firewall filter add chain=input action=drop connection-state=invalid
/ip firewall filter add chain=forward action=drop connection-state=invalid
/ip firewall filter add chain=input action=accept protocol=icmp
/ip firewall filter add chain=input action=drop
/ip firewall filter add chain=forward action=drop
По этой настройке разрешены любые уже установленные соединения. При этом любые проблемные пакеты отбрасываются. Пятое правило разрешает ICMP для диагностики. Последние два правила запрещают входящие соединения, а также любые пакеты адресованные не роутеру.
Следующий шаг предварительной настройки – обновление операционной системы роутера.
/system/package/update/install
/system/reboot
По умолчанию CHR идет в версии 6.х и команда выше обновит ее до новой версии 7.х.
ВАЖНО. Последний шаг предварительной настройки – это установка временной лицензии по инструкции:
https://habr.com/ru/articles/485128/
Без этого шага система будет урезать скорость до 1Mbps, что исключительно мало. Поэтому шаг обязательный.
Если вы уже зарегистрировались на сайте mikrotik.com, то команда следующая:
/system/license/renew
Система готова для дальнейшей настройки.
Шаг 3, настройка IPSec на сервере
Так как на сервере нет локальной сети, то потребуется создать внутреннюю подсеть для дальнейшего использования. Адресация произвольная.
/interface bridge add name=ipsec-bridge
/ip address add address=192.168.3.1/24 interface=ipsec-bridge
Фактически создан loopback интерфейс и ему назначена новая подсеть. Все коммуникации пойдут через нее.
Далее создается профиль для авторизации входящих подключений. Он указывает какие алгоритмы шифрования и хэширования мы принимаем. Аналогично создается предложение с указанием алгоритмов шифрования канала связи. Я использую разные варианты, так как дома и на даче разные по возможностям устройства.
/ip ipsec profile add dh-group=modp1024,modp1536 enc-algorithm=3des,aes-128 name=ipsec-p
/ip ipsec proposal add enc-algorithms=blowfish,3des,aes-128-cbc name=ipsec-p pfs-group=modp1024
Для удобства именую их ipsec-p.
Далее создаю точки для подключения. Так как дома и на даче у меня нет выделенного адреса, то входящая сеть 0.0.0.0/0.
/ip ipsec peer add address=0.0.0.0/0 local-address=<your server IP> passive=yes send-initial-contact=no exchange-mode=main name=peer-home profile=ipsec-p
/ip ipsec peer add address=0.0.0.0/0 local-address=<your server IP> passive=yes send-initial-contact=no exchange-mode=ike2 name=peer-dacha profile=ipsec-p
Также указываю, что сервер только отвечает на подключения (passive=yes send-initial-contact=no), именую точки подключения и указываю созданные выше профили.
ВАЖНО. Важно указать разные exchange-mode для разных подключений. Иначе роутер не сможет подключить одновременно два удаленных подключения. Такая вот особенность.
Следующим шагом надо создать сильные секретные ключи. У меня они очень длинные и рандомно сгенерированы. Ключи могут быть разными.
/ip ipsec identity add peer=peer-home secret="очень длинный ключ 1"
/ip ipsec identity add peer=peer-dacha secret="очень длинный ключ 2"
Последний шаг для создания туннеля – создать политики.
/ip ipsec policy add dst-address=192.168.1.0/24 src-address=192.168.3.0/24 tunnel=yes action=encrypt proposal=ipsec-p peer=peer-home
/ip ipsec policy add dst-address=192.168.2.0/24 src-address=192.168.3.0/24 tunnel=yes action=encrypt proposal=ipsec-p peer=peer-dacha
Политика собирает все вместе – локальный и удаленный адрес, предложение и точку подключения. Также политика говорит, что нужно поднять зашифрованный туннель.
Также я создаю временное правило для маршрутизации данных по этому тоннелю.
/ip route add dst-address=192.168.1.0/24 gateway=%ipsec-bridge
/ip route add dst-address=192.168.2.0/24 gateway=%ipsec-bridge
После поднятия GRE оно будет не нужно.
Шаг 4, настройка файрволла на сервере
Список правил для сервера дан ниже. По факту можно видеть, что часть правил не используется, так что потом можно отключать, посмотрев статистику пакетов по ним.
Все правила даны с учетом того, что у меня локальный интерфейс, подключенный проводом – это ether1.
При настройке файрволла учитывайте, что при добавлении нового правила оно добавляется в конец. Проверка правил идет сверху вниз, поэтому иногда нужно использовать команду /ip/firewall/filter/move <rule #> destination=<target #>
Итак, первый блок правил разрешает входящие подключения IPSec и обмен данными по нему.
/ip firewall filter add chain=input action=accept protocol=udp dst‑port=500,4500 in‑interface=ether1
/ip firewall filter add chain=input action=accept protocol=ipsec‑esp in‑interface=ether1
/ip firewall filter add chain=forward action=accept ipsec‑policy=in,ipsec in‑interface=ether1
/ip firewall filter add chain=input action=accept ipsec‑policy=in,ipsec in‑interface=ether1
Второй блок правил разрешает входящие подключения из наших домашних сетей.
/ip firewall filter add chain=input action=accept src‑address=192.168.1.0/24
/ip firewall filter add chain=input action=accept src‑address=192.168.2.0/24
Для IPSec тоннеля этого должно быть достаточно, но при диагностике подключения могут возникнуть потребности что-то добавить.
Дополнительно нужна будет трансляция адресов из одной сети в другую.
/ip firewall nat add chain=srcnat action=accept src-address=192.168.3.0/24 dst-address=192.168.1.0/24 place-before=0
/ip firewall nat add chain=srcnat action=accept src-address=192.168.3.0/24 dst-address=192.168.2.0/24 place-before=0
Последняя опция place-before=0 говорит о том, что правило должно встать в самый верх. В противном случае, первым сработает трансляция трафика в Интернет.
Шаг 5, начальная настройка домашнего роутера
Нужно повторить почти все то же самое, но на домашнем роутере
/ip ipsec profile add dh-group=modp1024 enc-algorithm= aes-128 hash-algorithm=md5 name=ipsec-p
/ip ipsec proposal add enc-algorithms= aes-128-cbc name=ipsec-p pfs-group=modp1024
/ip ipsec peer add address=<your server IP>/32 exchange-mode=main name=remote-peer profile=ipsec-p
/ip ipsec identity add peer=remote-peer secret="очень длинный ключ 1"
/ip ipsec policy add dst-address=192.168.3.0/24 src-address=192.168.1.0/24 tunnel=yes action=encrypt proposal=ipsec-p peer=remote-peer
/ip route add dst-address=192.168.3.0/24 gateway=%bridge
Здесь использованы сильные методы шифрования, так как у меня домашний роутер с аппаратной поддержкой IPSec AES-128. Без аппаратной поддержки шифрование сильно нагружает процессор.
Важно, чтобы все методы шифрования совпадали на домашнем роутере и на сервере. Также важно, чтобы совпали exchange-mode.
В последней строке использую локальный бридж домашнего роутера. У вас может быть иначе. Это правило также надо будет деактивировать после включения GRE туннеля.
Аналогично серверу, на домашнем роутере потребуется открыть файрволл для корректной работы туннеля. У меня следующие правила. Но, если счетчики показывают, что правило не используется, то можно его отключить.
/ip firewall filter add chain=input action=accept protocol=ipsec-esp
/ip firewall filter add chain=forward action=accept ipsec-policy=in,ipsec
/ip firewall filter add chain=input action=accept ipsec-policy=in,ipsec
/ip firewall filter add chain=forward action=accept connection-state=established,related src-address=192.168.3.0/24 dst-address=192.168.1.0/24
/ip firewall filter add chain=forward action=accept connection-state=established,related src-address=192.168.1.0/24 dst-address=192.168.3.0/24
/ip firewall filter add chain=input action=accept connection-state=established,related src-address=192.168.3.0/24 dst-address=192.168.1.0/24
/ip firewall filter add chain=input action=accept connection-state=established,related src-address=192.168.1.0/24 dst-address=192.168.3.0/24
И также аналогично серверу включаем NAT.
/ip firewall nat add chain=srcnat action=accept src-address=192.168.1.0/24 dst-address=192.168.3.0/24 place-before=0
Шаг 6, проверка работоспособности
В этот момент канал между двумя точками должен установиться и работать. Для проверки есть несколько команд.
/ip ipsec active-peers print
Команда должна показать строку с подключением.
/ip ipsec installed-sa print
Команда должна показать две строки (на сервере могут быть четыре) с установленными ассоциациями безопасности.
Если строк нет, то нужно проверить логи с ошибками.
/log print
Для диагностики можно использовать ping с разных хостов, так как ошибки в настройке могут повлечь недоступность сервера с домашнего роутера, либо из домашней сети.
Шаг 7, GRE туннель поверх IPSec, сервер
Так как IPSec не маршрутизирует, то перенаправить трафик из домашней сети на сервер не получится. Поэтому нужно поверх IPSec поднять дополнительный туннель GRE.
Необходимое условие – и домашний роутер и сервер «видят» друг друга, канал IPSec поднят, можно пинговать друг друга по своим адресам.
Для GRE для обеих точек сначала создается GRE интерфейс с локальным и удаленными адресами. Именуем интерфейсы сознательно.
/interface gre add name=gre-tunnel-home keepalive=10s,10 local-address=192.168.3.1 remote-address=192.168.1.1 allow-fast-path=no
/interface gre add name=gre-tunnel-dacha keepalive=10s,10 local-address=192.168.3.1 remote-address=192.168.2.1 allow-fast-path=no
При этом в самом туннеле GRE мы будем использовать другие IP адреса. Для построения туннеля с домом будет подсеть на 4 адреса 10.1.1.0/30, где адрес 10.1.1.1 будет на стороне сервера, а адрес 10.1.1.2 на стороне домашнего роутера. Аналогично подсеть 10.1.2.0/30 для дачи.
/ip address add address=10.1.1.1/30 interface=gre-tunnel-home
/ip address add address=10.1.2.1/30 interface=gre-tunnel-dacha
Завершает настройку маршрутизация: все обращения к домашним сетям мы направляем в туннель. Старые два маршрута можете убрать или отключить.
/ip route add dst-address=192.168.1.0/24 gateway=10.1.1.2 pref-src=192.168.3.1
/ip route add dst-address=192.168.2.0/24 gateway=10.1.2.2 pref-src=192.168.3.1
Желательно еще проверить, что создался автоматический маршрут до сети 10.1.1.0/30 и 10.1.2.0.30. Для этого запустите команду.
/ip route print
И вы должны увидеть наличие динамического маршрута (флаги DAc) с gateway вида gre-tunnel-home.
Последним шагом нужно открыть доступ к туннелю на файрволле.
/ip firewall filter add chain=input action=accept in-interface=gre-tunnel-home
/ip firewall filter add chain=forward action=accept in-interface=gre-tunnel-home
/ip firewall filter add chain=input action=accept in-interface=gre-tunnel-dacha
/ip firewall filter add chain=forward action=accept in-interface=gre-tunnel-dacha
Шаг 8, GRE туннель поверх IPSec, дом
Все аналогично серверу.
/interface gre add name=gre-tunnel1 keepalive=10s,10 local-address=192.168.1.1 remote-address=192.168.3.1 allow-fast-path=no
/ip address add address=10.1.1.2/30 interface=gre-tunnel1
/ip route add dst-address=192.168.3.0/24 gateway=10.1.1.1 pref-src=192.168.1.1
И файрволл.
/ip firewall filter add chain=input action=accept in-interface=gre-tunnel1
/ip firewall filter add chain=forward action=accept in-interface=gre-tunnel1
Также надо проверить наличие динамических маршрутов.
Шаг 9, проверка работы GRE
Если все сделано корректно, настроен туннель, открыт файрволл, то GRE туннель должен начать работать. Для проверки работоспособности можно использовать следующую команду.
/interface gre print
Напротив каждого туннеля должна появиться буква R в статусе. Это Running.
Если этого не произошло, то нужно смотреть статус IPSec туннеля, логи подключения, а также настройки туннеля и файрволла.
Если интерфейсы находятся в состоянии Running, то можно проверить их работу командами с сервера:
/ping 10.1.1.2
/ping 10.1.2.2
/ping 192.168.1.1
/ping 192.168.2.1
Аналогично надо сделать с домашнего роутера и с любого домашнего компьютера:
/ping 10.1.1.1
/ping 192.168.3.1
При это можно посмотреть на счетчики правил файрволла. Они должны увеличиваться для правил связанных с GRE.
/ip firewall filter print stats
Шаг 10, перенаправление трафика
После предыдущих шагов должен получиться работающий туннель между сервером и домашним роутером. Теперь осталось перенаправить выборочный трафик в сторону сервера.
Под перенаправлением лежит механизм маркировки трафика и перенаправление его в другую таблицу маршрутизации.
Для начала нужно создать альтернативную таблицу маршрутизации.
/routing table add fib name=alt-route
Затем настроить для этой таблицы маршрутизации нужные нам маршруты: весь трафик, помеченный для альтернативной таблицы перенаправлять на наш GRE туннель, на сервер.
/ip route add dst-address=0.0.0.0/0 gateway=10.1.1.1 routing-table=alt-route
После этого можно создать таблицу с адресами, в которую заносятся все интересующие нас адреса. На примере ниже можно добавить адреса DNS Google.
/ip firewall address-list add address=8.8.8.0/24 list=alt-list
ВАЖНО. На первом этапе не рекомендую заносить слишком много адресов. Лучше проверить на одном-двух, а затем расширять список.
Теперь осталось промаркировать трафик по заданному списку. Это делается с помощью механизма Mangle.
/ip firewall mangle add chain=prerouting action=mark-routing new-routing-mark=alt-route passthrough=yes src-address=192.168.1.0/24 dst-address-list=alt-list
Команда говорит о том, что на этапе до маршрутизации (prerouting) трафик, который приходит с внутренней подсети и уходит на адреса из alt-list, должен быть промаркирован меткой alt-route. В дальнейшем этот трафик попадет на альтернативную таблицу маршрутизации, а затем – в GRE туннель.
Шаг 11, проверка
Для проверки достаточно с любого домашнего компьютера сделать ping 8.8.8.8 и проверить, что счетчики на правиле Mangle будут увеличиваться.
/ip firewall mangle print stats
Далее добавляйте другие диапазоны адресов в список на перенаправление и можете проверять работу нужных вам ресурсов.
Шаг 12, дополнительный
У меня был вопрос про разные устройства – с аппаратной поддержкой IPSec и без нее. Вот мои замеры производительности. Далее каждый сам для себя решит, какое устройство ему потребуется.
Устройство без аппаратной поддержки IPSec, шифрование Blowfish:
Канал передачи данных от провайдера 40 Mbps
Скорость передачи данных 29 Mbps
Загрузка процессора 100%
Загрузка процессора на сервере 15%
Устройство с аппаратной поддержки IPSec, шифрование AES-128:
Канал передачи данных от провайдера 100 Mbps
Скорость передачи данных 90 Mbps
Загрузка процессора 23%
Загрузка процессора на сервере 30%
Как видно, IPsec в шифровании Blowfish (вроде как довольно слабое), затрачивает 100% времени CPU. С другой стороны, для каких-то решений, 30 мегабит будет вполне достаточно для работы с нужными вам сайтами.
Устройство с аппаратной поддержкой в принципе не имеет ограничений с учетом того, что удаленные серверы для домашнего использования в основном продаются со скоростью канала 100 мегабит.