Balanceo de carga y NAT-ing múltiples conexiones ISP en Linux

15

Tengo dos conexiones a Internet de dos ISP diferentes y necesito equilibrar el tráfico que se origina hacia y desde mi red entre los dos ISP. Estoy usando Debian GNU / Linux.

Mi configuración es así:

eth0 (192.168.0.0/24) - Red local

eth1 (192.168.1.0/24) - ISP # 1

eth2 (192.168.2.0/24) - ISP # 2

Mi red local está conectada a este servidor a través de eth0 y la caja es el servidor DHCP cum Gateway para todas las máquinas en la LAN.

El servidor necesita hacer un equilibrio de carga entre los dos ISP y también debe hacer NAT.

He seguido las instrucciones de enrutamiento en lartc.org pero todavía necesito instrucciones para hacer el NAT correctamente.

Cualquier ayuda será apreciada.

PD: sé sobre pFsense pero necesito usar Linux.

Baishampayan Ghose
fuente
2
¿Qué tipo de instrucciones necesitas? todo se explica en lartc.org. ¿Tienes algún problema en particular?
lorenzog

Respuestas:

19

He realizado el equilibrio de carga utilizando los métodos lartc.org e iptables , y encuentro que el método iptables es más fácil de entender e implementar. El único inconveniente es que necesita una versión de iptables bastante reciente para poder usar el módulo de estadística

Supongamos algunas cosas:

LAN: eth0: 192.168.0.1/24

ISP1: eth1: 192.168.1.1/24, gateway: 192.168.1.2/24

ISP2: eth2: 192.168.2.1/24, puerta de enlace: 192.168.2.2/24

Así que así es como lo haría usando el método iptables:

Tablas de ruta

Primero edite / etc / iproute2 / rt_tables para agregar un mapa entre los números de la tabla de ruta y los nombres de ISP

...
10 ISP1
20 ISP2
...

Entonces las tablas 10 y 20 son para ISP1 e ISP2, respectivamente. Necesito completar estas tablas con rutas desde la tabla principal con este fragmento de código (que he tomado de hxxp: //linux-ip.net/html/adv-multi-internet.html)

ip route show table main | grep -Ev '^default' \
   | while read ROUTE ; do
     ip route add table ISP1 $ROUTE
done

Y agregue la puerta de enlace predeterminada a ISP1 a través de la puerta de enlace de ese ISP1:

ip route add default via 192.168.1.2 table ISP1

Haga lo mismo para ISP2

Entonces ahora tengo 2 tablas de rutas, 1 para cada ISP.

Iptables

OK, ahora uso iptables para distribuir paquetes de manera uniforme en cada tabla de rutas. Puede encontrar más información sobre cómo funciona este trabajo aquí ( http://www.diegolima.org/wordpress/?p=36 ) y aquí ( http://home.regit.org/?page_id=7 )

# iptables -t mangle -A PREROUTING -j CONNMARK --restore-mark
# iptables -t mangle -A PREROUTING -m mark ! --mark 0 -j ACCEPT
# iptables -t mangle -A PREROUTING -j MARK --set-mark 10
# iptables -t mangle -A PREROUTING -m statistic --mode random --probability 0.5 -j MARK --set-mark 20
# iptables -t mangle -A PREROUTING -j CONNMARK --save-mark

NAT

Bueno, NAT es fácil:

# iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
# iptables -t nat -A POSTROUTING -o eth2 -j MASQUERADE
mefat
fuente
3
Buena respuesta con enlaces. No necesariamente necesita una nueva iptables para hacer esto, ya que antes de que existiera la coincidencia de estadísticas , existían las coincidencias aleatorias y enésimas , que servidor tenía la misma función.
SiegeX
1
Tengo una pregunta sobre las marcas en iptables. En el enlace publicado, están marcando solo los paquetes que coinciden con el nuevo estado. ¿Por qué lo haces de manera diferente?
Matías
¿Puedo usar una red más, como ISP3, ISP4, etc.?
Vitor Mazuco
3

La respuesta de mefat me ayudó mucho, pero en lugar de una copia única de todas las reglas de la tabla principal en las dos tablas de ISP, un mejor enfoque podría ser usar el prio de regla para agregar las reglas predeterminadas después de la tabla principal.

Configure / etc / iproute2 / rt_tables como de costumbre:

...
10 ISP1
20 ISP2
...

Tenga en cuenta que

ip rule show

Muestra las reglas 0-> local, 32766-> main y 32767-> default. Ver man ippara más detalles.

Crucialmente, el proceso de enrutamiento funcionará desde las reglas de prio bajo a las de prio alto ... pero 32767 no es la regla más alta #. Entonces, si la tabla de enrutamiento principal no tiene una ruta predeterminada (pero puede contener todo tipo de rutas que cambian dinámicamente para vpns, etc.), si no se realiza una coincidencia, se convierte en predeterminada (normalmente vacía) y luego busca reglas de prio más altas.

Vea la sección 'tirar' aquí: http://linux-ip.net/html/routing-tables.html

Así que ahora configura

ip route add default dev $ISP1_IFACE table ISP1
ip route add default dev $ISP2_IFACE table ISP2

y para asegurarse de que se vean después de la mesa principal:

ip rule add fwmark 20 table ISP1 prio 33000
ip rule add fwmark 10 table ISP2 prio 33000

Utilizar

ip rule show

nuevamente para verificar que estas reglas son más altas que las principales

Luego use CONNMARK destrozando como mefat dijo:

# iptables -t mangle -A PREROUTING -j CONNMARK --restore-mark
# iptables -t mangle -A PREROUTING -m mark ! --mark 0 -j ACCEPT
# iptables -t mangle -A PREROUTING -j MARK --set-mark 10
# iptables -t mangle -A PREROUTING -m statistic --mode random --probability 0.5 -j MARK --set-mark 20
# iptables -t mangle -A PREROUTING -j CONNMARK --save-mark

Cosas a tener en cuenta: pppd necesita lo nodefaultroutecontrario, se configura en main; cuando un dispositivo se reinicia, las tablas ISP1 / ISP2 se limpian, por lo que deben restaurarse mediante un script.

Yo uso un script en /etc/ppp/ip-{up,down}.d/dual-routing

# One of my connections is ~2x faster than the other
BALANCED=0.3
ALL_ISP1=0
ALL_ISP2=1

RULENUM=4
set_balance() {
    iptables -t mangle -R PREROUTING $RULENUM -m statistic --mode random --probability $0 -j MARK --set-mark 2
}

# if both up
set_balance $BALANCED
# if ppp1 down:
set_balance $ALL_ISP1
# if ppp0 down:
set_balance $ALL_ISP2

Este es un equilibrio de carga basado en la conexión, así que voy a ver el uso de la carga para monitorear y reemplazar la regla de estadísticas: iptables -t mangle -R PREROUTING <n>desde el espacio del usuario. Entonces, si hay una descarga de larga duración en una conexión y la otra conexión está ligeramente cargada, deberíamos preferir la conexión con poca carga.

lbt
fuente