
Tengo una máquina GNU/Linux que configuré como enrutador para mi red doméstica. Tengo tres interfaces de red...
- ppp0 es la conexión ascendente
- lan es la red local
- nordvpn es el túnel VPN
Estoy usando nftables para el firewall y estoy ejecutando un servidor DNS de almacenamiento en caché (dnsmasq). Las solicitudes de DNS de la LAN se interceptan y se envían al servidor DNS del enrutador. Hasta ahora todo bien, sin embargo...
Por defecto rutas NordVPNtodotráfico ascendente a través del túnel VPN, y si está configurado de esta manera funciona, pero no quiero esto. Quiero que la mayor parte del tráfico a Internet pase por la interfaz ppp0, y que el tráfico de hosts LAN específicos se envíe a través de la VPN. Las solicitudes de DNS para los hosts que utilizan la VPN deben dirigirse a los servidores DNS del proveedor de VPN en lugar del servidor local.
He leído varios artículos sobre cómo hacer cosas similares (pero no idénticas) y hasta ahora no he podido hacerlo funcionar. Claramente estoy haciendo al menos una cosa mal. Según tengo entendido, debería poder marcar paquetes en el firewall y luego enviarlos a través de la interfaz nordvpn utilizando una tabla de enrutamiento personalizada. Lo que tengo hasta ahora es lo siguiente...
He añadido la siguiente línea a /etc/iproute2/rt_tables
.
5 nordvpn
Para evitar que openvpn configure sus propias rutas, agregué estas líneas a /etc/openvpn/client/nordvpn.conf
.
route-noexec
script-security 2
route-up /etc/openvpn/client/mkroute.sh
Creo que necesito desactivar el filtrado de ruta inversa en la interfaz nordvpn para que todo funcione. Este es el script que usa openvpn para configurar mi enrutamiento.
#!/bin/bash
TABLE="nordvpn"
MARK="0x5"
die() {
echo "Error: $1"
exit 1
}
[ $(id -u) -eq 0 ] || die "Not running as root"
ip route flush cache || echo "error 1"
ip route flush table "$TABLE" || echo "error 2"
ip route add 192.168.2.0/24 dev lan src 192.168.2.1 table "$TABLE" || echo "error 3"
ip route add $route_vpn_gateway dev lan src $ifconfig_local table "$TABLE" || echo "error 4"
ip route add default via $route_vpn_gateway dev "$dev" table "$TABLE" || echo "error 5"
ip rule delete fwmark "$MARK" || :
ip rule add fwmark "$MARK" lookup "$TABLE" || echo "error 6"
sysctl -w net.ipv4.conf.nordvpn.rp_filter=0 || echo "error 7"
Finalmente, este es mi script de nftables.
flush ruleset
define i_wan = ppp0
define i_nordvpn = nordvpn
define i_lan = lan
define p_dns = 53
define a4_nordvpn_dns_1 = 103.86.96.100
define m_nordvpn = 5
define h4_nimrod = 192.168.2.21
table ip ip4_firewall {
set s_inet_nordvpn { type ipv4_addr; elements = { $h4_nimrod }; }
chain c_here_to_wan { tcp flags syn tcp option maxseg size set rt mtu; accept; }
chain c_here_to_nordvpn { tcp flags syn tcp option maxseg size set rt mtu; accept; }
chain c_here_to_lan { accept; }
chain c_wan_to_here { ip protocol icmp accept; drop; }
chain c_wan_to_lan { ip protocol icmp accept; drop; }
chain c_nordvpn_to_here { ip protocol icmp accept; drop; }
chain c_nordvpn_to_lan { ip protocol icmp accept; drop; }
chain c_lan_to_here { accept; }
chain c_lan_to_wan { tcp flags syn tcp option maxseg size set rt mtu; accept; }
chain c_lan_to_nordvpn { tcp flags syn tcp option maxseg size set rt mtu; accept; }
chain preroute_nordvpn {
udp dport $p_dns mark set $m_nordvpn dnat $a4_nordvpn_dns_1
tcp dport $p_dns mark set $m_nordvpn dnat $a4_nordvpn_dns_1
oif $i_wan mark set $m_nordvpn
}
chain prerouting { type nat hook prerouting priority -100
ip saddr @s_inet_nordvpn goto preroute_nordvpn
iif $i_lan oif $i_wan udp dport $p_dns redirect
iif $i_lan oif $i_wan tcp dport $p_dns redirect
}
chain postrouting { type nat hook postrouting priority 100
oif $i_nordvpn masquerade
oif $i_wan snat <my public IP address>
}
chain input { type filter hook input priority 0; policy drop
ct state established,related accept
ct state invalid drop
iif vmap {
lo: accept,
$i_wan : jump c_wan_to_here,
$i_nordvpn : jump c_nordvpn_to_here,
$i_lan : jump c_lan_to_here
}
log prefix "Unhandled input: " drop
}
chain output { type filter hook output priority 0; policy drop
ct state established,related accept
ct state invalid drop
oif vmap {
lo: accept,
$i_wan : jump c_here_to_wan,
$i_nordvpn : jump c_here_to_nordvpn,
$i_lan : jump c_here_to_lan
}
log prefix "Unhandled output: " drop
}
chain forward { type filter hook forward priority 0; policy drop
ct state established,related accept
ct state invalid drop
iif . oif vmap {
$i_lan . $i_wan : jump c_lan_to_wan,
$i_wan . $i_lan : jump c_wan_to_lan,
$i_lan . $i_nordvpn : jump c_lan_to_nordvpn,
$i_nordvpn . $i_lan : jump c_nordvpn_to_lan,
}
log prefix "Unhandled forward: " drop
}
}
Una vez configurado tengo lo siguiente.
[root@cerberus ~]# ip rule ls
0: from all lookup local
32765: from all fwmark 0x65 lookup nordvpn
32766: from all lookup main
32767: from all lookup default
[root@cerberus ~]# ip route ls
default dev ppp0 scope link
10.0.0.1 dev ppp0 proto kernel scope link src <my public IP address>
10.8.0.0/24 dev nordvpn proto kernel scope link src 10.8.0.12
192.168.2.0/24 dev lan proto kernel scope link src 192.168.2.1
[root@cerberus ~]# ip route ls table nordvpn
default via 10.8.0.1 dev nordvpn
10.8.0.1 dev lan scope link src 10.8.0.12
192.168.2.0/24 dev lan scope link src 192.168.2.1
[root@cerberus ~]# ip rule ls
0: from all lookup local
32764: from all fwmark 0x5 lookup nordvpn
32766: from all lookup main
32767: from all lookup default
Cuando los clientes habilitados asignados a la VPN fallan en sus búsquedas de DNS. Parece que las solicitudes se envían a través del túnel VPN, pero las respuestas llegan a la cadena de entrada en lugar de a la cadena de avance y no llegan a los clientes. ¿Dónde me equivoco?
Gracias de antemano por cualquier ayuda :)
Respuesta1
Trata de cambiar:
chain preroute_nordvpn {
udp dport $p_dns mark set $m_nordvpn dnat $a4_nordvpn_dns_1
tcp dport $p_dns mark set $m_nordvpn dnat $a4_nordvpn_dns_1
oif $i_wan mark set $m_nordvpn
}
chain prerouting { type nat hook prerouting priority -100
ip saddr @s_inet_nordvpn goto preroute_nordvpn
iif $i_lan oif $i_wan udp dport $p_dns redirect
iif $i_lan oif $i_wan tcp dport $p_dns redirect
}
a:
chain fwmark { type filter hook prerouting priority -150
ip saddr @s_inet_nordvpn mark set $m_nordvpn
}
chain lan_dns {
ip saddr @s_inet_nordvpn dnat $a4_nordvpn_dns_1
redirect
}
chain lan_dnat {
udp dport $p_dns goto lan_dns
tcp dport $p_dns goto lan_dns
}
chain prerouting { type nat hook prerouting priority -100
iif $i_lan goto lan_dnat
}