Ma méthode pour gérer les règles IpTables
Cette phrase a été prononcée au moins une fois par toute personne ayant administré les règles de Firewall d'un serveur. Les conséquences vont du simple blocage d'une application critique (dont on s’aperçoit de l'indisponibilité au prochain "check" sur son serveur de monitoring) à la perte de connexion pure et simple vers la machine (même pour corriger sa boulette).
Pour éviter de se retrouver dans cette situation et ainsi éviter les rires et moqueries des collègues, voici quelques pistes que j'utilise pour administrer mes règles IpTables sur mes serveurs Debian.
1. Regrouper la sécurité dans un script de démarrage
Il y a plusieurs écoles pour gérer les règles de Firewall. Celle proposée par le wiki officiel de Debian repose sur l'utilisation exclusive des commandes iptables-save et iptables-restore qui permettent respectivement de sauvegarder et de restaurer une configuration IpTables existante.
Pour ma part, je préfère inclure ces commandes dans un script de plus haut niveau que je positionne dans le répertoire /etc/init.d et qui sera donc lancé au démarrage du serveur. Ce fichier firewall.sh est disponible sur mon GitHub DebianPostInstall ou via Gist.
En voici une version à ce jour:
Par défait le script met en place les règles suivantes:
- autorise les connexions SSH entrantes (pour administrer son serveur à distance)
- autorise les connexions HTTP, HTTPs et DNS sortante (pour l'installation et mise à jour du système et des logiciels)
- interdiction et log des autres flux, entrant et sortant
- et en cadeau bonux (ce qui on plus de 35 ans peuvent comprendre) sécurise un peu plus le kernel Linux
L'utilisation de ce script est standard, ainsi pour appliquer les règles de Firewall:
sudo service firewall.sh start
Pour supprimer les règles de Firewall (attention votre serveur sera ainsi exposé aux attaques extérieures puisqu'aucunes restriction d'accès ne sera appliquée):
sudo service firewall.sh clear
Attention: Il est également possible d'utiliser cette commande avec l'option stop (sudo service firewall.sh stop), mais il faut être conscient que toutes les connexions, entrantes et sortantes seront alors interdites (même votre SSH !!!). Cette commandes est donc à éviter bannir si l'on utilise une connexion à distance pour administrer son serveur...
2. Modifier les règles
On entre ici dans le vif du sujet de ce billet: Comment procéder quand on doit modifier les règles de sécurité ?
La première chose à faire est d'être sûr d'avoir les connaissances nécessaires avant de toucher à quoi que ce soit. Cela peut sembler évident, mais faire des copier/coller de règles trouver sur le net et que l'on ne maîtrisent pas est, sans aucun doute, le meilleur moyen de tout faire planter. Pour modifier les tables IpTables, il faut donc avoir un verni de connaissance général sur le protocole TCP/IP (notamment les notions d'adresses et de port sources/destinations). On trouve pour cela quelques très bon cours en ligne comme celui de chez Developpez.com ou bien la bible de Tanenbaum: Réseaux 5em édition aux éditions Pearson. Bien évidemment, il faut également connaitre les rudiments de la commande IpTables en lisant la documentation officielle (disponible en Français) et notamment la section sur le filtrage de paquets.
On peut passer aux choses sérieuses en identifiant les règles courantes grâce à la commande:
sudo iptables -n -L -v --line-numbers
On obtiendra alors une sortie dépendante des règles actives (exemple pour un de mes serveurs):
Chain INPUT (policy DROP 13 packets, 1398 bytes) num pkts bytes target prot opt in out source destination 1 381M 138G fail2ban-ALL tcp -- * * 0.0.0.0/0 0.0.0.0/0 2 495K 83M fail2ban-SSH tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 3 251M 23G fail2ban-HTTP tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 4 380M 138G fail2ban-ALL tcp -- * * 0.0.0.0/0 0.0.0.0/0 5 606M 241G ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED 6 64473 3711K ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 7 12M 653M ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 8 1 44 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:1337 9 55724 3343K ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:4949 10 85 4064 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:5001 11 53603 3216K ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:61209 12 13 532 ACCEPT udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:123 13 224K 21M ACCEPT udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:161 14 0 0 ACCEPT udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:5001 15 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 16 230K 22M ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 17 4822K 289M ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0 18 3684K 435M LOG all -- * * 0.0.0.0/0 0.0.0.0/0 LOG flags 0 level 4 19 0 0 ACCEPT tcp -- * * 88.190.254.200 0.0.0.0/0 tcp spt:20 Chain FORWARD (policy DROP 0 packets, 0 bytes) num pkts bytes target prot opt in out source destination Chain OUTPUT (policy DROP 0 packets, 0 bytes) num pkts bytes target prot opt in out source destination 1 98M 183G ACCEPT all -- * lo 0.0.0.0/0 0.0.0.0/0 2 253M 912G ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED 3 1 84 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 4 0 0 ACCEPT tcp -- * * 0.0.0.0/0 195.20.242.89 tcp dpt:80 5 0 0 ACCEPT tcp -- * * 0.0.0.0/0 212.211.132.32 tcp dpt:80 6 0 0 ACCEPT tcp -- * * 0.0.0.0/0 212.211.132.250 tcp dpt:80 7 179 10740 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:21 8 276 14700 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 9 1254 75180 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:25 10 91789 5507K ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 11 12940 776K ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:443 12 688K 46M ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpts:1024:65534 13 90M 5705M ACCEPT udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:53 14 30171 2293K ACCEPT udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:123 15 0 0 ACCEPT tcp -- * * 0.0.0.0/0 88.190.254.200 tcp dpt:21 16 78 3120 LOG all -- * * 0.0.0.0/0 0.0.0.0/0 LOG flags 0 level 4 17 78 3120 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable Chain fail2ban-ALL (2 references) num pkts bytes target prot opt in out source destination 1 761M 277G RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 2 0 0 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 Chain fail2ban-HTTP (1 references) num pkts bytes target prot opt in out source destination 1 251M 23G RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 Chain fail2ban-SSH (1 references) num pkts bytes target prot opt in out source destination 1 10 1568 DROP all -- * * 61.155.150.217 0.0.0.0/0 2 408K 77M RETURN all -- * * 0.0.0.0/0 0.0.0.0/0
Une fois que vous avez identifié la règle IpTables à ajouter dans votre configuration, il est maintenant temps de passer à l'action.
Ne jamais, jamais, modifier directement la table avec une commande IpTables sur un serveur en production...
Plusieurs solutions sont possibles, personnellement, j'utilise la méthodologie suivantes:
- je commence par copier le script firewall.sh dans un autre répertoire (par exemple dans /tmp/firewall.sh)
- j'ajoute la règle IpTables dans la copie du script (/tmp/firewall.sh)
- je teste les nouvelles règles en utilisant l'option "test" du script ainsi modifié qui va sauvegarder les règles actuelles, appliquer les nouvelles, attendre 30 secondes puis ré-appliquer les règles actuelles (donc au pire au fait une boulette de 30 secondes...)
- si tout se passe comme attendu pendant les 30 secondes, alors je copie le fichier /tmp/firewall.sh sous /etc/init.d
- et j'applique les règles en production le moment voulu
Les lignes de commandes correspondantes sont:
sudo cp /etc/init.d/firewall.sh /tmp/ sudo vim /tmp/firewall.sh sudo sh /tmp/firewall.sh test sudo cp /tmp/firewall.sh /etc/init.d/ sudo service firewall.sh restart
Ainsi, en cas de problème dans les règles, le serveur ne sera indisponible que pendant 30 secondes. Dans le cas "pas de bol" ou le serveur crache durant ces 30 secondes alors les anciennes règles seront rechargées au redémarrage.
Pas de script ?
Si vous ne souhaitez pas mettre en place un tel script de démarrage des règles de Firewall, il est quand même possible (même si je ne le conseille pas pour avoir une vue d'ensemble des règles à appliquer) de reproduire la méthodologie d'écrite dans le chapitre précédant.
Ainsi, il est tout à fait possible d'utiliser une commande du type:
sudo iptables-save > /etc/iptables.backup && sudo iptables <nouvelle regle a appliquer> && sleep 30 && sudo iptables-restore < /etc/iptables.backup
Conclusion
Comment gérez-vous vos règles de Firewall sur vos serveurs GNU/Linux ? Des astuces à partager avec nous dans les commentaires ?
Cet article Ma méthode pour gérer les règles IpTables est apparu en premier sur Le blog de NicoLargo.