Linux como enrutador con múltiples proveedores de internet

16

Linux como enrutador: tengo 3 proveedores de Internet, cada uno con su propio módem.

Proveedor1 , que es la dirección de la puerta de enlace 192.168.1.1
Conectado al enrutador Linux eth1 /192.168.1.2

Proveedor2 , dirección de puerta de enlace 192.168.2.1
Conectado al enrutador Linux eth2 /192.168.2.2

Proveedor3 , dirección de puerta de enlace 192.168.3.1
Conectado al enrutador Linux eth3 /192.168.3.2

                                                                           ________
                                                   +------------+         /
                                                   |            |        |
                            +----------------------+ Provider 1 +--------|
        __                  |192.168.1.2           |192.168.1.1 |       /
    ___/  \_         +------+-------+              +------------+      |
  _/        \__      |    eth1      |              +------------+      /
 /             \ eth0|              |192.168.2.2   |            |      |
|Client network -----+  ROUTER  eth2|--------------+ Provider 2 +------|     Internet
 \10.0.0.0/24 __/    |              |              |192.168.2.1 |      |
   \__     __/       |    eth3      |              +------------+      \
      \___/          +------+-------+              +------------+       |
                            |192.168.3.2           |            |       \
                            +----------------------+ Provider 3 +-------|
                                                   |192.168.3.1 |       |
                                                   +------------+       \________

Me gustaría enrutar a los clientes en la red 10.0.0.0/24 por IP de origen a diferentes puertas de enlace.
La interfaz con la red del cliente es eth0 /10.0.0.1, que es la puerta de enlace predeterminada para todos los clientes.

Por ejemplo:
10.0.0.11 se debe enrutar al proveedor1 @ eth1
10.0.0.12 se debe enrutar al proveedor2 @ eth2
... y así sucesivamente ...

Creo que necesito usar ip routey iptablespara SNAT, pero no he descubierto exactamente cómo.
Aquí está el guión que tengo hasta ahora.
El reenvío de ipv4 está habilitado.

#!/bin/bash
# flush tables
ip route flush table connection1
ip route flush table connection2
ip route flush table connection3

# add the default gateways for each table
ip route add table connection1 default via 192.168.1.1
ip route add table connection2 default via 192.168.2.1
ip route add table connection3 default via 192.168.3.1

# add some IP addresses for marking
iptables -t mangle -A PREROUTING -s 10.0.0.11 -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -s 10.0.0.12 -j MARK --set-mark 2
iptables -t mangle -A PREROUTING -s 10.0.0.13 -j MARK --set-mark 3

# add the source nat rules for each outgoing interface
iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to-source 192.168.1.2
iptables -t nat -A POSTROUTING -o eth2 -j SNAT --to-source 192.168.2.2
iptables -t nat -A POSTROUTING -o eth3 -j SNAT --to-source 192.168.3.2

# link routing tables to connections (?)
ip rule add fwmark 1 table connection1
ip rule add fwmark 2 table connection2
ip rule add fwmark 3 table connection3

#default route for anything not configured above should be eth2
Flav
fuente
Necesitas agregar CONNMARK, creo, para guardar / restaurar la marca para que pueda aplicarse a los paquetes 2..n (que será NAT'd por el seguimiento de la conexión)
derobert
He agregado una respuesta con extractos de la configuración que usamos aquí. Intentaré registrarme durante el fin de semana para aclarar cualquier cosa ...
derobert

Respuestas:

13

Aquí hay una configuración similar de uno de nuestros enrutadores (con algunas cosas irrelevantes recortadas). Tenga en cuenta que esto maneja entrantes conexiones .

Tenga en cuenta el uso de variables en lugar de números de marca codificados. ¡Mucho más fácil de mantener! Se almacenan en un script separado y se obtienen. Los nombres de las tablas se configuran en /etc/iproute2/rt_tables. Los nombres de interfaz están configurados /etc/udev/rules.d/70-persistent-net.rules.

##### fwmark ######
iptables -t mangle -F
iptables -t mangle -X

iptables -t mangle -A PREROUTING -j CONNMARK --restore-mark
iptables -t mangle -A PREROUTING -m mark ! --mark 0 -j RETURN # if already set, we're done
iptables -t mangle -A PREROUTING -i wan      -j MARK --set-mark $MARK_CAVTEL
iptables -t mangle -A PREROUTING -i comcast  -j MARK --set-mark $MARK_COMCAST
iptables -t mangle -A PREROUTING -i vz-dsl   -j MARK --set-mark $MARK_VZDSL

iptables -t mangle -A POSTROUTING -o wan     -j MARK --set-mark $MARK_CAVTEL
iptables -t mangle -A POSTROUTING -o comcast -j MARK --set-mark $MARK_COMCAST
iptables -t mangle -A POSTROUTING -o vz-dsl  -j MARK --set-mark $MARK_VZDSL
iptables -t mangle -A POSTROUTING -j CONNMARK --save-mark

##### NAT ######
iptables -t nat -F
iptables -t nat -X
for local in «list of internal IP/netmask combos»; do
    iptables -t nat -A POSTROUTING -s $local -o wan     -j SNAT --to-source «IP»
    iptables -t nat -A POSTROUTING -s $local -o comcast -j SNAT --to-source «IP»
    iptables -t nat -A POSTROUTING -s $local -o vz-dsl  -j SNAT --to-source «IP»
done

# this is an example of what the incoming traffic rules look like
for extip in «list of external IPs»; do
    iptables -t nat -A PREROUTING   -p tcp -d $extip --dport «port» -j DNAT --to-destination «internal-IP»:443
done

Y las reglas:

ip rule flush
ip rule add from all               pref 1000  lookup main 
ip rule add from A.B.C.D/29        pref 1500  lookup comcast # these IPs are the external ranges (we have multiple IPs on each connection)
ip rule add from E.F.G.H/29        pref 1501  lookup cavtel
ip rule add from I.J.K.L/31        pref 1502  lookup vzdsl
ip rule add from M.N.O.P/31        pref 1502  lookup vzdsl # yes, you can have multiple ranges
ip rule add fwmark $MARK_COMCAST   pref 2000  lookup comcast
ip rule add fwmark $MARK_CAVTEL    pref 2001  lookup cavtel
ip rule add fwmark $MARK_VZDSL     pref 2002  lookup vzdsl
ip rule add                        pref 2500  lookup comcast # the pref order here determines the default—we default to Comcast.
ip rule add                        pref 2501  lookup cavtel
ip rule add                        pref 2502  lookup vzdsl
ip rule add                        pref 32767 lookup default

Las tablas de enrutamiento se configuran /etc/network/interfaces, por lo que quitar una interfaz hace que cambie a usar una diferente:

iface comcast inet static
        address A.B.C.Q
        netmask 255.255.255.248
        up ip route add table comcast default via A.B.C.R dev comcast
        down ip route flush table comcast

Nota: Si también está filtrando (lo que probablemente sea), también deberá agregar las reglas apropiadas FORWARDal ACCEPTtráfico. Especialmente para cualquier tráfico entrante.

derobert
fuente
¡Muchas gracias! Ahora voy a modificar esto a mis necesidades, cargarlo en el cuadro y actualizar esta publicación.
Flav
Funciona como un encanto, gracias de nuevo. Excepto por el orden pref / ruta predeterminada para 'comcast'. (Para mí, eso debería ser eth2) Pero creo que lo solucioné agregando una regla general ip rule add from 10.0.0.0/24 pref 1400 lookup eth2y creando las excepciones después.
Flav
1
@Flav también puede establecer sus excepciones con las marcas de firewall (en PREROUTING). Por cierto: una de las preguntas vinculadas ( unix.stackexchange.com/questions/70440/… ) tiene más explicaciones sobre parte de esta configuración. Esas reglas de ip / mask son en realidad para el tráfico no NAT'd en mi configuración (SNAT ocurre en POSTROUTING, por lo tanto, después de las cosas de la regla de ip)
derobert