w3.nonsenz.org

Configuration du firewall netfilter avec un script IPtables

Plan du réseau

Nous repartons de notre ancien script de configuration iptables avec bien entendu l'ajout de la nouvelle interface DMZ et la répartition des différents services sur les 3 serveurs. Le script sera sans doute à améliorer au fur et à mesure de la configuration mais un premier jet (déjà opérationnel) donne ceci :

#!/bin/bash
# firewall.sh
# Passerelle
# par NonSenZ - pollux.nonsenz.org
# Usage :
#       -no pour desactiver le firewall (sur lan protege par ex.)
#       -o  permet a toutes les requêtes de sortir
#                (ne protege pas contre les chevaux de Troie)
#       -a  protection maxi
##########
#Variables
##########
IPT="/sbin/iptables"
#interfaces
INET_DEV="eth0"
LAN_DEV="eth1"
WIFI_DEV="eth2"
DMZ_DEV="eth3"
VPN_DEV="ppp0"
#adresses ip
IP_SERVER_LAN="192.168.0.254"
IP_SERVER_WIFI="192.168.1.254"
IP_SERVER_DMZ="192.168.2.254"
IP_LAN="192.168.0.0/24"
IP_LAN_BROADCAST="192.168.0.255"
IP_WIFI="192.168.1.0/24"
IP_WIFI_BROADCAST="192.168.1.255"
IP_DMZ="192.168.2.0/24"
IP_VPN_CLIENT="192.168.3.1"
IP_VPN_SERVER="192.168.3.2"
IP_BITT="192.168.0.52" #hote interne bittorrent
IP_MULE="192.168.0.52" #hote interne e-mule
IP_SOUL="192.168.0.51" #hote SoulSeek
GM_IP_IN="192.168.0.52" #hote gnomemeeting interne
IP_MRTG="192.168.2.1" #hote sur lequel se trouve MRTG
#ports
FTP_PORTS="20:21"
FTP_CONTROL_PORT="21"
FTP_DATA_PORT="20"
HIGH_PORTS="1024:65535"
TCP_PORT_RANGE=30000:30010 #H245 si pas de tunnel
RTP_PORT_RANGE=5000:5016 #RTP connexions (2 audio, 2 video - RTP et RTCP)
TCP_LISTENING_PORT=1720 #H323
#GK_PORT_RANGE=5020:5023 #dans le cas d'une Gatekeeper
BITT_PORT="6881"
MULE_PORT="4662"
SOUL_PORT="2234"
BDD_PORTS="3306,5432"

#Suivant les options - flush et politique par defaut
case $1 in
-no)
        #Vide les regles
        $IPT -t filter -F
        $IPT -t filter -X
        $IPT -t nat -F
        $IPT -t nat -X
        #Politique par defaut
        $IPT -P INPUT ACCEPT
        $IPT -P OUTPUT ACCEPT
        $IPT -P FORWARD ACCEPT
        echo "Firewall desactive"
        exit 1
        ;;
-o)
        #Vide les regles
        $IPT -t filter -F
        $IPT -t filter -X
        $IPT -t nat -F
        $IPT -t nat -X
        #Politique par defaut
        $IPT -P INPUT DROP
        $IPT -P OUTPUT ACCEPT
        $IPT -P FORWARD DROP
        echo "Configuration protection mini"
        ;;
-a)
        #Vide les regles
        $IPT -t filter -F
        $IPT -t filter -X
        $IPT -t nat -F
        $IPT -t nat -X
        #Politique par defaut
        $IPT -P INPUT DROP
        $IPT -P OUTPUT DROP
        $IPT -P FORWARD DROP
        echo "Configuration protection maxi"
        ;;
*)
        echo "Argument manquant !"
        echo "Les options autorisees sont:"
        echo "-a pour une protection optimale"
        echo "-o autorise les output"
        echo "-no desactive le firewall"
        echo "$0 : ECHEC"
        exit 1
        ;;
esac

#Modules necessaires
modprobe ip_tables
modprobe ip_conntrack
modprobe ip_conntrack_ftp
modprobe ip_nat_ftp
modprobe ip_nat_irc

##Stateful firewall
#Tout ce qui a ete initialise peut sortir
$IPT -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
#autorise les requetes de connexions existantes
$IPT -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
#autorise le forward de connexions existantes
$IPT -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

#autorise les requetes locales (interface loopback)
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT

####################
#   LAN -> localhost
####################
#Webmin (depuis le lan)
#$IPT -A INPUT -p tcp -s ${IP_LAN} --dport 10000 -j ACCEPT
#autorise les requetes du et vers le LAN
#$IPT -A INPUT -s ${IP_LAN} -d ${IP_SERVER_LAN} -j ACCEPT
#$IPT -A OUTPUT -s ${IP_SERVER_LAN} -d ${IP_LAN} -j ACCEPT


####################
#   VPN -> localhost
####################

#autorise les requetes du et vers le client VPN (VPN etabli)
$IPT -A INPUT -s ${IP_VPN_CLIENT} -d ${IP_VPN_SERVER} -j ACCEPT
$IPT -A OUTPUT -s ${IP_VPN_SERVER} -d ${IP_VPN_CLIENT} -j ACCEPT


####################
#   DMZ -> localhost
####################
#autorise resolution DNS
#$IPT -A INPUT -p tcp --dport 53 -s ${IP_DMZ} -d ${IP_SERVER_DMZ} -j ACCEPT
#$IPT -A INPUT -p udp --dport 53 -s ${IP_DMZ} -d ${IP_SERVER_DMZ} -j ACCEPT
#autorise l'acces aux MIB SNMP
$IPT -A INPUT -p tcp --dport 161 -s ${IP_MRTG} -d ${IP_SERVER_DMZ} -j ACCEPT
$IPT -A INPUT -p udp --dport 161 -s ${IP_MRTG} -d ${IP_SERVER_DMZ} -j ACCEPT
$IPT -A INPUT -p tcp --dport 162 -s ${IP_MRTG} -d ${IP_SERVER_DMZ} -j ACCEPT
$IPT -A INPUT -p udp --dport 162 -s ${IP_MRTG} -d ${IP_SERVER_DMZ} -j ACCEPT

####################
#  ? -> localhost
####################
#repond aux pings
$IPT -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
$IPT -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT
$IPT -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
$IPT -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
#Services locaux
$IPT -A INPUT -p tcp --dport ssh -j ACCEPT
$IPT -A INPUT -p tcp --dport http -j ACCEPT
$IPT -A INPUT -p tcp --dport https -j ACCEPT
##FTP
#Autorise la connexion FTP
$IPT -A INPUT -p tcp --dport ${FTP_CONTROL_PORT} -j ACCEPT
#FTP actif
$IPT -A OUTPUT -p tcp --sport ${FTP_DATA_PORT} -j ACCEPT
#FTP passif
$IPT -A INPUT  -p tcp --sport ${HIGH_PORTS} --dport ${HIGH_PORTS} -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT -p tcp --sport ${HIGH_PORTS} --dport ${HIGH_PORTS} -m state --state ESTABLISHED,RELATED -j ACCEPT

####################
#  Localhost -> INET
####################
#$IPT -A OUTPUT -d 82.67.106.254 -j ACCEPT
#dns
$IPT -A OUTPUT -p tcp --dport 53 -o ${INET_DEV} -j ACCEPT
$IPT -A OUTPUT -p udp --dport 53 -o ${INET_DEV} -j ACCEPT
#ntp
$IPT -A OUTPUT -p tcp --dport 123 -o ${INET_DEV} -j ACCEPT
$IPT -A OUTPUT -p udp --dport 123 -o ${INET_DEV} -j ACCEPT

####################
#  Localhost -> LAN
####################
#$IPT -A OUTPUT -d 82.67.106.254 -j ACCEPT
#dns
$IPT -A OUTPUT -p tcp --dport 53 -o ${LAN_DEV} -j ACCEPT
$IPT -A OUTPUT -p udp --dport 53 -o ${LAN_DEV} -j ACCEPT
#syslogd
$IPT -A OUTPUT -p udp --dport 514 -o ${LAN_DEV} -j ACCEPT

####################
#  Localhost -> DMZ
####################
#http
$IPT -A OUTPUT -p tcp -s ${IP_SERVER_DMZ} -d ${IP_DMZ} --dport http -j ACCEPT
$IPT -A OUTPUT -p tcp -s ${IP_SERVER_DMZ} -d ${IP_DMZ} --dport 8080 -j ACCEPT
#ftp (autorise plus bas)
#ssh
$IPT -A OUTPUT -p tcp -s ${IP_SERVER_DMZ} -d ${IP_DMZ} --dport ssh -j ACCEPT
#syslogd
$IPT -A OUTPUT -p udp  -s ${IP_SERVER_DMZ} -d ${IP_DMZ} --dport 514 -j ACCEPT

####################
# Localhost -> ?
####################
#Autorise la connexion FTP pour les mises a jour et le reverse proxy ftp
#FTP actif
$IPT -A OUTPUT -p tcp --dport ${FTP_CONTROL_PORT} -j ACCEPT
$IPT -A INPUT -p tcp --sport ${FTP_DATA_PORT} -j ACCEPT


#FORWARD - Fait suivre certaines requetes vers des machines du rezo

#############
# INET -> LAN
#############

##bittorrent
$IPT -A FORWARD -p TCP --dport ${BITT_PORT} -j ACCEPT
$IPT -A PREROUTING -t nat -p tcp --dport ${BITT_PORT} -j DNAT --to-destination ${IP_BITT}:${BITT_PORT}
$IPT -A FORWARD -p UDP --dport ${BITT_PORT} -j ACCEPT
$IPT -A PREROUTING -t nat -p udp --dport ${BITT_PORT} -j DNAT --to-destination ${IP_BITT}:${BITT_PORT}
##emule
$IPT -A FORWARD -p TCP --dport ${MULE_PORT} -j ACCEPT
$IPT -A PREROUTING -t nat -p tcp --dport ${MULE_PORT} -j DNAT --to-destination ${IP_MULE}:${MULE_PORT}
##SoulSeek
$IPT -A PREROUTING -t nat -i ${INET_DEV} -p tcp --dport ${SOUL_PORT} -j DNAT --to-dest ${IP_SOUL}
##Gnomemeeting
$IPT -A PREROUTING -t nat -i ${INET_DEV} -p tcp --dport ${TCP_PORT_RANGE} -j DNAT --to-dest ${GM_IP_IN}
$IPT -A PREROUTING -t nat -i ${INET_DEV} -p udp --dport ${RTP_PORT_RANGE} -j DNAT --to-dest ${GM_IP_IN}
$IPT -A PREROUTING -t nat -i ${INET_DEV} -p tcp --dport ${TCP_LISTENING_PORT} -j DNAT --to-dest ${GM_IP_IN}
$IPT -A FORWARD -p tcp -i ${INET_DEV} --dport ${TCP_PORT_RANGE} -d ${GM_IP_IN} -j ACCEPT
$IPT -A FORWARD -p udp -i ${INET_DEV} --dport ${RTP_PORT_RANGE} -d ${GM_IP_IN} -j ACCEPT
$IPT -A FORWARD -p tcp -i ${INET_DEV} --dport ${TCP_LISTENING_PORT} -d ${GM_IP_IN} -j ACCEPT

#############
# LAN -> INET
#############
$IPT -A FORWARD -i ${LAN_DEV} -o ${INET_DEV} -m state --state ! INVALID -j ACCEPT

##############
# WIFI -> INET
##############
$IPT -A FORWARD -i ${WIFI_DEV} -o ${INET_DEV} -m state --state ! INVALID -j ACCEPT

##############
# LAN -> WIFI
##############
$IPT -A FORWARD -i ${LAN_DEV} -o ${WIFI_DEV} -m state --state ! INVALID -j ACCEPT

##############
# WIFI -> LAN
##############
#dns
$IPT -A FORWARD -p tcp -s ${IP_WIFI} -d ${IP_LAN} --dport 53 -j ACCEPT
$IPT -A FORWARD -p udp -s ${IP_WIFI} -d ${IP_LAN} --dport 53 -j ACCEPT

##############
# LAN -> VPN
##############
$IPT -A FORWARD -i ${LAN_DEV} -o ${VPN_DEV} -m state --state ! INVALID -j ACCEPT

##############
# VPN -> LAN
##############
$IPT -A FORWARD -i ${VPN_DEV} -o ${LAN_DEV} -m state --state ! INVALID -j ACCEPT

##############
# LAN -> DMZ
##############
#http Apache
$IPT -A FORWARD -p tcp -s ${IP_LAN} -d ${IP_DMZ} --dport http -j ACCEPT
#http Tomcat
$IPT -A FORWARD -p tcp -s ${IP_LAN} -d ${IP_DMZ} --dport 8080 -j ACCEPT
#ssh
$IPT -A FORWARD -p tcp -s ${IP_LAN} -d ${IP_DMZ} --dport ssh -j ACCEPT

##############
# DMZ -> LAN
##############
#bases de donnees
$IPT -A FORWARD -p tcp -s ${IP_DMZ} -d ${IP_LAN} -m multiport --dports ${BDD_PORTS} -j ACCEPT
$IPT -A FORWARD -p udp -s ${IP_DMZ} -d ${IP_LAN} -m multiport --dports ${BDD_PORTS} -j ACCEPT
#dns
$IPT -A FORWARD -p tcp -s ${IP_DMZ} -d ${IP_LAN} --dport 53 -j ACCEPT
$IPT -A FORWARD -p udp -s ${IP_DMZ} -d ${IP_LAN} --dport 53 -j ACCEPT
#snmp
$IPT -A FORWARD -p tcp --dport 161 -s ${IP_MRTG} -d ${IP_LAN} -j ACCEPT
$IPT -A FORWARD -p udp --dport 161 -s ${IP_MRTG} -d ${IP_LAN} -j ACCEPT
$IPT -A FORWARD -p tcp --dport 162 -s ${IP_MRTG} -d ${IP_LAN} -j ACCEPT
$IPT -A FORWARD -p udp --dport 162 -s ${IP_MRTG} -d ${IP_LAN} -j ACCEPT

##############
# DMZ -> INET
##############
#mises a jour apt par ftp
$IPT -A FORWARD -p tcp -i ${DMZ_DEV}  -o ${INET_DEV} --dport ${FTP_CONTROL_PORT} -j ACCEPT
$IPT -A FORWARD -p tcp -i ${DMZ_DEV}  -o ${INET_DEV} --dport ntp -j ACCEPT
$IPT -A FORWARD -p udp -i ${DMZ_DEV}  -o ${INET_DEV} --dport ntp -j ACCEPT
#############################
#Diverses protections et logs
#############################
$IPT -A FORWARD -m state --state INVALID -m limit --limit 3/s -j LOG --log-prefix "INVALID FORWARD: "
$IPT -A FORWARD -m state --state INVALID -j DROP
$IPT -A FORWARD -p TCP --tcp-flags ! ALL SYN -m state --state NEW -m limit --limit 3/s -j LOG --log-prefix "FORWARD TCP sans SYN: "
$IPT -A FORWARD -p TCP --tcp-flags ! ALL SYN -m state --state NEW -j DROP
$IPT -A FORWARD -j LOG -m limit --limit 3/s --log-prefix "BAD FORWARD "
$IPT -A FORWARD -j DROP

#NAT-Tout ce qui sort est nate avec l'adresse publique de l'interface INET

echo 1 > /proc/sys/net/ipv4/ip_forward
$IPT -t nat -A POSTROUTING -o ${INET_DEV} -j MASQUERADE

#empeche l'IP spoofing
echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter

#bloque et logue le reste
$IPT -N denylog
$IPT -A denylog  -m limit --limit 40/minute -j LOG --log-prefix "$IPT "
$IPT -A denylog -j DROP
$IPT -A INPUT -j denylog
#Save
$IPT-save >/etc/iptables-perso.conf
echo " DONE."


Je pense que le script parle de lui même. Dans une première partie, on définit les différents paramètres (ce qui aidera au portage du script sur une autre machine). Ensuite, on traite les différentes connexions aux machines en utilisant la propriété du firewall à état qui facilite énormément les choses. C'est-à-dire qu'une connexion autorisée pourra continuer tranquilement (les paquets de retour ne seront pas autorisés formellement avec une ligne, mais seront repérés comme faisant partie d'une connexion établie et seront donc autorisés de ce fait). Ce script sera placé dans /sbin sous le nom firewall.sh et nous lui donnons les droits 754 (sachant que root.root est son propriétaire).

Pour que le script soit lancé automatiquement au démarrage, nous éditons le fichier /etc/rc.local (qui sert justement à lancer des services au démarrage) :

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
/sbin/firewall.sh -a
exit 0

RETOUR

 


hébergé sur Pollux