Celà fait des siècles que je n'arrête pas de traverser le web dans tous les sens afin de trouver tel ou tel information sur tel ou tel problème et je doit dire qu'aujourd'hui c'est grâce à toi, posteur fou, habitué des forums, spécialiste du tutorial, webmaster hacker ou tout simplement blogueur à temps partiel que je suis devenu en (grande ?) partie le mec qu'on appelle au moindre problème informatique dans mon entourage (voire sur l'irc).
Ajourd'hui, je me rends compte que le temps est venu de vraiment apporter une aide "écrite" et stockable pour toi qui sera peut-être en galère demain.
Après cette longue introduction, passons aux choses sérieuses à savoir l'écriture d'une configuration de firewall (iptables).
Le but de ce script est avant tout éducatif et c'est pour celà que j'ai retenu les critères suivant avant de l'écrire :
- -> report en en-tête d'une partie du manpage iptable
-> utilisation d'un mode de debug/logging des règles
-> utilisation des options en mode "complet" (c'est-à-dire --append et non pas -a) pour une meilleur lisibilité
Code: Select all
#!/bin/sh
################################################################################
# QUELQUES EXPLICATIONS
#
# La commande iptables en quelques lignes :
# * iptables [-t table] -[AD] chaîne règle [options]
# * iptables [-t table] -I chaîne [numéro-de-règle] règle [options]
# * iptables [-t table] -R chaîne numéro-de-règle règle [options]
# * iptables [-t table] -D chaîne numéro-de-règle [options]
# * iptables [-t table] -[LFZ] [chaîne] [options]
# * iptables [-t table] -N chaîne
# * iptables [-t table] -X [chaîne]
# * iptables [-t table] -P chaîne cible [options]
# * iptables [-t table] -E ancien-nom-de-chaîne nouveau-nom-de-chaîne
#
# Les tables :
# [filter] ==> c'est la table par défaut.
# ---> INPUT : pour modifier les paquets entrants dans la machine
# ---> FORWARD : pour modifier les paquets routés à travers la machine
# ---> OUTPUT : pour modifier les paquets générés localement
#
# [nat] ==> Cette table est consultée lorsqu'on rencontre un paquet qui crée
# une nouvelle connexion.
# ---> PREROUTING : pour modifier les paquets dès qu'ils rentrent
# ---> OUTPUT : pour modifier les paquets générés localement (avant routage)
# ---> POSTROUTING : pour modifier les paquets sur le point de sortir
#
# [mangle] ==> Cette table est employée pour effectuer une modification
# spéciale des paquets.
# ---> INPUT : pour modifier les paquets entrants destinés à la machine
# ---> PREROUTING : pour modifier les paquets entrants (avant routage)
# ---> FORWARD : pour modifier les paquets routés à travers la machine
# ---> OUTPUT : pour modifier les paquets générés localement (avant routage)
# ---> POSTROUTING : pour modifier les paquets sur le point de sortir
#
################################################################################
################################################################################
# DEBUGGING
################################################################################
DEBUG="true"
if [ $DEBUG = "true" ]; then
DEBUG_LOOPBACK="true"
DEBUG_LAN1="true"
DEBUG_LAN2="true"
else
DEBUG_MASQUERADE="false"
DEBUG_LOOPBACK="false"
DEBUG_LAN1="false"
DEBUG_LAN2="false"
fi
################################################################################
# VARIABLES
#
# Il s'agit ici de mettre les paramètres concernant les différents réseaux
# Le but de cette configuration est de configurer le firewall du { ROUTEUR BOX }.
# Il s'agit d'un machine faisant partie de plusieurs réseaux différent, notemment
# un réseau public (internet par exemple) et un ou plusieurs réseaux locaux (lan1,
# et lan2 par exemple)
# La présence des deux réseaux locaux (assez rare en configuration de type "home")
# est présentée seulement pour montrer que la présence d'internet dans la
# configuration ne change rien au principe de configuration du firewall
#
#
#
# OUT_IP
# OUT_INTERFACE
# |
# |
# ________ |
# / \ |
# ( INTERNET ) : : : o { ROUTEUR BOX }
# \ ________ / o o----------- IN1_IP / IN1_INTERFACE
# /¨ ¨
# / ¨ ¨
# / ¨ (lan1) <------------- NETWORK1_IP / NETWORK1_MASK / NETWORK1_BITMASK
# / ¨ ¨
# IN2_IP / IN2_INTERFACE ¨ ¨ +------- M1_1_IP / M1_1_INTERFACE
# ¨ ¨ |
# ¨ ¨ |
# ¨ ¨: : : : : o { MACHINE 1_1 }
# ¨ ¨
# ¨ ¨
# ¨ ¨: : : : : o { MACHINE 1_2 }
# ¨ |
# ¨ +------- M1_2_IP / M1_2_INTERFACE
# ¨
# ¨
# ¨
# (lan2) <------------- NETWORK2_IP / NETWORK2_MASK / NETWORK2_BITMASK
# ¨
# ¨ +------- M1_1_IP / M1_1_INTERFACE
# ¨ |
# ¨ |
# ¨: : : : : : : o { MACHINE 2_1 }
# ¨
# ¨
# ¨: : : : : : : o { MACHINE 2_1 }
# |
# +------- M1_1_IP / M1_1_INTERFACE
#
################################################################################
# configuration du réseau local (LAN1)
NETWORK1_IP=192.168.1.0 # Adresse "réseau" du réseau local (LAN1)
NETWORK1_NETMASK=255.255.255.0 # Netmask du réseau local (LAN1)
NETWORK1_BITMASK=24 # Bitmask du réseau local (LAN1)
# configuration du réseau local (LAN2)
NETWORK2_IP=192.168.2.0 # Adresse "réseau" du réseau local (LAN2)
NETWORK2_NETMASK=255.255.255.0 # Netmask du réseau local (LAN2)
NETWORK2_BITMASK=24 # Bitmask du réseau local (LAN2)
# configuration du { ROUTEUR BOX }
IN1_IP=192.168.1.1 # Adresse IP du { ROUTEUR BOX } "côté" lan1
IN1_INTERFACE=eth1 # Interface du { ROUTEUR BOX } "côté" lan1
IN2_IP=192.168.2.1 # Adresse IP du { ROUTEUR BOX } "côté" lan2
IN2_INTERFACE=eth2 # Interface du { ROUTEUR BOX } "côté" lan2
OUT_IP=XXX.XXX.XXX.XXX # Adresse IP du { ROUTEUR BOX } "côté" internet
OUT_INTERFACE=eth0 # Interface du { ROUTEUR BOX } "côté" internet
###
# N.B.
# Ici, j'utilise eth0 car je suis connecté directement à internet via ma
# carte réseau. Néanmois dans le cas d'une configuration adsl avec connection
# pppoe, je pense que c'est ppp0 qui est utilisé. A vérifier sur votre
# configuration à l'aide de /sbin/ifconfig
###
################################################################################
# DESACTIVATION DU FORARDING IP
################################################################################
echo 0 > /proc/sys/net/ipv4/ip_forward
################################################################################
# INITIALISATION DES TABLES
#
# Il s'agit de vider puis effacer toutes les chaînes
# des tables filter/nat/mangle
#
# TODO
# Vider de l'espace kernel les modules chargés enpechant parfois la
# réinitialisation des tables...
################################################################################
iptables --table filter --flush
iptables --table filter --delete-chain
iptables --table mangle --flush
iptables --table mangle --delete-chain
iptables --table nat --flush
iptables --table nat --delete-chain
################################################################################
# INITIALISATION DES LOGGERS
#
# Pour créer un logger, on fait les choses suivantes :
# - On commence par créer une nouvelle chaîne pour la table ciblée.
# - On vide la chaîne fraîchement créée.
# - On loggue dans un premier temps le paquet (via --jump LOG)
# - On le traite comme il se doit par la ensuite
#
# C'est ainsi que la chaîne DEBUG_FILTER_DROP (resp. DEBUG_FILTER_ACCEPT) se
# comporte comme la chaîne DROP (resp. ACCEPT) mais avec une phase pré-phase
# de logging.
################################################################################
FILTER_DROP="DROP"
FILTER_ACCEPT="ACCEPT"
NAT_DROP="DROP"
NAT_ACCEPT="ACCEPT"
NAT_MASQUERADE="MASQUERADE"
MANGLE_DROP="DROP"
MANGLE_ACCEPT="ACCEPT"
if [ $DEBUG = "true" ]; then
iptables --table filter --new-chain DEBUG_FILTER_DROP
iptables --table filter --flush DEBUG_FILTER_DROP
iptables --table filter --append DEBUG_FILTER_DROP --jump LOG --log-prefix '[debug] FILTER DROP : '
iptables --table filter --append DEBUG_FILTER_DROP --jump DROP
FILTER_DROP="DEBUG_FILTER_DROP"
iptables --table filter --new-chain DEBUG_FILTER_ACCEPT
iptables --table filter --flush DEBUG_FILTER_ACCEPT
iptables --table filter --append DEBUG_FILTER_ACCEPT --jump LOG --log-prefix '[debug] FILTER ACCEPT : '
iptables --table filter --append DEBUG_FILTER_ACCEPT --jump ACCEPT
FILTER_ACCEPT="DEBUG_FILTER_ACCEPT"
iptables --table nat --new-chain DEBUG_NAT_DROP
iptables --table nat --flush DEBUG_NAT_DROP
iptables --table nat --append DEBUG_NAT_DROP --jump LOG --log-prefix '[debug] NAT DROP : '
iptables --table nat --append DEBUG_NAT_DROP --jump DROP
NAT_DROP="DEBUG_NAT_DROP"
iptables --table nat --new-chain DEBUG_NAT_ACCEPT
iptables --table nat --flush DEBUG_NAT_ACCEPT
iptables --table nat --append DEBUG_NAT_ACCEPT --jump LOG --log-prefix '[debug] NAT ACCEPT : '
iptables --table nat --append DEBUG_NAT_ACCEPT --jump ACCEPT
NAT_MASQUERADE="DEBUG_NAT_MASQUERADE"
iptables --table nat --new-chain DEBUG_NAT_MASQUERADE
iptables --table nat --flush DEBUG_NAT_MASQUERADE
iptables --table nat --append DEBUG_NAT_MASQUERADE --jump LOG --log-prefix '[debug] NAT MASQUERADE : '
iptables --table nat --append DEBUG_NAT_MASQUERADE --jump MASQUERADE
NAT_MASQUERADE="DEBUG_NAT_MASQUERADE"
iptables --table mangle --new-chain DEBUG_MANGLE_DROP
iptables --table mangle --flush DEBUG_MANGLE_DROP
iptables --table mangle --append DEBUG_MANGLE_DROP --jump LOG --log-prefix '[debug] MANGLE DROP : '
iptables --table mangle --append DEBUG_MANGLE_DROP --jump DROP
MANGLE_DROP="DEBUG_MANGLE_DROP"
iptables --table mangle --new-chain DEBUG_MANGLE_ACCEPT
iptables --table mangle --flush DEBUG_MANGLE_ACCEPT
iptables --table mangle --append DEBUG_MANGLE_ACCEPT --jump LOG --log-prefix '[debug] MANGLE ACCEPT : '
iptables --table mangle --append DEBUG_MANGLE_ACCEPT --jump ACCEPT
MANGLE_ACCEPT="DEBUG_MANGLE_ACCEPT"
fi
################################################################################
# POLITIQUE DE SECURITE PAR DEFAUT
#
# --> On rejette tout les paquets par défaut dans la table [filter]
# --> On accepte les autres paquets circulant "en interne" [nat/mangle]
################################################################################
iptables --table filter --policy INPUT DROP
iptables --table filter --policy OUTPUT DROP
iptables --table filter --policy FORWARD DROP
iptables --table nat --policy PREROUTING ACCEPT
iptables --table nat --policy POSTROUTING ACCEPT
iptables --table mangle --policy PREROUTING ACCEPT
iptables --table mangle --policy POSTROUTING ACCEPT
iptables --table mangle --policy OUTPUT ACCEPT
################################################################################
# POLITIQUE DE SECURITE SUR LE LOOPBACK
################################################################################
LOOPBACK_DROP="$FILTER_DROP"
LOOPBACK_ACCEPT="$FILTER_ACCEPT"
if [ $DEBUG_LOOPBACK = "true" ]; then
iptables --table filter --new-chain DEBUG_LOOPBACK_DROP
iptables --table filter --flush DEBUG_LOOPBACK_DROP
iptables --table filter --append DEBUG_LOOPBACK_DROP --jump LOG --log-prefix '[debug] LOOPBACK DROP : '
iptables --table filter --append DEBUG_LOOPBACK_DROP --jump DROP
LOOPBACK_DROP="DEBUG_LOOPBACK_DROP"
iptables --table filter --new-chain DEBUG_LOOPBACK_ACCEPT
iptables --table filter --flush DEBUG_LOOPBACK_ACCEPT
iptables --table filter --append DEBUG_LOOPBACK_ACCEPT --jump LOG --log-prefix '[debug] LOOPBACK ACCEPT : '
iptables --table filter --append DEBUG_LOOPBACK_ACCEPT --jump ACCEPT
LOOPBACK_ACCEPT="DEBUG_LOOPBACK_ACCEPT"
fi
iptables --table filter --append INPUT --in-interface lo $LOOPBACK_ACCEPT
iptables --table filter --append OUTPUT --out-interface lo $LOOPBACK_ACCEPT
iptables --table filter --append FORWARD --in-interface lo $LOOPBACK_ACCEPT
iptables --table filter --append FORWARD --out-interface lo $LOOPBACK_ACCEPT
################################################################################
# POLITIQUE DE SECURITE SUR LE RESEAU LOCAL (LAN1)
################################################################################
LAN1_DROP="$FILTER_DROP"
LAN1_ACCEPT="$FILTER_ACCEPT"
if [ $DEBUG_LAN1 = "true" ]; then
iptables --table filter --new-chain DEBUG_LAN1_DROP
iptables --table filter --flush DEBUG_LAN1_DROP
iptables --table filter --append DEBUG_LAN1_DROP --jump LOG --log-prefix '[debug] LAN1 DROP : '
iptables --table filter --append DEBUG_LAN1_DROP --jump DROP
LAN1_DROP="DEBUG_LAN1_DROP"
iptables --table filter --new-chain DEBUG_LAN1_ACCEPT
iptables --table filter --flush DEBUG_LAN1_ACCEPT
iptables --table filter --append DEBUG_LAN1_ACCEPT --jump LOG --log-prefix '[debug] LAN1 ACCEPT : '
iptables --table filter --append DEBUG_LAN1_ACCEPT --jump ACCEPT
LAN1_ACCEPT="DEBUG_LAN1_ACCEPT"
fi
iptables --table filter --append INPUT --in-interface $IN1_INTERFACE --jump $LAN1_ACCEPT
iptables --table filter --append OUTPUT --out-interface $IN1_INTERFACE --jump $LAN1_ACCEPT
iptables --table filter --append FORWARD --in-interface $IN1_INTERFACE --jump $LAN1_ACCEPT
iptables --table filter --append FORWARD --out-interface $IN1_INTERFACE --jump $LAN1_ACCEPT
################################################################################
# POLITIQUE DE SECURITE SUR LE RESEAU LOCAL (LAN2)
################################################################################
LAN2_DROP="$FILTER_DROP"
LAN2_ACCEPT="$FILTER_ACCEPT"
if [ $DEBUG_LAN2 = "true" ]; then
iptables --table filter --new-chain DEBUG_LAN2_DROP
iptables --table filter --flush DEBUG_LAN2_DROP
iptables --table filter --append DEBUG_LAN2_DROP --jump LOG --log-prefix '[debug] LAN2 DROP : '
iptables --table filter --append DEBUG_LAN2_DROP --jump DROP
LAN2_DROP="DEBUG_LAN2_DROP"
iptables --table filter --new-chain DEBUG_LAN2_ACCEPT
iptables --table filter --flush DEBUG_LAN2_ACCEPT
iptables --table filter --append DEBUG_LAN2_ACCEPT --jump LOG --log-prefix '[debug] LAN2 ACCEPT : '
iptables --table filter --append DEBUG_LAN2_ACCEPT --jump ACCEPT
LAN2_ACCEPT="DEBUG_LAN2_ACCEPT"
fi
iptables --table filter --append INPUT --in-interface $IN2_INTERFACE --jump $LAN2_ACCEPT
iptables --table filter --append OUTPUT --out-interface $IN2_INTERFACE --jump $LAN2_ACCEPT
iptables --table filter --append FORWARD --in-interface $IN2_INTERFACE --jump $LAN2_ACCEPT
iptables --table filter --append FORWARD --out-interface $IN2_INTERFACE --jump $LAN2_ACCEPT
################################################################################
# REGLES PERSONALISEES
################################################################################
iptables --table filter --append INPUT --in-interface $OUT_INTERFACE -m state --state NEW,INVALID --jump $FILTER_DROP
iptables --table filter --append INPUT --in-interface $OUT_INTERFACE -m state --state ESTABLISHED,RELATED --jump $FILTER_DROP
iptables --table filter --append OUTPUT --out-interface $OUT_INTERFACE -m state --state NEW,ESTABLISHED,RELATED --jump $FILTER_DROP
################################################################################
# PARTAGE DE LA CONNECTION [masquage des machines locales derrière le firewall]
################################################################################
iptables --table nat --append POSTROUTING -o $OUT_INTERFACE --jump $NAT_MASQUERADE
################################################################################
# REACTIVATION DU FORARDING IP
################################################################################
echo 1 > /proc/sys/net/ipv4/ip_forward
Vous vous demandez peut-être porquoi j'ai mis tant de loggers et bien s'est parce que j'ai un ordinateur sous XP en local et que je ne sais pas trop ce qu'il fout parfois d'où la présence de multiple logger afin de vérifier ce qu'il se passer exactement à un endroit précis des reglès.
CHANGELOG
---------------
13/01/2005 :
--> corrections de "bugs"
--> quelques annotations pour une meilleur compréhension
12/01/2005
--> initialisation du script
TODO
-------
--> finir la configuration pour un accès à internet
--> quelques explications & règles pour divers clients (irc, ftp, p2p, etc...)
--> explications sur le port fowarding (hebrgement d'un serveur sur le reseau local accessible depuis l'extérieur)
--> génération du script via un outils (peut-être XML)
--> meilleure prise en compte des loggeurs (notement au niveau de la lisibilité du script)
--> Implémentation de la vidange des modules (via rmmod) chargés dans le noyau lors de l'initialisation des tables





