Firewall pour passerelle : IpTables

IpTables (firewall à filtrage de paquet à état)

IpTables est l'interface utilisateur permettant d'administrer les règles de Firewall implémentées au niveau d'un noyau Linux supportant NetFilter.


Quelques rappels :


Scripts présentés :

Les trois scripts présentés ont les caractéristiques suivantes :


Ils pourraient par exemple être utilisés sur la distribution Debian Woody avec l'interface IpTables et le support noyau NetFilter.

custom_net.sh :

#!/bin/sh

### NETWORK CUSTOMIZATION

echo "0" > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
echo "60" > /proc/sys/net/ipv4/ip_default_ttl
# Don't forget this script is for a gateway !
echo "1" > /proc/sys/net/ipv4/ip_forward

ZERO_FLAGS="accept_redirects accept_source_route proxy_arp send_redirects";
ONE_FLAGS="rp_filter log_martians";
CHEMIN="/proc/sys/net/ipv4/conf";

for repert in `ls "$CHEMIN"` ; do
  for fichier in `echo "$ZERO_FLAGS"`; do
    if [ -e "$CHEMIN/$repert/$fichier" ]
      then
        echo "0" > "$CHEMIN/$repert/$fichier";
      fi
  done
  for fichier in `echo "$ONE_FLAGS"`; do
    if [ -e "$CHEMIN/$repert/$fichier" ]
      then echo "1" > "$CHEMIN/$repert/$fichier"; fi
    done
done

Iptables_rules_down.sh :

#!/bin/sh

IPT=/sbin/iptables

### CHECK KERNEL VERSION AND BINARY PRESENCE

if [ ! -f $IPT ] && [ ! -x $IPT ] ; then exit 0 ; fi
CHECK=`$IPT -L -n 2>&1 > /dev/null || echo "bad"`
if [ "$CHECK" ]
  then
    echo "$0 : Not with this kernel"
    exit 0
fi

### VARIABLES

DEFAULT_POL="INPUT OUTPUT FORWARD" # Default policies

### BEGIN

# Flush and remove all chains then default the policies to ACCEPT
$IPT -F
$IPT -X
for i in $DEFAULT_POL
  do
    $IPT -P $i ACCEPT
done

echo "$0 done"

Iptables_rules_up.sh :

#!/bin/sh

#
# Firewall pour passerelle : Iptables - v1.0
# http://www.entreelibre.com/simsim/fws/station_iptables.html
#
# Rappel de quelques commandes :
#
# iptables -t [Table] -L [Chaine] -n --line-numbers => Affiche les politiques et
# regles activees (de la chaine concernee dans la table concernee).
# iptables -t [Table] -D Chaine Num_de_regle => Efface la regle Num_de_regle
# dans la chaine Chaine de la table Table.
# iptables-save > iptables_rules.txt => Sauvegarde les regles au format IpTables
# dans le fichier iptables_rules.txt.
# iptables-restore < iptables_rules.txt => Charge en memoire (en ajout et non en
# remplacement) le fichier de regles au format Iptables iptables_rules.txt
#

IPT=/sbin/iptables

### CHECK KERNEL VERSION AND BINARY PRESENCE

if [ ! -f $IPT ] && [ ! -x $IPT ] ; then exit 0 ; fi
CHECK=`$IPT -L -n 2>&1 > /dev/null || echo "bad"`
if [ "$CHECK" ]
  then
    echo "$0 : Not with this kernel"
    exit 0
fi

### Set OUR value to the printk variable
echo "6 4 1 7" > /proc/sys/kernel/printk

### NETWORK CUSTOMIZATION

test -f /home/system/fw/custom_net.sh && test -x /home/system/fw/custom_net.sh && /home/system/fw/custom_net.sh

### VARIABLES

EXTIF="ppp0" # External Interface
INTIF="eth0" # Internal Interface

# Personal Chains and default policie
DEFAULT_POL="INPUT OUTPUT FORWARD"
LOG_ACCEPT="LogAccept"
LOG_DROP="LogDrop"
LOOPBACK="DLoopBack"
CHECK_TCP="DCheckTcp"

NOROUTEIPS="127.0.0.1/8 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8 224.0.0.0/16"

# Internal addresses
ADM_IP="10.1.1.77" # Ip Address of the internal administration station service
ADM_PORT="22" # Tcp port of the internal administration station service

DNS_IP="10.1.1.10 10.1.1.11"
PROXY_IP="10.1.1.20 10.1.1.21"
MAIL_IP="10.1.1.30 10.1.1.31"

# Internal addresses allowed for masquerading...
INTERN_IP="10.1.1.10 10.1.1.11 10.1.1.20 10.1.1.21 10.1.1.30 10.1.1.31 10.1.1.77"

# External Addresses
SMARTMAILER="A B C"
SMARTDNS="D E F"
### Uncomment and set if you allow that kind of functionality
#SMARTFTPS="G H I"

# Ports
GP_SSH="22"
GP_MAIL="25 110"
GP_DNS="53"
GP_WEB="80 443"
GP_FTPDATA="20"
GP_FTP="21"

# Various
RPORTS=":1024"
NRPORTS="1024:"

### BEGIN

# Flush and remove all chains then default the policies to DROP
$IPT -F -t filter
$IPT -F -t nat
$IPT -X
for i in $DEFAULT_POL
  do
    $IPT -P $i DROP
done

### Create and set personnal chains

# Log and accept chain
$IPT -N $LOG_ACCEPT # Create a new one
$IPT -A $LOG_ACCEPT -j LOG --log-prefix 'Packet log '$LOG_ACCEPT' ' --log-tcp-options --log-ip-options --log-level 7 # Log and accept
$IPT -A $LOG_ACCEPT -j ACCEPT

# Log and drop chain
$IPT -N $LOG_DROP # Create a new one
$IPT -A $LOG_DROP -j LOG --log-prefix 'Packet log '$LOG_DROP' ' --log-tcp-options --log-ip-options --log-level 7 # Log and drop
$IPT -A $LOG_DROP -j DROP

# Check valid tcp connections chain
$IPT -N $CHECK_TCP
$IPT -A $CHECK_TCP -p tcp --tcp-flags SYN,ACK,FIN,RST SYN -m state --state NEW -j RETURN
$IPT -A $CHECK_TCP -p tcp ! --syn -m state --state ESTABLISHED -j RETURN
$IPT -A $CHECK_TCP -j LOG --log-prefix 'Packet log '$LOG_DROP'/Invalid ' --log-tcp-options --log-ip-options --log-level 7 # Log and drop
$IPT -A $CHECK_TCP -j DROP

# Accept chain on loopback (to get a cleaver 'iptables -L -n')
$IPT -N $LOOPBACK
$IPT -A $LOOPBACK -j ACCEPT

### LOOPBACK, TCP DEFAULT CHECK, LOGIN AND SECURITY

# Allow whatever on loopback
$IPT -A INPUT -i lo -j $LOOPBACK
$IPT -A OUTPUT -o lo -j $LOOPBACK

# Check TCP flags on related connections
$IPT -A INPUT -i $INTIF -p tcp -j $CHECK_TCP
$IPT -A OUTPUT -o $INTIF -p tcp -j $CHECK_TCP
$IPT -A INPUT -i $EXTIF -p tcp -j $CHECK_TCP
$IPT -A OUTPUT -o $EXTIF -p tcp -j $CHECK_TCP

# Logging and denying these strange events
for i in $NOROUTEIPS
  do
    # No source private address coming from the outside
    $IPT -A INPUT -i $EXTIF -s $i -j $LOG_DROP
    # No source private address going outside
    $IPT -A OUTPUT -o $EXTIF -s $i -j $LOG_DROP
    # Not going to destination private address
    $IPT -A OUTPUT -o $EXTIF -d $i -j $LOG_DROP
done

# Logging and denying broadcast
$IPT -A INPUT -i $EXTIF -d 255.255.255.255 -j $LOG_DROP
$IPT -A OUTPUT -o $EXTIF -d 255.255.255.255 -j $LOG_DROP

### ALLOW THESE INCOMING CONNECTIONS FROM INTERNET

### Uncomment here if you allow external hosts to connect to this firewall box ?!?!?
## Allow inbound 22 tcp connections to this box on the 22 port (ssh ?)
#$IPT -A INPUT -i $EXTIF -p tcp --sport $NRPORTS --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
#$IPT -A OUTPUT -o $EXTIF -p tcp --sport 22 --dport $NRPORTS -m state --state ESTABLISHED -j ACCEPT

# Allow redirection to admin station from the outside
$IPT -A INPUT -i $EXTIF -p tcp --sport $NRPORTS --dport $GP_SSH -m state --state NEW,ESTABLISHED -j ACCEPT
$IPT -A OUTPUT -o $EXTIF -p tcp --sport $GP_SSH --dport $NRPORTS -m state --state ESTABLISHED -j ACCEPT
$IPT -t nat -A PREROUTING -i $EXTIF -p tcp --sport $NRPORTS --dport $GP_SSH -j DNAT --to-destination $ADM_IP:$ADM_PORT
$IPT -A FORWARD -i $EXTIF -o $INTIF -p tcp --sport $NRPORTS -d $ADM_IP --dport $ADM_PORT -m state --state NEW,ESTABLISHED -j ACCEPT
$IPT -A FORWARD -i $INTIF -o $EXTIF -p tcp -s $ADM_IP --sport $ADM_PORT --dport $NRPORTS -m state --state ESTABLISHED -j ACCEPT

### ALLOW THESE OUTGOING CONNECTIONS TO INTERNET

# Allow Smtp/Pop trafic to outside defined hosts
for i in $SMARTMAILER
  do
    for j in $GP_MAIL
        do
          $IPT -A OUTPUT -o $EXTIF -p tcp --sport $NRPORTS -d $i --dport $j -m state --state NEW,ESTABLISHED -j ACCEPT
          $IPT -A INPUT -i $EXTIF -p tcp -s $i --sport $j --dport $NRPORTS -m state --state ESTABLISHED -j ACCEPT
      done
done

# Allow Http/Https trafic to any webserver
for j in $GP_WEB
  do
    $IPT -A OUTPUT -o $EXTIF -p tcp --sport $NRPORTS --dport $j -m state --state NEW,ESTABLISHED -j ACCEPT
    $IPT -A INPUT -i $EXTIF -p tcp --sport $j --dport $NRPORTS -m state --state ESTABLISHED -j ACCEPT
done

# Allow SSH trafic to any SSHD server
$IPT -A OUTPUT -o $EXTIF -p tcp --sport $NRPORTS --dport $GP_SSH -m state --state NEW,ESTABLISHED -j ACCEPT
$IPT -A INPUT -i $EXTIF -p tcp --sport $GP_SSH --dport $NRPORTS -m state --state ESTABLISHED -j ACCEPT

# Allow DNS trafic to DNS defined servers
for i in $SMARTDNS
  do
    $IPT -A OUTPUT -o $EXTIF -p udp --sport $NRPORTS -d $i --dport $GP_DNS -m state --state NEW,ESTABLISHED -j ACCEPT
    $IPT -A INPUT -i $EXTIF -p udp -s $i --sport $GP_DNS --dport $NRPORTS -m state --state ESTABLISHED -j ACCEPT
done

### Uncomment if you allow FTP access to defined SMARTFTPS
### => Also uncomment and set SMARTFTPS at the beginning of the script.
## Allow Ftp trafic to the defined SMARTFTPS
#for i in $SMARTFTPS
#  do
#    # Commands channel
#    $IPT -A OUTPUT -o $EXTIF -p tcp --sport $NRPORTS -d $i --dport $GP_FTP -m state --state NEW,ESTABLISHED -j ACCEPT
#    $IPT -A INPUT -i $EXTIF -p tcp -s $i --sport $GP_FTP --dport $NRPORTS -m state --state ESTABLISHED,RELATED -j ACCEPT
#    # Data channel : Active FTP...
#    $IPT -A INPUT -i $EXTIF -p tcp -s $i --sport $GP_FTPDATA --dport $NRPORTS -m state --state NEW,ESTABLISHED -j ACCEPT
#    $IPT -A OUTPUT -o $EXTIF -p tcp --sport $NRPORTS -d $i --dport $GP_FTPDATA -m state --state RELATED,ESTABLISHED -j ACCEPT
#    # Data channel : Passive FTP...
#    $IPT -A OUTPUT -o $EXTIF -p tcp --sport $NRPORTS -d $i --dport $NRPORTS -m state --state NEW,ESTABLISHED -j ACCEPT
#    $IPT -A INPUT -i $EXTIF -p tcp -s $i --sport $NRPORTS --dport $NRPORTS -m state --state RELATED,ESTABLISHED -j ACCEPT
#done

### Uncomment here if you allow such kind of ICMP requests to be sent...
## Allow that kind of ICMP packets
#$IPT -A OUTPUT -o $EXTIF -p icmp --icmp-type echo-request -m state --state NEW -j ACCEPT
#$IPT -A INPUT -i $EXTIF -p icmp --fragment -j DROP
#$IPT -A INPUT -i $EXTIF -p icmp --icmp-type destination-unreachable -j ACCEPT
#$IPT -A INPUT -i $EXTIF -p icmp --icmp-type time-exceeded -m state --state RELATED -j ACCEPT
#$IPT -A INPUT -i $EXTIF -p icmp --icmp-type echo-reply -m state --state ESTABLISHED,RELATED -j ACCEPT

### ALLOW THESE OUTGOING CONNECTIONS TO THE LAN

# Allow SSH anywhere on the LAN
$IPT -A OUTPUT -o $INTIF -p tcp --sport $NRPORTS --dport $GP_SSH -m state --state NEW,ESTABLISHED -j ACCEPT
$IPT -A INPUT -i $INTIF -p tcp --sport $GP_SSH --dport $NRPORTS -m state --state ESTABLISHED -j ACCEPT

### Uncomment here if you allow such kind of ICMP requests to be sent...
## Allow that kind of ICMP packets
#$IPT -A OUTPUT -o $INTIF -p icmp --icmp-type echo-request -m state --state NEW -j ACCEPT
#$IPT -A INPUT -i $INTIF -p icmp --fragment -j DROP
#$IPT -A INPUT -i $INTIF -p icmp --icmp-type destination-unreachable -j ACCEPT
#$IPT -A INPUT -i $INTIF -p icmp --icmp-type time-exceeded -m state --state RELATED -j ACCEPT
#$IPT -A INPUT -i $INTIF -p icmp --icmp-type echo-reply -m state --state ESTABLISHED,RELATED -j ACCEPT

### ALLOW THESE INCOMING CONNECTIONS FROM THE LAN

# Allow remote management from the admin station
$IPT -A INPUT -i $INTIF -p tcp -s $ADM_IP --sport $NRPORTS --dport $GP_SSH -m state --state NEW,ESTABLISHED -j ACCEPT
$IPT -A OUTPUT -o $INTIF -p tcp --sport $GP_SSH -d $ADM_IP --dport $NRPORTS -m state --state ESTABLISHED -j ACCEPT

### NAT AND FORWARD THESE INTERNAL STATIONS USING THE OUTSIDE IP ADDRESS

# Masquerading rule
for k in $INTERN_IP
  do
    $IPT -t nat -A POSTROUTING -s $k -o $EXTIF -j MASQUERADE
done

# Allowing services for the defined internal stations...
for k in $INTERN_IP
  do

    # Allow Smtp/Pop trafic to outside defined hosts
    for i in $SMARTMAILER
       do
         for j in $GP_MAIL
           do
             for k in $MAIL_IP
               do
                 $IPT -A FORWARD -i $INTIF -o $EXTIF -p tcp -s $k --sport $NRPORTS -d $i --dport $j -m state --state NEW,ESTABLISHED -j ACCEPT
                 $IPT -A FORWARD -i $EXTIF -o $INTIF -p tcp -s $i --sport $j -d $k --dport $NRPORTS -m state --state ESTABLISHED -j ACCEPT
           done
       done
    done
    
    # Allow Http/Https trafic to any webserver
     for i in $PROXY_IP
       do
         for j in $GP_WEB
           do
             $IPT -A FORWARD -i $INTIF -o $EXTIF -p tcp -s $i --sport $NRPORTS --dport $j -m state --state NEW,ESTABLISHED -j ACCEPT
             $IPT -A FORWARD -i $EXTIF -o $INTIF -p tcp --sport $j --dport $NRPORTS -d $i -m state --state ESTABLISHED -j ACCEPT
       done
     done
    
    # Allow SSH trafic to any SSHD server
    $IPT -A FORWARD -i $INTIF -o $EXTIF -p tcp --sport $NRPORTS --dport $GP_SSH -m state --state NEW,ESTABLISHED -j ACCEPT
    $IPT -A FORWARD -i $EXTIF -o $INTIF -p tcp --sport $GP_SSH --dport $NRPORTS -m state --state ESTABLISHED -j ACCEPT
    
    # Allow DNS trafic to DNS defined servers
     for i in $DNS_IP
       do
         for j in $SMARTDNS
           do
             $IPT -A FORWARD -i $INTIF -o $EXTIF -p udp -s $i --sport $NRPORTS -d $j --dport $GP_DNS -m state --state NEW,ESTABLISHED -j ACCEPT
             $IPT -A FORWARD -i $EXTIF -o $INTIF -p udp -s $j --sport $GP_DNS --dport $NRPORTS -d $i -m state --state ESTABLISHED -j ACCEPT
         done
     done
    
done

### AND LAST : LOG AND DENY

for i in $DEFAULT_POL
do $IPT -A $i -j $LOG_DROP ; done

echo "$0 done"

Simon Castro
Maj le 02 Novembre 2003