Router VPN con OpenBSD y WireGuard
Por el 4 de Abril de 2022
Con un router VPN podrás conectar varios dispositivos de forma que, sin realizar ninguna configuración especial en ellos, saldrán a internet desde un servidor remoto.
Parto de estos dos artículos sobre configuración de router firewall y de VPN road warrior:
Estas son las interfaces del router que usaré, un EdgeRouter Lite:
- cnmac0 en modo cliente DHCP conectada al cablemodem
- vport0 es un puente de red que une cnmac1 y cnmac2
El router creará una red interna en la interfaz vport0 con la dirección de red 172.16.0.1/12, donde estará funcionando el servidor DHCP asignando direcciones a los anfitriones que se conecten. Packet filter se encargará del NAT para que éstos puedan salir a Internet.
En vez de unwind es conveniente usar unbound para dar servicio de DNS, de forma ideal junto con unbound-adblock y pf-badhost para bloquear anuncios y malware. La configuración en el sistema se hace de la misma forma que con unwind, esto es, corriendo dos instancias, una para cada dominio de enrutado.
Si no funciona el DNS al arrancar el router no se podrá configurar la fecha, y si la fecha está mal no funcionará el túnel VPN, por eso le paso como parámetro una IP a rdate
en lugar de es.pool.ntp.org.example.com
.
Para ejecutar las dos instancias de unbound hay que crear el enlace correspondiente en /etc/rc.d:
# ln -s /etc/rc.d/unwind /etc/rc.d/unwind1
A continuación muestro las configuraciones con la filosofía de siempre: hacer las mínimos cambios necesarios a los ejemplos de la documentación oficial, de forma que sean fácilmente adaptables en el futuro. He realizado esta configuración con OpenBSD 7.0 en el servidor y OpenBSD 7.1 en el router.
Configuración en el router
- /etc/hostname.cnmac0
rdomain 1 up autoconf
- /etc/hostname.cnmac1
up
- /etc/hostname.cnmac2
up
- /etc/hostname.vport0
inet 172.16.0.1 255.240.0.0 172.31.255.255 up
- /etc/hostname.veb0
add vport0 add cnmac1 add cnmac2 up
- /etc/rc.local
# Reemplazar esta IP por la de un servidor público NTP cercano. route -T 1 exec rdate 203.0.113.1
- /etc/rc.conf.local
dhcpd_flags="vport0" ntpd_flags= resolvd_flags=NO unwind1_flags=-s /var/run/unwind1.sock -f /etc/unwind1.conf unwind1_rtable=1 unwind_flags=
- /var/unbound/etc/unbound.conf
server: interface: 127.0.0.1 interface: 172.16.0.1 access-control: 127.0.0.0/8 allow access-control: 172.16.0.0/12 allow hide-identity: yes hide-version: yes remote-control: control-enable: yes control-interface: /var/run/unbound.sock
- /etc/hostname.lo1
rdomain 1 inet 127.0.0.1 255.0.0.0 description "rdomain 1 loopback address"
- /etc/hostname.wg0
wgkey <clave-privada-router> wgpeer <clave-publica-servidor> wgendpoint 203.0.113.1 4433 wgaip 0.0.0.0/0 wgpka 20 inet 10.0.0.2/8 wgrtable 1 up !route add -net default 10.0.0.1
- /etc/dhcpd.conf
subnet 172.16.0.0 netmask 255.240.0.0 { option domain-name-servers 172.16.0.1; option routers 172.16.0.1; range 172.16.0.100; }
- /etc/pf.conf
int_if = "vport0" table <martians> { 0.0.0.0/8 10.0.0.0/8 127.0.0.0/8 169.254.0.0/16 \ 172.16.0.0/12 192.0.0.0/24 192.0.2.0/24 224.0.0.0/3 \ 192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 \ 203.0.113.0/24 } set block-policy drop set loginterface egress set skip on lo0 match in all scrub (no-df random-id max-mss 1440) match out on egress inet from !(egress:network) to any nat-to (egress:0) antispoof quick for { egress vport0 } block in on egress from <martians> to any block return out quick on egress from any to <martians> block all pass out quick inet pass in on $int_if inet
Configuración en el servidor
- /etc/hostname.wg0
wgkey <clave-privada-servidor> wgpeer <clave-pública-router> wgaip 10.0.0.0/8 inet 10.0.0.1/8 wgport 4433 up
- /etc/pf.conf
# $OpenBSD: pf.conf,v 1.55 2017/12/03 20:40:04 sthen Exp $ # # See pf.conf(5) and /etc/examples/pf.conf set skip on lo pass out quick on egress from wg0:network to any nat-to (egress) block return # block stateless traffic pass # establish keep-state # By default, do not permit remote connections to X11 block return in on ! lo0 proto tcp to port 6000:6010 # Port build user does not need network block return out log proto {tcp udp} user _pbuild