Миграция от OpenVPN към WireGuard за консолидиране на мрежи в една L2 мрежа

Миграция от OpenVPN към WireGuard за консолидиране на мрежи в една L2 мрежа

Бих искал да споделя опита си от комбинирането на мрежи в три географски отдалечени апартамента, всеки от които използва рутери с OpenWRT като шлюз, в една обща мрежа. При избора на метод за комбиниране на мрежи между L3 с подмрежово маршрутизиране и L2 с мостово свързване, когато всички мрежови възли ще бъдат в една и съща подмрежа, се дава предпочитание на втория метод, който е по-труден за конфигуриране, но предоставя повече възможности, тъй като прозрачен използването на технологиите беше планирано в създадената мрежа Wake-on-Lan и DLNA.

Част 1: Предистория

OpenVPN първоначално беше избран като протокол за изпълнение на тази задача, тъй като, първо, той може да създаде кран устройство, което може да бъде добавено към моста без никакви проблеми, и второ, OpenVPN поддържа работа през TCP протокола, което също беше важно, т.к. нито един от апартаментите нямаше специален IP адрес и не успях да използвам STUN, защото по някаква причина моят ISP блокира входящите 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 за рутер в апартамент No2
  • 192.168.10.150 с диапазон 192.168.10.151 - 192.168.10.199 за рутер в апартамент No3

Също така беше необходимо да се присвоят точно тези адреси на клиентските рутери на OpenVPN сървъра, като се добави редът към неговата конфигурация:

ifconfig-pool-persist /etc/openvpn/ipp.txt 0

и добавяне на следните редове към файла /etc/openvpn/ipp.txt:

flat1_id 192.168.10.100
flat2_id 192.168.10.150

където flat1_id и flat2_id са имената на устройствата, посочени при генериране на сертификати за свързване към OpenVPN

След това OpenVPN клиентите бяха конфигурирани на рутерите, устройствата tap0 и на двата бяха добавени към br-lan моста. На този етап всичко изглеждаше наред, тъй като и трите мрежи се виждат и работят като едно цяло. Оказа се обаче една не много приятна подробност: понякога устройствата могат да получат IP адрес не от своя рутер, с всички произтичащи от това последствия. По някаква причина рутерът в един от апартаментите не е имал време да отговори навреме на DHCPDISCOVER и устройството е получило грешен адрес. Разбрах, че трябва да филтрирам такива заявки в tap0 на всеки от рутерите, но както се оказа, iptables не може да работи с устройство, ако е част от мост и ebtables трябва да ми помогне. За мое съжаление не беше във фърмуера ми и трябваше да компилирам отново изображенията за всяко устройство. Като направите това и добавите тези редове към /etc/rc.local на всеки рутер, проблемът беше решен:

ebtables -A INPUT --in-interface tap0 --protocol ipv4 --ip-protocol udp --ip-destination-port 67:68 -j DROP
ebtables -A INPUT --in-interface tap0 --protocol ipv4 --ip-protocol udp --ip-source-port 67:68 -j DROP
ebtables -A FORWARD --out-interface tap0 --protocol ipv4 --ip-protocol udp --ip-destination-port 67:68 -j DROP
ebtables -A FORWARD --out-interface tap0 --protocol ipv4 --ip-protocol udp --ip-source-port 67:68 -j DROP

Тази конфигурация продължи три години.

Част 2: Представяне на WireGuard

Напоследък Интернет все повече говори за WireGuard, възхищавайки се на простотата на неговата конфигурация, висока скорост на трансфер, нисък ping със сравнима сигурност. Търсенето на повече информация за него стана ясно, че нито работата като член на моста, нито работата по TCP протокола се поддържа от него, което ме накара да мисля, че все още няма алтернативи на OpenVPN за мен. Затова отложих запознаването с WireGuard.

Преди няколко дни новината се разпространи сред ресурси, по един или друг начин свързани с ИТ, че WireGuard най-накрая ще бъде включен в ядрото на Linux, започвайки с версия 5.6. Новинарските статии, както винаги, възхваляваха WireGuard. Отново се потопих в търсенето на начини да заменя добрия стар OpenVPN. Този път попаднах на тази статия. Говореше се за създаване на Ethernet тунел над L3 с помощта на GRE. Тази статия ми даде надежда. Остана неясно какво да правим с UDP протокола. Търсенето ме доведе до статии за използването на socat във връзка със SSH тунел за препращане на UDP порт, но те отбелязаха, че този подход работи само в режим на единична връзка, което означава, че множество VPN клиенти биха били невъзможни. Дойдох с идеята да настроя VPN сървър на VPS и да настроя GRE за клиенти, но както се оказа, GRE не поддържа криптиране, което ще доведе до факта, че ако трети страни получат достъп до сървъра , целият трафик между моите мрежи е в техни ръце, което изобщо не ме устройваше.

Отново решението беше взето в полза на излишно криптиране, чрез използване на VPN през VPN съгласно следната схема:

Слой XNUMX VPN:
VPS е сървър с вътрешен адрес 192.168.30.1
MS е клиент VPS с вътрешен адрес 192.168.30.2
MK2 е клиент VPS с вътрешен адрес 192.168.30.3
MK3 е клиент VPS с вътрешен адрес 192.168.30.4

Слой XNUMX VPN:
MS е сървър с външен адрес 192.168.30.2 и вътрешен 192.168.31.1
MK2 е клиент MS с адрес 192.168.30.2 и има вътрешен IP 192.168.31.2
MK3 е клиент MS с адрес 192.168.30.2 и има вътрешен IP 192.168.31.3

* MS - рутер-сървър в апартамент 1, MK2 - рутер в апартамент 2, MK3 - рутер в апартамент 3
* Конфигурациите на устройствата са публикувани в спойлера в края на статията.

И така, пинговете между възлите на мрежата 192.168.31.0/24 вървят, време е да преминете към настройка на GRE тунела. Преди това, за да не загубите достъп до рутери, струва си да настроите SSH тунели за пренасочване на порт 22 към VPS, така че например рутер от апартамент 10022 да бъде достъпен на порт 2 на VPS и a рутер от апартамент 11122 ще бъде достъпен на порт 3 на VPS рутер от апартамент XNUMX. Най-добре е да конфигурирате препращането със същия sshtunnel, тъй като той ще възстанови тунела в случай, че падне.

Тунелът е конфигуриран, можете да се свържете към SSH през пренасочения порт:

ssh root@МОЙ_VPS -p 10022

След това деактивирайте OpenVPN:

/etc/init.d/openvpn stop

Сега нека настроим GRE тунел на рутера от апартамент 2:

ip link add grelan0 type gretap remote 192.168.31.1 local 192.168.31.2
ip link set grelan0 up

И добавете създадения интерфейс към моста:

brctl addif br-lan grelan0

Нека изпълним подобна процедура на рутера на сървъра:

ip link add grelan0 type gretap remote 192.168.31.2 local 192.168.31.1
ip link set grelan0 up

И също така добавете създадения интерфейс към моста:

brctl addif br-lan grelan0

от този момент пинговете започват успешно да отиват в новата мрежа и аз със задоволство отивам да пия кафе. След това, за да видя как работи мрежата от другия край на кабела, се опитвам да вляза SSH в един от компютрите в апартамент 2, но ssh клиентът замръзва, без да ме подкани за парола. Опитвам се да се свържа с този компютър чрез telnet на порт 22 и виждам ред, от който можете да разберете, че връзката се установява, SSH сървърът отговаря, но по някаква причина не ми предлага да вляза.

$ telnet 192.168.10.110 22
SSH-2.0-OpenSSH_8.1

Опитвам се да се свържа с него чрез VNC и виждам черен екран. Убеждавам се, че въпросът е в отдалечения компютър, защото лесно мога да се свържа с рутера от този апартамент, използвайки вътрешния адрес. Въпреки това решавам да направя SSH в този компютър през рутера и с изненада установявам, че връзката е успешна и отдалеченият компютър работи добре, но не успява да се свърже и с моя компютър.

Изваждам устройството grelan0 от моста и стартирам OpenVPN на рутера в апартамент 2 и се уверявам, че мрежата отново работи правилно и връзките не прекъсват. Търсейки попадам на форуми, където хората се оплакват от същите проблеми, където ги съветват да вдигнат MTU. Казано, сторено. Въпреки това, докато MTU не беше настроен на достатъчно голяма стойност от 7000 за gretap устройства, се наблюдаваха или прекъснати TCP връзки, или бавни предавания. Поради високото MTU за gretap, MTU за WireGuard връзки на първо и второ ниво бяха зададени съответно на 8000 и 7500.

Направих подобна настройка на рутера от апартамент 3, с единствената разлика, че към рутера на сървъра беше добавен втори интерфейс gretap, наречен grelan1, който също беше добавен към моста br-lan.

Всичко работи. Сега можете да поставите модула gretap в автоматично зареждане. За това:

Поставете тези редове в /etc/rc.local на рутера в апартамент 2:

ip link add grelan0 type gretap remote 192.168.31.1 local 192.168.31.2
ip link set dev grelan0 mtu 7000
ip link set grelan0 up
brctl addif br-lan grelan0

Добавено е това към /etc/rc.local на рутера в апартамент 3:

ip link add grelan0 type gretap remote 192.168.31.1 local 192.168.31.3
ip link set dev grelan0 mtu 7000
ip link set grelan0 up
brctl addif br-lan grelan0

И на рутера на сървъра:

ip link add grelan0 type gretap remote 192.168.31.2 local 192.168.31.1
ip link set dev grelan0 mtu 7000
ip link set grelan0 up
brctl addif br-lan grelan0

ip link add grelan1 type gretap remote 192.168.31.3 local 192.168.31.1
ip link set dev grelan1 mtu 7000
ip link set grelan1 up
brctl addif br-lan grelan1

След като рестартирах клиентските рутери, открих, че по някаква причина не са се свързали със сървъра. Свързвайки се с техния SSH (за щастие, преди това бях конфигурирал sshtunnel за това), беше открито, че WireGuard по някаква причина създава маршрут за крайната точка, но е неправилен. И така, за 192.168.30.2 таблицата с маршрути беше посочена в таблицата с маршрути през интерфейса pppoe-wan, тоест през интернет, въпреки че маршрутът към него трябваше да бъде насочен през интерфейса wg0. След изтриването на този маршрут връзката беше възстановена. Никъде не можах да намеря инструкции как да принудя WireGuard да не създава тези маршрути. Освен това дори не разбрах дали това е функция на OpenWRT или на самия WireGuard. Без да се налага да се занимавам с този проблем дълго време, просто добавих към двата рутера в скрипт, зациклил от таймер, ред, който изтри този маршрут:

route del 192.168.30.2

Обобщавайки

Все още не съм постигнал пълно отхвърляне на OpenVPN, тъй като понякога трябва да се свържа с нова мрежа от лаптоп или телефон и настройката на gretap устройство на тях обикновено е невъзможна, но въпреки това получих предимство при пренос на данни скорост между апартаменти и, например, използването на VNC вече не е неудобно. Ping леко намаля, но стана по-стабилен:

Когато използвате OpenVPN:

[r0ck3r@desktop ~]$ ping -c 20 192.168.10.110
PING 192.168.10.110 (192.168.10.110) 56(84) bytes of data.
64 bytes from 192.168.10.110: icmp_seq=1 ttl=64 time=133 ms
...
64 bytes from 192.168.10.110: icmp_seq=20 ttl=64 time=125 ms

--- 192.168.10.110 ping statistics ---
20 packets transmitted, 20 received, 0% packet loss, time 19006ms
rtt min/avg/max/mdev = 124.722/126.152/136.907/3.065 ms

Когато използвате WireGuard:

[r0ck3r@desktop ~]$ ping -c 20 192.168.10.110
PING 192.168.10.110 (192.168.10.110) 56(84) bytes of data.
64 bytes from 192.168.10.110: icmp_seq=1 ttl=64 time=124 ms
...
64 bytes from 192.168.10.110: icmp_seq=20 ttl=64 time=124 ms
--- 192.168.10.110 ping statistics ---
20 packets transmitted, 20 received, 0% packet loss, time 19003ms
rtt min/avg/max/mdev = 123.954/124.423/126.708/0.675 ms

Най-вече се влияе от висок ping към VPS, който е приблизително 61.5 ms

Скоростта обаче се увеличи значително. И така, в апартамент с рутер-сървър имам скорост на интернет връзка 30 Mbps, а в други апартаменти 5 Mbps. В същото време, докато използвах OpenVPN, не можах да постигна скорост на трансфер на данни между мрежи от повече от 3,8 Mbps според iperf, докато WireGuard го „изпомпва“ до същите 5 Mbps.

Конфигурация на WireGuard на VPS[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

Конфигурация на WireGuard на MS (добавена към /etc/config/network)

#VPN первого уровня - клиент
config interface 'wg0'
        option proto 'wireguard'
        list addresses '192.168.30.2/24'
        option private_key 'ЗАКРЫТЫЙ_КЛЮЧ_VPN_1_МС'
        option auto '1'
        option mtu '8000'

config wireguard_wg0
        option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_1_VPS'
        option endpoint_port '51820'
        option route_allowed_ips '1'
        option persistent_keepalive '25'
        list allowed_ips '192.168.30.0/24'
        option endpoint_host 'IP_АДРЕС_VPS'

#VPN второго уровня - сервер
config interface 'wg1'
        option proto 'wireguard'
        option private_key 'ЗАКРЫТЫЙ_КЛЮЧ_VPN_2_МС'
        option listen_port '51821'
        list addresses '192.168.31.1/24'
        option auto '1'
        option mtu '7500'

config wireguard_wg1
        option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_2_МК2'
        list allowed_ips '192.168.31.2'

config wireguard_wg1ip link add grelan0 type gretap remote 192.168.31.1 local 192.168.31.3

        option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_2_МК3'
        list allowed_ips '192.168.31.3'

WireGuard конфигурация на MK2 (добавена към /etc/config/network)

#VPN первого уровня - клиент
config interface 'wg0'
        option proto 'wireguard'
        list addresses '192.168.30.3/24'
        option private_key 'ЗАКРЫТЫЙ_КЛЮЧ_VPN_1_МК2'
        option auto '1'
        option mtu '8000'

config wireguard_wg0
        option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_1_VPS'
        option endpoint_port '51820'
        option persistent_keepalive '25'
        list allowed_ips '192.168.30.0/24'
        option endpoint_host 'IP_АДРЕС_VPS'

#VPN второго уровня - клиент
config interface 'wg1'
        option proto 'wireguard'
        option private_key 'ЗАКРЫТЫЙ_КЛЮЧ_VPN_2_МК2'
        list addresses '192.168.31.2/24'
        option auto '1'
        option listen_port '51821'
        option mtu '7500'

config wireguard_wg1
        option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_2_МС'
        option endpoint_host '192.168.30.2'
        option endpoint_port '51821'
        option persistent_keepalive '25'
        list allowed_ips '192.168.31.0/24'

WireGuard конфигурация на MK3 (добавена към /etc/config/network)

#VPN первого уровня - клиент
config interface 'wg0'
        option proto 'wireguard'
        list addresses '192.168.30.4/24'
        option private_key 'ЗАКРЫТЫЙ_КЛЮЧ_VPN_1_МК3'
        option auto '1'
        option mtu '8000'

config wireguard_wg0
        option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_1_VPS'
        option endpoint_port '51820'
        option persistent_keepalive '25'
        list allowed_ips '192.168.30.0/24'
        option endpoint_host 'IP_АДРЕС_VPS'

#VPN второго уровня - клиент
config interface 'wg1'
        option proto 'wireguard'
        option private_key 'ЗАКРЫТЫЙ_КЛЮЧ_VPN_2_МК3'
        list addresses '192.168.31.3/24'
        option auto '1'
        option listen_port '51821'
        option mtu '7500'

config wireguard_wg1
        option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_2_МС'
        option endpoint_host '192.168.30.2'
        option endpoint_port '51821'
        option persistent_keepalive '25'
        list allowed_ips '192.168.31.0/24'

В описаните конфигурации за VPN от второ ниво посочвам към клиентите на WireGuard порт 51821. На теория това не е необходимо, тъй като клиентът ще установи връзка от всеки свободен непривилегирован порт, но направих така, че всички входящи връзки може да бъде отказан на wg0 интерфейсите на всички рутери, с изключение на входящи UDP връзки на порт 51821.

Надявам се, че статията ще бъде полезна за някого.

PS Също така искам да споделя своя скрипт, който ми изпраща PUSH известие до телефона ми в приложението WirePusher, когато в мрежата ми се появи ново устройство. Ето линк към скрипта: github.com/r0ck3r/device_discover.

UPDATE: OpenVPN сървър и конфигурация на клиенти

OpenVPN сървър

client-to-client

ca /etc/openvpn/server/ca.crt
cert /etc/openvpn/server/vpn-server.crt
dh /etc/openvpn/server/dh.pem
key /etc/openvpn/server/vpn-server.key

dev tap
ifconfig-pool-persist /etc/openvpn/ipp.txt 0
keepalive 10 60
proto tcp4
server-bridge 192.168.10.1 255.255.255.0 192.168.10.80 192.168.10.254
status /var/log/openvpn-status.log
verb 3
comp-lzo

OpenVPN клиент

client
tls-client
dev tap
proto tcp
remote VPS_IP 1194 # Change to your router's External IP
resolv-retry infinite
nobind

ca client/ca.crt
cert client/client.crt
key client/client.key
dh client/dh.pem

comp-lzo
persist-tun
persist-key
verb 3

Използвах easy-rsa за генериране на сертификати.

Източник: www.habr.com

Добавяне на нов коментар