|
|
Mise en place d'une double connexion ADSL sous linux
Comme son nom l'indique justement, ce document présente la mise en place d'une double connexion
ADSL sous linux. Mais d'autres points intéressants sont abordés, comme la NAT, le port forwarding,
la QOS, etc. Tout cela pour pouvoir tirer le meilleur parti de votre double connexion :-)
Merci à Pierre de Luca pour m'avoir aiguillé vers cette solution ;-)
Merci à Filip Supera pour ses corrections orthographiques.
Pourquoi une double connexion ?
1- Pour garantir un accès à Internet sans coupures.
2- Pour augmenter la capacité de la bande passante
3- Pour pouvoir offrir des services qui peuvent difficilement soufrir de coupures de connexion,
comme le DNS(serveur de noms) ou le SMTP(mail)
4- Pour faire de l'hébergement (Votre nom de domaine par exemple)
5- Pour le fun étant donné que c'est un beau projet réseau :-)
Voilà en gros les raisons qui m'ont poussé à vouloir mettre en oeuvre une telle configuration,
mais les raisons peuvent être tout autres, à vous de voir l'intérêt que vous pouvez y trouver.
Sommaire:
1- Préambule
2- Les connexions ADSL
3- La mise en place des connexions (à venir)
4- Le routage avancé sous linux
5- Mise en place du routage pour notre double connexion
6- Optimisation de l'accès
7- Tester si ca marche
8- Gestion d'une coupure d'accès (à venir)
Le script de connexion complet (02/07/04)
Le script iptables complet (non testé... 02/07/04)
J'ai donc mis en place cette configuration chez moi (Schéma)
Je dois avouer que ma configuration n'est pas des plus simples, donc en suivant les instructions
et en essayant de comprendre un minimum ce qui est fait, vous devriez facilement être en mesure
de reproduire cela chez vous.
Le principe est donc de se servir en même temps des deux connexions ADSL. Le routeur/NAT
linux aura donc pour rôle de router alternativement les connexions d'un coté puis de
l'autre. La balance des connexions entrantes pouvant se faire par un round Robin DNS
(si ces termes vous semblent barbares, ils sont expliqués plus en détail par la suite)
Il s'agit d'une connexion ADSL 1024/256 9telecom et d'un accès Free par Freebox dégroupé
(j'obtiens un accès en pointe d'environ 4Mbps en download, sans télé ou téléphone)
L'accès 9telecom se fait par un modem alcatel USB vers la linux. Mais je vous conseille
d'éviter les connexions USB qui apportent, à mon avis, plus de problèmes que les connexions
à base d'Ethernet. M'enfin bon, ca met du piment ;-)
L'accès Free se fait donc par une Freebox connectée à mon routeur/NAT linux Mandrake 9.0
en Ethernet 10Mbps .
Avant de commencer, il faut savoir que cette réalisation est extrèmement simple si vous
connaissez les principes de routage de base, et même d'ailleurs si vous ne les connaissez
pas. La suite de la lecture vous permettra de mieux comprendre ce qui est mis en place,
mais vous pouvez directement passer aux commandes à entrer si la compréhension du sujet ne
vous intéresse pas.
On a l'habitude d'utiliser les commandes de gestion IP simples de linux comme "ifconfig",
"route" ou autres "arp".
Il faut savoir que linux permet une utilisation avancée des possibilités IP et cela à travers
la commande "ip" (documentation officielle ici)
Ce sont ces fonctions avancées que nous allons utiliser pour faire notre balance de charge.
Elles permettent notamment pour notre cas de mettre en place deux passerelles par défaut
utilisées alternativement, ainsi que du policy routing pour faire du routage selon l'adresse source.
Aperçu rapide du fonctionnement du routage avancé
Le routage tel qu'on l'entend se base sur l'utilisation par le système d'exploitation
d'une table de routage permettant d'aiguiller le traffic en fonction des adresses destination
voir la faq sur le routage. Rien d'extraordinaire là dedans, il s'agit des principes de base
du fonctionnement d'Internet.
Le routage avancé sous linux grâce au logiciel iproute2 permet non seulement de définir plusieurs
tables de routage, mais aussi de n'utiliser ces tables de routage qu'en fonction de certains
critères, comme les adresses source dans notre mise en oeuvre.
Le fonctionnement
Par défaut, trois tables de routage sont en place (Eh oui ! même si vous n'avez rien fait de
spécial sur votre linux préféré, ces tables sont toujours présentes !) Il s'agit des tables local,
main et default.
La table que vous avez l'habitude de voir par la commande "route -n" ou "netstat -nr" est
en fait la table main. Les autres tables sont présentes et même utilisées, à l'insu de votre
plein gré !
Pour lister les tables en place, rien de plus simple, il faut utiliser la commande "ip rule list":
[root@Belleville init.d]# ip rule list
0: from all lookup local
32766: from all lookup main
32767: from all lookup default
et pour votre votre table de routage préférée...
[root@Belleville init.d]# route -n
Table de routage IP du noyau
Destination Passerelle Genmask Indic Metric Ref Use Iface
62.39.237.1 0.0.0.0 255.255.255.255 UH 0 0 0 ppp0
192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
82.226.217.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1
127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo
0.0.0.0 62.39.237.155 0.0.0.0 UG 0 0 0 ppp0
Qui n'affiche donc que la table "main".
Pour pouvoir lister le contenu d'une autre table, il va falloir le demander explicitement
et utiliser notre commande "ip" pour accéder aux fonctions avancées:
[root@Belleville root]# ip route list table local
local 192.168.0.254 dev eth0 proto kernel scope host src 192.168.0.254
broadcast 192.168.0.255 dev eth0 proto kernel scope link src 192.168.0.254
broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1
broadcast 82.226.217.255 dev eth1 proto kernel scope link src 82.226.217.65
broadcast 192.168.0.0 dev eth0 proto kernel scope link src 192.168.0.254
broadcast 82.226.217.0 dev eth1 proto kernel scope link src 82.226.217.65
broadcast 127.0.0.0 dev lo proto kernel scope link src 127.0.0.1
local 82.226.217.65 dev eth1 proto kernel scope host src 82.226.217.65
local 62.39.237.155 dev ppp0 proto kernel scope host src 62.39.237.155
local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1
local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1
Et voilà. Maintenant, comment savoir quelle table est utilisée quand un paquet IP
arrive ?
C'est très simple, il parcourt simplement les tables une par une jusu'à trouver
une entrée correspondant à l'adresse IP de destination spécifiée. L'ordre dans
lequel les tables sont parcourues provient simplement du numéro accocié à la table
(le numéro qui apparaît en début de ligne lors de la commande "ip rule list")
Ainsi, dans notre exemple, si aucune entrée n'est trouvée dans la table locale,
la table main sera parcourue, puis la table default.
L'ordre entre les différentes tables est donc très important. Si vous n'y faites
pas attention, vous risquez d'avoir des surprises...
Mais maintenant, comment agir sur ces tables, en ajouter ou en enlever ?
Ajout de tables et de routes au sein d'une table
Pour ajouter une table, il faut utiliser la commande "ip rule add". Mais avant
cela, il faut faire connaître à iproute le nom de notre table:
[root@Belleville init.d]# echo 201 nom_de_table >> /etc/iproute2/rt_tables
Puis ajouter notre table:
[root@Belleville init.d]# ip rule add lookup nom_de_table
[root@Belleville init.d]# ip rule list
0: from all lookup local
32765: from lookup nom_de_table
32766: from all lookup main
32767: from all lookup default
C'est bien, mais si vous avez saisi le principe, l'ajout de notre table ne nous
apporte pas grand chose à partir du moment ou elle ne se différencie pas des
autres tables présentes. Nous pourrions par exemple ajouter des critères à notre
table pour qu'elle ne soit parcourue que dans certains cas, et c'est là où
l'utilisation de plusieurs tables va s'avérer puissante.
Par exemple, nous allons créer une table qui ne sera parcourue que si l'adresse
source du paquet IP est l'adresse voulue (ici, ma machine ayant pour adresse
10.0.0.1) Ainsi, nous pourrons aiguiller les paquets de façon spécifique pour
telle ou telle machine.
[root@Belleville init.d]# echo 202 pour_ma_machine >> /etc/iproute2/rt_tables
[root@Belleville init.d]# ip rule add from 10.0.0.1 lookup pour_ma_machine
[root@Belleville init.d]# ip rule list
0: from all lookup local
32764: from 10.0.0.1 lookup pour_ma_machine
32765: from lookup nom_de_table
32766: from all lookup main
32767: from all lookup default
Maintenant, un paquet ayant pour adresse ip source 10.0.0.1 passera par la table
pour_ma_machine.
La table est vide pour l'instant, mais si nous y ajoutons par exemple une route
par défaut, ma machine utilisera toujours cette route par défaut, et non celle
spécifiée dans la table "main". Ajoutons par exemple une route par défaut dans la
table "pour_ma_machine":
[root@Belleville init.d]# ip route add default via 10.0.0.254 table pour_ma_machine
et hop:
[root@Belleville init.d]# ip route list table pour_ma_machine
default via 10.0.0.254 dev eth1
Ajout d'une double route par défaut
L'intérêt majeur de l'utilisation d'iproute2 dans notre cas est avant tout celui-ci,
c'est à dire de pouvoir spécifier deux routes par défaut qui seront toutes deux utilisées.
Pour cela, iproute bénéficie d'une commande très simple et efficace
"ip route add default equalize"
Ce qui nous donne par exemple:
[root@Belleville init.d]# ip route add default equalize nexthop via 10.0.0.253 dev ppp0 \
weight 1 nexthop via 192.168.0.254 dev eth1 weight 1
Nous n'avons pas spécifié de table pour l'entrée de cette route, elle sera donc ajoutée
à la table main.
[root@Belleville init.d]# ip route list table main
10.0.0.1 dev ppp0 proto kernel scope link src 62.39.237.155
192.168.0.1/24 dev eth1 proto kernel scope link src 82.226.217.65
127.0.0.0/8 dev lo scope link
default equalize
nexthop via 10.0.0.253 dev ppp0 weight 1
nexthop via 192.168.0.254 dev eth1 weight 1
Et maintenant nos paquets vont alternativement passer par les passerelles 10.0.0.253 et
192.168.0.254.
Maintenant que nous avons abordé la majorité des concepts nécessaires, nous allons mettre
cela en oeuvre pour notre double accès ADSL.
Le but dans un premier temps va donc simplement être de balancer la charge entre nos
deux connexions Internet (Schéma)
Le premier problème rencontré est l'adressage de la passerelle coté 9telecom. Etant
donné que cette adresse est dynamique, il nous est impossible de la mettre en dur
dans le script qui va gérer le routage. Pour régler ce problème, nous allons utiliser
une variable qui va chercher la valeur de l'adresse IP coté 9telecom ainsi que
l'adresse de la passerelle par défaut.
NEUF_IP=`ifconfig | grep inet | grep P- | cut -d : -f 2 | cut -d P -f 1`
NEUF_GW=`ifconfig | grep inet | grep P- | cut -d : -f 3 | cut -d M -f 1`
Pour la suite, nous mettons simplement en place une double route par défaut dans
notre table "main" (en pensant bien à effacer préalablement toute trace d'ancienne route
par défaut):
ip route add default equalize nexthop via $NEUF_GW dev ppp0 weight 1 nexthop \
via 82.226.217.254 dev eth1 weight 1
On peut remarquer que pour l'instant, j'ai mis un poids égal pour chacun des liens.
Ceci pourra être changé par la suite.
Normalement, si tout se passe bien, la balance de charge dynamique devrait
maintenant fonctionner. Mais en lisant bien la doc sur le routage avancé, il est dit
de mettre en place des routes de retour pour chacun des deux liens (ici)
Je n'ai absolument pas compris pourquoi ceci était nécessaire pour l'instant. Si
quelqu'un a l'info, elle est la bienvenue :-)
On crée donc deux tables dans lesquelles on place une route par défaut vers le réseau
local.
ip rule add from $NEUF_IP lookup 1
ip rule add from 82.226.217.65 lookup 2
ip route add 192.168.0.0/24 via 192.168.0.254 table 1
ip route add 192.168.0.0/24 via 192.168.0.254 table 2
Il ne nous reste plus qu'à mettre en place la NAT sur iptables pour chacun des fournisseurs
d'accès:
# Pour l'accès 9telecom
NEUF_IP=`ifconfig | grep inet | grep P- | cut -d : -f 2 | cut -d P -f 1`
NEUF_IFACE="ppp0"
# Pour l'accès Free
FREE_IP="82.226.217.65"
FREE_IFACE="eth1"
iptables -t nat -A POSTROUTING -o $NEUF_IFACE -j SNAT --to-source $NEUF_IP
iptables -t nat -A POSTROUTING -o $FREE_IFACE -j SNAT --to-source $FREE_IP
Maintenant, ca roule, notre double connexion à Internet fonctionne !
On pourrait se dire que c'est gagné... et bien non, à l'usage on se rend vite compte que
quelques problèmes sont rencontrés...
Le problème des serveurs DNS et SMTP des fournisseurs d'accès
Bizarrement, la connexion ne fonctionne que par intermitence. En y regardant de plus près,
on peut remarquer que les requêtes DNS ne fonctionnent pas très bien. Et c'est normal.
Pour des raisons de charge, les fournisseurs d'accès n'autorisent que les adresses IP qu'ils
allouent eux-mêmes à accéder à leurs serveurs. Ainsi, si un de mes clients décide d'interroger
le serveur DNS de free, et que le routage dynamique le fait passer par 9telecom, la réponse
à la requête n'aboutira pas. Il faut donc s'assurer que les requêtes pour les serveurs DNS de
Free passeront bien par Free, et de même pour 9telecom.
Pour cela, il nous suffit de mettre en place des routes dédiées pour les adresses IP des
serveurs DNS de Free et 9telecom (et de même pour les serveurs POP et SMTP)
# Les DNS de Free
ip route add 212.27.32.176 via 82.226.217.254 table main
ip route add 212.27.32.177 via 82.226.217.254 table main
# Les DNS 9telecom
ip route add 212.30.96.108 via $NEUF_GW table main
ip route add 213.203.124.146 via $NEUF_GW table main
# Le POP 9telecom
ip route add 212.30.113.205 via $NEUF_GW table main
# Le SMTP 9telecom
ip route add 62.62.156.10 via $NEUF_GW table main
ip route add 62.62.156.27 via $NEUF_GW table main
ip route add 62.62.156.28 via $NEUF_GW table main
Bon, maintenant c'est sûr ça y est, ça marche !
Oui, mais ce n'est pas vraiment optimisé...
!Attention!: Il est important que les adresses des serveurs DNS des deux opérateurs soient
configurées sur les postes clients, sans quoi l'accès à Internet serait perdu si jamais un
des liens venait à tomber.
Encore une fois, à l'usage je me suis vite rendu compte que la connexion n'était pas vraiment
optimisée. Cela est notamment dû au fait que le débit de mes deux liens vers Internet est
asymétrique (le débit de Free est à peu près 4 fois plus gros que celui de 9telecom)
Donc quand je téléchargeais par Free c'était la fête, mais quand ça passait par 9tel, ca
l'était moins :-( C'est un peu dommage de télécharger à 100kbps alors qu'on peut le faire
à 400kbps.
Il faut donc maintenant que les flux de download passent par free, et qu'au contraire, les
flux qui ne nécessitent pas une grande bande passante passent par 9telecom.
Le problème est que comme tout routeur, la table de routage ne peut normalement pas aiguiller
les paquets en fonction de critères de couche 4 (ici, les ports HTTP et FTP) mais seulement de
couche 3. La solution vient d'iptables qui peut mettre une marque dans l'en-tête IP en
fonction de ses différents critères d'analyse. Notamment, en fonction des ports TCP/UDP
utilisés. Il sufit donc de marquer les paquets selon le port, avant qu'ils soient routés.
Par exemple pour les flux HTTP et FTP:
iptables -t mangle -A PREROUTING -i eth0 -p tcp --dport 80 -j MARK --set-mark 80
iptables -t mangle -A PREROUTING -i eth0 -p tcp --dport 21 -j MARK --set-mark 21
Il faut maintenant créer une table de routage pour chacun des flux (ou une seule si l'on préfère
regrouper les critères) et mettre comme route par défaut le routeur de Free:
echo 201 http >> /etc/iproute2/rt_tables
echo 202 ftp >> /etc/iproute2/rt_tables
ip rule add fwmark 80 table http
ip rule add fwmark 21 table ftp
ip route add default via 82.226.217.254 table ftp
ip route add default via 82.226.217.254 table http
Bon, maintenant, ca commence quand même à fonctionner pas mal :-)
En faisant de même pour tous les flux critiques, on arrive à bien optimiser les connexions.
Il ne nous reste plus qu'à mettre en place de la QOS en amont sur l'OpenBSD, et à mettre en
place les scripts qui permettront de changer les tables de routage si jamais un lien vient à
tomber.
A priori tout fonctionne bien, vous êtes assez content de vous, mais comment être sûr
que la balance de charge fonctionne bien ?
Il y a plusieurs façons de faire. Le plus simple à mon avis, si vous n'avez pas mis de
route particulière en fonction du protocole est de tester à travers des pages web qui
affichent l'adresse IP avec laquelle vous vous connectez chez elles. Voici quelques
sites qui font cela:
www.myip.com
www.bellamyjc.net
www.whatismyip.com
www.whatismyipaddress.com
whatismyipaddress.net
!! Attention !!
Pour bien vous rendre compte que la balance de charge est effective, il faut faire le test
sur plusieurs sites. En effet, étant donné qu'une route est conservée en cache un certain
temps, le même chemin sera employé pour un même site. La visite d'un seul site n'est donc
pas du tout significative du fonctionnement de la balance de charge.
Mais si vous avez balancé le traffic en fonction du protocole, le plus simple est peut-être
d'utiliser le programme traceroute (ou tracert sous windows)
Vous verrez ainsi par lequel des deux fournisseurs d'accès vous passez. Si vous passez
toujours par le même, c'est qu'il doit y avoir un problème quelque part. Repassez par
la case départ, ou contactez-moi.
Bla bla
|