Cuento,
3 interfaces, eth0 (LAN), eth1 (ADSL), eth2 (4G).
eth0 -> eth1: funciona
(puertos 80, 443, 4070) eth0 -> eth2: no sucede
Esta es una representación gráfica de la idea:
Puerto 80 y 443 a través de eth2
y el resto a través de eth1
Netscheme:
eth0: -ip 10.0.0.1 -net 10.0.0.0/8 -gw 10.0.0.1 (the servers own intf)
eth1: -ip 192.168.1.74 -net 192.168.1.0/24 -gw 192.168.1.254
eth2: -ip 192.168.1.91 -net 192.168.0.0/24 -gw 192.168.0.1
Creo que este nuevo guión redirige 22 y 4070 a la tabla adecuada.
Sin embargo, después de llegar a esa tabla, no se redirige a eth2.
¡Este script funciona, excepto 22 y 4070!
(El puerto 80 no está comentado y funciona, pero a través de eth1, lo cual está mal).
modprobe iptable_nat
modprobe ip_conntrack
echo "1" > /proc/sys/net/ipv4/ip_forward
iptables -P INPUT ACCEPT
iptables -F INPUT
iptables -P OUTPUT ACCEPT
iptables -F OUTPUT
iptables -P FORWARD DROP
iptables -F FORWARD
iptables -F PREROUTING
iptables -t nat -F
iptables -t mangle -F
iptables -F
# This next line restores any issues trying to connect to something
# if you get weird ACK packets when trying to connect (at least i did)!
iptables -t mangle -A PREROUTING -p tcp -j CONNMARK --restore-mark
ip route flush table main
iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport 22 -j MARK --set-mark 1
### iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport 80 -j MARK --set-mark 1
iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport 4070 -j MARK --set-mark 1
## Setup routes
# LAN
route add -net 10.0.0.0 netmask 255.0.0.0 dev eth0
# ADSL
route add -net 192.168.1.0 netmask 255.255.255.0 dev eth1
# 4G (Only accessible if marking packages with \x01
route add -net 192.168.0.0 netmask 255.255.255.0 dev eth2
# Default via ADSL
## -- Does the same as ip route below? route add default gw 192.168.1.254
echo "201 eth2.out" >> /etc/iproute2/rt_tables
ip rule add fwmark 1 table eth2.out
ip route add default via 192.168.0.1 dev eth2 table eth2.out
ip route add default via 192.168.1.254 dev eth1
## Setup forwards
# From 4G to LAN
iptables -A FORWARD -i eth2 -o eth0 -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
# From ADSL to LAN
iptables -A FORWARD -i eth1 -o eth0 -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
# From LAN to ADSL (Default route out)
# - Note: If marked packages is sent to ADSL they will be mangled and rerouted to 4G
iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
iptables -t nat -A POSTROUTING -o eth2 -j MASQUERADE
Guión antiguo:
Ignore everything below unless you're interested in retracing my steps!!
He creado un script router.sh para configurar mi entorno en caso de que haga algo malo. Tengo 3 puertos que quiero enviar a una conexión 4G y el resto a través de una conexión ADSL de línea fija. Para hacer esto, he dado instrucciones a iptables para que manipule los paquetes en la ruta predeterminada y los envíe a través de mi interfaz 4G si --dport == 443 | 80 4070
Sin embargo, esto no funciona; Todavía me enrutan a través de mi teléfono fijo sin importar qué.
Así es como se ve mi script:
#!/bin/bash
## routing tables
# wireless = 4G via eth2
# adsl = adsl via eth1
modprobe iptable_nat
modprobe ip_conntrack
echo "1" > /proc/sys/net/ipv4/ip_forward
iptables -P INPUT ACCEPT
iptables -F INPUT
iptables -P OUTPUT ACCEPT
iptables -F OUTPUT
iptables -P FORWARD DROP
iptables -F FORWARD
iptables -t nat -F
ip route flush table main
ip route flush table wireless
ip route flush table adsl
## Setup routing tables
# ADSL
ip route add table adsl to 192.168.1.0/24 dev eth1
# 4G
ip route add table wireless to 192.168.0.0 dev eth2
ip rule add fwmark 0x1 table wireless
## Setup routes
# LAN
route add -net 10.0.0.0 netmask 255.0.0.0 dev eth0
# ADSL
route add -net 192.168.1.0 netmask 255.255.255.0 dev eth1
# 4G (Only accessible if marking packages with \x01
route add -net 192.168.0.0 netmask 255.255.255.0 dev eth2
# Default via ADSL
route add default gw 192.168.1.254
## Forward ports into the LAN
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j DNAT --to 10.0.0.3:80
## Lets mark all packets we want for 4G forward
# HTTPS
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 443 -j MARK --set-mark 1
# HTTP
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 80 -j MARK --set-mark 1
# Spotify
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 4070 -j MARK --set-mark 1
## Setup forwards
# From 4G to LAN
iptables -A FORWARD -i eth2 -o eth0 -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
# From ADSL to LAN
iptables -A FORWARD -i eth1 -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
# From LAN to ADSL (Default route out)
# - Note: If marked packages is sent to ADSL they will be mangled and rerouted to 4G
iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
iptables -A FORWARD -j LOG
#iptables --table nat --append POSTROUTING --out-interface eth2 --jump SNAT --to-source "192.168.1.74"
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
También he intentado agregar estos 3 al fondo del guión:
iptables -t nat -A POSTROUTING -o eth2 -p tcp --dport 80 -j SNAT --to "192.168.0.91"
iptables -t nat -A POSTROUTING -o eth2 -p tcp --dport 443 -j SNAT --to "192.168.0.91"
iptables -t nat -A POSTROUTING -o eth2 -p tcp --dport 4070 -j SNAT --to "192.168.0.91"
También intentado sin éxito:
iptables -A PREROUTING -t mangle -i eth0 -p tcp --dport 80 -j MARK --set-mark 1
Por último, pero no menos importante, probé:
## Lets mark all packets we want for 4G forward
# HTTPS
iptables -A POSTROUTING -t mangle -o eth1 -p tcp --dport 443 -j MARK --set-mark 1
# HTTP
iptables -A POSTROUTING -t mangle -o eth1 -p tcp --dport 80 -j MARK --set-mark 1
# Spotify
iptables -A POSTROUTING -t mangle -o eth1 -p tcp --dport 4070 -j MARK --set-mark 1
El enrutamiento funciona, puedo navegar por la web, escuchar música y demás, pero lo estoy haciendo a través de la interfaz incorrecta. He buscado en Google por mucho tiempo y he encontrado fragmentos para entender lo que estoy haciendo y por qué lo estoy haciendo. Podría configurar el tráfico a través de tc, pero si es posible marcando paquetes en iptables, me ayudaría mucho.
Supongo que estoy haciendo mal el orden en las diferentes reglas, principalmente en la parte de MASQUERADE . o si eso debería estar allí?
¿Alguien puede explicar cómo el puerto DNAT dice, tcp: 80 desde una interfaz externa (ya sea uno o AMBOS protocolos) a un espacio de direcciones interno 10.0.0.0?
Salidas:
root@Netbridge:~# route -n Kernel IP routing table Destination
Gateway Genmask Flags Metric Ref Use Iface<br>
0.0.0.0 192.168.1.254 0.0.0.0 UG 0 0 0 eth1<br>
10.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 eth0<br>
192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth2<br>
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1
root@Netbridge:~# ifconfig
eth0 Link encap:Ethernet HWaddr 00:0c:29:7e:9e:4e
inet addr:10.0.0.1 Bcast:10.255.255.255 Mask:255.0.0.0
eth1 Link encap:Ethernet HWaddr 00:0c:29:7e:9e:58
inet addr:192.168.1.74 Bcast:192.168.1.255 Mask:255.255.255.0
eth2 Link encap:Ethernet HWaddr 00:0c:29:7e:9e:62
inet addr:192.168.0.91 Bcast:192.168.0.255 Mask:255.255.255.0
Seguí estas instrucciones:
output-traffic-on-different-interfaces-based-on-destination-por
iptables-forward-Specific-port-to-Specific-nic
Entre algunos otros hilos relacionados.
localhost
a la dirección de laeth2
interfaz?ethX
la dirección IP de una persona evitará que los hosts en laethX
LAN accedan al servidor local utilizandoethY
la dirección IP de la misma, y no impedirá que los hostsethY
accedan al servidor utilizandoethX
la dirección IP de la misma. Recuerde que Linux usa un modelo de host débil.Respuestas:
BatchyX ya da una muy buena explicación sobre iptables y enrutamiento, por lo que ejerceré mi pereza e iré directamente al script.
Debe NAT todo el tráfico al puerto 80,443,22,4070 hasta 192.168.0.91. Todo lo demás será NAT hasta 192.168.1.254.
Vuelvo a hacer mis pruebas y termino siguiendo esta guía . Lo que falta en esa guía son las últimas 3 líneas en mi script. Lo descubrí desde otro puerto, pero perdí el rastro de ese enlace.
Es un script de trabajo probado.
Necesita ruta predeterminada
Una cosa que no puse en el script es configurar la ruta predeterminada. Debería ser
Cuando lo haga
route -n
, debería ser la única ruta predeterminada (Dest: 0.0.0.0)fw-router.sh
PS1: En resumen,
MASQUERADE
no funciona (en la mayoría de los casos, y definitivamente en su caso) para NAT con múltiples IP externas que necesitan algún tipo de equilibrio de carga o necesitan DNAT para manejar el tráfico entrante. NecesitasSNAT
control de dirección.PS2: iptables puro no es suficiente.
fuente
Nota: Solo he considerado el primer guión, ignorando el anterior.
route
yip route
. Esto es pura maldad. Solo use enip
todas partes y olvídeseifconfig
yroute
/etc/iproute2/rt_tables
no se restablece a través de reinicios. Agregar la misma entrada una y otra vez no es una buena idea, solo debe hacerlo una vez. Recuerde quert_tables
solo defina alias de nombre a valores numéricos, no cambia ninguna configuración.Ahora para
iptables
: En suFORWARD
cadena, deja caer paquetes que vienen de LAN a 4G. Esto es malo. elFORWARD
gancho se usa después de que se realiza el enrutamiento. En este punto, se realiza todo el enrutamiento de políticas y ya se sabe si el paquete debe enviarse a 4G o ADSL. No hay redireccionamiento realizado enFORWARD
o despuésFORWARD
(bueno, técnicamente, el redireccionamiento puede realizarse despuésPOSTROUTING
en casos severos, pero volviendo al punto).Ahora para su enrutamiento: recuerde que Ubuntu habilita el filtrado de ruta inversa de forma predeterminada. El filtrado de ruta inversa funciona de la siguiente manera: cuando el núcleo recibe un paquete (se reenvíe o no) desde una interfaz A, invertirá la dirección de origen y la dirección de destino, y comprobará si el paquete resultante debe enrutarse a través de la interfaz A. Si no es así, el paquete se descarta como un intento de suplantación de dirección.
Para los paquetes recibidos de
eth0
, esto no es un problema. Para los paquetes recibidos deeth1
, esto tampoco es un problema, porque al invertir la dirección IP de origen y la dirección IP de destino, el núcleo será la ruta predeterminada en la tablamain
. Para los paquetes recibidos deeth2
, que no marca, esto es un problema, porque el núcleo alcanzará la ruta predeterminada en la tablamain
, y considera que estos paquetes deberían haberse recibidoeth1
. La solución más fácil es deshabilitar el filtrado de ruta inversa en eth1:fuente