Migración de OpenVPN a WireGuard para consolidar redes nunha rede L2

Migración de OpenVPN a WireGuard para consolidar redes nunha rede L2

Gustaríame compartir a miña experiencia de combinar redes en tres apartamentos xeograficamente distantes, cada un dos cales usa enrutadores con OpenWRT como pasarela, nunha rede común. Ao elixir un método para combinar redes entre L3 con enrutamento de subrede e L2 con ponte, cando todos os nodos da rede estarán na mesma subrede, deuse preferencia ao segundo método, que é máis difícil de configurar, pero ofrece máis oportunidades, xa que é transparente. planificouse o uso de tecnoloxías na rede creada Wake-on-Lan e DLNA.

Parte 1: Antecedentes

OpenVPN foi elixido inicialmente como protocolo para implementar esta tarefa, xa que, en primeiro lugar, pode crear un dispositivo de toque que se pode engadir á ponte sen ningún problema, e en segundo lugar, OpenVPN admite o funcionamento a través do protocolo TCP, o que tamén foi importante, porque ningún dos apartamentos tiña un enderezo IP dedicado e non puiden usar STUN, porque por algún motivo o meu ISP bloquea as conexións UDP entrantes das súas redes, mentres que o protocolo TCP permitíame reenviar o porto do servidor VPN no VPS alugado usando SSH. Si, este enfoque dá unha gran carga, xa que os datos están cifrados dúas veces, pero non quería introducir o VPS na miña rede privada, xa que aínda existía o risco de que terceiros tivesen o control del, polo tanto, tendo tal dispositivo na rede doméstica era moi indesexable e decidiuse pagar a seguridade cunha gran sobrecarga.

Para reenviar o porto do enrutador no que estaba previsto despregar o servidor, utilizouse o programa sshtunnel. Non vou describir as complejidades da súa configuración: isto faise con bastante facilidade, só observo que a súa tarefa era reenviar o porto TCP 1194 do enrutador ao VPS. A continuación, configurouse o servidor OpenVPN no dispositivo tap0, que estaba conectado á ponte br-lan. Despois de comprobar a conexión co servidor recén creado dende o portátil, quedou claro que a idea do reenvío de portos se xustificou e o meu portátil converteuse nun membro da rede do enrutador, aínda que non estaba fisicamente nel.

O asunto quedou pequeno: foi necesario distribuír enderezos IP en diferentes apartamentos para que non entrasen en conflito e configurar os enrutadores como clientes OpenVPN.
Seleccionáronse os seguintes enderezos IP do enrutador e intervalos de servidor DHCP:

  • 192.168.10.1 con alcance 192.168.10.2 - 192.168.10.80 para o servidor
  • 192.168.10.100 con alcance 192.168.10.101 - 192.168.10.149 para un router no apartamento no 2
  • 192.168.10.150 con alcance 192.168.10.151 - 192.168.10.199 para un router no apartamento no 3

Tamén foi necesario asignar exactamente estes enderezos aos routers cliente do servidor OpenVPN engadindo a liña á súa configuración:

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

e engadindo as seguintes liñas ao ficheiro /etc/openvpn/ipp.txt:

flat1_id 192.168.10.100
flat2_id 192.168.10.150

onde flat1_id e flat2_id son os nomes de dispositivos especificados ao xerar certificados para conectarse a OpenVPN

A continuación, os clientes OpenVPN foron configurados nos enrutadores, os dispositivos tap0 en ambos foron engadidos á ponte br-lan. Nesta fase, todo parecía estar en orde, xa que as tres redes se ven e funcionan como un todo. Non obstante, resultou un detalle non moi agradable: ás veces os dispositivos podían obter un enderezo IP que non fose do seu enrutador, con todas as consecuencias derivadas. Por algún motivo, o enrutador dun dos apartamentos non tivo tempo para responder a DHCPDISCOVER a tempo e o dispositivo recibiu o enderezo incorrecto. Decateime de que necesitaba filtrar tales solicitudes en tap0 en cada un dos enrutadores, pero como resultou, iptables non pode funcionar cun dispositivo se forma parte dunha ponte e ebtables debería vir ao meu rescate. Para o meu pesar, non estaba no meu firmware e tiven que reconstruír as imaxes para cada dispositivo. Facendo isto e engadindo estas liñas a /etc/rc.local de cada enrutador, resolveuse o problema:

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

Esta configuración durou tres anos.

Parte 2: Presentación de WireGuard

Recentemente, Internet está a falar cada vez máis de WireGuard, admirando a sinxeleza da súa configuración, a alta velocidade de transferencia, o ping baixo cunha seguridade comparable. Ao buscar máis información sobre el, deixou claro que nin traballar como membro da ponte nin traballar no protocolo TCP é compatible con el, o que me fixo pensar que aínda non hai alternativas para OpenVPN para min. Así que deixo de coñecer a WireGuard.

Hai uns días, a noticia difundiuse a través de recursos dunha ou outra forma relacionados coas informáticas de que WireGuard será finalmente incluído no núcleo de Linux, comezando pola versión 5.6. Os artigos de noticias, coma sempre, eloxiaron a WireGuard. De novo mergulleime na procura de formas de substituír o bo vello OpenVPN. Esta vez topeime Este artigo. Falaba de crear un túnel Ethernet sobre L3 usando GRE. Este artigo deume esperanza. Non estaba claro que facer co protocolo UDP. A busca levoume a artigos sobre o uso de socat xunto cun túnel SSH para reenviar un porto UDP, non obstante, observaron que este enfoque só funciona en modo de conexión única, o que significa que sería imposible varios clientes VPN. Ocorréuseme configurar un servidor VPN nun VPS e configurar GRE para os clientes, pero resultou que GRE non admite o cifrado, o que provocará que se terceiros acceden ao servidor, todo o tráfico entre as miñas redes está nas súas mans, o que non me convenía nada.

De novo, a decisión tomouse a favor do cifrado redundante, usando VPN sobre VPN segundo o seguinte esquema:

VPN de capa XNUMX:
Estudantes é servidor con enderezo interno 192.168.30.1
MS é clienta VPS con enderezo interno 192.168.30.2
MK2 é clienta VPS con enderezo interno 192.168.30.3
MK3 é clienta VPS con enderezo interno 192.168.30.4

VPN de capa XNUMX:
MS é servidor con enderezo externo 192.168.30.2 e interno 192.168.31.1
MK2 é clienta MS co enderezo 192.168.30.2 e ten unha IP interna de 192.168.31.2
MK3 é clienta MS co enderezo 192.168.30.2 e ten unha IP interna de 192.168.31.3

* MS - router-servidor no apartamento 1, MK2 - router no apartamento 2, MK3 - router no apartamento 3
* As configuracións do dispositivo publícanse no spoiler ao final do artigo.

E así, os pings entre os nodos da rede 192.168.31.0/24 van, é hora de pasar á configuración do túnel GRE. Antes diso, para non perder o acceso aos enrutadores, paga a pena configurar túneles SSH para reenviar o porto 22 ao VPS, de xeito que, por exemplo, un enrutador do apartamento 10022 estará dispoñible no porto 2 do VPS, e un o enrutador do apartamento 11122 estará dispoñible no porto 3 do VPS, o enrutador do apartamento XNUMX. É mellor configurar o reenvío co mesmo sshtunnel, xa que restaurará o túnel no caso de que caia.

O túnel está configurado, pode conectarse a SSH a través do porto reenviado:

ssh root@МОЙ_VPS -p 10022

A continuación, desactiva OpenVPN:

/etc/init.d/openvpn stop

Agora imos configurar un túnel GRE no router do apartamento 2:

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

E engade a interface creada á ponte:

brctl addif br-lan grelan0

Imos realizar un procedemento similar no router do servidor:

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

E, ademais, engade a interface creada á ponte:

brctl addif br-lan grelan0

a partir deste momento, os pings comezan a ir con éxito á nova rede e eu, satisfeito, vou tomar café. Entón, para ver como funciona a rede do outro extremo do cable, intento conectar un SSH a un dos ordenadores do apartamento 2, pero o cliente ssh conxélase sen pedirme un contrasinal. Intento conectarme a este ordenador a través de telnet no porto 22 e vexo unha liña dende a que podes entender que se está a establecer a conexión, o servidor SSH responde, pero por algún motivo non me ofrece entrar.

$ telnet 192.168.10.110 22
SSH-2.0-OpenSSH_8.1

Estou tentando conectar a el a través de VNC e vexo unha pantalla negra. Convénzome de que o asunto está no ordenador remoto, porque podo conectarme facilmente ao router desde este apartamento usando o enderezo interno. Non obstante, decido facer SSH neste ordenador a través do enrutador e sorpréndeme ao descubrir que a conexión se realiza correctamente e que o ordenador remoto funciona ben, pero tampouco se conecta ao meu ordenador.

Saco o dispositivo grelan0 da ponte e inicio OpenVPN no enrutador do apartamento 2 e asegúrese de que a rede está funcionando correctamente de novo e que as conexións non están caendo. Buscando atópome con foros onde a xente se queixa dos mesmos problemas, onde se lles aconsella subir o MTU. Nada máis dicir que feito. Non obstante, ata que o MTU se axustou a un valor suficientemente grande de 7000 para os dispositivos gretap, observáronse conexións TCP caídas ou transmisións lentas. Debido ao alto MTU para gretap, os MTU para conexións WireGuard dos primeiros e segundos niveis establecéronse en 8000 e 7500, respectivamente.

Fixen unha configuración similar no enrutador do apartamento 3, coa única diferenza de que se engadiu unha segunda interface gretap chamada grelan1 ao enrutador do servidor, que tamén se engadiu á ponte br-lan.

Todo está funcionando. Agora podes poñer o conxunto gretap na carga automática. Para isto:

Colocou estas liñas en /etc/rc.local no router do apartamento 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

Engadido isto a /etc/rc.local no router no apartamento 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

E no router do servidor:

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

Despois de reiniciar os enrutadores do cliente, descubrín que por algún motivo non se conectaron ao servidor. Conectándome ao seu SSH (afortunadamente, previamente configurara sshtunnel para iso), descubriuse que WireGuard por algún motivo crea unha ruta para o punto final, aínda que é incorrecto. Entón, para 192.168.30.2, a táboa de rutas especificouse na táboa de rutas a través da interface pppoe-wan, é dicir, a través de Internet, aínda que a ruta a ela debería estar dirixida a través da interface wg0. Despois de eliminar esta ruta, restableceuse a conexión. Non puiden atopar instrucións en ningún lugar sobre como forzar a WireGuard a non crear estas rutas. Ademais, nin sequera entendín se esta é unha característica de OpenWRT ou do propio WireGuard. Sen ter que tratar con este problema durante moito tempo, simplemente engadín a ambos enrutadores nun script en bucle por un temporizador, unha liña que eliminaba esta ruta:

route del 192.168.30.2

Resumindo

Aínda non conseguín un rexeitamento completo de OpenVPN, xa que ás veces teño que conectarme a unha rede nova desde un portátil ou un teléfono e, en xeral, é imposible configurar un dispositivo gretap neles, pero a pesar diso, tiven vantaxe na transferencia de datos. a velocidade entre apartamentos e, por exemplo, usar VNC xa non é inconveniente. O ping diminuíu lixeiramente, pero tornouse máis estable:

Cando use 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

Cando use 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

Está afectado principalmente por un ping alto a VPS, que é de aproximadamente 61.5 ms

Non obstante, a velocidade aumentou significativamente. Así, nun apartamento cun enrutador-servidor, teño unha velocidade de conexión a Internet de 30 Mbps, e noutros apartamentos, de 5 Mbps. Ao mesmo tempo, mentres usaba OpenVPN, non puiden acadar unha taxa de transferencia de datos entre redes de máis de 3,8 Mbps segundo iperf, mentres que WireGuard "bombeaba" ata os mesmos 5 Mbps.

Configuración de WireGuard en 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

Configuración de WireGuard en MS (engadida a /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'

Configuración de WireGuard en MK2 (engadida a /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'

Configuración de WireGuard en MK3 (engadida a /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'

Nas configuracións descritas para a VPN de segundo nivel, especifico para os clientes WireGuard o porto 51821. En teoría, isto non é necesario, xa que o cliente establecerá unha conexión desde calquera porto gratuíto non privilexiado, pero eu fixen que todas as conexións entrantes pódese denegar nas interfaces wg0 de todos os enrutadores, excepto nas conexións UDP entrantes no porto 51821.

Espero que o artigo sexa útil para alguén.

PS Ademais, quero compartir o meu script que me envía unha notificación PUSH ao meu teléfono na aplicación WirePusher cando aparece un dispositivo novo na miña rede. Aquí tedes unha ligazón ao guión: github.com/r0ck3r/device_discover.

Update: Configuración do servidor e dos clientes OpenVPN

Servidor 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

Cliente 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

Usei easy-rsa para xerar certificados.

Fonte: www.habr.com

Engadir un comentario