¿Cómo redirijo sólo el tráfico DNS para utilizar una interfaz de túnel cuando está activo?
Cualquier otro tipo de tráfico debería utilizar la tabla de enrutamiento del kernel. Siempre que la interfaz del túnel no esté activa, el tráfico DNS debe utilizar la tabla de enrutamiento del kernel. ¿Es esto posible con iptables?
Nota: Estoy usando Strongswan 5.9.1, por lo que si hay una manera de configurar esta funcionalidad desde Strongswan, me gustaría hacerlo. Sin embargo, estoy usando el sistema como una política basada en rutas. Además, actualmente estoy marcando paquetes con strongswan, no estoy seguro si eso estaría relacionado.
Interfaces:
# ip -br a
lo UNKNOWN 127.0.0.1/8 ::1/128
ens3 UP 192.168.0.15/24 fe80::e74:fcff:fe28:cb00/64
ens4 UP 2.2.1.2/30 fe80::e74:fcff:fe28:cb01/64
virbr0 DOWN 192.168.122.1/24
virbr0-nic DOWN
ip_vti0@NONE DOWN
vti01@NONE UNKNOWN 172.21.0.3/32 fe80::200:5efe:202:102/64
Rutas:
# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.0.1 0.0.0.0 UG 0 0 0 ens3
2.2.0.1 0.0.0.0 255.255.255.255 UH 101 0 0 ens4
2.2.1.0 0.0.0.0 255.255.255.252 U 101 0 0 ens4
3.3.0.0 2.2.0.1 255.255.255.252 UG 101 0 0 ens4
3.3.1.0 2.2.1.1 255.255.255.252 UG 101 0 0 ens4
10.212.134.0 192.168.0.1 255.255.255.0 UG 100 0 0 ens3
172.21.0.0 0.0.0.0 255.255.255.248 U 0 0 0 vti01
192.168.0.0 0.0.0.0 255.255.255.0 U 100 0 0 ens3
192.168.122.0 0.0.0.0 255.255.255.0 U 0 0 0 virbr0
Intenté usar la siguiente regla:
# iptables -t mangle -A OUTPUT -p udp --dport 53 --out-interface vti01
Puedo ver la regla, pero cuando la miro, no entran paquetes en la regla cuando hago una solicitud de excavación en el mismo host.
# watch -n1 iptables -t mangle -nvL
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 udp -- * vti01 0.0.0.0/0 0.0.0.0/0 udp dpt:53
¿Qué me estoy perdiendo?
Respuesta1
Gracias a @AB. Los comandos que utilicé fueron los siguientes (tenga en cuenta que hice que la identificación de la tabla fuera la misma que el número de protocolo DNS [53]):
ip route add table 53 0.0.0.0/0 dev vti01
ip rule add iif lo ipproto udp dport 53 lookup 53
sysctl -w net.ipv4.conf.vti01.rp_filter=2
Ejecuté lo siguiente para verificar el estado:
ip route list table 53
ip rule list | grep 53
Pude implementar esto en mi script _updown personalizado para que Strongswan creara y eliminara estas entradas cada vez que el túnel sube o baja, y funciona.
#!/bin/bash
set -o nounset
set -o errexit
VTI_IF="vti01"
PORT="53"
TABLE="53"
case "${PLUTO_VERB}" in
up-client)
ip tunnel add $VTI_IF local 2.2.1.2 remote 3.3.0.2 mode vti key 41
ip link set $VTI_IF up
ip addr add 172.21.0.3 dev $VTI_IF
ip route add 172.21.0.0/29 dev $VTI_IF
ip route add table $TABLE 0.0.0.0/0 dev $VTI_IF
ip rule add iif lo ipproto udp dport $PORT lookup $TABLE
sysctl -w "net.ipv4.conf.$VTI_IF.rp_filter=2"
sysctl -w "net.ipv4.conf.$VTI_IF.disable_policy=1"
sysctl -w "net.ipv4.conf.$VTI_IF.rp_filter=0"
sysctl -w "net.ipv4.conf.$VTI_IF.forwarding=1"
;;
down-client)
ip rule del iif lo ipproto udp dport $PORT lookup $TABLE
ip route del table $TABLE 0.0.0.0/0 dev $VTI_IF
ip tunnel del $VTI_IF
;;
esac
Luego invoco mi script en mi archivo swanctl.conf, así es como se ve una conexión. La sección debajo del elemento secundario "updown=" es cómo llamar al script.
connections {
remote-sa {
version = 2
local {
id = 2.2.1.2
}
local_addrs = 2.2.1.2
remote_addrs = 3.3.0.2
proposals = aes256-sha256-ecp384
local {
auth = psk
}
remote {
auth = psk
}
children {
remote-sa-child {
local_ts = 172.21.0.0/29
remote_ts = 0.0.0.0/0
mark_in = 41
mark_out = 41
esp_proposals = aes256-sha256-ecp384
updown = /opt/_updown_vti01 iptables
start_action = start
close_action = start
}
}
}
}