Añadir rutas en Linux mediante script .sh
NetRoute Pro genera un script Bash simple con comandos ip route add. Se aplica con un solo comando. Hacer las rutas persistentes entre reinicios requiere un paso extra según tu distribución.
Sintaxis del comando
Sintaxis (idempotente — usa esta forma en scripts):
ip route replace <CIDR> via <GATEWAY> dev <VPN_IF>
Ejemplo:
ip route replace 1.1.1.0/24 via 10.0.0.1 dev wg0
Ejecuta como root o con sudo. NetRoute Pro las genera en un script .sh — aplícalas con bash routes.sh. replace es idempotente: crea la ruta si no existe y la actualiza si existe, así que re-ejecutar el script es seguro; add fallaría con RTNETLINK answers: File exists en duplicados (y junto a set -e abortaría el script).
Requisitos previos
iproute2(preinstalado en casi todas las distros: Ubuntu, Debian, Fedora, Arch)- Acceso root/sudo
- Interfaz VPN configurada y funcional (WireGuard, OpenVPN, IKEv2, etc.)
- Extensión NetRoute Pro instalada en Chrome
Paso 1. Genera .sh en NetRoute Pro
- Abre el sitio web objetivo en Chrome
- Lanza la extensión NetRoute Pro
- Selecciona la plataforma Linux
- Introduce el gateway VPN (p.ej.
10.8.0.1) - Haz clic en Analyze Website
- Descarga
routes.sh
Paso 2. Aplica el script
chmod +x routes.sh
sudo bash routes.sh
El script añade todas las rutas al kernel en una sola pasada. Las rutas son inmediatamente efectivas.
Paso 3. Haz las rutas persistentes
Las rutas añadidas con ip route add se pierden al reiniciar. Elige una opción según tu distribución:
systemd-networkd
Crea un drop-in para la interfaz VPN:
sudo mkdir -p /etc/systemd/network/10-vpn.network.d
sudo nano /etc/systemd/network/10-vpn.network.d/routes.conf
Contenido del archivo (repite el bloque [Route] por cada subred):
[Route]
Destination=104.21.32.0/24
Gateway=10.8.0.1
[Route]
Destination=172.67.0.0/16
Gateway=10.8.0.1
Aplicar:
sudo systemctl restart systemd-networkd
NetworkManager dispatcher
Crea un script dispatcher que se ejecuta cuando la interfaz VPN sube:
sudo nano /etc/NetworkManager/dispatcher.d/99-vpn-routes
sudo chmod +x /etc/NetworkManager/dispatcher.d/99-vpn-routes
Contenido:
#!/bin/bash
# $1 = nombre de interfaz, $2 = acción
if [ "$1" = "wg0" ] && [ "$2" = "up" ]; then
ip route add 104.21.32.0/24 via 10.8.0.1
ip route add 172.67.0.0/16 via 10.8.0.1
fi
Ajusta wg0 al nombre real de tu interfaz VPN.
servicio systemd oneshot (recomendado)
Funciona en cualquier distro con systemd (Ubuntu, Debian, Fedora, Arch, RHEL, openSUSE — prácticamente todas las distros modernas). Espera correctamente a que el túnel VPN esté arriba antes de aplicar rutas — sin race conditions ni hacks con sleep.
sudo mv routes.sh /usr/local/bin/routes.sh
sudo chmod +x /usr/local/bin/routes.sh
sudo tee /etc/systemd/system/vpn-routes.service > /dev/null <<'EOF'
[Unit]
Description=Apply VPN split-tunnel routes
After=network-online.target wg-quick@wg0.service
Wants=network-online.target
Requisite=wg-quick@wg0.service
BindsTo=wg-quick@wg0.service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/routes.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now vpn-routes.service
Reemplaza wg-quick@wg0.service con tu unidad VPN:
- OpenVPN:
openvpn-client@<name>.service - strongSwan / IPsec:
strongswan.service - Sin dependencia VPN específica: elimina las líneas
Requisite=yBindsTo=, deja sóloAfter=network-online.target
Verifica el servicio:
systemctl status vpn-routes.service
journalctl -u vpn-routes.service
@reboot cron? El demonio cron normalmente arranca antes de que el túnel VPN esté arriba — ip route add se ejecuta contra una interfaz que aún no existe, falla silenciosamente, y descubres las rutas rotas sólo tras un reinicio. After= y Requisite= de systemd esperan a la unidad VPN y eliminan el race. BindsTo= también detiene las rutas cuando la VPN cae.
DNS leak — lectura obligatoria
Esta guía enruta tráfico por IP. No enruta DNS. Tu navegador sigue preguntando al resolver del sistema (normalmente el de tu ISP, vía DHCP) por example.com — sólo el tráfico IP resultante pasa por la VPN. El ISP ve qué sitios visitas aunque los datos estén cifrados.
Tres opciones, según tu modelo de amenazas:
- Ocultar DNS del ISP totalmente (split-DNS). En systemd-resolved, configura el DNS por enlace sólo para los dominios tunelizados:
Las consultas desudo resolvectl dns wg0 10.0.0.1 sudo resolvectl domain wg0 ~example.com ~another-site.comexample.comahora pasan por la VPN; el resto usa el resolver por defecto. Sustituye10.0.0.1por el DNS interno de tu proveedor VPN. - Reducir visibilidad para el ISP (DoH/DoT público). Apunta el resolver del sistema a un DNS cifrado público:
El ISP deja de ver consultas de dominio; el resolver público sí las ve.sudo resolvectl dns wg0 1.1.1.1#cloudflare-dns.com sudo resolvectl dnsovertls wg0 yes - Aceptar la fuga. Si tu objetivo es acceder a contenido, no evitar vigilancia, esto está bien — sólo se filtran los lookups, los datos siguen cifrados.
Verifica el estado actual en dnsleaktest.com o browserleaks.com/dns — el resolver mostrado debe pertenecer a tu VPN o al DoH elegido, no al ISP. Localmente, resolvectl status muestra la configuración por enlace.
Fuga por IPv6 dual-stack
Si el destino tiene un registro AAAA (la mayoría de sitios populares lo tienen — Cloudflare, Google, AWS son dual-stack), el SO prefiere IPv6 sobre IPv4 (RFC 6724). Las rutas añadidas en esta guía son sólo IPv4 — el tráfico IPv6 elude la VPN y sale por la ruta v6 por defecto del ISP. Resultado: la VPN parece activa pero no hace nada para destinos dual-stack.
Comprobación rápida:
curl -6 -s -o /dev/null -w "remote=%{remote_ip}\n" https://example.com
ip -6 route get $(dig +short AAAA example.com | head -1)
Si la traza IPv6 no pasa por tu interfaz VPN, estás eludiendo el túnel. Dos soluciones:
- Enrutar v6 por la VPN también (si tu proveedor tiene endpoint IPv6). Genera rutas IPv6 en NetRoute Pro — mismo flujo, prefijos distintos (
2606:4700::/32, etc). - Deshabilitar IPv6 a nivel de sistema:
Todo el tráfico cae a v4 y se tuneliza correctamente.sudo sysctl -w net.ipv6.conf.all.disable_ipv6=1 sudo sysctl -w net.ipv6.conf.default.disable_ipv6=1 # Permanente: las mismas líneas en /etc/sysctl.d/99-disable-ipv6.conf
Fail-closed (kill switch)
Cuando el túnel VPN cae (cambio de red, problema del proveedor, sleep/wake), el kernel elimina las rutas asociadas a la interfaz muerta — y el tráfico a los CIDR antes tunelizados cae a la ruta por defecto del ISP. Resultado: fuga silenciosa sin error visible. Para forzar fail-closed (bloquear en vez de filtrar):
# nftables (Linux moderno)
sudo nft add table inet vpnkill
sudo nft add chain inet vpnkill output { type filter hook output priority 0 \; }
sudo nft add rule inet vpnkill output ip daddr 1.1.1.0/24 oif != wg0 drop
sudo nft add rule inet vpnkill output ip daddr 8.8.8.0/24 oif != wg0 drop
# Repite para cada CIDR tunelizado.
Equivalente con iptables:
sudo iptables -I OUTPUT ! -o wg0 -d 1.1.1.0/24 -j REJECT
sudo iptables -I OUTPUT ! -o wg0 -d 8.8.8.0/24 -j REJECT
Ahora el tráfico a esos prefijos por cualquier interfaz que no sea wg0 se bloquea — VPN caída = bloqueado, no filtrado. El usuario ve un error de conexión (señal clara de que la VPN no funciona) en vez de una salida silenciosa por el ISP. Este es el modo de fallo seguro.
Verificar
ip route show | grep 10.8.0.1
Debes ver todas las subredes enrutadas por tu gateway VPN. Prueba con traceroute:
traceroute example.com
Revertir
El script guarda un snapshot de la tabla de rutas en /tmp/route-table.<timestamp>.txt antes de aplicar cambios — útil para diagnosticar qué cambió. Para eliminar las rutas añadidas por NetRoute Pro, borra cada prefijo:
for cidr in 1.1.1.0/24 8.8.8.0/24 162.159.0.0/16; do
sudo ip route del "$cidr" 2>/dev/null || true
done
O, más conservadoramente, genera una lista inversa desde tu routes.sh, sustituyendo replace (o add) por del:
awk '/ip route /{ sub(/^ip route (replace|add)/, "ip route del"); print }' routes.sh | sudo bash
Si algo salió catastróficamente mal, el snapshot en /tmp/route-table.<timestamp>.txt muestra el estado previo — puedes restaurar manualmente lo necesario.
Problemas comunes
Network is unreachable
La interfaz VPN no está activa. Comprueba con ip link show que tu interfaz VPN (p.ej. wg0, tun0) está UP. Activa la VPN antes de aplicar rutas.
Permission denied
Necesitas privilegios root. Ejecuta con sudo.
Las rutas no se aplican tras reiniciar
No configuraste persistencia. Elige una de las tres opciones del Paso 3.
Archivo de configuración de ejemplo
Plantilla lista para editar con comentarios. Reemplaza las rutas de ejemplo con la salida de NetRoute Pro para tus sitios.
linux-routes.sh— Script Bash con comandosip route add
#!/bin/bash
# Example Linux routing script for split tunneling.
# Generated by NetRoute Pro: https://alexander2k.github.io/netroute-site/
#
# Run as root or with sudo. Routes added here last until reboot —
# for persistence see the Linux guide (systemd-networkd / NetworkManager).
#
# Idempotent: uses `ip route replace` so re-running the script is safe.
# `add` would fail with "RTNETLINK answers: File exists" on a duplicate;
# combined with `set -e`, the first existing route would abort the script
# and skip the rest. `replace` creates if missing, updates if present.
set -euo pipefail
DEV="wg0" # VPN interface name (wg0, tun0, ppp0, ...)
GW="10.0.0.1" # VPN gateway IP (or use only "dev $DEV" if VPN is point-to-point)
# Snapshot current route table — useful for rollback if something breaks.
SNAPSHOT="/tmp/route-table.$(date +%s).txt"
ip route show > "$SNAPSHOT"
echo "Route table snapshot saved to $SNAPSHOT"
ip route replace 1.1.1.0/24 via "$GW" dev "$DEV"
ip route replace 8.8.8.0/24 via "$GW" dev "$DEV"
ip route replace 162.159.0.0/16 via "$GW" dev "$DEV"
# Verify with: ip route show
# Remove a single route: ip route del <CIDR>
# Full rollback (delete all routes added by this script):
# for cidr in 1.1.1.0/24 8.8.8.0/24 162.159.0.0/16; do
# ip route del "$cidr" 2>/dev/null || true
# done
Consejo: ¿Necesitas un config sin estas líneas de comentarios? En las opciones de NetRoute Pro desactiva «Incluir comentarios en archivos exportados» — la extensión exportará solo los comandos de rutas. Útil para routers que no toleran comentarios.
Ver todos los ejemplos en GitHub →
Documentación oficial
- ip-route(8) man page (en)
- systemd.network(5) (en)
- NetworkManager Dispatcher (en)
- Arch Wiki: systemd-networkd (en)
Guías relacionadas
- Keenetic — rutas desde archivo
.bat - MikroTik — importación de script
.rscde RouterOS - WireGuard — split tunneling con
AllowedIPs - OpenVPN — directivas
routeen config cliente
¿Listo para probar?
NetRoute Pro — extensión gratuita de Chrome para generar rutas desde cualquier sitio web.
Instalar extensión