Mes passions, le boulots, mes coups de gueule...




Raspberry Pi : Configurer IPtables

Categorie : Geek, Informatique, Raspberry Pi · par 14 Juil 2014

IPtables-01

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

# !!! Priorités : DROP toujours avant ACCEPT !!!
########
# 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/

(10) comments

Baudoux
2 années ago · Répondre

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

    fanjoe
    2 années ago · Répondre

    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.

Youri
11 mois ago · Répondre

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

    fanjoe
    11 mois ago · Répondre

    Merci,

    C’est modifié !

    Didier.

Bluescreen
10 mois ago · Répondre

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. ^^

    fanjoe
    10 mois ago · Répondre

    Merci pour la remontée. 😉
    C’est corrigé.

PP
7 mois ago · Répondre

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

    fanjoe
    7 mois ago · Répondre

    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.

pp
7 mois ago · Répondre

Merci de votre réponse mais j’ai réussi en rajoutant le lien du script dans rc.local.

PP
7 mois ago · Répondre

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?

Laisser un commentaire