Voila 3 scripts qui permettent de réaliser un firewall minimaliste mais efficace testé sous Debian et Ubuntu (transposable sur tout autre distrib basé sur Debian ou non d'ailleurs avec des petites modifications). Le script d'initialisation des tables iptables sont largement inspirés de ceux trouvés ici http://olivieraj.free.fr/fr/linux/programme/netfilter_cfg/

Ces scripts sont prévus pour une machine personnelle sur la quelle peut tourner les services http, ftp et ssh accessible depuis l'internet, la machine en question est derrière une freebox v4 en mode routeur et le DHCP est activé (fixé sur adresse MAC)

network.png

Maj 12/08/2006

/etc/scripts/iptables_init.sh

Script d'initialisation des tables iptables, à placer dans le dossier /etc/scripts. Les variables globales sont à rensengner selon l'environnement

#!/bin/sh -norc
###############################################################################
# NOM: /etc/scripts/iptables_init.sh
# COMMENTAIRE : Utilisation du suivi de connexion (ip_conntrack)
###############################################################################
###############################################################################
# Variables globales
###############################################################################
echo "  + ============== INITIALISATION DES TABLES NETFILTER ==============="
# Parametrage du reseau local (LAN = Local Area Network)
DHCP=1            ; # 1:DHCP actif / 0:DHCP inactif pour l'attribution d'IP local
VMWARE=1                        ; # 1:VmWare actif / 0:VmWare inactif
VMWARE_ETH1=vmnet1            ; # Interface reseau virtuelle VmWare 1
VMWARE_LAN_NET1=192.168.218.0/24; # Reseau interne VmWare 1
VMWARE_IP1=192.168.218.1        ; # IP Interface reseau virtuelle VmWare 1
VMWARE_BCAST1=192.168.218.255   ; # Adresse de broadcast Interface reseau virtuelle VmWare 1
VMWARE_ETH2=vmnet8            ; # Interface reseau virtuelle VmWare 2
VMWARE_LAN_NET2=172.16.120.0/24 ; # Reseau interne VmWare 2
VMWARE_IP2=172.16.120.1  ; # IP Interface reseau virtuelle VmWare 2
VMWARE_BCAST2=172.16.120.255    ; # Adresse de broadcast Interface reseau virtuelle VmWare 2
LAN_ETH=eth0            ; # Interface reseau interne
LAN_IP=192.168.0.1            ; # Adresse reseau interne
LAN_NETWORK=192.168.0.0/24      ; # Reseau interne
LAN_BROADCAST=192.168.0.255     ; # Adresse de broadcast interne
MULE_TCP_PORT=8270            ; # Port TCP utilise par *mule       
MULE_UDP_PORT=8271            ; # Port UDP utilise par *mule
FTP_SRV=0                     ; # Serveur FTP local 1:actif / 0:inactif
FTP_SRV_PORT=21   ; # Port d'ecoute du serveur FTP local
SSH_SRV=0                     ; # Serveur SSH local 1:actif / 0:inactif
SSH_PORT=22               ; # Port d'ecoute du serveur SSH local
WEB_SRV=0                     ; # Serveur WEB local 1:actif / 0:inactif
WEB_PORT=80               ; # Port d'ecoute du serveur SWEB local
###############################################################################
### Initialisation des tables
###############################################################################
# Initialise la table Filter (par defaut tout les echanges sont refuses)
echo "  + Initialisation de la table Filter"
iptables -t filter -F
iptables -t filter -X
iptables -t filter -P INPUT   DROP
iptables -t filter -P FORWARD DROP
iptables -t filter -P OUTPUT  DROP

# Initialise la table NAT (par defaut tout les echanges sont actives)
echo "  + Initialisation de la table NAT"
iptables -t nat -F
iptables -t nat -X
iptables -t nat -P PREROUTING  ACCEPT
iptables -t nat -P OUTPUT      ACCEPT
iptables -t nat -P POSTROUTING ACCEPT

# Initialise la table Mangle (par defaut tout les echanges sont actives)
echo "  + Initialisation de la table MANGLE"
iptables -t mangle -F
iptables -t mangle -X
iptables -t mangle -P PREROUTING  ACCEPT
iptables -t mangle -P INPUT       ACCEPT
iptables -t mangle -P FORWARD     ACCEPT
iptables -t mangle -P OUTPUT      ACCEPT
iptables -t mangle -P POSTROUTING ACCEPT

# Desactivation du NAT (fonction routeur)
echo "  + Desactivation du NAT"
echo 0 > /proc/sys/net/ipv4/ip_forward

###############################################################################
### Creation des regles de filtrages
###############################################################################
# Autorise l'interface loopback à dialoguer avec elle-meme
echo "  + Regles du localhost"
iptables -t filter -A OUTPUT -o lo -p all -j ACCEPT
iptables -t filter -A INPUT  -i lo -p all -j ACCEPT

# Autorise les connexions avec le reseau LAN connecte à l'interface $LAN_ETH
echo "  + Regles du reseau local ($LAN_ETH - $LAN_IP - $LAN_NETWORK)"
# Connexions firewall <-> reseau
iptables -t filter -A OUTPUT -o $LAN_ETH -s $LAN_IP -d $LAN_NETWORK -m state --state ! INVALID -j ACCEPT
iptables -t filter -A INPUT  -i $LAN_ETH -s $LAN_NETWORK -d $LAN_IP -m state --state ! INVALID -j ACCEPT
 
# Connexions firewall <-> broadcast reseau
iptables -t filter -A OUTPUT -o $LAN_ETH -s $LAN_IP -d $LAN_BROADCAST -m state --state ! INVALID -j ACCEPT
iptables -t filter -A INPUT  -i $LAN_ETH -s $LAN_NETWORK -d $LAN_BROADCAST -m state --state ! INVALID -j ACCEPT

# Autorise l'attribution d'IP par DHCP
if [ "$DHCP" == "1" ]; then
echo "  + DHCP actif"
iptables -A INPUT  -i $LAN_ETH -s 0.0.0.0 -d 255.255.255.255 \
                                -p udp --sport bootpc --dport bootps -m state --state NEW,ESTABLISHED -j ACCEPT
else
  echo "  + DHCP desactive" 
fi

# Autorise le dialogue avec les interfaces virtuelles VmWare
if [ "$VMWARE" == "1" ]; then
echo "  + VmWare actif"
        echo "  + Regles du reseau local ($VMWARE_ETH1 - $VMWARE_IP1 - $VMWARE_LAN_NET1)"
        # Connexions firewall <-> reseau VMWARE_LAN_NET1
        iptables -t filter -A OUTPUT -o $VMWARE_ETH1 -s $VMWARE_IP1 -d $VMWARE_LAN_NET1 -m state --state ! INVALID -j ACCEPT
        iptables -t filter -A INPUT  -i $VMWARE_ETH1 -s $VMWARE_LAN_NET1 -d $VMWARE_IP1 -m state --state ! INVALID -j ACCEPT
        # Connexions firewall <-> broadcast reseau VMWARE_LAN_NET1
        iptables -t filter -A OUTPUT -o $VMWARE_ETH1 -s $VMWARE_IP1 -d $VMWARE_BCAST1 -m state --state ! INVALID -j ACCEPT
        iptables -t filter -A INPUT  -i $VMWARE_ETH1 -s $VMWARE_LAN_NET1 -d $VMWARE_BCAST1 -m state --state ! INVALID -j ACCEPT
        echo "  + Regles du reseau local ($VMWARE_ETH2 - $VMWARE_IP2 - $VMWARE_LAN_NET2)"
        # Connexions firewall <-> reseau VMWARE_LAN_NET2
        iptables -t filter -A OUTPUT -o $VMWARE_ETH2 -s $VMWARE_IP2 -d $VMWARE_BCAST2 -m state --state ! INVALID -j ACCEPT
        iptables -t filter -A INPUT  -i $VMWARE_ETH2 -s $VMWARE_LAN_NET2 -d $VMWARE_BCAST2 -m state --state ! INVALID -j ACCEPT
        # Connexions firewall <-> broadcast reseau VMWARE_LAN_NET2
        iptables -t filter -A OUTPUT -o $VMWARE_ETH2 -s $VMWARE_IP2 -d $VMWARE_LAN_NET2 -m state --state ! INVALID -j ACCEPT
        iptables -t filter -A INPUT  -i $VMWARE_ETH2 -s $VMWARE_LAN_NET2 -d $VMWARE_IP2 -m state --state ! INVALID -j ACCEPT
else
  echo "  + VmWare desactive" 
fi

# Autorise l'acces au serveur FTP local depuis l'internet
if [ "$FTP_SRV" == "1" ]; then
echo "  + Serveur FTP actif"
iptables -A INPUT  -i $LAN_ETH -d $LAN_IP -p tcp --dport $FTP_SRV_PORT -m state --state ! INVALID           -j ACCEPT
iptables -A OUTPUT -o $LAN_ETH -s $LAN_IP -p tcp --sport $FTP_SRV_PORT -m state --state ESTABLISHED,RELATED -j ACCEPT
else
  echo "  + Serveur FTP desactive" 
fi

# Autorise l'acces au serveur SSH local depuis l'internet
if [ "$SSH_SRV" == "1" ]; then
echo "  + Serveur SSH actif"
iptables -A INPUT  -i $LAN_ETH -d $LAN_IP -p tcp --dport $SSH_PORT -m state --state ! INVALID           -j ACCEPT
iptables -A OUTPUT -o $LAN_ETH -s $LAN_IP -p tcp --sport $SSH_PORT -m state --state ESTABLISHED,RELATED -j ACCEPT
else
  echo "  + Serveur SSH desactive" 
fi

# Autorise l'acces au serveur SWEB local depuis l'internet
if [ "$WEB_SRV" == "1" ]; then
echo "  + Serveur WEB actif"
iptables -A INPUT  -i $LAN_ETH -d $LAN_IP -p tcp --dport $WEB_PORT -m state --state ! INVALID           -j ACCEPT
iptables -A OUTPUT -o $LAN_ETH -s $LAN_IP -p tcp --sport $WEB_PORT -m state --state ESTABLISHED,RELATED -j ACCEPT
else
  echo "  + Serveur WEB desactive"
fi


###############################################################################
# Regles de connexion à Internet
# Seul les connexions initialises par la machine sont autorisees
# C'est le suivit de connexion
###############################################################################

# Chargement des modules pour le suivi de connexion
modprobe ip_conntrack
modprobe ip_conntrack_ftp
modprobe ip_conntrack_irc
echo "  + Regles pour Internet (Initie par soft locale --> ALL_IP:ALL_PORT)"
iptables -A OUTPUT -o $LAN_ETH -s $LAN_IP -d 0.0.0.0/0 -p all -m state --state ! INVALID           -j ACCEPT
iptables -A INPUT  -i $LAN_ETH -s 0.0.0.0/0 -d $LAN_IP -p all -m state --state RELATED,ESTABLISHED -j ACCEPT

# Overture des ports d'aMule
echo "  + Regles pour la mule (Port TCP=$MULE_TCP_PORT / Port UDP=$MULE_UDP_PORT)"

iptables -A INPUT -i $LAN_ETH -p tcp -d $LAN_IP --dport $MULE_TCP_PORT -m state --state ! INVALID -j ACCEPT
iptables -A INPUT -i $LAN_ETH -p udp -d $LAN_IP --dport $MULE_UDP_PORT -m state --state ! INVALID -j ACCEPT

# Regles pour le Multiposte FREE
echo "  + Regles pour le Multiposte FREE"
iptables -A INPUT -i $LAN_ETH -p udp -s 212.27.38.253 --dport 1024:65535 -j ACCEPT
iptables -A OUTPUT -o $LAN_ETH -p udp -d 212.27.38.253 --sport 1024:65535 -j ACCEPT

# Log des paquets rejetes dans /var/log/messages
echo "  + Regles log des paquets rejetes ([IN/FO/OU_PKTS_DROP]==>)"
iptables -A INPUT -j LOG --log-prefix="[IN_PKTS_DROP]==> "
iptables -A FORWARD -j LOG --log-prefix="[FO_PKTS_DROP]==> "
iptables -A OUTPUT -j LOG --log-prefix="[OU_PKTS_DROP]==> "

echo "  + ======================== SCRIPT TERMINE! ========================="
echo "  + Afficher la configuration de la table filter : 'iptables -L -n -v'"
echo "  + Ou 'iptables -L -n -v -t nat ou mangle' pour les autres tables"
echo "  + =================================================================="

Voila le resultat de lexécution du script

$ /etc/scripts/iptables_init.sh
Starting FIREWALL...
  + ============== INITIALISATION DES TABLES NETFILTER ===============
  + Initialisation de la table Filter
  + Initialisation de la table NAT
  + Initialisation de la table MANGLE
  + Desactivation du NAT
  + Regles du localhost
  + Regles du reseau local (eth0 - 192.168.0.1 - 192.168.0.0/24)
  + DHCP actif
  + VmWare actif
  + Regles du reseau local (vmnet1 - 192.168.218.1 - 192.168.218.0/24)
  + Regles du reseau local (vmnet8 - 172.16.120.1 - 172.16.120.0/24)
  + Serveur FTP desactive
  + Serveur SSH desactive
  + Serveur WEB desactive
  + Regles pour Internet (Initie par soft locale --> ALL_IP:ALL_PORT)
  + Regles pour la mule (Port TCP=8270 / Port UDP=8271)
  + Regles pour le Multiposte FREE
  + Regles log des paquets rejetes ([IN/FO/OU_PKTS_DROP]==>)
  + ======================== SCRIPT TERMINE! =========================
  + Afficher la configuration de la table filter : 'iptables -L -n -v'
  + Ou 'iptables -L -n -v -t nat ou mangle' pour les autres tables
  + ==================================================================
0

/etc/script/iptables_stat.sh

Script, à placer dans le dossier /etc/scripts, qui affiche des stats d'utilisation de iptables, download et upload global , flux droppé

#!/bin/sh
###############################################################################
# NOM: /etc/scripts/iptables_stat.sh
# COMMENTAIRE : Statistiques d'utilisation de iptables
###############################################################################
###############################################################################
# Variables globales
###############################################################################
LAN_ETH=ETH0            ; # Interface réseau interne
LAN_IP=192.168.0.1            ; # Adresse réseau interne
LAN_NETWORK=192.168.0.0/24      ; # Réseau interne
###############################################################################
clear
echo '============ STATISTIQUES FLUX RESEAU ============'
###############################################################################
# Variables globales
###############################################################################
echo
echo '====> Flux Ok (bytes)'
echo
echo "   - [DOWNLOAD] $LAN_ETH <-- INTERNET :"`iptables -L -n -v | grep "0.0.0.0/0            $LAN_IP         state RELATED,ESTABLISHED" | cut -c6-12`
echo "   - [UPLOAD]   $LAN_ETH --> INTERNET :"`iptables -L -n -v | grep "$LAN_IP          0.0.0.0/0           state NEW,RELATED,ESTABLISHED,UNTRACKED" | cut -c6-12`
echo "   - [DOWNLOAD] $LAN_ETH <-- LAN      :"`iptables -L -n -v | grep "$LAN_NETWORK       $LAN_IP" | cut -c6-12`
echo "   - [UPLOAD]   $LAN_ETH --> LAN      :"`iptables -L -n -v | grep "$LAN_IP          $LAN_NETWORK" | cut -c6-12`
echo
echo '====> Flux global Dropé'

echo
echo "   - [DOWNLOAD] $LAN_ETH <-- LAN : pakets ="`iptables -L -n -v | grep IN_PKTS_DROP | cut -c0-6`
echo "                               octets ="`iptables -L -n -v | grep IN_PKTS_DROP | cut -c6-12`
echo "   - [UPLOAD]   $LAN_ETH --> LAN : pakets ="`iptables -L -n -v | grep OU_PKTS_DROP | cut -c0-6`
echo "                               octets ="`iptables -L -n -v | grep OU_PKTS_DROP | cut -c6-12`
echo
echo '=================================================='

Voila le résultat

$ /etc/scripts/iptables_stat.sh
============ STATISTIQUES FLUX RESEAU ============

====> Flux Ok (bytes)

   - [DOWNLOAD] ETH0 <-- INTERNET : 34M
   - [UPLOAD]   ETH0 --> INTERNET : 2330K
   - [DOWNLOAD] ETH0 <-- LAN      : 0
   - [UPLOAD]   ETH0 --> LAN      : 10980

====> Flux global Dropé

   - [DOWNLOAD] ETH0 <-- LAN : pakets = 0
                               octets = 0
   - [UPLOAD]]   ETH0 --> LAN : pakets = 93
                               octets = 12600

==================================================

/etc/init.d/firewall

Script d'initialisation du firewall, rêgles iptable, au démarage de la machine. Utilisation possible start|stop|restart|status|panic|stats

  • start : no comment
  • stop : no comment
  • restart : no comment
  • status : affiche les rêgles iptables actives
  • panic : bloque tous par défaut et log les paquets droppé dans /var/log/messages
  • stats : lance le script iptables_stat.sh
#!/bin/sh
# Start/stop the FIREWALL.

case "$1" in
start)  echo "Starting FIREWALL..."
        /etc/scripts/iptables_init.sh
        echo $?
        ;;
stop)   echo "Stopping FIREWALL..."
        echo "  + Initialisation de la table FILTER"
        /sbin/iptables -t filter -F
        /sbin/iptables -t filter -X
        /sbin/iptables -t filter -P INPUT   ACCEPT
        /sbin/iptables -t filter -P FORWARD ACCEPT
        /sbin/iptables -t filter -P OUTPUT  ACCEPT
        echo "  + Initialisation de la table NAT"
        /sbin/iptables -t nat -F
        /sbin/iptables -t nat -X
        /sbin/iptables -t nat -P PREROUTING  ACCEPT
        /sbin/iptables -t nat -P OUTPUT      ACCEPT
        /sbin/iptables -t nat -P POSTROUTING ACCEPT
        echo "  + Initialisation de la table MANGLE"
        /sbin/iptables -t mangle -F
        /sbin/iptables -t mangle -X
        /sbin/iptables -t mangle -P PREROUTING  ACCEPT
        /sbin/iptables -t mangle -P INPUT       ACCEPT
        /sbin/iptables -t mangle -P FORWARD     ACCEPT
        /sbin/iptables -t mangle -P OUTPUT      ACCEPT
        /sbin/iptables -t mangle -P POSTROUTING ACCEPT 
        echo $?
        ;;
restart)   
        $0 stop     

        $0 start
        ;;
status)   
        /sbin/iptables -L -n -v
        ;;
panic)   
        echo "Starting PANIC FIREWALL !!!..."
        /sbin/iptables -t filter -F
        /sbin/iptables -t filter -X
        /sbin/iptables -t filter -P INPUT   DROP
        /sbin/iptables -t filter -P FORWARD DROP
        /sbin/iptables -t filter -P OUTPUT  DROP
        /sbin/iptables -A INPUT -j LOG --log-prefix="[IN_PKTS_PANIC_DROP]==> "
        /sbin/iptables -A FORWARD -j LOG --log-prefix="[FO_PKTS_PANIC_DROP]==> "
        /sbin/iptables -A OUTPUT -j LOG --log-prefix="[OU_PKTS_PANIC_DROP]==> "
        echo $?
        ;;
stats) 
        /etc/scripts/iptables_stat.sh  
        ;;   
*)      echo "Usage: /etc/init.d/firewall start|stop|restart|status|panic|stats"
        exit 1
        ;;
esac
exit 0

Sous Ubuntu pour exécuter le firewall au démarrrage du système il faut faire un lien symbolique vers le srcipt dans le dossier /etc/rc2.d, sans oublier de les rendre exécutable

$ sudo chmod +x /etc/scripts/firewall
$ sudo chmod +x /etc/scripts/iptables_stat.sh
$ sudo chmod +x /etc/scripts/iptables_init.sh
$ sudo ln -s /etc/scripts/firewall /etc/rc2.d/S88firewall
$ ll /etc/rc2.d/S99firewall

lrwxrwxrwx 1 root root 19 2006-05-25 00:57 S88firewall -> ../scripts/firewall