Migración de OpenVPN a WireGuard para unir redes en una red L2



Me gustaría compartir la experiencia de combinar redes en tres apartamentos geográficamente remotos, en cada uno de los cuales los enrutadores con OpenWRT se utilizan como puerta de entrada a una red común. Al elegir un método para combinar redes entre L3 con enrutamiento de subredes y L2 con puente, cuando todos los nodos de la red estarán en la misma subred, se prefirió el segundo método, que era más difícil de configurar, pero que daba más oportunidades, ya que la red estaba planeada para usar tecnologías transparentes Wake-on-Lan y DLNA.

Parte 1: antecedentes


OpenVPN se eligió inicialmente como el protocolo para implementar esta tarea, porque, en primer lugar, puede crear un dispositivo de tap que se puede agregar fácilmente al puente, y en segundo lugar, OpenVPN admite la operación del protocolo TCP, que también era importante, porque ninguno de los apartamentos tenía una dirección IP dedicada, y no pude usar STUN, porque por alguna razón mi proveedor bloquea las conexiones entrantes a través de UDP desde sus redes, mientras que TCP me permitió reenviar el puerto del servidor VPN a VPS arrendado utilizando SSH. Sí, este enfoque genera una gran carga, porque los datos se cifran dos veces, pero no quería ingresar VPS en mi red privada, ya que existía el riesgo de que terceros obtuvieran el control sobre ellos, por lo tanto,tener un dispositivo de este tipo en la red doméstica era extremadamente indeseable y se decidió pagar por la seguridad con una gran sobrecarga.

Para reenviar el puerto en el enrutador en el que se planeó implementar el servidor, se utilizó el programa sshtunnel. No describiré las complejidades de su configuración: esto se hace con bastante facilidad, solo noto que su tarea era reenviar el puerto TCP 1194 desde el enrutador al VPS. Luego, el servidor OpenVPN se configuró en el dispositivo tap0, que terminó en el puente br-lan. Después de verificar la conexión al servidor que acaba de crear desde la computadora portátil, quedó claro que la idea del reenvío de puertos había valido la pena y mi computadora portátil se convirtió en miembro de la red del enrutador, aunque yo no estaba físicamente allí.

El asunto seguía siendo pequeño: era necesario distribuir direcciones IP en diferentes apartamentos para que no entraran en conflicto y configurar los enrutadores como clientes OpenVPN.
Se seleccionaron las siguientes direcciones IP de enrutador y rangos de servidor DHCP:

  • 192.168.10.1 con un rango de 192.168.10.2 - 192.168.10.80 para el servidor
  • 192.168.10.100 con un rango de 192.168.10.101 - 192.168.10.149 para el enrutador en el apartamento No. 2
  • 192.168.10.150 con un rango de 192.168.10.151 - 192.168.10.199 para el enrutador en el apartamento No. 3

También fue necesario asignar estas direcciones a los enrutadores del cliente del servidor OpenVPN agregando las siguientes líneas a su configuración:

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

y agregando las siguientes líneas al archivo /etc/openvpn/ipp.txt:

flat1_id 192.168.10.100
flat2_id 192.168.10.150

donde flat1_id y flat2_id son los nombres de dispositivo especificados al crear certificados para conectarse a OpenVPN

A continuación, los clientes OpenVPN se configuraron en los enrutadores, se agregaron dispositivos tap0 en ambos al puente br-lan. En esta etapa, parecía que todo estaba en orden, ya que las tres redes se ven y funcionan como un todo. Sin embargo, resultó ser un detalle no muy agradable: a veces los dispositivos no podían obtener una dirección IP de su enrutador, con todas las consecuencias resultantes. Por alguna razón, el enrutador en algunos de los apartamentos no tuvo tiempo de responder a tiempo a DHCPDISCOVER y el dispositivo no recibió su dirección. Me di cuenta de que necesito filtrar tales solicitudes en tap0 en cada uno de los enrutadores, pero resultó que iptables no puede funcionar con el dispositivo si es parte del puente y ebtables deberían ayudarme. Desafortunadamente, no estaba en mi firmware y tuve que reconstruir las imágenes para cada dispositivo.Después de hacer esto y agregar tales líneas a /etc/rc.local de cada enrutador, el problema se resolvió:

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 duró tres años.

Parte 2: Presentación de WireGuard


Recientemente, en Internet, comenzaron a hablar cada vez más sobre WireGuard, admirando la simplicidad de su configuración, alta velocidad de transmisión, bajo ping con seguridad comparable. La búsqueda de información adicional sobre él dejó en claro que no apoyaban trabajar como miembro puente o trabajar con TCP, lo que me hizo pensar que todavía no había alternativas a OpenVPN para mí. Así que dejé de conocer WireGuard.

Hace unos días, a través de los recursos, de una forma u otra relacionados con TI, apareció la noticia de que WireGuard finalmente se incluirá en el kernel de Linux, comenzando con la versión 5.6. Los artículos de noticias, como siempre, elogiaron a WireGuard. Nuevamente me sumergí en la búsqueda de formas de reemplazar el buen viejo OpenVPN. Esta vez me encontré con este artículo. Hablaba de construir un túnel Ethernet sobre L3 usando GRE. Este artículo me dio esperanza. No quedó claro qué hacer con el protocolo UDP. La búsqueda me llevó a artículos sobre el uso de socat junto con un túnel SSH para reenviar un puerto UDP, sin embargo, notaron que este enfoque solo funciona en modo de conexión única, es decir, el trabajo de varios clientes VPN sería imposible. Se me ocurrió la idea de crear un servidor VPN en VPS y configurar GRE para clientes, pero resultó que GRE no admite el cifrado, lo que conducirá al hecho de que, en caso de que terceros accedan al servidor, todo el tráfico entre mis redes está en sus manos. eso no me convenía en principio.

Nuevamente, la decisión se tomó a favor del cifrado excesivo, mediante el uso de una VPN sobre una VPN de acuerdo con el siguiente esquema:

VPN de primer nivel:
VPS es un servidor con una dirección interna de 192.168.30.1
MS es un cliente VPS con una dirección interna de 192.168.30.2
MK2 es un cliente VPS con una dirección interna de 192.168.30.3
MK3 es un cliente VPS con una dirección interna de 192.168.30.3 MK2 es una

VPN de segundo nivel:
MS es un servidor con una dirección externa 192.168.30.2 y una interna 192.168.31.1
MK2 es un cliente MS con una dirección 192.168.30.2 y tiene una IP interna 192.168.31.2
MK3 es un cliente MScon la dirección 192.168.30.2 y tiene una IP interna 192.168.31.3

* MS - enrutador-servidor en el apartamento 1, MK2 - enrutador en el apartamento 2, MK3 - enrutador en el apartamento 3
* Las configuraciones del dispositivo se publican en el spoiler al final del artículo.

Y así, los pings entre los nodos de la red 192.168.31.0/24 van, es hora de pasar a configurar el túnel GRE. Antes de esto, para no perder el acceso a los enrutadores, vale la pena configurar túneles SSH para reenviar 22 puertos en el VPS, de modo que, por ejemplo, el enrutador del apartamento 2 estará disponible en el puerto VPS 10022 y en el puerto 11122 el VPS estará disponible el enrutador es del departamento 3. Es mejor configurar el reenvío con el mismo sshtunnel, ya que restaurará el túnel si se cae.

El túnel está configurado, puede conectarse a SSH a través del puerto reenviado:

ssh root@_VPS -p 10022

A continuación, deshabilite OpenVPN:

/etc/init.d/openvpn stop

Ahora configure el túnel GRE en el enrutador desde el apartamento 2:

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

Y agregue la interfaz creada al puente:

brctl addif br-lan grelan0

Realizaremos un procedimiento similar en el servidor enrutador:

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

Y, también, agregue la interfaz creada al puente:

brctl addif br-lan grelan0

a partir de este momento, los pings comienzan a ir con éxito a la nueva red y yo, con satisfacción, voy a tomar café. Luego, para evaluar cómo funciona la red en el otro extremo del cable, intento conectarme a través de SSH a una de las computadoras en el departamento 2, pero el cliente ssh se congela sin solicitar una contraseña. Intento conectarme a esta computadora a través del telnet al puerto 22 y veo una línea desde la cual se puede entender que se está estableciendo la conexión, el servidor SSH está respondiendo, solo por alguna razón no me ofrece iniciar sesión.

$ telnet 192.168.10.110 22
SSH-2.0-OpenSSH_8.1

Intento conectarme a él a través de VNC y veo una pantalla en negro. Me aseguro que es una computadora remota, porque puedo conectarme fácilmente al enrutador desde este departamento en la dirección interna. Sin embargo, decido conectarme a la SSH de esta computadora a través de un enrutador y me sorprende ver que la conexión es exitosa y que la computadora remota funciona correctamente, pero tampoco puede conectarse a mi computadora.

Quito el dispositivo grelan0 del puente y ejecuto OpenVPN en el enrutador en el apartamento 2 y me aseguro de que la red vuelva a funcionar como se esperaba y que las conexiones no se rompan. Cuando busco, me encuentro con foros donde las personas se quejan de los mismos problemas, donde se les aconseja elevar el MTU. Sin embargo, no pude aumentar la MTU para la VPN de primer nivel (wg0): con MTU superiores a 1420, que se configura automáticamente, comienzan los descansos, pero al mismo tiempo, la VPN de segundo nivel wg1 que funciona sobre wg0 funcionó correctamente con MTU 1600. Esto es suficiente para instalar La MTU es 1500 para el dispositivo gretap, por lo que esta interfaz tiene el mismo valor de MTU que el puente br-lan en el que se planeó agregar gretap. Según tengo entendido, el puente establece la MTU igual al menor de los valores disponibles en todos los dispositivos.

Hice una configuración similar en el enrutador desde el Apartamento 3, con la única diferencia de que en el enrutador el servidor agregó una segunda interfaz gretap llamada grelan1, que también se agregó al puente br-lan.

Todo esta funcionando. Ahora puede poner el ensamblaje gretap al inicio. Para hacer esto:

coloque estas líneas en /etc/rc.local en el enrutador en el apartamento 2:

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

Agregó esto a /etc/rc.local en el enrutador en el apartamento 3:

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

Y en el enrutador del servidor:

ip link add grelan0 type gretap remote 192.168.31.2 local 192.168.31.1
ip link set dev grelan0 mtu 1500
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 1500
ip link set grelan1 up
brctl addif br-lan grelan1

Después de reiniciar los enrutadores del cliente, descubrí que por alguna razón no se conectaban al servidor. Después de conectarme a su SSH (afortunadamente, preconfigé sshtunnel para esto), se descubrió que WireGuard estaba creando una ruta para el punto final por alguna razón, pero era incorrecto. Entonces, para 192.168.30.2, la tabla de rutas indicaba la ruta a través de la interfaz pppoe-wan, es decir, a través de Internet, aunque la ruta a ella debería haberse enrutado a través de la interfaz wg0. Después de eliminar esta ruta, se restableció la conexión. No pude encontrar en alguna parte instrucciones sobre cómo hacer que WireGuard no cree estas rutas. Además, ni siquiera entendí, una característica es OpenWRT o WireGuard en sí. Sin tener que lidiar con este problema durante mucho tiempo, acabo de agregar una línea a este enrutador al script en bucle por un temporizador al bucle del temporizador:

route del 192.168.30.2

Para resumir


Todavía no he logrado un rechazo completo de OpenVPN, ya que a veces necesito conectarme a una nueva red desde una computadora portátil o teléfono, y configurar un dispositivo gretap en ellos generalmente es imposible, pero a pesar de esto, obtuve una ventaja en la velocidad de transferencia de datos entre apartamentos y, por ejemplo, el uso de VNC ahora no causa inconvenientes. Ping disminuyó ligeramente, pero se volvió más estable:

cuando se usa 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

Cuando 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

Se ve más afectado por el ping alto antes de VPS, que es de aproximadamente 61,5 ms.

Sin embargo, la velocidad ha aumentado significativamente. Entonces, en un departamento con un enrutador-servidor, tengo una velocidad de conexión a Internet de 30 Mbit / s, y en otros departamentos: 5 Mbit / s. Al mismo tiempo, mientras usaba OpenVPN, no pude lograr una velocidad de transferencia de datos entre redes de más de 3.8 Mb / s según iperf, mientras que WireGuard la "bombeó" a los mismos 5 Mb / s.

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 (agregado 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'

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 '1600'

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 (agregado 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'

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 '1600'

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 (agregado 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'

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 '1600'

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'


En las configuraciones descritas para la VPN de segundo nivel, especifico el puerto 51821 para los clientes WireGuard. En principio, esto no es necesario, ya que el cliente establecerá una conexión desde cualquier puerto libre sin privilegios, pero lo hice para poder bloquear todas las conexiones entrantes en las interfaces wg0 de todos los enrutadores, excepto conexiones UDP entrantes al puerto 51821.

Espero que este artículo sea útil para alguien.

PD: También quiero compartir mi script que me envía una notificación PUSH en el teléfono a la aplicación WirePusher cuando aparece un nuevo dispositivo en mi red. Aquí está el enlace al script: github.com/r0ck3r/device_discover .

ACTUALIZACIÓN: Configuración de OpenVPN Server y Clientes

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



Para generar certificados se utiliza easy-rsa

Source: https://habr.com/ru/post/undefined/


All Articles