LINUX MULTI DSL

Détails

Ce howto, inspiré par celui de Christoph Simon, propose de mettre en place un routeur sous Linux qui va partager plusieurs connections internet. Cela permet de virtuellement augmenter la bande passante et d'avoir une ou plusieurs lignes de secours en cas de panne. La technique ne convient réellement que dans le cas où le trafic viens majoritairement du réseau interne et où ce réseau comporte plusieurs postes.

Versions :

- Patch de Julian Anastasov
- iproute2-2.6.11-050330 / Custom Build ou Debian Package

Plan Multiline

Il faut dans un premier temps recompiler votre noyau avec le patch de Julian Anastasov (voir versions) et les options minimums requise pour faire de Linux un routeur avancé. Downloadez les patchs et appliquez les sur vos sources. Vérifier que vous avez au moins les options suivantes avant de recompiler votre noyau :

#
# Networking options
#
CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_IP_ROUTE_MULTIPATH=y

Une fois le noyau fraîchement recompiler passons aux scripts. Pour faciliter les modifications ultérieures il est préférable de mettre toutes les informations (IPs, passerelles, interface, etc...) dans des variables auxquelles nous feront référence par la suite. Voilà à quoi peut ressembler un tel fichier :

SCRIPTS=/etc/network/scripts
IPTABLES=/usr/local/bin/iptables
IP=/usr/local/sbin/ip
TC=/usr/local/sbin/tc

IF_PROVIDER1=eth2
IP_PROVIDER1=X.X.106.208
GW_PROVIDER1=X.X.106.254
BRD_PROVIDER1=X.X.106.255
NET_PROVIDER1=X.X.106.0

IF_PROVIDER2=eth3
IP_PROVIDER2=X.X.137.2
GW_PROVIDER2=X.X.137.1
BRD_PROVIDER2=X.X.137.7
NET_PROVIDER2=X.X.137.0

IF_LAN=eth0
IP_LAN=192.168.0.254

Bien entendu les informations ci-dessus sont spécifiques à mon systeme, à vous de les adapter à vos besoins. Une fois ce fichier fait, je vais l'inclure dans mes scripts. Un seul script contiendra ici l'ensemble de la gestion des interfaces et des table de routage et remplacera pour plus de clarté l'habituel fichier /etc/network/interface de Debian. On commence donc par inclure le fichier et par activer nos interfaces de loopback et celle du LAN :

. /etc/network/scripts/common
 
### LOOPBACK INTERFACE
$IP link set lo up
echo "Loopback up"

### LAN INTERFACE
$IP link set $IF_LAN up
$IP addr add $IP_LAN/24 brd + dev $IF_LAN
echo "Lan up"

En plus de monter les interfaces, ceci rajoute aussi les routes correspondantes dans la table par défaut main. Ensuite on s'occupe des interfaces de nos lignes DSL :

### PROVIDER1
$IP link set $IF_PROVIDER1 up
$IP addr add $IP_PROVIDER1/29 brd $BRD_PROVIDER1 dev $IF_PROVIDER1
echo "PROVIDER1 up"
		
### PROVIDER2
$IP link set $IF_PROVIDER2 up
$IP addr add $IP_PROVIDER2/29 brd $BRD_PROVIDER2 dev $IF_PROVIDER2
echo "PROVIDER2 up"

Notez que les masques réseaux (/29) sont à changer selon votre topologie. Une fois toutes nos interfaces activées vous devriez pouvoir les pinger et pinger les machines qui sont sur les réseaux qui y sont directement connectés. Au tour des tables de routage maintenant, on veut par ordre chronologique que nos paquets traversent les tables suivantes :

- La table main pour router les paquets rapidement vers les interfaces locales.
- Une table par ligne DSL. Les paquets seront identifiés par leur IP source.
- Une table par défaut pour tous les autres paquets qui répartira la charge entre les deux lignes.

Cela donne dans notre script :
$IP rule add prio 50 table main

$IP rule add prio 150 from $IP_PROVIDER1/32 table PROVIDER1
$IP route add default via $GW_PROVIDER1 dev $IF_PROVIDER1 proto static table PROVIDER1
$IP route append prohibit default metric 1 proto static table PROVIDER1
 
$IP rule add prio 150 from $IP_PROVIDER2/32 table PROVIDER2
$IP route add default via $GW_PROVIDER2 dev $IF_PROVIDER2 proto static table PROVIDER2
$IP route append prohibit default metric 1 proto static table PROVIDER2
 
$IP rule add prio 200 table providers
$IP route add default table providers proto static \
	nexthop via $GW_PROVIDER2 dev $IF_PROVIDER2 weight 1\
	nexthop via $GW_PROVIDER1 dev $IF_PROVIDER1 weight 4

Vous pouvez déclarer vos noms de tables dans le fichier /etc/iproute2/rt_tables si les chiffres ne vous parle pas. La première ligne attribut une forte priorité à la table main de sorte qu'elle soit "traversée" en premier. Nous declarons ensuite une nouvelle table de priorite moindre que traverserons les paquets ayant l'IP correspondant à la première ligne DSL. On rajoute à cette table une route par défaut via la gateway du PROVIDER1 et une route "prohibit" qui servira à renvoyer des paquets ICMP de type "network-prohibited" en cas de problème sur l'interface. Même chose pour le PROVIDER2.
Enfin on crée une dernière table avec la plus basse priorité à laquelle on rajoute une route par défaut avec une destination par provider. On peut aussi leur attribuer un poid différent si les lignes ne sont pas de la même capacité. Ici j'aurais donc 1 connection qui passera par PROVIDER2 pour 4 par PROVIDER1.
Nous pouvons aussi rajouter à cela des règles nécessaires dans des cas précis. Par exemple la majorité des providers qui n'ont pas de serveurs SMTP avec authentification, n'accepte à juste titre que l'on envoi des mails que si l'on est connecté physiquement à leur réseau. Les lignes ci-dessous forcent toute les connections sur les serveur SMTP de chaque provider à passer par la table du provider correspondant et donc par la ligne DSL correspondante.

$IP rule add to X.X.48.4/32 table free # SMTP Provider 1
$IP rule add to X.X.56.3/32 table free # SMTP Provider 2

Voilà vous n'avez plus qu'a activer le forward si ce n'est déjà fait :

echo 1 > /proc/sys/net/ipv4/ip_forward

Voilà un exemple de script finalisé que l'on pourra inclure au démarrage du système : /etc/networking/scripts/route
Dans mon cas je n'ai aucune interfaces de configurée dans /etc/network/interface et j'ai complétement remplacer le fichier par défaut de Debian pour la configuration du réseau, le voici : /etc/init.d/networking.
Je ne vais pas aborder ici tous les autres appels présent mais cela peut vous donner des idées :)

Vous pouvez ensuite effectuer quelques vérifications de vos tables avec iproute et faire tomber vos interfaces pour voir ce que cela donne. Toutes les connections en cours sur l'interface qui tombe seront perdus mais dés lors tout sera rédirigé vers la ou les routes disponibles. Il est possible de mettre en place des systèmes automatique pour se rendre compte qu'une route n'est plus disponible mais en pratique je préfère monitorer les lignes par des graphs par exemple et faire tomber les interfaces au besoin. En effet il m'est arrivé plus d'une fois que le problème soit situé en amont chez mon provider ou que le débit tombe brusquement a vous de bien faire vos scripts de test de lignes dans ce cas :)