Hola, quién halla llegado a este artículo ya sabe lo que quiere, entonces no me tomaré el tiempo de explicar de que se trata el balanceo de carga de conexiones a internet. Para nuestro caso contamos con lo siguiente:
- Debian Lenny AMD64 (igual para i386)
- Kernel 2.6.26-2-1-amd64
- Tres tarjetas de red Ethernet
- Dos conexiones ADSL
- Switch o AP inalámbrico
- Cerebro inquieto y paciente
- Café, mucho café.

Lo único que hay que tener en cuenta para que esta configuración funcione es quitarle los gateway a todas las interfaces de red, quedando entonces su /etc/network/interfaces sin líneas que digan gateway. En el sentido mas estricto tendríamos que limpiar la tabla main y esas cosas pero en fin, no es necesario y se pueden obviar algunos mensajes de error.
Este es mi /etc/network/interfaces:
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
# The loopback network interface
auto lo
iface lo inet loopback
address 127.0.0.1
netmask 255.0.0.0
# The primary network interface
# LAN
iface eth0 inet static
address 192.168.1.1
netmask 255.255.255.0
auto eth0
# ADSL1
allow-hotplug eth1
iface eth1 inet static
address 10.1.0.2
netmask 255.255.255.0
network 10.1.0.0
broadcast 10.1.0.255
#gateway 10.1.0.1
dns-nameservers 10.1.0.1 10.1.1.1
auto eth1
# ADSL2
iface eth2 inet static
address 10.1.1.2
netmask 255.255.255.0
network 10.1.1.0
broadcast 10.1.1.255
#gateway 10.1.1.1
dns-nameservers 10.1.1.1 10.1.0.1
auto eth2
A continuación dos scripts usados suficientemente comentados, incluyendo el NAT para la red local (compartir internet) y redireccionamiento para proxy transparente (pueden quitarlo si prefieren), estos scripts deben ponerse a correr desde /etc/rc.local o como prefieran, primero el de rutas y luego el de NAT. Antes de ejecutar los scripts debemos agregar las tablas de rutas al archivo de rutas, esto se hace una sola vez:
echo 200 T1 >> /etc/iproute2/rt_tables
echo 201 T2 >> /etc/iproute2/rt_tables
echo 202 lento >> /etc/iproute2/rt_tables
echo 203 rapido >> /etc/iproute2/rt_tables
#!/bin/bash
IF0="eth0" # Interface conectada a la LAN
IF1="eth1" # Interface conectada a ADSL1 Lenta
IF2="eth2" # Interface conectada a ADSL2 Rápida
IP0="192.168.1.1" # Gateway Local, IP Local
IP1="10.1.0.2" # IP de la IF1
IP2="10.1.1.2" # IP de la IF2
P0_NET="192.168.1.0/24" # Red Local
P1_NET="10.1.0.0/24" # Red para IF1
P2_NET="10.1.1.0/24" # Red para IF2
P1="10.1.0.1" # Gateway para ADSL1
P2="10.1.1.1" # Gateway para ADSL2
# Creo las tablas de rutas para las dos interfaces uplink
echo "Creando las rutas para cada tabla"
ip route add ${P1_NET} dev ${IF1} src ${IP1} table T1
ip route add default via ${P1} table T1
ip route add ${P2_NET} dev ${IF2} src ${IP2} table T2
ip route add default via ${P2} table T2
echo "Hecho."
# Aseguro que cada red enviará sus solicitudes a la ip correcta
echo "Asegurando la ruta para cada interface e IP"
ip route add ${P1_NET} dev ${IF1} src ${IP1}
ip route add ${P2_NET} dev ${IF2} src ${IP2}
echo "Hecho."
# Creo dos reglas para que cada ip se fije a su tabla de rutas
echo "Creando reglas para cada tabla"
ip rule add from ${IP1} table T1
ip rule add from ${IP2} table T2
echo "Hecho."
# Hago el balanceo 1 a 2
echo "Haciendo el balanceo"
ip route add default scope global nexthop via ${P1} dev ${IF1} weight 1 \
nexthop via ${P2} dev ${IF2} weight 2
echo "Hecho."
# Agrego dos tablas de rutas estáticas para hacer marcado de paquetes sobre ellas
echo "Creando tablas para marcado de paquetes ..."
# Enlace lento
ip rule add fwmark 1 table lento
ip route add table lento via ${P1} dev eth1
# Enlace rápido
ip rule add fwmark 2 table rapido
ip route add table rapido via ${P2} dev eth2
echo "Refrescando las rutas"
ip route flush cache
echo "Hecho."
Y bien, noten que el balanceo se hizo de 1 a 2 para que la conexión rápida trabaje el doble de lo que trabaja la lenta, esto depende en si de lo bueno que sea cada isp y del uso que quieran hacer de cada conexión. Noten que se usa fwmark para marcar cada ruta y así poder usar esta marca en el marcado de paquetes. Existen otras técnicas mucho mas pulidas y con mejores resultados que esta, por ejemplo parchando el kernel para rutas dinámicas y cuanta cosa los gurús saben, pero a mi me va funcionando de 10 esta técnica. Así mismo se pueden usar marcas sobre las tablas T1 y T2, pero aquí están separadas por simple claridad.
Si todo está bien tendríamos las siguientes salidas:
edoras:~# ip route
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.1
10.1.0.0/24 dev eth1 proto kernel scope link src 10.1.0.2
10.1.1.0/24 dev eth2 proto kernel scope link src 10.1.1.2
default
nexthop via 10.1.0.1 dev eth1 weight 1
nexthop via 10.1.1.1 dev eth2 weight 2
edoras:~# ip route list table T1
10.1.0.0/24 dev eth1 scope link src 10.1.0.2
default via 10.1.0.1 dev eth1
edoras:~# ip route list table T2
10.1.1.0/24 dev eth2 scope link src 10.1.1.2
default via 10.1.1.1 dev eth2
edoras:~# ip route show table lento
default via 10.1.0.1 dev eth1
edoras:~# ip route show table rapido
default via 10.1.0.1 dev eth1
Con esto ya tenemos nuestras rutas y balanceo, en este punto el equipo que hace de router en el que estamos aplicando estas reglas debería navegar sin problemas. Pero nos falta el NAT para la red local y es aquí donde entra el otro script, noten como se usan las marcas:
#!/bin/bash
echo "Limpiando Reglas Anteriores..."
iptables -F
iptables -X
iptables -Z
iptables -t nat -F
iptables -t mangle -F
IF0="eth0" # Interface conectada a la LAN
IF1="eth1" # Interface conectada a ADSL1 Lenta
IF2="eth2" # Interface conectada a ADSL2 Rápida
IP0="192.168.1.1" # Gateway Local, IP Local
IP1="10.1.0.2" # IP de la IF1
IP2="10.1.1.2" # IP de la IF2
P0_NET="192.168.1.0/24" # Red Local
P1_NET="10.1.0.0/24" # Red para IF1
P2_NET="10.1.1.0/24" # Red para IF2
P1="10.1.0.1" # Gateway para ADSL1
P2="10.1.1.1" # Gateway para ADSL2
# Ahora hago el NAT
echo "Activando NAT ..."
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -s ${P0_NET} -o ${IF1} -j MASQUERADE
iptables -t nat -A POSTROUTING -s ${P0_NET} -o ${IF2} -j MASQUERADE
# Redirecciono al Proxy
iptables -t nat -A PREROUTING -i ${IF0} -p tcp --dport http -j DNAT --to ${IP0}":8080"
iptables -t nat -A PREROUTING -i ${IF0} -p tcp --dport 81 -j DNAT --to ${IP0}":8080"
iptables -t nat -A PREROUTING -i ${IF0} -p tcp --dport 8080:8099 -j DNAT --to ${IP0}":8080"
iptables -t nat -A PREROUTING -i ${IF0} -p tcp --dport 3128:3130 -j DNAT --to ${IP0}":8080"
# Hago marcado de paquetes para asegurar que los paquetes de estos puertos encontrarán el camino de vuelta
echo "Realizando marcado de paquetes ..."
iptables -t mangle -A PREROUTING -i ${IF0} -s ${P0_NET} -p tcp --dport 1863 -m state --state NEW,ESTABLISHED,RELATED -j MARK --set-mark 2
iptables -t mangle -A PREROUTING -i ${IF0} -s ${P0_NET} -p tcp --dport 6667 -m state --state NEW,ESTABLISHED,RELATED -j MARK --set-mark 2
echo "Listo."
echo "Reglas Aplicadas"
iptables -L -n -v
iptables -t nat -L -n -v
iptables -t mangle -L -n -v
El buen observador se habrá dado cuenta que con la tabla mangle se marcan los paquetes que pertenecen a determinados protocolos y que esto le da la posibilidad de definir que servicios quiere a través de que enlace, por ejemplo se podría pensar en mandar el molesto P2P a través del enlace lento (tarea para el lector).
Creo que eso es todo, recuerden que a la primera no funciona, que es bueno que lean algo de LARTC para que aprendan sobre rutas y control de tráfico en Linux y que siempre habrá una forma mas elegante, eficiente y simple de hacer las cosas. También recuerden que pueden añadir un servidor dns local, un proxy transparente y todo lo que quieran a esta configuración.
Si falla, reinicien la red y hagan ip route flush table sobre cada tabla creada. Modifiquen y vuelvan a probar.
Aquí un interesante artículo sobre balanceo de carga manual (Definir varios Gateway), puede servir también de acuerdo a la necesidad.
---

11 comentarios:
Gracias por tomarte el tiempo de hacer el tutorial de configuración, apenas tenga la posibilidad lo intentaré
interesante... desde hace tiempo quiero hacer esto je
Hola..
Muy bueno el tuto.
Pero tengo una duda.
Esta entrada no esta de mas?
# Aseguro que cada red enviará sus solicitudes a la ip correcta
echo "Asegurando la ruta para cada interface e IP"
ip route add ${P1_NET} dev ${IF1} src ${IP1}
ip route add ${P2_NET} dev ${IF2} src ${IP2}
echo "Hecho."
Gracias de nuevo.
Así está en el tutorial de LARTC no me lo he cuestionado.
Hola Haldrik.
Te hago una consulta, el hecho de tener un balance de carga entre 2 o 3 salidas a internet (ADSLs o líneas dedicadas) significa que siempre se usara la conexión que yo determine como primaria y si esta tuviera un problema se podrian usar las restantes?
Muchas Gracias.
Para este caso no, si se cae la conexión que tiene marcado determinado servicio entonces ese servicio caerá. Lo que tu necesitas es alta disponibilidad.
Odair, gracias por el aporte.
Sabes de alguna metodología que ante la caida de una conexión automáticamente rutee todo por las otras conexiones disponibles?
Muchas Gracias.
Saludos.-
Haldrik, buenas.
Leyendo sobre Balance de carga he visto además de tu artículo este:
http://bourneagainshell.blogspot.com/2008/05/de-como-conectar-13-adsls-en-balanceo.html
Que opinas al respecto?
Mi idea sobre Balance de Carga sería lograr esto:
Dadas 3 conexiones a internet tener una conexión principal por donde salen todos mis clientes y ante una caida de esta conexion que automaticamente los paquetes se resuelvan por otra conexion.
Tambien me interesa forzar que ciertos clientes salgan por determinada conexion.
Esto es posible?
Que opinas?
Muchas Gracias.
Saludos.-
Buen tuto, por lo que veo tiene lo que necesitas.
Puedo agregar que lo que tu necesitas se puede hacer con linux, pero hasta allá no llego yo.
buenas tardes Odair, esto sirve si en mi pais, las conexiones de internet adsl... vienen dhcp solamente? osea si mis 2 conexiones de internet vienen dhcp, yo puedo usar esa configuracion para las targetas de red?
disculpa si la pregunta es algo boba, pero estoy aprendiendo :P y tengo esa tarea aqui en mi trabajo :)
mira, si tienes router ADSL puedes entrar a su página de configuración y desactivar el DHCP o ponerlo desde una ip mas arriba de la que ha de tener tu equipo.
Publicar un comentario en la entrada