Je me suis récemment rendu compte des dangers auxquels mon Raspberry Pi était exposé.
Bien qu’il soit placé derrière un router avec des fonctions de pare-feu activées, le Pi n’est pas à l’abri de nombreuses attaques. J’ai donc activé quelques protections dont la première est IPtables.
Voici d’autres articles de mon blog qui traitent du même sujet :
Normalement, IPtables est installé d’origine sur le RPi.
Si ce n’était pas le cas, il suffit de l’installer comme ceci :
$ sudo apt-get update && sudo apt-get upgrade && sudo apt-get install iptables
Une fois le pare-feu installé, on va vérifier qu’aucune règle n’a été configurée :
$ sudo iptables -L
On devrait obtenir ceci :
Chain INPUT (policy DROP) target prot opt source destination Chain FORWARD (policy DROP) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination
Pour bloquer des ports et modifier les restrictions d’accès, il faut appeler iptables
en ligne de commande avec les privilèges root. Mais dès que le RPi est redémarré, tous ce qui a été configuré est perdu et il faut tout recommencer.
Pour éviter ces inconvénients, on va créer un script comprenant toutes les commandes pour configurer le pare-feu et l’exécuter lors du démarrage du Pi.
On crée un fichier que l’on va nommer firewall
et que l’on va placer dans le dossier /etc/init.d/
:
$ sudo nano /etc/init.d/firewall
On va y copier les lignes suivantes :
#!/bin/sh ### BEGIN INIT INFO # Provides: firewall rules # Required-Start: $remote_fs $syslog # Required-Stop: $remote_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start daemon at boot time # Description: Enable service provided by daemon. ### END INIT INFO #Suppression des règles précédentes iptables -F iptables -X ######## # DROP # ######## # Définition du blocage général iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -P FORWARD DROP # Drop des scans XMAS et NULL iptables -A INPUT -p tcp --tcp-flags FIN,URG,PSH FIN,URG,PSH -j DROP iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP ########## # ACCEPT # ########## # Conservations des connexions déjà établies iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT # Autorisation du loopback (127.0.0.1) iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT # Autorisation des échanges avec le serveur DNS (53) iptables -A OUTPUT -p udp -m udp --dport 53 -m conntrack --ctstate NEW,RELATED,ESTABLISHED -j ACCEPT iptables -A INPUT -p udp -m udp --sport 53 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT # NTP (123) iptables -A INPUT -p udp --sport 123 -j ACCEPT iptables -A OUTPUT -p udp --dport 123 -j ACCEPT # HTTP (80) iptables -A INPUT -p tcp --dport 80 -j ACCEPT iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT # HTTPS (443) iptables -A INPUT -p tcp --dport 443 -j ACCEPT iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT # HTTP (81 - PHPMyAdmin) iptables -A INPUT -s 192.168.0.1/24 -p tcp --dport 81 -j ACCEPT iptables -A OUTPUT -s 192.168.0.1/24 -p tcp --dport 81 -j ACCEPT # HTTP (8200 - MiniDLNA) iptables -A INPUT -s 192.168.0.1/24 -p tcp --dport 8200 -j ACCEPT iptables -A OUTPUT -s 192.168.0.1/24 -p tcp --dport 8200 -j ACCEPT # MiniDLNA (1900) iptables -A INPUT -s 192.168.0.1/24 -p tcp -m tcp --dport 1900 -j ACCEPT iptables -A INPUT -s 192.168.0.1/24 -p udp -m udp --dport 1900 -j ACCEPT iptables -A OUTPUT -s 192.168.0.1/24 -p udp -m udp --dport 1900 -j ACCEPT # HTTP (9091 - Transmission-Daemon WebInterface - Direct Access) iptables -A INPUT -s 192.168.0.1/24 -p tcp --dport 9091 -j ACCEPT iptables -A OUTPUT -s 192.168.0.1/24 -p tcp --dport 9091 -j ACCEPT # SSH (22) iptables -A INPUT -p tcp --dport 22 -j ACCEPT iptables -A OUTPUT -p tcp --dport 22 -j ACCEPT # VNC (5900:5910) iptables -A INPUT -p tcp --dport 5900:5910 -j ACCEPT iptables -A OUTPUT -p tcp --dport 5900:5910 -j ACCEPT # Transmission (51413) iptables -A INPUT -p tcp -m tcp --dport 51413 -j ACCEPT iptables -A INPUT -p udp -m udp --dport 51413 -j ACCEPT iptables -A OUTPUT -p tcp -m tcp --dport 51413 -j ACCEPT iptables -A OUTPUT -p udp -m udp --dport 51413 -j ACCEPT # Announces trackers (9200) iptables -A OUTPUT -p tcp --dport 9200 -j ACCEPT # Ports Torrents (49152:65535) iptables -A INPUT -p tcp --dport 49152:65535 -j ACCEPT iptables -A INPUT -p udp --dport 49152:65535 -j ACCEPT iptables -A OUTPUT -p tcp --dport 49152:65535 -j ACCEPT iptables -A OUTPUT -p udp --dport 49152:65535 -j ACCEPT # ICMP (Ping) iptables -A INPUT -p icmp -j ACCEPT iptables -A OUTPUT -p icmp -j ACCEPT # Parer les attaques de type Déni de Service iptables -A FORWARD -p tcp --syn -m limit --limit 1/second -j ACCEPT iptables -A FORWARD -p udp -m limit --limit 1/second -j ACCEPT iptables -A FORWARD -p icmp --icmp-type echo-request -m limit --limit 1/second -j ACCEPT # Parer les scans de ports iptables -A FORWARD -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s -j ACCEPT
Ci-dessus le SSH est ouvert depuis n’importe quelle adresse sur le net, ce qui va nous permettre de nous connecter depuis n’importe où dans le monde.
Si vous modifiez cette règle, vous risquez de perdre l’accès à votre RPi en SSH.
On va maintenant rendre le script exécutable :
$ sudo chmod +x /etc/init.d/firewall
Puis, l’exécuter manuellement :
$ sudo /etc/init.d/firewall
Pour l’exécuter à chaque démarrage, on va l’inclure dans la liste des scripts qui s’exécutent au boot :
$ sudo update-rc.d firewall defaults
Voilà, une partie des ports sont bloqués, mais ceux qui sont restés ouverts (principalement pour les torrents) courent un risque.
Pour compléter la sécurité, on va installer Fail2Ban. Mais ça, c’est une autre histoire… 😉
Edit – 16 juillet 2014 :
J’ai remarqué que les logs de Fail2Ban comportaient régulièrement des attaques depuis des adresses IP situées dans les mêmes tranches.
2014-07-16 17:27:29,371 fail2ban.actions: WARNING [ssh] Ban 116.10.191.223 2014-07-16 17:27:29,549 fail2ban.actions: WARNING [ssh] Ban 116.10.191.212 2014-07-16 17:27:29,709 fail2ban.actions: WARNING [ssh] Ban 120.33.29.226 2014-07-16 17:27:29,889 fail2ban.actions: WARNING [ssh] Ban 61.174.51.224 2014-07-16 17:27:30,079 fail2ban.actions: WARNING [ssh] Ban 109.75.160.67 2014-07-16 17:27:30,238 fail2ban.actions: WARNING [ssh] Ban 202.137.9.53 2014-07-16 17:27:30,422 fail2ban.actions: WARNING [ssh] Ban 61.174.51.214 2014-07-16 17:27:30,587 fail2ban.actions: WARNING [ssh] Ban 116.10.191.163 2014-07-16 17:27:30,759 fail2ban.actions: WARNING [ssh] Ban 61.174.51.215 2014-07-16 17:27:30,948 fail2ban.actions: WARNING [ssh] Ban 116.10.191.234 2014-07-16 17:27:31,126 fail2ban.actions: WARNING [ssh] Ban 116.10.191.179 2014-07-16 17:27:31,305 fail2ban.actions: WARNING [ssh] Ban 116.10.191.231 2014-07-16 17:27:31,491 fail2ban.actions: WARNING [ssh] Ban 61.174.50.235
NB.: Toutes les heures sont identiques car j’ai reloadé Fail2Ban après avoir modifié les règles. Il a alors re-banni toutes les attaques trouvées dans la période décrite dans le findtime = 86400
(1 jour).
J’ai alors décidé d’ajouter quelques lignes dans la partie DROP
d’IPtables, dans le fichier /etc/init.d/firewall
:
# Bloquer certaines IP connues pour les attaques # De 116.10.191.1 => 116.10.191.254 iptables -A INPUT -s 116.10.191.0/24 -j DROP # De 61.174.50.1 => 61.174.51.254 iptables -A INPUT -s 61.174.50.0/23 -j DROP
Un calculateur de masque IPv4 pourra vous être utile :
http://cric.grenoble.cnrs.fr/Administrateurs/Outils/CalculMasque/
8 ans ago ·
Bonjour,
Merci pour ce tuto : fantastique !
Eventuellement pourriez-vous m’aider (je suis loin d’être un spécialiste).
Voilà – j’aimerais modifier l’adresse 192.168.0.1 en 192.168.1.1. J’ai fait les modifs dans le script mais lorsque je veux intégrer la nouvelle version par ‘sudo update-rc.d firewall defaults’, j’ai une série de warnings et mon iptables (‘sudo iptables -L’) est remise à zéro (vide).
Cordialement
FBx
8 ans ago ·
Bonjour,
La commande « sudo update-rc.d firewall defaults » permet de lancer la script firewall lors de chaque démarrage.
Elle ne doit être exécutée qu’une fois.
Si vous voulez changer les règles du firewall, modifiez simplement le script avec la commande : « sudo nano /etc/init.d/firewall ».
C’est ce script modifié qui sera appelé au boot…
Pour éviter de redemarrer le RPi, vous pouvez exécuter le script en vous plaçant dans le dossier « /etc/init.d/ » et en tapant la commande : « ./firewall ».
Didier.
7 ans ago ·
Bonjour,
Petite précision (qui évitera peut être à certains de chercher pendant un moment), le HTTPS semble bloquer avec ces règles (si je ne dis pas de bêtises). Il faut l’autoriser avec les lignes :
iptables -A INPUT -p tcp –dport 443 -j ACCEPT
iptables -A OUTPUT -p tcp –dport 443 -j ACCEPT
7 ans ago ·
Merci,
C’est modifié !
Didier.
7 ans ago ·
Histoire d’être pointilleux, les lignes pour 443 que tu as rajouté ne fonctionnent pas si on « copie/colle » le pavé.
Le « – » a été transformé et fait foirer la ligne. ^^
7 ans ago ·
Merci pour la remontée. 😉
C’est corrigé.
7 ans ago ·
Bonjour j’ai réalisé le script au démarrage, il fonctionne très bien quand je le lance manuellement mais lors du démarrage le fichier Blacklist.txt est vide, donc je pense qu’il ne fonctionne pas? Auriez-vous une solution?
Merci
7 ans ago ·
Bonjour,
Comme le script s’exécute au démarrage, il est possible que la connexion internet ne soit pas encore initialisée.
D’où le retour d’un fichier vide.
Peut-être ajouter un WAIT ?
Didier.
7 ans ago ·
Merci de votre réponse mais j’ai réussi en rajoutant le lien du script dans rc.local.
7 ans ago ·
Bonjour, j’ai donc installé iptables sur mon Raspberry mais le problème c’est qu’il met 2 voir 3 heures pour mettre à jour, avec la Blacklist, j’ai pris la blacklist avec toutes les IP’s? Est-ce normal?
6 ans ago ·
Bonjour, pouvez-vous me donner la manip pour avoir Geoip sur Raspberry, il me met ce message d’erreur: iptables: No chain/target/match by that name?
Merci
6 ans ago ·
Bonjour,
Oui, c’est normal.
La méthode n’est pas très adaptée aux très grandes listes d’IP à bannir.
Voyez un autre article qui répondra mieux à votre cas : https://www.fanjoe.be/?p=3233
Didier.
6 ans ago ·
merci beaucoup. Par contre, il me marque: ipset v6.30: The set with the given name does not exist
je dois m’en inquiéter?
6 ans ago ·
Une recherche Google ?
6 ans ago ·
Déjà fait, il n’ y a pas grand chose! Du moins rien qui fonctionne pour moi!
6 ans ago ·
Bonjour,
Je monte actuellement un raspberry Pi pour faire de la domestique entre autres. Je suis informaticien dans une grosse entreprise et j’y ai appris pas mal de choses, que je souhaite appliquer avec le Pi également: sécurité, backups monitoring etc. Mais je ne suis pas un féru du monde Linux, c’est pourquoi cela me prend un peu de temps.
J’ai analysé le fichier fourni ci-dessus, de règles IPtables et j’ai été surpris de voir trois règles « DROP » intégral en premier lieu… J’imagine que le principe d’IPtables est de filtrer les paquets TCP/IP sur base des règles qui lui sont fournies, et dès qu’un paquet correspond à une règle d’appliquer la règle de filtrage en question et le paquet est traité c’est terminé au suivant… Du coup, si on fait un DROP complet sur l’entrée, la sortie et le forward en commençant, pour moi tous les paquets seront filtrés par ces règles « DROP » et ne se verront appliquer aucune des règles suivantes…
J’ai montré ces règles à des collègues spécialisés en Linux qui partagent mon avis… Du coup j’imagine que quelque chose doit nous échapper mais quoi ? Merci d’avance d’éclairer nos lanternes.
Cordialement,
6 ans ago ·
Bonjour,
Le paramettre -P définit la « politique par défaut » de la chaine INPUT, FORWARD et OUTPUT.
En bref, on verrouille tout et ouvre un par un en attachant des règles avec le paramettre -A.
Je ne suis pas spécialiste d’IPtables. Je partage juste ma configuration largement inspirée de ce que j’ai glané un peu partout sur le web.
Un exemple de la doc Ubuntu : https://doc.ubuntu-fr.org/iptables
Didier.
6 ans ago ·
Bonjour,
@fanjoe merci beaucoup pour le retour… Comme vous le voyez je suis loin d’être un spécialiste d’IPtables ou de Linux moi-même, mais j’apprends progressivement…
Bien à vous,
6 ans ago ·
Bonjour,
J’ai commencé à personnaliser le fichier de règles fourni ici… Une bonne base, indiscutablement. J’ai retiré le range VNC (un seul port suffit j’imagine), le HTTP et le HTTPS en entrée (pas de serveur web pour l’instant). Pouvez-vous encore me dire à quoi sert le port 9200 ouvert dans votre fichier ? Je n’ai trouvé que du « WAP » comme infos sur ce port, je ne vois pas bien ce que viendrait faire une vieille technologie de navigateur sur GSM dans un PC…
Merci d’avance,
Cordialement;
Michel
6 ans ago ·
Bonjour,
C’est un port d’annonce (non standard) pour un tracker BitTorrent.
Exemple : http://tracker.torrent.com:9200/announce
Didier.
6 ans ago ·
Bonjour Didier,
Super merci beaucoup pour le retour et compliments pour la disponibilité… Les gens qui partagent leurs connaissances, j’apprécie bcp.
Cordialement,
Michel
6 ans ago ·
Bonjour,
Je dis peut être une bêtise mais si on redirige uniquement un port ssh de notre box vers celui de notre raspberry. Il n’est alors pas vraiment nécessaire de mettre en place toutes les règles sur les ports nn ?
Fail2Ban est quant à lui très utile pour sécurisé le port ssh.
Mais je ne comprend pas l’intérêt de protéger tous les autres ports qui ne sont accessible que chez nous en local.
Cordialement,
Maxime.
6 ans ago ·
Bonjour Didier,
Je suis nouveau dans le domaine mais j’ai du mal a comprendre cette crainte au niveau de la sécurité. Par exemple si on redirige un port ssh de notre box vers notre raspberry (ex : 22), à ce moment le sécuriser ce port devient intéressant. Mais pourquoi aller sécuriser tous les autres ports ? La raspberry est sur notre réseau local, il n’y a que en local que nous pouvons accéder à ces ports.
Cordialement.
6 ans ago ·
Bonjour,
Effectivement, sur un réseau local, le risque est faible, mais en entreprise, l’attaque peut être menée en interne.
Pour divers raisons, il peut être nécessaire de placer le serveur en DMZ. Ce n’est peut-être pas la meilleure idée, mais c’est possible.
Aussi, avec l’arrivée des objets connectés (domotique, caméras IP, …) on n’est pas à l’abris d’une faille dans le firmware de ceux-ci qui ouvrirait une brèche sur le réseau local.
En matière de sécurité, à mon sens, mieux vaut être parano et prévoir le pire.
Didier.
6 ans ago ·
Merci beaucoup pour cette réponse très rapide.
Je vais donc me diriger vers la solution parano ^^
Cordialement,
Maxime.
5 ans ago ·
Bonjour
Pour les règles avec OUTPUT sur un port particulier, ne faut il pas plutôt écrire –sport plutôt que –dport ??
Car en appliquant uniquement la règle SSH de votre tuto j’étais bloqué et impossible de me connecter à mon serveur.
Cela s’est débloqué en corrigeant en –sport
Très bon tuto cela m’a fait grandement progresser dans la compréhension d’iptables.
5 ans ago ·
Formidable. C’est une belle base pour sécuriser son raspi. De plus partager ses connaissances est bien dans l’esprit linux. Félicitations.
5 ans ago ·
Thanks! 😉