iptables --set-mark - Enruta diferentes puertos a través de diferentes interfaces

14

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
ingrese la descripción de la imagen aquí

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.

Torxed
fuente
Lo siento, pero ¿hay alguna razón para no vincular apache solo localhosta la dirección de la eth2interfaz?
Jan Marek
@ JanMarek: No hay mención de apache aquí. Y para su información, vincular un zócalo en ethXla dirección IP de una persona evitará que los hosts en la ethXLAN accedan al servidor local utilizando ethYla dirección IP de la misma, y ​​no impedirá que los hosts ethYaccedan al servidor utilizando ethXla dirección IP de la misma. Recuerde que Linux usa un modelo de host débil.
BatchyX
De acuerdo, es posible que haya más servidores web, no solo servidores apache ... Sin embargo, ese servidor web enlazado en la interfaz eth2 puede ser una solución simple. Pero puedo estar equivocado, lo sé.
Jan Marek

Respuestas:

5

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

route add default gw 192.168.1.254

Cuando lo haga route -n, debería ser la única ruta predeterminada (Dest: 0.0.0.0)

0.0.0.0    192.168.1.254    0.0.0.0    UG    0    0    0    eth1

fw-router.sh

# Reset / Flush iptables
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P ACEPTACIÓN DE ENTRADA
iptables -P ADELANTE ADELANTE
iptables -P ACEPTACIÓN DE SALIDA

# Reset / Flush / Setup IP Route (tabla 4)
tabla de descarga de ruta ip 4
ip route show table main | grep -Ev ^ predeterminado | mientras lee RUTA; hacer ruta ip agregar tabla 4 $ RUTA; hecho
ruta IP agregar tabla 4 por defecto a través de 192.168.0.1

#Paquete Mark con puerto D. a juego
iptables -t mangle -A PREROUTING -p tcp --dport 22 -s 10.0.0.0/24 -j MARK --set-mark 4
iptables -t mangle -A PREROUTING -p tcp --dport 80 -s 10.0.0.0/24 -j MARK --set-mark 4
iptables -t mangle -A PREROUTING -p tcp --dport 443 -s 10.0.0.0/24 -j MARK --set-mark 4
iptables -t mangle -A PREROUTING -p tcp --dport 4070 -s 10.0.0.0/24 -j MARK --set-mark 4

Reglas #SNAT
iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to-source 192.168.1.74
iptables -t nat -A POSTROUTING -o eth2 -j SNAT --to-source 192.168.0.91

Ruta #IP
regla ip agregar fwmark 4 tabla 4
ip cache flush cache

#IP Stack
# Esta es la parte faltante de la guía
echo 1> / proc / sys / net / ipv4 / ip_forward
para f en / proc / sys / net / ipv4 / conf / * / rp_filter; hacer eco 0> $ f; hecho
echo 0> / proc / sys / net / ipv4 / route / flush

PS1: En resumen, MASQUERADEno 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. Necesitas SNATcontrol de dirección.

PS2: iptables puro no es suficiente.

John Siu
fuente
En primer lugar, felicidades por ir directamente al script :) ¡Lo intentaré esta noche cuando vuelva al entorno en el que se ejecutará!
Torxed
hmm, puede necesitar una fuerte revisión. Déjame saber el resultado.
John Siu
Revisado, debería estar funcionando ahora.
John Siu
Sweet, nos pondremos en
contacto
Te amo, mucho dolor de cabeza y lo resolviste! ¡Gracias!
Torxed
6

Nota: Solo he considerado el primer guión, ignorando el anterior.

  • No es necesario que modprobe los módulos de netfilter a mano con las iptables actuales. Esto solo es necesario para rastreadores de conexión personalizados.
  • No te confundas routey ip route. Esto es pura maldad. Solo use en iptodas partes y olvídese ifconfigyroute
  • /etc/iproute2/rt_tablesno 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 que rt_tablessolo defina alias de nombre a valores numéricos, no cambia ninguna configuración.

  • Ahora para iptables: En su FORWARDcadena, deja caer paquetes que vienen de LAN a 4G. Esto es malo. el FORWARDgancho 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 en FORWARDo después FORWARD(bueno, técnicamente, el redireccionamiento puede realizarse después POSTROUTINGen 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 de eth1, 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 tabla main. Para los paquetes recibidos de eth2, que no marca, esto es un problema, porque el núcleo alcanzará la ruta predeterminada en la tabla main, y considera que estos paquetes deberían haberse recibido eth1. La solución más fácil es deshabilitar el filtrado de ruta inversa en eth1:

sysctl -w net.ipv4.conf.eth1.rp_filter=0
BatchyX
fuente
Todos los excelentes comentarios y sí, hay una lógica defectuosa de mi parte, por ejemplo, agregar rt_tables cada vez y especialmente no borrar ciertas tablas como debería, pero llegaré :) Voy a intentarlo todo y veré si funciona, si es así, ¡+50 para ti y lo más importante es que has salvado a un hombre de ser cortado en pedazos! :)
Torxed
1
El siguiente script funciona, pero usted también se merece toda la gratitud, me dio una cosa o dos para pensar y rp_filter = 0 me ayudó mucho. : D
Torxed
@BatchyX muy informativo, vota también a ti.
John Siu
@Torxed La publicación que vi mencionar rp_filter para TODAS las interfaces debe estar deshabilitada. No estoy seguro si funciona de otra manera.
John Siu
@JohnSiu: solo necesita deshabilitar el filtro rp en las interfaces donde es problemático. En ese caso, es eth1, porque no hay una ruta que vaya a esa interfaz cuando las marcas no están establecidas. eth2 no tiene ese problema, ya que la ruta predeterminada entra en esa interfaz. Para eth0, en realidad es útil mantener habilitado el filtro rp, de lo contrario, alguien en la LAN podría falsificar un paquete IP con una dirección de origen en Internet y una dirección de destino en la LAN, y el enrutador lo aceptaría con gusto, y reenviaría volver a ... eth0.
BatchyX