Переход с OpenVPN на WireGuard для объединения сетей в одну сеть L2
Хотел бы поделиться опытом объединения сетей в трех географически удаленных квартирах, в каждой из которых в качестве шлюза используются роутеры с OpenWRT, в одну общую сеть. При выборе способа объединения сетей между L3 с маршрутизацией подсетей и L2 с бриджингом, когда все узлы сети будут находиться в одной подсети, было отдано предпочтение второму способу, более сложному в настройке, но дающим бОльшие возможности, так как в создаваемой сети планировалось прозрачное использование технологий Wake-on-Lan и DLNA.
Часть 1: Предыстория
В качестве протокола для реализации этой задачи изначально был выбран OpenVPN, так как, во-первых, он может создавать устройство tap, которое без проблем добавляется в мост, а во-вторых, OpenVPN поддерживает работу по протоколу TCP, что было также немаловажно, ведь ни в одной из квартир не имелось выделенного IP-адреса, а использовать STUN мне не удалось, так как мой провайдер почему-то блокирует входящие подключения по протоколу UDP из своих сетей, в то время как протокол TCP позволял мне пробросить порт VPN-сервера на арендуемый VPS при помощи SSH. Да, такой подход дает большую нагрузку, так как данные шифруются дважды, но вводить VPS в свою частную сеть я не захотел, так как оставался риск получения третьими лицами контроля над ним, следовательно, иметь в домашней сети такое устройство являлось крайне нежелательным и было решено заплатить за безопасность большим оверхедом.
Для проброса порта на роутере, на котором планировалось развернуть сервер, была использована программа sshtunnel. Описывать тонкости ее конфигурации не буду — это делается достаточно легко, просто отмечу, что ее задачей был проброс TCP-порта 1194 с роутера на VPS. Далее был настроен сервер OpenVPN на устройстве tap0, которое заводилось в мост br-lan. Проверив подключение к только что созданному серверу с ноутбука — стало понятно, что идея с пробросом порта себя оправдала и мой ноутбук стал членом сети роутера, хотя физически в ней не находился.
Дело оставалось за малым: нужно было распределить IP-адреса в разных квартирах так, чтобы они не конфликтовали и настроить маршрутизаторы в качестве OpenVPN-клиентов.
Были выбраны такие IP-адреса маршрутизаторов и диапазоны DHCP-серверов:
- 192.168.10.1 с диапазоном 192.168.10.2 — 192.168.10.80 для сервера
- 192.168.10.100 с диапазоном 192.168.10.101 — 192.168.10.149 для маршрутизатора в квартире №2
- 192.168.10.150 с диапазоном 192.168.10.151 — 192.168.10.199 для маршрутизатора в квартире №3
и добавлением следующих строк в файл /etc/openvpn/ipp.txt:
где flat1_id и flat2_id — это имена устройств, указываемые при создании сертификатов для подключения к OpenVPN
Далее на роутерах были настроены OpenVPN-клиенты, устройства tap0 на обоих были занесены в мост br-lan. На этом этапе казалось, что все в порядке, так как все три сети видят друг друга и работают как единое целое. Однако, выяснилась не очень приятная деталь: иногда устройства могли получить IP-адрес не от своего маршрутизатора, со всеми вытекающими последствиями. По какой-то причине, маршрутизатор в какой-то из квартир не успевал ответить вовремя на DHCPDISCOVER и устройство получало не свой адрес. Я понял, что мне нужно отфильтровать такие запросы в tap0 на каждом из маршрутизаторов, но, как выяснилось, iptables не может работать с устройством, если оно является частью моста и мне на помощь должен прийти ebtables. К моему сожалению, в моих прошивках его не оказалось и пришлось пересобирать образы для каждого устройства. Сделав это и добавив такие строки в /etc/rc.local каждого маршрутизатора проблема была решена:
Такая конфигурация просуществовала на протяжении трех лет.
Часть 2: Знакомство с WireGuard
В последнее время в Интернете все чаще стали говорить о WireGuard, восхищаясь простотой его конфигурации, высокой скоростью передачи, низким пингом при сопоставимой безопасности. Поиск дополнительной информации о нем давал понять, что ни работа в качестве члена моста, ни работа по протоколу TCP им не поддерживается, что наводило меня на мысли о том, что альтернатив OpenVPN для меня по-прежнему нет. Так я откладывал знакомство с WireGuard.
Несколько дней назад по ресурсам, так или иначе связанным с IT, пролетела новость о том, что WireGuard наконец будет включен в ядро Linux, начиная с версии 5.6. Новостные статьи, как всегда, хвалили WireGuard. Я вновь погрузился в поиски путей замены старого доброго OpenVPN. На этот раз я напоролся на эту статью. В ней говорилось о создании Ethernet-туннеля поверх L3 при помощи GRE. Эта статья вселила в меня надежду. Оставалось неясно что делать с протоколом UDP. Поиск приводил меня к статьям об использовании socat в связке с SSH-туннелем, для проброса UDP-порта, однако, в них отмечалось, что такой подход работает только в режиме одного соединения, то есть работа нескольких VPN-клиентов оказалась бы невозможной. Мне пришла идея поднять VPN-сервер на VPS, а для клиентов настроить GRE, но, как оказалось, GRE не поддерживает шифрование, что приведет к тому, что в случае получения доступа к серверу третьими лицами, в их руках оказывается весь трафик между моими сетями, что меня не устраивало в принципе.
Вновь было принято решение в пользу избыточного шифрования, путем использования VPN поверх VPN по следующей схеме:
VPN первого уровня:
VPS является сервером с внутренним адресом 192.168.30.1
МС является клиентом VPS с внутренним адресом 192.168.30.2
МК2 является клиентом VPS с внутренним адресом 192.168.30.3
МК3 является клиентом VPS с внутренним адресом 192.168.30.4
VPN второго уровня:
МС является сервером с внешним адресом 192.168.30.2 и внутренним 192.168.31.1
МК2 является клиентом МС с адресом 192.168.30.2 и имеет внутренний IP 192.168.31.2
МК3 является клиентом МС с адресом 192.168.30.2 и имеет внутренний IP 192.168.31.3
* МС — маршрутизатор-сервер в квартире 1, МК2 — маршрутизатор в квартире 2, МК3 — маршрутизатор в квартире 3
* Конфигурации устройств опубликованы в спойлере в конце статьи.
И так, пинги между узлами сети 192.168.31.0/24 ходят, пора перейти к настройке GRE-туннеля. Перед этим, дабы не терять доступ к маршрутизаторам, стоит настроить SSH-туннели для проброса 22 порта на VPS, таким образом, что, например, на 10022-ом порту VPS будет доступен маршрутизатор из квартиры 2, а на 11122-порту VPS будет доступен маршрутизатор из квартиры 3. Настройку проброса лучше всего выполнить все тем-же sshtunnel, так как он восстановит туннель в случае его падения.
Туннель настроен, можно подключаться к SSH через проброшенный порт:
Далее следует отключить OpenVPN:
Теперь настроим GRE-туннель на маршрутизаторе из квартиры 2:
И добавим созданный интерфейс в мост:
Аналогичную процедуру выполним на маршрутизаторе-сервере:
И, также, добавим созданный интерфейс в мост:
начиная с этого момента пинги начинают успешно ходить в новую сеть и я, с удовлетворением отправляюсь пить кофе. Затем, чтобы оценить, как работает сеть на другом конце провода, я пытаюсь подключиться по SSH к одному из компьютеров в квартире 2, но ssh-клиент «зависает», не предлагая ввести пароль. Пробую подключиться к этому компьютеру по telnet на 22 порт и вижу строку, из которой можно понять, что соединение устанавливается, SSH-сервер отвечает, просто по какой-то причине не предлагает мне войти.
Пытаюсь подключиться к нему же по VNC и вижу черный экран. Я убеждаю себя, что дело в удаленном компьютере, ведь к маршрутизатору из этой квартиры я спокойно могу подключиться по внутреннему адресу. Однако, я решаю подключиться к SSH этого компьютера через маршрутизатор и с удивлением обнаруживаю, что подключение удается, а удаленный компьютер работает вполне штатно, но при этом также не может подключиться к моему компьютеру.
Я вывожу устройство grelan0 из моста и запускаю OpenVPN на маршрутизаторе в квартире 2 и убеждаюсь, что сеть вновь работает как положено и соединения не обрываются. Поиском натыкаюсь на форумы, где люди жалуются на такие же проблемы, где им советуют поднять MTU. Однако, повысить MTU для VPN первого уровня (wg0) мне не удалось: при MTU выше 1420, который выставляется автоматически, начинаются обрывы, но при этом, VPN второго уровня wg1, работающий поверх wg0, корректно работал с MTU 1600. Этого достаточно для установки MTU в 1500 для устройства gretap, для того чтобы этот интерфейс имел то же значение MTU, что и мост br-lan, в который планировалось добавить gretap. Насколько я понял, мост выставляет MTU равное меньшему из доступных значений на всех устройствах.
Провел аналогичную настройку и на маршрутизаторе из квартиры 3, с той лишь разницей, что на маршрутизаторе сервере добавился второй интерфейс gretap с именем grelan1, который также был добавлен в мост br-lan.
Все работает. Теперь можно поместить сборку gretap в автозагрузку. Для этого:
Поместил эти строки в /etc/rc.local на маршрутизаторе в квартире 2:
Добавил это в /etc/rc.local на маршрутизаторе в квартире 3:
И на маршрутизаторе-сервере:
После перезагрузки клиентских роутеров я обнаружил, что они по какой-то причине не подключаются к серверу. Подключившись к их SSH (благо, я предварительно настроил sshtunnel для этого) было обнаружено, что WireGuard зачем-то создает маршрут для endpoint, при этом неверный. Так, для 192.168.30.2 в таблице маршрутов был указан маршрут через интерфейс pppoe-wan, то есть через интернет, хотя маршрут до него должен был быть направлен через интерфейс wg0. После удаления этого маршрута соединение восстановилось. Найти где-то инструкций о том, как заставить WireGuard не создавать этих маршрутов мне не удалось. Более того, я даже не понял, особенность это OpenWRT, либо самого WireGuard. Не став долго разбираться с этой проблемой, я просто добавил на оба роутера в скрипт, зацикленный по таймеру, строку удалявшую этот маршрут:
Подводя итоги
Полного отказа от OpenVPN я пока не добился, так как мне нужно иногда подключаться к новой сети с ноутбука, либо телефона, а настройка gretap устройства на них в общем случае невозможна, но, несмотря на это, я получил преимущество в скорости передачи данных между квартирами и, например, использование VNC теперь не доставляет неудобств. Пинг уменьшился незначительно, но стал более стабильным:
При использовании OpenVPN:
При использовании WireGuard:
На него в большей степени влияет высокий пинг до VPS, который составляет примерно 61.5 мс
Однако, скорость увеличилась значительно. Так, в квартире с маршрутизатором-сервером я имею скорость подключения к Интернету 30 мбит/сек, а в остальных квартирах по 5 мбит/сек. При этом, во время использования OpenVPN мне не удавалось достичь скорости передачи данных между сетями больше 3,8 мбит/сек по показаниями iperf, в то время как WireGuard «прокачал» ее до тех же 5 мбит/сек.
[Interface]
Address = 192.168.30.1/24
ListenPort = 51820
PrivateKey = <ЗАКРЫТЫЙ_КЛЮЧ_ДЛЯ_VPS>
[Peer]
PublicKey = <ОТКРЫТЫЙ_КЛЮЧ_VPN_1_МС>
AllowedIPs = 192.168.30.2/32
[Peer]
PublicKey = <ОТКРЫТЫЙ_КЛЮЧ_VPN_2_МК2>
AllowedIPs = 192.168.30.3/32
[Peer]
PublicKey = <ОТКРЫТЫЙ_КЛЮЧ_VPN_2_МК3>
AllowedIPs = 192.168.30.4/32
В описанных конфигурациях для VPN второго уровня я указываю клиентам WireGuard порт 51821. По идее это не нужно, так как клиент установит соединение с любого свободного непривилегированного порта, но я сделал так, чтобы можно было запретить все входящие соединения на интерфейсах wg0 всех маршрутизаторов, кроме входящих UDP-соединений на порт 51821.
Объединение локальных сетей на оборудовании Mikrotik
Одной из довольно распространенных задач, встающих перед администраторами сетей, например на предприятиях, является задача по объединению двух различных сетей, с полноценной маршрутизацией.
Если в качестве маршрутизаторов для этих сетей, используются оборудование компании Mikrotik, то реализация этой задачи, не займет много времени.
Предположим, что у нас есть две локальные сети. 192.168.0.0/24 и 192.168.2.0/24, частью которых, являются роутеры под управлением Mikrotik RouterOS level 6, с IP адресами 192.168.0.1 и 192.168.2.1 соответственно. Для объединения их в одну маршрутизируемую сеть, в качестве передающей среды, мы будем использовать виртуальную сеть VLAN, где в качестве шлюза для соседней сети, будет использоваться соответствующий интерфейс имеющий адрес с сетевой маской /32. Топологически, это будет выглядеть так:

Предположим, что мы соединили оба роутера RouterBoard Mikrotik через порты ether5.
Начнем настройку с Router A, который работает в сети 192.168.0.0/24, и имеет IP адрес 192.168.0.1.
Первое, что мы делаем, это создаем виртуальную сеть VLAN. Открываем раздел Interfaces и переходим на вкладку VLAN. Добавляем новую запись с такими параметрами: Name — можем оставить без изменений vlan1, VLAN ID — 2, ставим 2 или любое другое число. И Interface — ether5, так как мы решили, что роутеры у нас будут объединены портами №5.

Далее в разделе IP Addresses мы добавляем новый адрес для только что созданного виртуального интерфейса. В поле Address мы вписываем IP нашего роутера с маской /32 — 192.168.0.1/32, в поле Network мы указываем IP второго роутера Router B — 192.168.2.1 и в качестве интерфейса, выбираем vlan1.

Последнее, что нам надо сделать, это добавить новый маршрут в разделе IP Routes.
Здесь на вкладке Routes, добавляем новое правило маршрутизации, где в качестве Dst.Addresses мы укажем префикс соседней сети — 192.168.2.0/24, а в качестве Gateway — 192.168.2.1, IP адрес соседнего роутера.

На этом настройку Router A, можно считать законченной. Переходим к настройке второго роутера Router B. В принципе, нам надо сделать точно такие же операции, только с другими IP адресами.
Открываем раздел Interfaces и на вкладке VLAN, добавляем новую запись с такими же параметрами, как и в первый раз. Name — оставляем без изменений vlan1, VLAN ID — 2, должен совпадать с этим же значением Router A, и Interface — ether5.

Как и в первом случае, следующий шаг, это назначение IP адреса для интерфейса vlan1. В разделе IP Addresses, добавляем новый адрес. В поле Address мы вписываем IP нашего роутера с маской /32 — 192.168.2.1/32, а вот в поле Network мы указываем IP первого роутера Router A — 192.168.0.1, в качестве интерфейса, выбираем vlan1.

И закончим настройку, добавлением нового маршрута. В разделе IP Routes, на вкладке Routes, добавляем новое правило маршрутизации, где в качестве Dst.Addresses мы укажем префикс соседней сети — 192.168.0.0/24, а в качестве Gateway — 192.168.0.1, IP адрес первого роутера.

Теперь наши две сети объединены и мы можем иметь доступ с одной сети к ресурсам другой.
Объединение сегментов сети статическими маршрутами
Цель этого руководства — объяснить, как объединить разные сегменты сети (подсети) вместе, используя статические маршруты для пересылки трафика в нужную подсеть другого маршрутизатора. Не будем вдаваться в подробности подсетей в целом, хотя скажем, что использование подсетей имеет такие преимущества, как уменьшение сетевого трафика (меньше широковещательных кадров) и улучшение контроля доступа между узлами. Важно отметить, что связывание подсетей называется маршрутизацией, а используемые для этого интерфейсы не должны быть объединены в сетевой мост с любыми другими для правильной работы.
[edit] Создание подсетей
Существует множество способов создания подсетей в DD-WRT. По умолчанию только порт WAN не объединен в сетевой мост с другими интерфейсами, а коммутатор LAN (который является аппаратным мостом) и беспроводные интерфейсы объединены друг с другом программным обеспечением.
Способы создания дополнительных подсетей включают в себя:
- Задайте для беспроводного интерфейса значение «Unbridged», чтобы он не был объединен в сетевой мост с интерфейсами LAN коммутатора.
- Настройте VLAN, если коммутатор поддерживает их.
- Добавьте виртуальные интерфейсы к любому существующему интерфейсу, который может преодолеть аппаратные ограничения, такие как коммутаторы без поддержки VLAN.
[edit] Пример
Теперь предположим, что у вас есть три маршрутизатора Router1..3, соединенных вместе. Порт WAN маршрутизатора Router1 подключен к Интернету, что делает его шлюзом всей локальной сети, а маршрутизаторы Router2 и 3 имеют порты WAN, подключенные к портам LAN Router1. Маршрутизатор Router2 и/или 3 также может использовать режим клиента (Client mode) или повторителя (Repeater mode) (без сетевого моста!).
По умолчанию все эти маршрутизаторы будут работать в режиме маршрутизации ‘Gateway’ («Шлюз»), что означает, что они выполняют преобразование сетевых адресов (Network Address Translation, NAT), что делает компьютеры в подсети LAN невидимыми со стороны интерфейса WAN. Поскольку каждый маршрутизатор имеет интерфейс, подключенный к подсети 192.168.1.0/24, все они имеют маршруты к этой подсети. Однако маршрутизатор Router1 не имеет маршрута к 192.168.2.0/24 или 192.168.3.0/24, Router2 не имеет маршрута к 192.168.3.0/24, а Router3 не имеет маршрута к 192.168.2.0/24.
[edit] Настройка статических маршрутов
Для этой конкретной топологии только маршрутизатор Router1 должен быть настроен со статическими маршрутами, потому что у двух других есть маршруты по умолчанию, которые указывают им направлять трафик к Router1 для любой подсети, к которой у них явно нет маршрутов.
Статические маршруты настраиваются со следуюшими параметрами на странице Setup → Advanced Routing веб-интерфейса DD-WRT:
- Destination LAN NET — удаленная подсеть, для которой вы создаете маршрут.
- Subnet Mask — маска подсети удаленной подсети. Как правило, используется маска подсети класса C 255.255.255.0, которая в нотации CIDR равна /24, как показано на изображении выше.
- Gateway — адрес шлюза по умолчанию, который должен быть задан как IP-адрес следующего перехода к подсети назначения. В нашем случае это IP-адрес интерфейса WAN маршрутизаторов Router2 и Router3. В сетях с большим количеством устройств следующим переходом может не быть устройство, напрямую подключенное к целевой подсети, на пути к ней могут быть еще несколько сегментов сети с маршрутизаторами.
- Interface — это должен быть интерфейс, к которому подключен следующий переход. В нашем примере маршрутизаторы Router2 и Router3 подключены к интерфейсу LAN/WLAN (br0) маршрутизатора Router1.
Настройте маршрутизатор Router1 так, как указано на следующих изображениях:
С настроенными статическими маршрутами теперь можно безопасно отключить преобразование сетевых адресов NAT на маршрутизаторах Router2 и Router3, переключив их режим работы Operating Mode с «Gateway» на «Router» на странице Setup → Advanced Routing веб-интерфейса.
Также понадобится использовать команды Iptables, чтобы разрешить трафик через брандмауэры маршрутизаторов Router2 и Router3, чтобы обеспечить полноценную связь между подсетями. Команды Iptables необходимо сохранить в сценарии брандмауэра (firewall script) на странице Administration → Commands веб-интерфейса. Вот несколько примеров того, как это можно сделать:
[edit] Готово
Если вы всё сделали правильно — настроили маршруты и брандмауэры, то теперь устройства в разных сегментах сети смогут общаться друг с другом, не полагаясь на мостовые соединения. Если на компьютерах сети установлены программные брандмауэры, возможно, нужно будет их настроить или отключить, чтобы разрешить подключения из других подсетей.
Если вы хотите, чтобы компьютеры отображались в сетевом окружении Windows, необходимо настроить сервер WINS и настроить DHCP-сервер для объявления сервера WINS.
Соединить часть компов из разных подсетей.
Всем здравствуйте! Подсобите советом, пожалуйста. Две подсети 192.168.0.0 и 192.168.10.0 как их соединить так, чтобы 2 компа из одной видели 2 компа из другой, а другие не подозревали о существовании другой подсети? Как это проще сделать? Сети в одном здании. Есть dir-300 c dd-wrt, шлюз в .10.1 это zeroshell. 0.1 — dir100.

другие не подозревали о существовании другой подсети
Делить vlan’ами. Как это сделать следует смотреть из документации к роутерам. Клиенты должны знать только о своих шлюзах (10.1 и 0.1), а вот шлюзы уже будут обмениваться пакетами между подсетями.


т.е на шлюзах тоже надо маршруты указывать?

так это еще vpn настраивать, а поверх потом все равно vlan’ы и iptables? Я же вместо vpn могу физически соединить две сети.

Из пушек да по воробьям. Выше правильно ответили — объединить виланами.

Как вам уже написали, компьютеры и не должны знать о существовании другой сети, весь трафик они должны отправлять в шлюз, а тот должен отправлять его другому шлюзу. Поэтому сначла нужна связь между шлюзами, как вы её будете делать решать вам. Может в здании уже есть локальная сеть или шлюзы подключены к одному провадеру, может проще кабель протянуть.
После этого указываете на шлюзах маршруты в другую подсеть через другой шлюз и на обоих шлюзах (или на одном) разрешаете прохождения трафика от нужных компов к нужным. Если у вас пользователи не могут сами поменять ip-адреса и они не меняются, то этого достаточно. А если там царит свобода, то брать «умный» свич, делать vlan’ы и, фактически, предоставляя доступ в другую сеть не компьютеру, а порту коммутатора. А если там и кабеле перетыкают, то делать для нужных компов VPN.
И что подразумевается под:
Пинговать они будут, а в сетевом окружении не появятся, особенно если там домен (AD).