Afficher la pageAnciennes révisionsLiens de retourHaut de page Cette page est en lecture seule. Vous pouvez afficher le texte source, mais ne pourrez pas le modifier. Contactez votre administrateur si vous pensez qu'il s'agit d'une erreur. ====== IPTables - Installation et gestion de pare-feu ====== <label type="info">Création</label> --- //[[nekan@shyrkasystem.com|Nicolas THOREZ]] 2022/07/20 08:47// Un pare-feu est un élément indispensable à la sécurité d'un serveur. Il permet de de contrôler les flux réseaux entrants, sortants et/ou transitant par ce serveur en autorisant ou interdisant ces dît flux. Le principe est simple : le pare-feu est composé de règles et de politiques globales. Lorsqu'un flux passe sur le serveur, il est automatiquement analysé par ce dernier selon son trajet (entrant, sortant, transit). Le pare-feu va comparer ce flux à chacune de ces règles jusqu'à la dernière (si tout est bien configuré, cette dernière règle est la politique globale). Dès qu'il trouve une correspondance, il applique la règle et passe au flux suivant. <callout type="warning" title="Ordre des règles" icon="true">L'ordre des règles de pare-feu est extrêmement importante, ce dernier traitant la première règle correspondante trouvée. Ainsi, si votre 1ère règle autorise ou refuse tous les flux, les suivantes ne seront jamais traitées. Il est donc indispensable de commencer la liste des règles par les plus spécifiques possibles et de terminer par les règles plus générales, la dernière devant toujours être la politique par défaut.</callout> <callout type="warning" title="Politique par défaut" icon="true">Pour des raisons de sécurité, les politiques par défaut sont généralement des ''refus'' (DROP). Il est toujours préférable de tout interdire et de n'autoriser que les flux identifiés comme utiles ou nécessaires. Cependant, il arrive qu'une exception pour le flux sortant soit faite. La politique par défaut pour ce flux devient alors ''autorisé'' (ACCEPT), considérant que les flux de l'intérieur vers l'extérieur sont maitrisés et légitimes (ce qui n'est pas toujours le cas).</callout> ====== Installation de IPTables ====== <callout type="danger" title="Droits" icon="true">Attention, l'installation et le paramétrage de IPTables nécessitent des droits ''root''. La plus grande prudence est donc requise.</callout> * L'installation est assez simple : <sxh bash>apt update && apt upgrade -y iptables</sxh> * On s'assure d'utiliser le bon programme de pare-feu : <sxh bash>update-alternatives --set iptables /usr/sbin/iptables-legacy</sxh> Le service ''iptables'' est désormais installé, on peut vérifier les règles actuelles avec la commande : <sxh bash>iptables -L -n</sxh> Ce qui nous donne : <sxh>Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination</sxh> Comme on peut le voir, par défaut le pare-feu autorise absolument tout, le rendant de fait particulièrement inutile. Il nous faut donc le paramétrer avant de pouvoir correctement l'utiliser. ====== Paramétrage ====== ====== Service ====== Le fichier principal du service est ''/etc/init.d/iptables''. On va donc le modifier pour qu'il ressemble à cela : <sxh bash>#!/bin/bash -e ### BEGIN INIT INFO # Provides: iptables # Required-Start: $network $syslog # Required-Stop: $network $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Set firewall rules at boot # Description: Set firewall rules at boot from /etc/iptables-base.conf and /etc/iptables.d ### END INIT INFO PATH=/sbin:/usr/sbin:/bin:/usr/bin do_start () { iptables -t nat -F iptables -t nat -X iptables -t mangle -F iptables -t mangle -X iptables-restore < /etc/iptables-base.conf find /etc/iptables.d/ -type f | sort | while read f do iptables-restore -n < $f done iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT } do_stop () { iptables -P INPUT ACCEPT iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT iptables -F iptables -X iptables -t nat -F iptables -t nat -X iptables -t mangle -F iptables -t mangle -X } case "$1" in start) do_start ;; restart|reload|force-reload) do_start ;; stop) do_stop ;; *) echo "Usage: iptables [start|stop]" >&2 exit 3 ;; esac :</sxh> Quelques explication pour ''do_start'' : <sxh bash> iptables -t nat -F iptables -t nat -X iptables -t mangle -F iptables -t mangle -X</sxh> On supprime les règles existantes dans les tables ''NAT'' (qui permet le routage d'une adresse vers une autre) et ''MANGLE'' (qui permet la modification des paquets). A noter qu'on ne touche pas aux règles dynamiques afin de ne pas couper les connexions en cas de recharge du pare-feu. <sxh bash> iptables-restore < /etc/iptables-base.conf</sxh> On recharge les règles de base contenues dans le fichier ''/etc/iptables-base.conf''. <sxh bash> find /etc/iptables.d/ -type f | sort | while read f do iptables-restore -n < $f done</sxh> On recharge les règles spécifiques contenues dans le dossier ''/etc/iptables.d/''. <sxh bash> iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT</sxh> On applique les politiques par défaut pour les chaînes d'entrée (''INPUT''), de transit (''FORWARD'') et de sortie (''ACCEPT''). A noter que l'on trouve souvent ces règles en début de script, hors, d'expérience, il est préférable de les mettre en dernière position afin de s'assurer qu'elles ne seront pas écrasées par d'autres règles. Concernant le ''do_stop'', on active un politique globale permissive et on supprime toutes les règles existantes. Le fichier de service étant prêt, on s'assure qu'il est exécutable : <sxh bash>chmod +x /etc/init.d/iptables</sxh> On s'assure aussi que le service démarrera automatiquement : <sxh bash>systemctl enable iptables</sxh> ====== Configuration de base ====== On crée maintenant le fichier de configuration de base ''/etc/iptables-base.conf'' : <sxh bash>nano /etc/iptables-base.conf</sxh> Son contenu doit être : <sxh bash>*filter :LOGACCEPT - [0:0] :LOGDROP - [0:0] # Allows all loopback (lo) traffic and drop all traffic to 127/8 that doesn't use lo -A INPUT -i lo -j ACCEPT -A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT # Accepts all established inbound connections -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # Allows all outbound traffic -A OUTPUT -j ACCEPT # Custom chains for logging -A LOGACCEPT -m limit --limit 1/sec --limit-burst 10 -j LOG --log-prefix "ipt-logaccept " --log-level 7 --log-uid -A LOGACCEPT -j ACCEPT -A LOGDROP -m limit --limit 1/sec --limit-burst 10 -j LOG --log-prefix "ipt-logdrop " --log-level 7 --log-uid -A LOGDROP -j DROP COMMIT </sxh> <callout type="warning" title="Espace" icon="true">Attention, les lignes vides ne doivent pas contenir d'espace (elles doivent être vraiment vides, juste un retour à la ligne) sinon, le script ''iptables'' va vouloir les interpréter, ce qui causera des erreurs.</callout> Niveau explication : <sxh bash>*filter ... COMMIT</sxh> Tous les fichiers de configurations doivent commencé par ''*filter'' et finir par ''COMMIT''. Il s'agit de la syntaxe du langage utilisé par ''iptables''. <sxh bash>:LOGACCEPT - [0:0] :LOGDROP - [0:0]</sxh> On crée les chaînes ''LOGACCEPT'' et ''LOGDROP'' pour les besoins de logs. <sxh bash>-A INPUT -i lo -j ACCEPT -A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT</sxh> On accepte tous les paquets de la boucle interne sauf ceux qui ne proviennent pas de cette boucle (la machine peut discuter avec elle-même mais les paquets extérieurs ne peuvent pas atteindre la boucle interne). <sxh bash>-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT</sxh> On accepte les connexions déjà établies (évite les coupures de flux). <sxh bash>-A OUTPUT -j ACCEPT</sxh> On accepte le flux sortant (permet l'établissement dynamique des flux sortant en réponse aux flux entrants). <sxh bash>-A LOGACCEPT -m limit --limit 1/sec --limit-burst 10 -j LOG --log-prefix "ipt-logaccept " --log-level 7 --log-uid -A LOGACCEPT -j ACCEPT -A LOGDROP -m limit --limit 1/sec --limit-burst 10 -j LOG --log-prefix "ipt-logdrop " --log-level 7 --log-uid -A LOGDROP -j DROP</sxh> On paramètre la chaîne de log pour les flux acceptés et refusés, en ajoutant notamment, un préfixe à chaque ligne de logs (pour les retrouver plus facilement dans ''syslog'', un niveau de logs, des limites de saturations, etc... ====== Configurations spécifiques ====== Pour la suite, on peut ajouter des règles spécifiques selon les besoins de la machine. Pour cela, on va déjà créer le dossier qui contiendra ces règles : <sxh bash> mkdir /etc/iptables.d</sxh> <callout type="info" title="Selon vos besoins" icon="true">Les règles suivantes sont des exemples. Elles sont à mettre en place et à adapter selon vos besoins. A noter aussi que les noms de fichiers de configurations utilisés sont arbitraires.</callout> Dans ce dossier, chaque fichier sera numéroté afin d'établir une hiérarchie. ===== Les groupes ===== On commence alors par créer le fichier ''00-lists'' qui contiendra les groupes d'adresses IP (pratique pour appliquer une règle spécifique sur plusieurs adresses en même temps) : <sxh bash>nano /etc/iptables.d/00-lists</sxh> Contenu : <sxh bash>*filter # Réseau local :SHYRKA - -A SHYRKA -s 10.0.0.0/8 -j ACCEPT COMMIT </sxh> Dans cet exemple, je crée un groupe ''SHYRKA'' qui comprend toutes les adresses IP sur le réseau 10.0.0.0/8. Ainsi, si j'autorise un port pour ce groupe, toutes les adresses inclues dans ce groupe seront autorisées. ===== Les paquets invalides et/ou malformés ===== Il peut être intéressant de log les paquets invalides ou malformés suite à des micro-coupures ou des erreurs de communications avant de les supprimer. Pour cela, on ajoute le fichier ''05-invalid'' dont le contenu est : <sxh bash>*filter # log iptables denied calls (access via 'dmesg' command) -A INPUT -m state --state INVALID -m limit --limit 5/min -j LOG --log-prefix "[ipt4-in-invalid] " --log-level 7 -A INPUT -m state --state INVALID -j DROP -A FORWARD -m state --state INVALID -m limit --limit 5/min -j LOG --log-prefix "[ipt4-fwd-invalid] " --log-level 7 -A FORWARD -m state --state INVALID -j DROP COMMIT </sxh> ===== Ping ===== Le ping peut être autorisé sur la machine avec le fichier ''10-ping'' : <sxh bash>*filter # Allow ping -A INPUT -p icmp -m icmp --icmp-type echo-request -j ACCEPT COMMIT </sxh> En remplaçant ''ACCEPT'' par ''DROP'', le ping est alors explicitement refusé. ===== SSH ===== Sur un machine linux, il est fréquent de s'y connecter en ''SSH''. Le port doit donc être autorisé mais surveillé. Pour cela, on aura recours au fichier ''22-ssh'' : <sxh bash>*filter # Allows SSH from SHYRKA -A INPUT -p tcp --dport 22 -m state --state NEW,ESTABLISHED,RELATED -j SHYRKA # Allows SSH from UNIVERSE -A INPUT -s 12.34.56.78 -p tcp --dport 22 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT COMMIT </sxh> Ici, on applique l'ouverture du port 22 (''SSH'') pour le groupe ''SHYRKA'' (qui accepte les règles pour le réseau 10.0.0.0/8). Pour des connexions ''SSH'' depuis l'extérieur, j'utilise le paramètre ''-s'' pour spécifier l'adresse IP source (ici ''12.34.56.78'') pour laquelle l'ouverture du port est autorisé et ce afin d'éviter d'ouvrir ce port à tout internet, question de sécurité. ===== Log ===== On termine généralement par loguer tout ce qui n'est pas accepté via la configuration du fichier ''99-log'' : <sxh bash>*filter # log iptables denied calls (access via 'dmesg' command) -A INPUT -m limit --limit 5/min -j LOG --log-prefix "[ipt4-in-deny] " --log-level 7 -A FORWARD -m limit --limit 5/min -j LOG --log-prefix "[ipt4-fwd-deny] " --log-level 7 COMMIT </sxh> ====== Autres exemples de configurations ====== Ci-dessous, des exemples de configurations additionnelles selon des services courants. ===== NTP ===== * Fichier : ''12-ntp'' * Contenu : <sxh bash>*filter # Allow NTP -A INPUT -p udp --dport 123 -j ACCEPT COMMIT </sxh> ===== FTP ===== * Fichier : ''21-ftp'' * Contenu : <sxh bash>*filter # Allow FTP and FTPS -A INPUT -p tcp --dport 20,21 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT -A INPUT -p tcp --dport 989 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT COMMIT </sxh> ===== Messagerie ===== * Fichier : ''25-mail'' * Contenu : <sxh bash>*filter # Allows POP3 and POP3S -A INPUT -p tcp --dport 110 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT -A INPUT -p tcp --dport 995 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT # Allow IMAP and IMAPS -A INPUT -p tcp --dport 143 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT -A INPUT -p tcp --dport 995 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT # Allow SMTP, SMTPS and SMTPS with STARTTLS -A INPUT -p tcp --dport 25 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT -A INPUT -p tcp --dport 465 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT -A INPUT -p tcp --dport 587 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT COMMIT </sxh> ===== Munin node ===== * Fichier : ''26-munin-node'' * Contenu : <sxh bash>*filter # Allows Munin connections from Munin server(s) -A INPUT -p tcp -s 10.1.2.3 --dport 4949 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT COMMIT </sxh> ===== Serveur Web ===== * Fichier : ''30-web-server'' * Contenu : <sxh bash>*filter # Allows HTTP(s) connections -A INPUT -p tcp --dport 80 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT -A INPUT -p tcp --dport 443 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT COMMIT </sxh> ===== MySQL ===== * Fichier : ''34-mysql'' * Contenu : <sxh bash>*filter # Allows MySQL connections -A INPUT -p tcp --dport 3306 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT COMMIT </sxh> ===== Rsyslog (pour les puist de logs) ===== * Fichier : ''50-rsyslog'' * Contenu : <sxh bash>*filter # Allows Rsyslog connections -A INPUT -p tcp -s 10.4.5.6 --dport 514 -j ACCEPT -A INPUT -p udp -s 10.4.5.6 --dport 514 -j ACCEPT COMMIT </sxh> ===== DNS ===== * Fichier : ''53-dns'' * Contenu : <sxh bash>*filter # Allows DNS connections -A INPUT -p udp --dport 53 -j ACCEPT COMMIT </sxh> ===== NRPE (Services actifs Nagios) ===== * Fichier : ''90-nrpe'' * Contenu : <sxh bash>*filter # Allows NRPE connections from Nagios server(s) -A INPUT -p tcp -s 10.7.8.9 --dport 5666 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT COMMIT </sxh> ===== NSCA (Services passifs Nagios) ===== * Fichier : ''91-nsca'' * Contenu : <sxh bash>*filter # Allows NSCA connections from local network -A INPUT -p tcp -s 10.0.0.0/8 --dport 5667 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT COMMIT </sxh> ====== Conclusion ====== Une fois les différentes configutions mises en place et le service ''iptables'' redémarrés, on peut voir les différentes règles appliquées avec ''iptables -L -n'' : Exemple : <sxh bash>Chain INPUT (policy DROP) target prot opt source destination ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 REJECT all -- 0.0.0.0/0 127.0.0.0/8 reject-with icmp-port-unreachable ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED LOG all -- 0.0.0.0/0 0.0.0.0/0 state INVALID limit: avg 5/min burst 5 LOG flags 0 level 7 prefix "[ipt4-in-invalid] " DROP all -- 0.0.0.0/0 0.0.0.0/0 state INVALID ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0 icmptype 8 SHYRKA tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 state NEW,RELATED,ESTABLISHED ACCEPT tcp -- 12.34.56.78 0.0.0.0/0 tcp dpt:22 state NEW,RELATED,ESTABLISHED ACCEPT tcp -- 10.1.2.3 0.0.0.0/0 tcp dpt:4949 state NEW,RELATED,ESTABLISHED ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 state NEW,RELATED,ESTABLISHED ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:443 state NEW,RELATED,ESTABLISHED ACCEPT tcp -- 10.7.8.9 0.0.0.0/0 tcp dpt:5666 state NEW,RELATED,ESTABLISHED LOG all -- 0.0.0.0/0 0.0.0.0/0 limit: avg 5/min burst 5 LOG flags 0 level 7 prefix "[ipt4-in-deny] " Chain FORWARD (policy DROP) target prot opt source destination LOG all -- 0.0.0.0/0 0.0.0.0/0 state INVALID limit: avg 5/min burst 5 LOG flags 0 level 7 prefix "[ipt4-fwd-invalid] " DROP all -- 0.0.0.0/0 0.0.0.0/0 state INVALID LOG all -- 0.0.0.0/0 0.0.0.0/0 limit: avg 5/min burst 5 LOG flags 0 level 7 prefix "[ipt4-fwd-deny] " Chain OUTPUT (policy ACCEPT) target prot opt source destination ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 Chain LOGACCEPT (0 references) target prot opt source destination LOG all -- 0.0.0.0/0 0.0.0.0/0 limit: avg 1/sec burst 10 LOG flags 8 level 7 prefix "ipt-logaccept " ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 Chain LOGDROP (0 references) target prot opt source destination LOG all -- 0.0.0.0/0 0.0.0.0/0 limit: avg 1/sec burst 10 LOG flags 8 level 7 prefix "ipt-logdrop " DROP all -- 0.0.0.0/0 0.0.0.0/0 Chain SHYRKA (1 references) target prot opt source destination ACCEPT all -- 10.0.0.0/8 0.0.0.0/0 </sxh> <callout type="success" title="Fini" icon="true"> Voilà, votre pare-feu est actif et entièrement paramétrable selon vos souhaits.</callout> ~~DISCUSSION~~ iptables.txt Dernière modification : 2022/07/20 12:20de nekan