======= Firewall redondant =======
===== Présentation de l'architecture =====
Voici l'architecture que nous allons réaliser :
{{:wiki:divers:ha:firewall_redoundancy-1.png?900|}}
Nous allons donc partager deux ips entre nos deux firewalls redondants (une de chaque coté), et synchroniser les deux conntracks entre elles.
===== Mise en place des interfaces CARP =====
Pour obtenir deux IP virtuelles communes aux deux firewalls, nous aurions pu utiliser [[wiki:divers:HA:keepalived | KeepAlived ]], mais j'ai préféré choisir une autre solution d'IP virtuelle non basée ((du moins il me semble)) sur **LVS**.
**CARP** est une réponse de **BSD** au protocole **VRRP**, propriétaire.
Pour l'utiliser sous LiNUX, nous allons utiliser **ucarp** :
apt-get install ucarp iputils-arping
Toute la config est ensuite effectuée dans ''/etc/network/interfaces''.
Voici ce fichier pour le master :
allow-hotplug eth0
iface eth0 inet static
address 192.168.103.208
netmask 255.255.255.0
ucarp-vid 3
ucarp-vip 192.168.103.210
ucarp-password toto
ucarp-advskew 0
ucarp-advbase 1
ucarp-master yes
iface eth0:ucarp inet static
address 192.168.103.210
netmask 255.255.255.0
allow-hotplug eth1
iface eth1 inet static
address 157.159.40.137
netmask 255.255.255.192
ucarp-vid 4
ucarp-vip 157.159.40.139
ucarp-password toto
ucarp-advskew 0
ucarp-advbase 1
ucarp-master yes
iface eth1:ucarp inet static
address 157.159.40.139
netmask 255.255.255.192
gateway 157.159.40.129
Pour expliquer, on commence par spécifier une interface de management ( 192.168.103.208 ), à laquelle on attache une ip virtuelle supplémentaire. Cette ip supplémentaire fait appel à un numéro de session CARP ( ici 3 ) ainsi qu'un mot de passe histoire de sécuriser un peu tout ça... On spécifie cette ip virtuelle.
On fait la même chose pour eth1. On rajoute cepandant une gateway sur l'ip virtuelle.
Voici maintenant la conf du slave :
allow-hotplug eth0
iface eth0 inet static
address 192.168.103.209
netmask 255.255.255.0
ucarp-vid 3
ucarp-vip 192.168.103.210
ucarp-password toto
ucarp-advskew 0
ucarp-advbase 1
ucarp-master no
iface eth0:ucarp inet static
address 192.168.103.210
netmask 255.255.255.0
allow-hotplug eth1
iface eth1 inet static
address 157.159.40.138
netmask 255.255.255.192
ucarp-vid 4
ucarp-vip 157.159.40.139
ucarp-password toto
ucarp-advskew 0
ucarp-advbase 1
ucarp-master no
iface eth1:ucarp inet static
address 157.159.40.139
netmask 255.255.255.192
gateway 157.159.40.129
Ici les seules choses qui changent c'est les adresses IP propres à la machine, ainsi que l'on est ce coup ci en mode slave.
Voilà c'est aussi simple que ça et très robuste !
Note pour les OpenVZ : il faut désactiver le filtrage mac sur les instances utilisant uCarp. Ceci se fait avec la commande suivante avec l'instance **ÉTEINTE** :
vzctl set --mac_filter=off --ifname=eth0 --save
===== Synchronisation des conntracks des deux firewalls =====
Ce que nous cherchons à redonder, c'est un parefeu statefull. Il nous faut donc synchroniser les conntracks entre le slave et le master. Pour ce faire, nous allons utiliser l'outil qui permet de controller la conntrack de netfilter depuis l'espace utilisateur : **conntrackd**.
Pour l'installer, rien de plus simple :
apt-get install conntrackd
Bon passons maintenant à la réplication de la conntrack. Différents modes de synchronisations existent :
- **notrack** qui consiste à faire au plus simple : on bombarde en face et on se fout de si ça arrive ou pas...
- **ft-fw** qui repose sur un protocole fiable (réordonne, détecte les corruptions et les pertes )
- **alarm** qui est le plus coûteux en terme de bande passante, mais résout rapidement les problèmes de synchronisations ( c'est pour lui que le failover indura le moins de pertes ). À MiNET, comme on est des fous, c'est ce mode que nous choisirons.
Ensuite, il nous faut ensuite choisir un protocole pour le transport de ces options. On a le choix entre UDP et du multicast. J'ai choisit de l'UDP car on a que deux noeuds ((et que je pouvais facilement voir ce qui se passe)). Si on avait plus de firewall en parallèle j'aurais plus misé sur le multicast.
Enfin avant d'aller plus loin, il faut se rendre compte que les infos de la conntrack sont sensibles, et qu'il fat pas quelles se ballades n'importe où... Ainsi c'est mieux de faire du binding entre deux interfaces qui utilisent un lien dédié...
Sans plus vous faire attendre, voici mon fichier de configuration :
Sync {
Mode ALARM {
RefreshTime 5
CacheTimeout 600
}
UDP {
IPv4_address 192.168.103.208
IPv4_Destination_Address 192.168.103.209
Port 3780
Interface eth0
Checksum on
}
}
General {
Nice -20
HashSize 32768
HashLimit 131072
LogFile on
LockFile /var/lock/conntrack.lock
UNIX {
Path /var/run/conntrackd.ctl
Backlog 20
}
NetlinkBufferSize 2097152
NetlinkBufferSizeMaxGrowth 8388608
Filter From Userspace {
Protocol Accept {
TCP
ICMP
}
Address Ignore {
IPv4_address 127.0.0.1
IPv4_address 192.168.103.210
IPv4_address 157.159.40.139
IPv4_address 157.159.40.137
IPv4_address 192.168.103.209
IPv4_address 192.168.103.208
}
}
}
Revenons un peu sur cette conf' :
Paramètres de synchronisation :
* **RefreshTime** : On envoie des notifications toutes les x secondes pour les entrées non modifiées de la conntrack sur le master. Ce mécanisme permet de mettre à jour les nouveaux slaves. Dans cet exemple, il faut 5 secondes pour que la conntrack du slave fraîchement rallumé soit consistante.
* **cacheTimeout** : En cas de non notification pour une entrée de la conntrack sur le master pendant x secondes, on la supprime sur le slave. Typiquement, on se débrouille pour que cette valeur soit égale au time out de notre conntrack.
* Je ne reviendrais pas sur les paramètres de UDP, c'est explicite. En revanche, vous noterez que j'ai activé les check sums pour un maximum de sécurité.
Paramètres généraux :
* Nice permet de régler la fréquence de sheduling du daemon. Plus la valeur est basse, moins le failover sera coûteux en terme connections perdues.
* Filter permet de synchroniser la conntrack que sur les protocoles qui nous intéressent (TCP et ICMP disons), et d'ignorer les entrées de la conntrack propres au firewall utilisé (typiquement celles de ces adresses ips virtuelles ou réelles).
Note : Je n'arrive pas à redémarrer conntrackd par le script d'init. Il me faut killer le processus, et virer le lock et le socket... Un petit défaut ! Il suffit juste de réécrire un script d'init plus bourrin sur le stop...
Néanmoins, mes sessions SSH établies à travers les ips virtuelles survivent à l'arrêt de chacune des deux machines. Ça marche, et même bien ;-)
===== Conclusions =====
Ma première conclusion concerne CARP et **ucarp**. **ucarp** est simple à mettre en place, et à mon sens potentiellement plus efficace que **keepalived**. J'ai été surpris à l'extinction de la vm master de constater une indisponibilité de l'IP partagée de moins d'une demie seconde ( !!! ) alors que je n'ai fais aucune optimisation.
Seul point : je n'ai pas encore testé **ucarp** sous OpenVZ...
Ma deuxième conclusion est qu'on a ici en libre ce que des appliances proposent à des prix hallucinants. Avec un peu d'huile de coude et quelques optimisations, je suis sûr que ça marche aussi bien ;-)
===== Liens utiles =====
* Le lien qui a inspiré cet article : http://www.openbsd.org/faq/pf/fr/carp.html
* Le lien dont je me suis inspiré pour **CARP** : http://3molo.blogspot.fr/2009/10/configuring-carp-on-debian-gnulinux.html
* Un lien d'où est inspirée la partie **conntrackd** : http://conntrack-tools.netfilter.org/manual.html
--- //[[benwa@minet.net|Benoit Tellier]] 2014/01/26 22:12//