[Tuto]Création d'un service FIREWALL !

Proposer ou rechercher un tutoriel concernant le Raspberry Pi

Modérateur : Francois

Artemus24
Raspinaute
Messages : 1077
Enregistré le : ven. 15 sept. 2017 19:15

[Tuto]Création d'un service FIREWALL !

Message par Artemus24 » dim. 19 août 2018 15:20

Salut à toutes et à tous.

Ce didacticiel va traiter de la création d'un service de nom "firewall" (pare-feu) sous la raspberry.
Il a été testé et a priori, il fonctionne.
Je vais détailler les différentes étapes à sa création et à son test :

1) ou créer le service ?
Cela se fait dans le répertoire "/etc/init.d".
Il suffit de créer un fichier, par exemple de nom "firewall" dans ce répertoire.
Il est inutile de mettre un suffixe à ce fichier.

2) Que faire quand le fichier "firewall" est créé ?
Se mettre dans le répertoire "/etc/init.d", puis faire :

Code : Tout sélectionner

chmod 755 firewall
chown root:root firewall
3) Ou trouver un modèle ?
Je me suis inspiré d'un service déjà existant (DHCPCD) mais aussi de ce qui a été proposé sous google.

4) Comment supprimer le service "firewall" ?

Code : Tout sélectionner

sudo update-rc.d -f firewall remove
5) Comment créer le service "firewall" ?

Code : Tout sélectionner

sudo update-rc.d firewall default
A ne faire qu'une fois, et le service sera actif au démarrage de votre raspberry.

6) Si vous avez besoin de changer les valeurs par défaut, de la création d'un service :

Code : Tout sélectionner

sudo update-rc.d firewall start 2 3 4 5 . stop 0 1 6 .
7) comment vérifier su le service "firewall" est présent ou absent ?
Vous devez vous rendre dans les répertoires "/etc/rc*.d".
L'étoile va correspondre à un nombre.
Si le service existe déjà, il sera présent.

8) Comment démarrer le service "firewall" ?
Se mettre dans le répertoire "/etc/init.d", puis faire :

Code : Tout sélectionner

firewall start
9) Comment arrêter le service "firewall" ?
Se mettre dans le répertoire "/etc/init.d", puis faire :

Code : Tout sélectionner

firewall stop
9) Vérifier l'état du service "firewall" ?
Se mettre dans le répertoire "/etc/init.d", puis faire :

Code : Tout sélectionner

firewall status
10) Quel est la structure de pare-feu ?
Nous avons adopté les règles suivantes :

Au démarrage, nous interdisons tout, sauf.
A l'arrêt, nous autorisons tout, sauf.

11) Comment ajouter un journal au service "firewall" ?
Cela se passe dans le répertoire "/etc/rsyslog.d".

J'ai créé un fichier de nom "firewall.conf" avec ceci comme contenu :

Code : Tout sélectionner

:msg, contains, " IN4: "   -/var/log/firewall.log
:msg, contains, " OUT4: "  -/var/log/firewall.log
:msg, contains, " FOR4: "  -/var/log/firewall.log
:msg, contains, " IN6: "   -/var/log/firewall.log
:msg, contains, " OUT6: "  -/var/log/firewall.log
:msg, contains, " FOR6: "  -/var/log/firewall.log
:msg, contains, " SSH: "   -/var/log/firewall.log
:msg, contains, " ERR: "   -/var/log/firewall.log
Nous verrons à quoi correspond ces libellés dans le service "firewall".

12) Comment remplir le journal "firewall" ?
Cela se fait dans le service "firewall" en précisant dans une règle le journal "LOG" ainsi que le libellé.
Par exemple :

Code : Tout sélectionner

iptables -A  INPUT  -j LOG --log-prefix 'IN: '
Toutes les règles en entrées (INPUT) basées sur l'IPv4, qui n'ont pas été sélectionnés auparavant, auront une trace préfixée par "IN:" dans le journal "firewall".
Afin d'orienter le flux vers notre journal "firewall", il faut un identifiant qui est, dans notre cas, la chaîne "IN:".

13) Comment tester ?
Nous avons ajouter après "start" et "stop" le paramètre "test", qui en réalité est un "start" suivie d'une pause de 2 minutes puis enfin un "stop".
Ceci permet, dans une autre console, de tester votre modification dans le service "service" sans perdre la main au cas où elle serait fausse.

Avant d'installer cette astuce, je me suis retrouvé bloqué, et j'ai dû utiliser mon autre raspberry (Rpi2 + carte Micro SD), afin de monter mon disque et de corriger le problème.
Beaucoup de manipulations inutiles qui seront résolus par cette astuce.

14) Que faire durant les tests ?
Voici ce que j'ai testé sur mon ordinateur windows ou dans ma raspberry :

14-a) ping sur les adresses suivantes :
--> 127.0.0.1
--> ::1
--> 192.168.1.20 (ordinateur windows en IPv4).
--> 2a02:8435:342:3001::200 (ordinateur windows en IPv6).
--> www.google.fr (en IPv4).
--> www.google.fr (en IPv6).

14-b) renew sur le dhcpcd.

Code : Tout sélectionner

dhcpcd -k wlan0; dhcpcd -d wlan0
14-c) VNC Viewer (depuis windows 10).

14-d) navigateur chromium (depuis le bureau de la raspberry).

14-e) les accès en SSH.

14-f) les accès aux noms DNS que j'ai mis dans ma box.

14-g) Je n'ai pas encore testé les scans des ports.

15) Voici le script du service "firewall" :

Code : Tout sélectionner

#!/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:       Firewall for raspberry pi
### END INIT INFO

# ============== #
# Initialisation #
# ============== #

PATH=/usr/sbin:/usr/bin:/sbin:/bin

IPTv4='/sbin/iptables '
IPTv6='/sbin/ip6tables '

. /lib/lsb/init-functions

test -x $IPTv4 || exit 0
test -x $IPTv6 || exit 0

# ============================== #
# Nettoyage de toutes les règles #
# ============================== #

do_clear()
{
	# ---------------------------------------- #
	# Suppression des règles existantes (IPv4) #
	# ---------------------------------------- #

	$IPTv4 -F
	$IPTv4 -X

	$IPTv4 -t nat -F
	$IPTv4 -t nat -X

	# ---------------------------------------- #
	# Suppression des règles existantes (IPv6) #
	# ---------------------------------------- #

	$IPTv6 -F
	$IPTv6 -X

	$IPTv6 -t nat -F
	$IPTv6 -t nat -X
}

# ============================================ #
# Les Règles de la table 'FILTER' au Démarrage #
# ============================================ #

do_filter_start()
{
	# ---------------------------- #
	# Les Règles par défaut (IPv4) #
	# ---------------------------- #

	$IPTv4 -P  INPUT   DROP
	$IPTv4 -P OUTPUT   DROP
	$IPTv4 -P FORWARD  DROP

	# ---------------------------- #
	# Les Règles par défaut (IPv6) #
	# ---------------------------- #

	$IPTv6 -P  INPUT   DROP
	$IPTv6 -P OUTPUT   DROP
	$IPTv6 -P FORWARD  DROP

	# ---- #
	# Scan #
	# ---- #

#	$IPTv4 -A  INPUT -p tcp --tcp-flags ALL      ALL             -j DROP
#	$IPTv4 -A  INPUT -p tcp --tcp-flags ALL      NONE            -j DROP
#	$IPTv4 -A  INPUT -p tcp --tcp-flags ALL      URG,PSH,SYN,FIN -j DROP
#	$IPTv4 -A  INPUT -p tcp --tcp-flags ALL      FIN,URG,PSH     -j DROP
#	$IPTv4 -A  INPUT -p tcp --tcp-flags ALL      SYN,FIN         -j DROP
#	$IPTv4 -A  INPUT -p tcp --tcp-flags ALL      FIN             -j DROP
#	$IPTv4 -A  INPUT -p tcp --tcp-flags SYN,RST  SYN,RST         -j DROP

	# -------- #
	# Spoofing #
	# -------- #

	$IPTv4 -A  INPUT -d 224.0.0.0/3 -j DROP
	$IPTv4 -A OUTPUT -d 224.0.0.0/3 -j DROP

	# ---------------------------- #
	# Les connexions déjà établies #
	# ---------------------------- #

	$IPTv4 -A  INPUT  -m state --state ESTABLISHED -j ACCEPT
	$IPTv4 -A OUTPUT  -m state --state ESTABLISHED -j ACCEPT
	$IPTv4 -A FORWARD -m state --state ESTABLISHED -j ACCEPT

	# ------------- #
	# Protocole DNS #
	# ------------- #

	$IPTv4 -A OUTPUT -p udp -m udp --dport 53 -m conntrack --ctstate NEW,RELATED,ESTABLISHED -j ACCEPT
	$IPTv4 -A  INPUT -p udp -m udp --sport 53 -m conntrack --ctstate     RELATED,ESTABLISHED -j ACCEPT

	$IPTv6 -A OUTPUT -p udp        --sport 5353 --dport 5353                                 -j ACCEPT
	$IPTv6 -A  INPUT -p udp        --sport 5353 --dport 5353                                 -j ACCEPT

	# -------------- #
	# Protocole DHCP #
	# -------------- #

	$IPTv4 -A OUTPUT -p udp -m udp --sport 68  --dport 67  -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT 

	$IPTv6 -A OUTPUT -p udp -m udp --sport 546 --dport 547                                        -j ACCEPT
	$IPTv6 -A  INPUT -p udp -m udp --sport 547 --dport 546                                        -j ACCEPT

	# -------- #
	# Loopback #
	# -------- #

	$IPTv4 -A  INPUT -i lo          -j ACCEPT
	$IPTv4 -A OUTPUT -o lo          -j ACCEPT

	$IPTv6 -A  INPUT -i lo          -j ACCEPT
	$IPTv6 -A OUTPUT -o lo          -j ACCEPT

	$IPTv4 -A  INPUT -d 127.0.0.0/8 -j REJECT
	$IPTv4 -A OUTPUT -s 127.0.0.0/8 -j REJECT

	# ------------- #
	# Protocole SSH #
	# ------------- #

	$IPTv4 -N SSH_DROP
	$IPTv4 -A SSH_DROP -m limit --limit 1/second -j LOG --log-prefix 'SSH: '
	$IPTv4 -A SSH_DROP                           -j DROP

	$IPTv4 -A  INPUT   -p tcp   --dport 22 -m recent --update --seconds 60 --hitcount 3 --name SSH -j SSH_DROP
	$IPTv4 -A  INPUT   -p tcp   --dport 22 -m recent --set                              --name SSH
	$IPTv4 -A  INPUT   -p tcp   --dport 22 -m state  --state NEW                         -j ACCEPT

	$IPTv4 -A OUTPUT   -p tcp   --sport 22                                               -j ACCEPT

	# ------------------------------------- #
	# Protocole ICMPv6 (Messages d'erreurs) #
	# ------------------------------------- #

	$IPTv6 -A OUTPUT  -p icmpv6 --icmpv6-type destination-unreachable                   -j ACCEPT
	$IPTv6 -A  INPUT  -p icmpv6 --icmpv6-type destination-unreachable                   -j ACCEPT

	$IPTv6 -A OUTPUT  -p icmpv6 --icmpv6-type packet-too-big                            -j ACCEPT
	$IPTv6 -A  INPUT  -p icmpv6 --icmpv6-type packet-too-big                            -j ACCEPT

	$IPTv6 -A OUTPUT  -p icmpv6 --icmpv6-type time-exceeded                             -j ACCEPT
	$IPTv6 -A  INPUT  -p icmpv6 --icmpv6-type time-exceeded                             -j ACCEPT

	$IPTv6 -A OUTPUT  -p icmpv6 --icmpv6-type parameter-problem                         -j ACCEPT
	$IPTv6 -A  INPUT  -p icmpv6 --icmpv6-type parameter-problem                         -j ACCEPT

	# ----------------------- #
	# Protocole ICMPv4 (Ping) #
	# ----------------------- #

	$IPTv4 -A OUTPUT  -p icmp    --icmp-type   echo-request   -m limit --limit 1/second -j ACCEPT
	$IPTv4 -A  INPUT  -p icmp    --icmp-type   echo-reply     -m limit --limit 1/second -j ACCEPT

	$IPTv4 -A  INPUT  -p icmp    --icmp-type   echo-request   -m limit --limit 1/second -j ACCEPT
	$IPTv4 -A OUTPUT  -p icmp    --icmp-type   echo-reply     -m limit --limit 1/second -j ACCEPT

	# ----------------------- #
	# Protocole ICMPv6 (Ping) #
	# ----------------------- #

	$IPTv6 -A OUTPUT  -p icmpv6  --icmpv6-type echo-request   -m limit --limit 1/second -j ACCEPT
	$IPTv6 -A  INPUT  -p icmpv6  --icmpv6-type echo-reply     -m limit --limit 1/second -j ACCEPT

	$IPTv6 -A  INPUT  -p icmpv6  --icmpv6-type echo-request   -m limit --limit 1/second -j ACCEPT
	$IPTv6 -A OUTPUT  -p icmpv6  --icmpv6-type echo-reply     -m limit --limit 1/second -j ACCEPT

	# ---------------- #
	# Protocole ICMPv6 #
	# ---------------- #

	$IPTv6 -A OUTPUT  -p icmpv6 --icmpv6-type router-solicitation     -m hl --hl-eq 255 -j ACCEPT
	$IPTv6 -A  INPUT  -p icmpv6 --icmpv6-type router-solicitation                       -j DROP

	$IPTv6 -A OUTPUT  -p icmpv6 --icmpv6-type router-advertisement                      -j DROP
	$IPTv6 -A  INPUT  -p icmpv6 --icmpv6-type router-advertisement    -m hl --hl-eq 255 -j ACCEPT

	$IPTv6 -A OUTPUT  -p icmpv6 --icmpv6-type neighbor-solicitation   -m hl --hl-eq 255 -j ACCEPT
	$IPTv6 -A  INPUT  -p icmpv6 --icmpv6-type neighbor-solicitation   -m hl --hl-eq 255 -j ACCEPT

	$IPTv6 -A OUTPUT  -p icmpv6 --icmpv6-type neighbor-advertisement  -m hl --hl-eq 255 -j ACCEPT
	$IPTv6 -A  INPUT  -p icmpv6 --icmpv6-type neighbor-advertisement  -m hl --hl-eq 255 -j ACCEPT

	$IPTv6 -A OUTPUT  -p icmpv6 --icmpv6-type redirect                                  -j DROP
	$IPTv6 -A  INPUT  -p icmpv6 --icmpv6-type redirect                -m hl --hl-eq 255 -j ACCEPT

	$IPTv6 -A OUTPUT  -p icmpv6 --icmpv6-type 143                                       -j ACCEPT
	$IPTv6 -A  INPUT  -p icmpv6 --icmpv6-type 143                                       -j ACCEPT

	# ------------------------- #
	# Protocole ICMPv6 (Autres) #
	# ------------------------- #

	$IPTv6 -A OUTPUT  -p icmpv6 -j LOG --log-prefix 'ERR: ' 
	$IPTv6 -A  INPUT  -p icmpv6 -j LOG --log-prefix 'ERR: ' 
	$IPTv6 -A FORWARD -p icmpv6 -j LOG --log-prefix 'ERR: ' 

	$IPTv6 -A OUTPUT  -p icmpv6  -j DROP
	$IPTv6 -A  INPUT  -p icmpv6  -j DROP
	$IPTv6 -A FORWARD -p icmpv6  -j DROP

	# ------------------------------- #
	# Protocole HTTP / HTTPS (Client) #
	# ------------------------------- #

	$IPTv4 -A OUTPUT -p tcp -m multiport --dport 80,443,8080 -j ACCEPT
	$IPTv4 -A  INPUT -p tcp -m multiport --sport 80,443,8080 -j ACCEPT

	$IPTv6 -A OUTPUT -p tcp -m multiport --dport 80,443,8080 -j ACCEPT
	$IPTv6 -A  INPUT -p tcp -m multiport --sport 80,443,8080 -j ACCEPT

	# ---------------------- #
	# Network Time Protocole #
	# ---------------------- #

	$IPTv4 -A OUTPUT -p udp --dport 123 -j ACCEPT
	$IPTv4 -A  INPUT -p udp --sport 123 -j ACCEPT

	$IPTv6 -A OUTPUT -p udp --dport 123 -j ACCEPT
	$IPTv6 -A  INPUT -p udp --sport 123 -j ACCEPT

	# --------------------------------- #
	# Virtual Network Connection Viewer #
	# --------------------------------- #

	$IPTv4 -A  INPUT -p tcp --dport 5901:5902 -j ACCEPT
	$IPTv4 -A OUTPUT -p tcp --sport 5901:5902 -j ACCEPT

	$IPTv6 -A  INPUT -p tcp --dport 5901:5902 -j ACCEPT
	$IPTv6 -A OUTPUT -p tcp --sport 5901:5902 -j ACCEPT

	# -------------- #
	# Samba (Server) #
	# -------------- #

	$IPTv4 -A OUTPUT -p udp              --sport 137:138 --dport 137:138 -j ACCEPT
	$IPTv4 -A  INPUT -p udp              --sport 137:138 --dport 137:138 -j ACCEPT

	$IPTv4 -A OUTPUT -p tcp -m multiport --sport 139,445 -j ACCEPT
	$IPTv4 -A  INPUT -p tcp -m multiport --dport 139,445 -j ACCEPT

	# ------------------------------- #
	# Attaque de type Déni de Service #
	# ------------------------------- #
 
#	$IPTv4 -A FORWARD -p tcp  --syn  -m limit --limit 1/second -j ACCEPT
#	$IPTv4 -A FORWARD -p udp         -m limit --limit 1/second -j ACCEPT

	# ------------------ #
	# Les scans de ports #
	# ------------------ #

#	$IPTv4 -A FORWARD -p tcp --tcp-flags SYN,ACK,FIN,RST  RST -m limit --limit 1/second -j ACCEPT

	# ------------- #
	# Autres (IPv4) #
	# ------------- #

	$IPTv4 -A  INPUT  -j LOG --log-prefix 'IN4: '
	$IPTv4 -A OUTPUT  -j LOG --log-prefix 'OUT4: '
	$IPTv4 -A FORWARD -j LOG --log-prefix 'FOR4: '

	$IPTv4 -A  INPUT  -j REJECT
	$IPTv4 -A OUTPUT  -j REJECT
	$IPTv4 -A FORWARD -j REJECT

	# ------------- #
	# Autres (IPv6) #
	# ------------- #

	$IPTv6 -A  INPUT  -j LOG --log-prefix 'IN6: '
	$IPTv6 -A OUTPUT  -j LOG --log-prefix 'OUT6: '
	$IPTv6 -A FORWARD -j LOG --log-prefix 'FOR6: '

	$IPTv6 -A OUTPUT  -j REJECT
	$IPTv6 -A  INPUT  -j REJECT
	$IPTv6 -A FORWARD -j REJECT
}

# ========================================= #
# Les Règles de la table 'NAT' au démarrage #
# ========================================= #

do_nat_start()
{
	# --------------------------- #
	# Network Address Translation #
	# --------------------------- #

	$IPTv4 -t nat -A POSTROUTING -o eth0 -j MASQUERADE

	$IPTv6 -t nat -A POSTROUTING -o eth0 -j MASQUERADE
}

# ========================================= #
# Les Règles de la table 'FILTER' à l'arrêt #
# ========================================= #

do_filter_stop()
{
	# ---------------------------- #
	# Les Règles par défaut (IPv4) #
	# ---------------------------- #

	$IPTv4 -P  INPUT   ACCEPT
	$IPTv4 -P OUTPUT   ACCEPT
	$IPTv4 -P FORWARD  ACCEPT

	# ---------------------------- #
	# Les Règles par défaut (IPv6) #
	# ---------------------------- #

	$IPTv6 -P  INPUT   ACCEPT
	$IPTv6 -P OUTPUT   ACCEPT
	$IPTv6 -P FORWARD  ACCEPT
}

# ====================================== #
# Les Règles de la table 'NAT' à l'arrêt #
# ====================================== #

#do_nat_stop()
#{
#}

# ============================== #
# les fonctionnalités du service #
# ============================== #

case "$1" in
	start|restart)
	do_clear
	do_filter_start
	do_nat_start
	;;

	stop)
	do_clear
	do_filter_stop
#	do_nat_stop
	;;

	test)
	$0 start

	sleep 120

	$0 stop
	;;

	*)
	log_failure_msg "Usage: /etc/init.d/firewall {start|stop|restart|test}" || true
	exit 1
esac
Conclusion :
Concernant le script, si vous avez des remarques à me faire, je suis preneur.
Je ne suis pas un expert des iptables sous linux (raspbian). J'ai fait quelques recherches sur google et fait beaucoup de tests.
Les parties encore en commentaires n'ont pas été testés.

Si j'ai oublié quelque chose, je compléterais ce message.

@+
RPI4B/8GB + Argon FanHAt
Rpi3A+, Rpi3B+
RPi 2B + Joy-It I2C Serial 20x4 2004 LCD Module
RPi 2B + PIM273 Unicorn HAT HD 16x16 Leds RGB
RPi0v1.3, RPi0W + LibreElec/Kodi, Rpi0WH + Tuner TV HAT
NodeMCU ESP32

dyox
Raspinaute
Messages : 969
Enregistré le : dim. 28 déc. 2014 15:28
Localisation : Le long de la côte, au dessus du pays des bigoudennes, aïe

Re: [Tuto]Création d'un service FIREWALL !

Message par dyox » lun. 20 août 2018 10:28

Bonjour Artemus24,

Merci pour votre tuto. Cela a dû vous prendre énormément de temps et d'essais. J'avais commencé à faire pareil et plus je cherchais plus je me mélangeais les pinceaux. On trouve de tout et son contraire, 36 sortes pour sauvegarder / restaurer les règles...

J'ai plusieurs questions / avis :

Peut-être faut-il compartimenter les différentes règles dans un autre post pour une meilleure visibilité et si on veut comparer rapidement ?
Comme ça, chacun peut piocher rapidement les règles qui lui conviennent et surtout se différencier de ce que l'on trouve ailleurs.

Je rajouterais personnellement une variable pour le port ssh (si on veut le changer) et une autre pour l'ip management.

Je séparerais les règles http pour client / serveur, la plupart ne se servira pas du serveur.

HTTP client

Code : Tout sélectionner

$IPTv4 -A OUTPUT -p tcp -m multiport --dport 80,443,8080 -j ACCEPT
$IPTv6 -A OUTPUT -p tcp -m multiport --dport 80,443,8080 -j ACCEPT
HTTP serveur

Code : Tout sélectionner

$IPTv4 -A  INPUT -p tcp -m multiport --sport 80,443,8080 -j ACCEPT
$IPTv6 -A  INPUT -p tcp -m multiport --sport 80,443,8080 -j ACCEPT
La ligne "PATH=/usr/sbin:/usr/bin:/sbin:/bin" est-elle bien utile ?

Que veulent dire ces lignes ?
. /lib/lsb/init-functions

test -x $IPTv4 || exit 0
test -x $IPTv6 || exit 0

Artemus24
Raspinaute
Messages : 1077
Enregistré le : ven. 15 sept. 2017 19:15

Re: [Tuto]Création d'un service FIREWALL !

Message par Artemus24 » lun. 20 août 2018 12:27

Salut dyox.
Dyox a écrit :Merci pour votre tuto.
Pas de quoi ! :D
Dyox a écrit :Cela a dû vous prendre énormément de temps et d'essais.
Beaucoup de recherches car je ne connaissais pas la commande IPTABLES.
Des essais aussi, car les règles n'ont pas fonctionné du premier coup.
Pour l'instant, ça à l'air de fonctionner, mais je devrais certainement revenir sur certaines règles afin de les perfectionner.
Dyox a écrit :J'avais commencé à faire pareil et plus je cherchais plus je me mélangeais les pinceaux.
C'est pas évident de comprendre comment fonctionner iptables. J'avais un peu d'expérience puisque j'ai configuré le pare-feu de windows.
Dyox a écrit :On trouve de tout et son contraire, 36 sortes pour sauvegarder / restaurer les règles...
Il est fréquent de voir des règles qui ne fonctionnent pas car tout le monde se copie sans vraiment tester au préalable.
Dyox a écrit :Peut-être faut-il compartimenter les différentes règles dans un autre post pour une meilleure visibilité et si on veut comparer rapidement ?
Vous voulez dire que je devrais faire une liste de toutes les règles les plus couramment utilisées ?
Pourquoi pas, mais le script du service firewall est déjà compartimenté. Cela serait peut-être plus lisible.
Dyox a écrit :Comme ça, chacun peut piocher rapidement les règles qui lui conviennent et surtout se différencier de ce que l'on trouve ailleurs.
Ce n'est pas aussi simple que cela car ça dépend du réseau local que vous utilisez.
Dans mon cas, je possède déjà une box/routeur où j'ai verrouillé la plupart des problèmes que l'on rencontre.
Il est donc inutile que je les précise, à nouveau, dans le pare-feu de la raspberry.

Par exemple, depuis internet, je ne peux pas lancer une commande SSH pour prendre le contrôle de ma raspberry.
Le port 22, dans la section NAT de ma box/routeur n'est pas redirigé, et de ce fait, le port 22 est bloqué en entrée.

Mais il y a encore pire, pour m'identifier, je n'utilise pas le mot de passe, mais une clef SSH public qui est présent sur mon ordinateur Windows et présent aussi dans la raspberry.

Comment j'ai écrit ma règle SSH en tenant compte des deux points ci-dessus ?

1) je ne traite que les adresses IPv4 (iptables) et non les adresses IPv6 (ip6tables) qui, elles, seront rejetés.

2) pour l'IPv4, je pars de l'hypothèse que l'origine de la connexion se fait dans mon réseau local.
C'est pourquoi, je n'ai pas précisé par un "-s 192.168.1.33" l'adresse IPv4 de mon ordinateur windows.

3) je considère que si quelqu'un pouvait pénétrer ma raspberry (ce qui est impossible), qu'il aurait droit à trois accès par minute.
Au quatrième accès, il sera rejeté (SSH_DROP) et je conserve une trace de sa forfaiture.
Dyox a écrit :Je rajouterais personnellement une variable pour le port ssh (si on veut le changer) et une autre pour l'ip management.
Chacun peut modifier le script à sa convenance.
Je ne vois pas trop l'intérêt de modifier le port 22 (SSH), histoire de le masquer.
Comme je l'ai dit ci-dessus, j'utilise une clef SSH public, ce qui rend le piratage impossible.
Dyox a écrit :Je séparerais les règles http pour client / serveur, la plupart ne se servira pas du serveur.
Vous n'avez pas bien compris ce que je nomme client et serveur.

Prenons le cas du ping pour comprendre comment cela fonctionne.
Deux cas peuvent se présenter quand un utilisateur désire faire un ping.
"client" signifie qu'en premier, une requête d'interrogation sera envoyé.
"serveur" signifie qu'en premier, une requête d'interrogation sera reçue.

Pour bien préciser le rôle joué par la requête d'interrogation vis-a-vis de la raspberry, elle est sortante pour le "client", et entrante pour le "serveur".

Comment cela va se traduire dans les faits ?

Pour le "client", dans le cas du "ping", cela se traduit par :

Code : Tout sélectionner

$IPTv4 -A OUTPUT  -p icmp    --icmp-type   echo-request   -m limit --limit 1/second -j ACCEPT
$IPTv4 -A  INPUT  -p icmp    --icmp-type   echo-reply     -m limit --limit 1/second -j ACCEPT
Comme on peut le constater, la requête d'interrogation (echo request) est en premier, donc sortante.

Pour le "serveur", c'est exactement l'inverse.

Code : Tout sélectionner

$IPTv4 -A  INPUT  -p icmp    --icmp-type   echo-request   -m limit --limit 1/second -j ACCEPT
$IPTv4 -A OUTPUT  -p icmp    --icmp-type   echo-reply     -m limit --limit 1/second -j ACCEPT
Ici, la requête d'interrogation (echo request), toujours en premier, est entrante.

Comment distinguer, dans le cas du ping, le sens des requêtes ?
Celui qui interroge fait un "echo request" en premier. Celui qui donne la réponse se fait par un "echo reply" en second.

J'espère avoir été clair sur le sens de ce que l'on nomme "client" et "serveur".
Dyox a écrit :La ligne "PATH=/usr/sbin:/usr/bin:/sbin:/bin" est-elle bien utile ?
J'ai répété cette ligne car je me suis inspiré d'un modèle.
Dyox a écrit :Que veulent dire ces lignes ?

Code : Tout sélectionner

. /lib/lsb/init-functions
C'est pour le status dans la commande "firewall status", qui sans cela ne fonctionne pas.

Code : Tout sélectionner

test -x $IPTv4 || exit 0
test -x $IPTv6 || exit 0
C'est pour tester l'existante des commandes "iptables" (IPv4) et "ip6tables" (IPv6).
Pas très utile. Comme je l'ai dit, j'ai repris un existant.

@+
RPI4B/8GB + Argon FanHAt
Rpi3A+, Rpi3B+
RPi 2B + Joy-It I2C Serial 20x4 2004 LCD Module
RPi 2B + PIM273 Unicorn HAT HD 16x16 Leds RGB
RPi0v1.3, RPi0W + LibreElec/Kodi, Rpi0WH + Tuner TV HAT
NodeMCU ESP32

dyox
Raspinaute
Messages : 969
Enregistré le : dim. 28 déc. 2014 15:28
Localisation : Le long de la côte, au dessus du pays des bigoudennes, aïe

Re: [Tuto]Création d'un service FIREWALL !

Message par dyox » mar. 4 sept. 2018 13:18

Bonjour Artemus24,

J'ai plusieurs questions. Je vois que dans votre script vous utilisez les 2 écritures :
-m state --state
-m conntrack --ctstate
Pour moi elle font la même chose et je pense que "state" est antérieure mais je ne trouve aucunes autres infos dessus.
En savez-vous plus ?
[EDIT] conntrack est une version améliorée de state : https://www.inetdoc.net/guides/iptables ... trackmatch

J'ai vu sur d'anciens scripts qu'ils pouvaient être lancés via "interfaces" au démarrage et je viens de voir que dhcpcd le peut aussi.
Avez-vous essayé ?
https://wiki.archlinux.org/index.php/Dhcpcd

Artemus24
Raspinaute
Messages : 1077
Enregistré le : ven. 15 sept. 2017 19:15

Re: [Tuto]Création d'un service FIREWALL !

Message par Artemus24 » mer. 5 sept. 2018 21:41

Salut Dyox.

Conntrack sert à connaitre l'état dans lequel se trouve une connexion.
Dyox a écrit :Je vois que dans votre script vous utilisez les 2 écritures :
Je me suis grandement inspiré de ce que j'ai pu trouvé sur internet.
Comme il n'existe pas qu'une seule écriture dans iptable pour obtenir le résultat escompté, il y a certainement plus simple.
Dyox a écrit :Pour moi elle font la même chose et je pense que "state" est antérieure mais je ne trouve aucunes autres infos dessus.
Je ne sais pas répondre à votre question.
Mon but était de bloquer les flux indésirables et non d'avoir une connaissance pussée sur la mécanique du pare-feu.
J'ai procédé par tatonnement pour trouver la bonne façon de faire.

Que cherchez-vous à faire ?

@+
RPI4B/8GB + Argon FanHAt
Rpi3A+, Rpi3B+
RPi 2B + Joy-It I2C Serial 20x4 2004 LCD Module
RPi 2B + PIM273 Unicorn HAT HD 16x16 Leds RGB
RPi0v1.3, RPi0W + LibreElec/Kodi, Rpi0WH + Tuner TV HAT
NodeMCU ESP32

dyox
Raspinaute
Messages : 969
Enregistré le : dim. 28 déc. 2014 15:28
Localisation : Le long de la côte, au dessus du pays des bigoudennes, aïe

Re: [Tuto]Création d'un service FIREWALL !

Message par dyox » mer. 5 sept. 2018 23:21

Je m'étais auto-répondu. Conntrack est une amélioration de state et possède des options supplémentaires.

Pour info, j'ai lu que RELATED possèdait une faille. Je ne sais pas si elle a été corrigée depuis et est surtout utile pour du FTP.

Si j'ai bien compris le fonctionnement de iptables et du réseau, on initie une connection en NEW (qui devient ESTABLISHED plus tard) et on attend la réponse en ESTABLISHED. Une sorte de ping-pong en quelque sorte.
Hors dans votre script vous avez noté au début:
# Les connexions déjà établies #
# ---------------------------- #

$IPTv4 -A INPUT -m state --state ESTABLISHED -j ACCEPT
$IPTv4 -A OUTPUT -m state --state ESTABLISHED -j ACCEPT
$IPTv4 -A FORWARD -m state --state ESTABLISHED -j ACCEPT
Donc pour moi les lignes suivantes qui correspondent à un "pong" est inutile puisque la porte est déjà ouverte, du genre :
$IPTv4 -A INPUT -p udp -m udp --sport 53 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
Je cherche à apprendre et à comprendre, comme vous :mrgreen: :ugeek:

Artemus24
Raspinaute
Messages : 1077
Enregistré le : ven. 15 sept. 2017 19:15

Re: [Tuto]Création d'un service FIREWALL !

Message par Artemus24 » ven. 7 sept. 2018 19:12

Salut Dyox.
Dyox a écrit :Je m'étais auto-répondu. Conntrack est une amélioration de state et possède des options supplémentaires.
Le conntrack sert à filtrer d'une manière plus fine les flux entrants et sortants.
Si vous désirez rester le plus simple possible, vous pouvez ne pas l'utiliser.

D'ailleurs, dans mon firewall, je n'ai traité que les flux en "input" et en "output".
A vrai dire, je n'ai pas bien compris à quoi servent les autres flux (forward, prerouting, postrouting), hormis le routage du flux de wlan0 vers eth0, comme dans le cas du point d'accès wifi.

Oui, je reconnais que j'ai quelques lacunes en la matière, mais quand un problème se pose, je vais m'investir afin de le résoudre.
Dyox a écrit :Pour info, j'ai lu que RELATED possèdait une faille.
Je l'ai lu aussi. Il suffit de ne pas faire référence à RELATED dans l'usage du conntrack.
Dyox a écrit :Je ne sais pas si elle a été corrigée depuis et est surtout utile pour du FTP.
A bien comprendre ce que cela représente, je pense qu'un nouveau flux peut être associé à un flux déjà existant.
Genre un flux est dormant et on le réveil. Pour l'instant, je n'ai pas eu besoin de faire usage de ce paramètre.
Dyox a écrit :Si j'ai bien compris le fonctionnement de iptables et du réseau, on initie une connection en NEW (qui devient ESTABLISHED plus tard) et on attend la réponse en ESTABLISHED.
Le démarrage d'un nouveau flux se fait en NEW. Attente de la réponse de la connexion.
Et quand la connexion est établie, elle passe en ESTABLISHED.
Dyox a écrit :Une sorte de ping-pong en quelque sorte.
Pas exactement, je dirais plutôt un dialogue, du genre le premier dit bonjour, et le second vous répond.
Dyox a écrit :Hors dans votre script vous avez noté au début:
Après quelques améliorations, j'ai constaté, dans mon cas, que cet ajout n sert à rien.
En le mettant en commentaire, mais en ayant d'autres déclaratives comme celles concernant le DNS, je n'ai pas de messages d'anomalies.
Dyox a écrit :Donc pour moi les lignes suivantes qui correspondent à un "pong" est inutile puisque la porte est déjà ouverte, du genre :
Ce n'est pas un pong, mais plutôt une garantie au cas où l'on aurait oublié de déclarer quelque chose d'important.

Code : Tout sélectionner

$IPTv4 -A OUTPUT -p udp -m udp --dport 53 -m conntrack --ctstate NEW,RELATED,ESTABLISHED -j ACCEPT
$IPTv4 -A  INPUT -p udp -m udp --sport 53 -m conntrack --ctstate     RELATED,ESTABLISHED -j ACCEPT
Si vous trouvez cette écriture un peu compliqué, on peut la simplifier.
Le port 53 concerne le serveur DNS de votre box. Comme l'adresse est fréquemment 192.168.1.1, on peut mettre :

Code : Tout sélectionner

$IPTv4 -A OUTPUT -p udp --dport 53 -d 192.168.1.1  -j ACCEPT
$IPTv4 -A INPUT  -p udp --sport 53 -s 192.168.1.1  -j ACCEPT
Je fais cela de tête. Avec les messages d'anomalies, on peut verifier le sens (source ou destination) de l'adresse IP de la box.

En fait, je construis les règles en fonction des anomalies que j'obtiens.
Au départ, je bloque tout, et en fonction de ce que je désire libérer, je crée la ou les règles. Et ainsi de suite.

Si cela ne vous dérange pas trop, on peut continuer à discuter de l'iptables par email (artemus @ jcz.fr).

@+
RPI4B/8GB + Argon FanHAt
Rpi3A+, Rpi3B+
RPi 2B + Joy-It I2C Serial 20x4 2004 LCD Module
RPi 2B + PIM273 Unicorn HAT HD 16x16 Leds RGB
RPi0v1.3, RPi0W + LibreElec/Kodi, Rpi0WH + Tuner TV HAT
NodeMCU ESP32

dyox
Raspinaute
Messages : 969
Enregistré le : dim. 28 déc. 2014 15:28
Localisation : Le long de la côte, au dessus du pays des bigoudennes, aïe

Re: [Tuto]Création d'un service FIREWALL !

Message par dyox » mer. 12 sept. 2018 13:59

Si cela ne vous dérange pas trop, on peut continuer à discuter de l'iptables par email
Pas de problèmes et il y a aussi les messages privés sur le forum ;)

Artemus24
Raspinaute
Messages : 1077
Enregistré le : ven. 15 sept. 2017 19:15

Re: [Tuto]Création d'un service FIREWALL !

Message par Artemus24 » jeu. 13 sept. 2018 06:23

Salut Dyox.

Par email, cela me convient parfaitement.
Si vous désirez que je teste quelque chose, dans le cadre du firewall, je peux le faire !

@+
RPI4B/8GB + Argon FanHAt
Rpi3A+, Rpi3B+
RPi 2B + Joy-It I2C Serial 20x4 2004 LCD Module
RPi 2B + PIM273 Unicorn HAT HD 16x16 Leds RGB
RPi0v1.3, RPi0W + LibreElec/Kodi, Rpi0WH + Tuner TV HAT
NodeMCU ESP32

dyox
Raspinaute
Messages : 969
Enregistré le : dim. 28 déc. 2014 15:28
Localisation : Le long de la côte, au dessus du pays des bigoudennes, aïe

Re: [Tuto]Création d'un service FIREWALL !

Message par dyox » mar. 22 déc. 2020 11:04

Bonjour Artemus24,

Si tu es courageux, il faudrait faire maintenant la même chose avec nftables, le successeur d'iptables :ugeek: :mrgreen:

Répondre

Retourner vers « Tutoriels »