Introduction et rappels sur le routage IP

Passez cette section, si vous connaissez déjà tout ça.

Le principe du routage IP est l'utilisation de tables de routage; une table comporte des entrées identifiant un réseau et l'itinéraire à suivre pour le rejoindre (interface réseau ou routeur suivant).

Voici une table de routage typique d'une machine connectée à un réseau local (obtenue avec route -n par exemple) :

Dest		Passerelle	Masque		Interface
192.168.1.0	0.0.0.0		255.255.255.0	eth0
0.0.0.0		192.168.1.1	0.0.0.0		eth0

Cette table veut dire que la machine est directement connectée au segment du réseau dont les machines ont des adresses IP en 192.168.1.X, elles sont accessibles directement sans routage IP. Pour toutes les autres destinations, les paquets sont envoyés à 192.168.1.1 (qui est directement joignable sur eth0). Sans rentrer dans les détails, l'envoi vers la passerelle se fait via son adresse MAC, tout en gardant l'IP de destination d'origine dans les en-têtes des paquets.

Imaginons maintenant, la table de routage de la passerelle typique :

Dest		Passerelle	Masque		Interface
192.168.1.0	0.0.0.0		255.255.255.0	eth0
42.41.40.39	0.0.0.0		255.255.255.255	ppp0
0.0.0.0		42.41.40.39	0.0.0.0		ppp0

La passerelle est connectée au réseau local avec eth0 et à Internet avec ppp0; le tunnel PPP est établi avec 42.41.40.39 une passerelle permettant de sortir sur Internet.

Si l'on oublie la translation d'adresses ou NAT (c'est un truc technique qui permet à des adresses locales non routables (car tout le monde peut utiliser chez soi des adresses en 192.168.0.0/24 par exemple) de sortir sur Internet en utilisant l'adresse IP publique, routable de la passerelle), lorsqu'un paquet arrive du réseau local vers Internet, il repart vers le saut suivant grâce à la dernière entrée de la table de routage. De même un paquet venant de l'extérieur est acheminé vers eth0 avec la première entrée.

Limites du routage traditionnel

Ce type de fonctionnement s'avère insuffisant lorsqu'on a plusieurs liens de sortie. Si un paquet provient du réseau local, on peut encore envisager d'utiliser l'une des sorties selon l'adresse de destination, mais quand une session est initiée de l'extérieur, par quelle sortie faire repartir les paquets de la réponse ? Théoriquement on pourrait recevoir un début de session par un lien et renvoyer la réponse par un autre, mais dans la pratique, probablement pour des raisons de sécurité, ce genre de réponse n'est pas routé, ou pas accepté par le réseau de destination.

Les deux problèmes des configurations multilien sont donc :

  • arriver à envoyer les paquets associés à une même session TCP par un seul et même lien réseau;
  • savoir à quel lien associer une session sortante.

Pour satisfaire à ces contraintes, on doit reconnaître les paquets associés à une même session et router un paquet non seulement par destination, mais aussi par rapport à la session à laquelle il appartient.

Sous Linux, on peut réaliser ces tâches grâce à Netfilter, et plus particulièrement aux modules conntrack et connmark et à la cible ROUTE. Malheureusement la configuration utilisant de manière brute ces outils et très difficile, longue et demande une grande maîtrise de Netfilter. Les fonctionnalités de routage des dernières versions du pare-feu Shorewall permettent d'arriver au même résultat avec une configuration simple, courte et élégante.

Premier exemple : passerelle à deux Freebox, redondance et load-balancing

Je suis sûr que vous avez toujours rêvé de le faire, et bien c'est possible !

Voici les branchements de la passerelle :

  • eth0 : 192.168.0.254, réseau local en 192.168.0.0/24;
  • eth1 : Freebox sans mode routeur (la passerelle recevra l'IP publique de l'abonnement par DHCP);
  • eth2 : deuxième Freebox, dans la même configuration, mais sur une autre ligne téléphonique.

Avec Shorewall nous allons pouvoir répondre à toutes les problématiques évoquées précédemment.

Voici les pages de documentation utiles pour comprendre ce qui se passe : shorewall and routing shorewall multiISP shorewall interfaces shorewall providers shorewall tcrules.

Passons sur l'installation, il vous faut Shorewall-perl 4.1 au moins (Debian Lenny), mais la version 4.2 dispose de quelques fonctionnalités très utiles (Debian Squeeze ou Sid).

Voici les principaux fichiers de configuration :

shorewall.conf (parties impotantes) :

IP_FORWARDING=On # Active le routage IP avec une commande sysctl
TC_EXPERT=No # N'y touchez surtout pas, l'activation de cette option
# rend les règles de l'utilisateur prioritaires sur les règles générées par l'option track
IMPLICIT_CONTINUE=Yes # Active l'hérédité des règles entre les zones imbriquées
MARK_IN_FORWARD_CHAIN=No
ROUTE_FILTER=No
FASTACCEPT=Yes
KEEP_RT_TABLES=Yes # Shorewall 4.1
USE_DEFAULT_RT=Yes # Shorewall 4.2 (voir plus loin)

zones :

fw	$FW
net ipv4
loc ipv4

interfaces :

eth0 loc routeback
eth1 net dhcp,routefilter=0,logmartians,rfc,optional
eth2 net dhcp,routefilter=0,logmartians,rfc,optional

L'option routefilter est très importante; en temps normal elle assure que les paquets d'une même session repartent et arrivent par la même route, cette option empêcherait le routage multilien de fonctionner (et vous pourriez passer des heures à vous demander pourquoi ça ne marche pas).

providers :

1	0x01	main eth1 detect track,balance,optional
2	0x02	main eth2 detect track,balance,optional

track indique à Shorewall de créer des règles pour faire repartir les paquets par le bon lien, selon l'origine de la connexion. balance permet de faire du load-balancing entre les deux liens (il est aussi possible de privilégier un lien par rapport à un autre en utilisant blanace=X, avec X le poids du lien). Avec optionnal, on obtient la redondance : si un lien marqué optionnal est indisponible, Shorewall travaille avec les liens restants. Attention, le troisième paramètre indique la table de routage à copier pour créer une table de routage spécifique au lien : si vous avez Shorewall 4.1, indiquez main, il faudra alors redémarrer Shorewall à chaque modification de la table de routage de la passerelle (route add/del, etc.). Avec Shorewall 4.2, vous pouvez activer USE_DEFAULT_RT, mettre copy à - au lieu de main, tous les paquets passeront alors par la table de routage principale avant d'aller dans les tables spécifiques aux différents liens; plus besoin de redémarrer Shorewall pour appliquer de nouvelles règles de routage.

Les explications sont un peu synthétiques, mais vu le caractère délicat de cette configuration, le seul moyen de comprendre vraiment ce qui se passe, est de lire les pages de manuel de Shorewall pour les options utilisées et peut-être commencer par une configuration plus simple (un seul lien de sortie) pour se familiariser avec Shorewall.

Dans un prochain billet, je vous expliquerai comment se connecter à un VPN PPTP (du genre Ipredator) et à faire du routage sélectif sur ce VPN (ce qui revient au fond à une configuration multilien un peu plus compliquée que celle décrite précédemment).