Introduction
Que ce soit pour les mise à jour du serveur Shorewall ou pour le «fail-over», configurez votre Shorewall en HA (haute disponibilité).
Ce 6è post cloture la série d’articles dédiés à Shorewall:
- 1. Shorewall – Configuration de base en quelques minutes
- 2. Shorewall en tant que routeur internet
- 3. Shorewall – Augmentez la réactivité avec la gestion de trafic
- 4. Shorewall – Configurations avancées
- 5. Shorewall en entreprise : Traçabilité, documentation des règles, revues d’audit, journalisation
Le firewall est un élément essentiel du réseau, il doit démarrer avant tout autre service (même avant les serveurs DNS en cas de DR – Disaster Recovery.
Quand vous remettez le jus sur votre infrastructure, s’il y a bien deux choses que vous voulez, c’est un firewall-routeur opérationnel et un service DNS.
Comme pour le service DNS, le firewall doit avoir un strict minimum de dépendances; par exemple ne pas dépendre de stockages répliqués. (Sinon c’est l’œuf et la poule) – Donc si les serveurs Shorewall sont virtualisés, ils doivent idéalement ne consommer que des stockage locaux aux hyperviseurs.
Shorewall ne fournit pas de mécanisme de HA. Et c’est là que des services comme Keepalived et CSync2 vienent à la rescousse pour gérer les IPs virtuelles flotantes et la réplication de la configuration.
Principe
Shorewall étant «state-less», il vous suffit de deux serveurs. Dans le chapitre précédent, nous avons vu comment déclencher une action à chaque mise à jour. Nous allons étendre cette configuration avec l’ajout de csync2
- Keepalived se charge de
- créer les IPs virtuelles
- monitorer les interfaces à l’aide de VRRP et éventuellement de scripts personnalisés
- basculer les IP virtuelles d’un firewall à l’autre en un seul groupe. En effet, il ne faudrait pas par exemple que l’IP internet soit active sur le premier nœud, et l’IP interne sur le second nœud
- envoyer un «gratuitous arp» afin de notifier le réseau et les switches du basculement, pour un basculement rapide
- déclencher des actions lors de basculement, par exemple pour démarrer le firewall et un haproxy
- Optionellement configurer les Linux IPVS pour des basculements sans interruptions. Cette utilisation ne sera pas vue dans les exemples ci-dessous. IPVS peut synchroniser les tables de NAT IPVS pour qu’il n’y ait pas d’interruption TCP lors du basculement pour les services exposés en externe.
- CSync2 est un outil simple et efficace de synchronisation bidirectionnelle de fichiers. Souvent utilisé pour synchroniser des configurations dans les clusters.
Nous terminerons par un exemple de configuration de serveur DHCP en HA sur les 2 Serveurs Shorewall.
Mise en œuvre
1. Installez un second serveur Shorewall
Le plus simple, c’est de faire un clone de l’existant sur un autre serveur et de modifier les IPs avant le boot.
S’ils sont virtualisés :
- Assurez-vous que les adresses MAC soient différentes.
- Utilisez le stockage local pour ne pas dépendre de stockages distants ou répliqués
- Utilisez une virtualisation complète de type KVM ou VMWare. Pas de LXC ou OpenVZ ici.
2. Installez keepalived et csync2
apt install keepalived csync2
3. Libérez les IPs de routage
Reconfigurez le réseau des 2 firewalls pour qu’ils n’utilisent plus les IPs de routage, mais uniquement des IPs de management. Par convention, je garde les .1
pour les IPs de routage (ou la première IP du subnet). Les IPs de routage seront gérées par Keepalived. Sous Debian/Ubuntu, vous devrez reconfigurer netplan. Exemple de /etc/netplan/50-cloud-init.yaml
network: version: 2 ethernets: ens18: addresses: [ "227.51.67.12/24" ] mtu: 1492 vlans: vlan10: id: 10 link: ens18 addresses: [ "227.51.67.2/24" ] routes: - to: 227.51.67.0/24 via: 227.51.67.40 metric: 100 - to: 227.51.67.0/24 via: 227.51.67.40 metric: 100 vlan66: id: 66 link: ens18 addresses: [ "227.51.67.2/24" ] vlan67: id: 67 link: ens18 addresses: [ "227.51.67.182/26" ] internet: id: 130 link: ens18 addresses: [ "227.51.67.12/24" ] mtu: 1492 nameservers: addresses: - 227.51.67.9 routes: - { to: default, via: 227.51.67.1 } - { to: 227.51.67.0/18, via: 227.51.67.1, metric: 100 } - { to: 227.51.67.0/19, via: 227.51.67.1, metric: 100 } - to: 227.51.67.84/32 via: 227.51.67.1 metric: 50 - to: 227.51.67.94/31 via: 227.51.67.1 metric: 100 vlan232: id: 232 link: ens18 addresses: [ "227.51.67.42/25" ]
Ne faites pas trop attention aux IPs, elles sont aléatoires, c’est juste un exemple pour vous montrer :
- Les noms d’interface sont libres, pourvu qu’ils soient facilement identifiables.
- Les noms d’interface doivent être identiques sur les 2 firewall routeurs, mais les IPs différentes, et différentes des IPs de routage.
- Pour les interfaces de VLANs (802.1q),
link:
identifie l’interface sous-jacente,id:
le numéro de VLAN (le tag). - Vous trouverez 2 syntaxes YAML équivalentes pour définir les routes statiques
- Définissez et respectez des conventions. Par exemple, les IPs se terminant par 2 sont pour le premier routeur, se terminant par 3 pour le second routeur. L’ip de routage (.1) sera gérée par Keepalived.
Configurez Keepalived
Configurez les IP de routage, la priorité et le fail-over dans /etc/keepalived/
Voici un exemple de /etc/keepalived/keepalived.conf
global_defs { process_names enable_script_security lvs_sync_daemon ens18 loc id 50 port 45678 } vrrp_instance loc { state MASTER interface vlan232 virtual_router_id 15 priority 110 advert_int 4 authentication { auth_type PASS auth_pass cuwa3GahP@ssW0rd } unicast_peer { 154.99.91.43 } virtual_ipaddress { 154.99.91.1 dev vlan232 label local:vip } } vrrp_instance dmz10 { state MASTER interface vlan10 virtual_router_id 10 priority 110 advert_int 4 authentication { auth_type PASS auth_pass cuwa3GahP@ssW0rd } unicast_peer { 154.99.91.3 } virtual_ipaddress { 154.99.91.1 dev vlan10 label dmz10:vip } } vrrp_instance dmz { state MASTER interface vlan66 virtual_router_id 66 priority 110 advert_int 4 authentication { auth_type PASS auth_pass cuwa3GahP@ssW0rd } unicast_peer { 154.99.91.3 } virtual_ipaddress { 154.99.91.1 dev vlan66 label dmz:vip 154.99.91.69 dev vlan66 label dmz:vip2 } } vrrp_instance dmzblu { state MASTER interface vlan67 virtual_router_id 67 priority 110 advert_int 4 authentication { auth_type PASS auth_pass cuwa3GahP@ssW0rd } unicast_peer { 154.99.91.253 } virtual_ipaddress { 154.99.91.129 dev vlan67 label vlan67:vip } } vrrp_instance netdmz { state MASTER interface ens18 virtual_router_id 129 priority 110 advert_int 4 authentication { auth_type PASS auth_pass cuwa3GahP@ssW0rd } unicast_peer { 154.99.91.13 } virtual_ipaddress { 154.99.91.11 dev ens18 label netdmz:vip } } vrrp_instance internet { state MASTER interface internet virtual_router_id 130 priority 110 advert_int 4 authentication { auth_type PASS auth_pass cuwa3GahP@ssW0rd } unicast_peer { 154.99.91.13 } virtual_ipaddress { 154.99.91.11 dev internet label internet:vip } } vrrp_sync_group VG1 { group { loc dmz dmz10 dmzblu internet netdmz } notify_master /etc/keepalived/scripts/notify_start.sh root notify_backup /etc/keepalived/scripts/notify_stop.sh root notify_fault /etc/keepalived/scripts/notify_stop.sh root notify_stop /etc/keepalived/scripts/notify_stop.sh root } include virtual_servers.conf
Les choses importantes sont :
- Définissez le state MASTER sur le premier firewall, et BACKUP sur le second.
- Les priorités doivent être inférieures sur le nœud de BACKUP. (Exemple : 90 sur le BACKUP, 110 sur le MASTER)
- Les
virtual_router_id
doivent être identiques sur chaque routeur, mais différents pour chaque réseau / VLAN. - Le
vrrp_sync_group
permet de synchroniser le basculement de toutes les interfaces et de définir les scripts à exécuter pour chaque changement d’état. - Le fichier est différent sur chaque nœud et ne peut être synchronisé avec CSync2. En revanche, on peut inclure un fichier commun. En dernière ligne par exemple l’inclusion de la configuration des IPVS qui est identique sur les 2 nœuds.
Exemple des scripts notify
/etc/keepalived/scripts/notify_start.sh
#!/bin/sh /usr/sbin/shorewall start /usr/bin/systemctl restart haproxy
/etc/keepalived/scripts/notify_stop.sh
#!/bin/sh /usr/sbin/shorewall stop /usr/bin/systemctl stop haproxy
Ces scripts gèrent entre autre le démarrage de Shorewall, car Shorewall ne peut démarrer qu’une fois que les interfaces et les IPs de routage sont disponibles.
Idem si vous utilisez également un haproxy au lieu de IPVS pour exposer des services externes clusterisés.
Haproxy est plus simple et peut travailler en layer 4 ou 7.
IPVS est plus performant, limité au layer 4, intégré à Keepalived et permet un switch-over
sans perte de session TCP avec la synchronisation des sessions TCP par l’envoi de notifications UDP au nœud passif (ligne lvs_sync_daemon
dans le fichier keepalived.conf
)
CSync2
Nous n’allons pas voir la configuration complète de CSync2 et des certificats OpenSSL, mais uniquement son fichier principal qui régit son fonctionnement.
CSync2 est exécuté pour chaque modification par vim d’un fichier dans un des répertoires à synchroniser.
/etc/vim/vimrc.local
:autocmd BufWritePost /etc/shorewall/* !shorewall check && /usr/sbin/csync2 -x :autocmd BufWritePost /etc/keepalived/* !/usr/sbin/csync2 -x :autocmd BufWritePost /etc/dhcp/* !/usr/sbin/csync2 -x
/etc/csync2.cfg
group burns { host burns2 burns3; key /etc/csync2.key_burns; include /etc/shorewall/; include /etc/keepalived/virtual_servers.conf; include /etc/dhcp/dhcpd.shared; include /etc/dhcp/dhcpd.hosts; include /etc/haproxy/haproxy.cfg; exclude *~ .*; action { pattern /etc/dhcp/dhcpd.hosts; exec "dhcpd -t -cf /etc/dhcp/dhcpd.conf"; logfile "/var/log/csync2_dhcpd.log"; } action { pattern /etc/shorewall/*; exec "/usr/sbin/shorewall reload"; logfile "/var/log/csync2_shorewall.log"; } action { pattern /etc/shorewall/*; exec "cd /etc/shorewall && /usr/bin/git commit -a -m 'AutoCommit from csync2'"; do-local; logfile "/var/log/csync2_git_action.log"; } action { pattern /etc/keepalived/*; exec "keepalived -C && echo Config OK && /usr/bin/git commit -a -m 'AutoCommit from csync2'"; logfile "/var/log/csync2_git_action.log"; } }
- Remarquez que dans cette configuration, ce n’est pas vim qui déclenche le
git commit
, maiscsync2
. - Les 2 fichiers sont identiques sur les deux nœuds firewall-router, même la ligne «host» car l’ordre des hosts n’a pas d’importance.
- Le fichier d’exemple fait aussi référence au démon dhcp en cluster synchronisé «fail-over». Je mettrai sa configuration dans la section suivante.
DHCP
On sort du cadre de Shorewall, mais il peut être intéressant de faire tourner un démon DHCP sur le firewall-routeur. Et comme on est dans la section HA, la configuration doit permettre la réplication des lease
s.
/etc/dhcp/dhcpd.conf
failover peer "dhcp-failover" { primary; # Declared Primary DHCP Server address 192.168.232.42; # Primary DHCP Server IP port 647; peer address 192.168.232.43; # Secondary DHCP Server IP peer port 647; max-response-delay 60; max-unacked-updates 10; mclt 900; split 255; load balance max seconds 5; } include "/etc/dhcp/dhcpd.shared"; # Configuration commune aux 2 nœuds include "/etc/dhcp/dhcpd.hosts"; # Réservations DHCP, commune aux 2 nœuds
Shorewall est gratuit
Ce n’est pas une nouvelle, mais c’est un fameux atout.
Cela signifie que vous pouvez le multiplier sans coût pour augmenter la disponibilité de votre réseau.
Par exemple:
- Une paire de Shorewall «Internet Facing»
- Une paire de Shorewall sur chaque site, pour les réseaux propres au site
- Une paire de Shorewall sur 2 sites pour les VLANs «trunkés» ou «spread VLANs» qui sont une réelle menace pour la disponibilité du réseau. Ces «spread-vlans» entre sites sount souvent nécessaires si vous avez de vielles applications qui ne supportent pas de haute-disponibilité ou des applications coûteuses en licenses qui vous obligent à garder la possibilité de « live-migration » entre les sites. Vous gagnerez à dédier un cluster Shorewall pour ces réseaux plus fragiles en attendant de pouvoir vous en passer.