Mise en place du firewall ipfw

Un article de DocAstairs.

Sommaire

[modifier] Choix du firewall

Freebsd possède nativement 3 type de firewall :

  • PF (Packet Filter) : le firewall de OpenBSD
  • IPF (IPFILTER)
  • IPFW (IPFIREWALL) le Firewall développé par FreeBSD

Perso, je suis pas une tête en réseau donc système D. On se documente comme on peut, on essaye de comprendre, on mélange et on regarde ce qui se passe...

Je me suis penché ipfw qui me semble être un bonne alternative pour ce système et pas trop trop compliqué à mettre en place. C'est LE firewall de FreeBSD, et c'est également de firewall de base sur mac os (comme quoi il doit pas être si mauvais que ça ;).

[modifier] mise en place

Bon, alors pour activer le firewall, la première chose à faire est d'activer le module dans le noyau (cf: la compilation du kernel, toutes les options nécessaires y sont). Ensuite, dans /etc/rc.conf ajouter les lignes suivantes :

firewall_enable="YES"     #lancement automatique du firewall
firewall_logging="YES"    #on autorise ipfw à faire ses petits log dans son coin tranquillement
firewall_script="/etc/ipfw.rules" (ou un autre nom... peu importe)    #on précise un fichier dans lequel on placera nos règles

Remarque : Alors à la place de firewall_script="...", on peut utiliser l'option firewall_type="...", mais cela implique une petite nuance dans la rédaction du fichier.

[modifier] Ma configuration pour un serveur web

Le but du jeu et de pouvoir :

  • Utiliser le loopback sans restriction vers lui même
  • Éliminer les packets broadcastés
  • Permettre la résolution de noms de domaines
  • Autoriser les commandes systèmes (Pour les mises à jour par exemple)
  • Permettre l'accès aux services (http, ssh, ...)

Voici mon fichier de config (je l'ai scindé en deux parties, un fichier contenant les variables et un autre configurant les règles).

  • fichier contenant les variables
#!/bin/sh
# definition des variables utilisees dans les regles du firewall

# commande invoquer pour ajouter des regles au firewall
fwcmd="/sbin/ipfw -q add" #commande du firewall

# interface publique
pif="de0"
imask="255.255.255.0" #masque
loopback="127.0.0.0/8" #adresse du loopback

# recuperation des dns du fichier /etc/resolv.conf
ns_tmp=`grep nameserver /etc/resolv.conf|awk '{ print  $2}'`
set $ns_tmp
dns=$*
  • fichier de construction des règles de firewall
#!/bin/sh
# fichier de regles pour le firewall ipfw

# recuperer le fichier de configuration afin de savoir
# ce qui est lance au demarrage
if [ -z "${source_rc_confs_defined}" ]; then
    if [ -r /etc/defaults/rc.conf ]; then
	. /etc/defaults/rc.conf
	source_rc_confs
    elif [ -r /etc/rc.conf ]; then
	. /etc/rc.conf
    fi
fi

# Definition des variables
if [ -r /etc/ipfw.var ]; then
    . /etc/ipfw.var
else
    echo "Fichier de variables introuvable"
    exit 0
fi

# Debut de la construction des regles du firewall

# vidage des regles
/sbin/ipfw -q -f flush

## regles sur le loopback ##
# pas de restriction du loopback vers loopback
$fwcmd allow all from any to any via lo0

# on refuse les autres vers le loopback et reciproquement
$fwcmd deny all from any to $loopback
$fwcmd deny ip from $loopback to any

# verifier l etat de tous les packets
$fwcmd check-state

# Rejet du broadcast
$fwcmd 3000 deny ip from any to 0.0.0.255:0.0.0.255 in via $pif

# permetre la resolution de domaines
for ip_ns in $dns
do
    $fwcmd allow tcp from any to $ip_ns 53 out via $pif setup keep-state
    $fwcmd allow udp from any to $ip_ns 53 out via $pif keep-state
done

# permettre les fonctionnalites systeme de freebsd (installation des ports, mises a jour, etc)
$fwcmd allow tcp from me to any out via $pif setup keep-state uid root

## regles dependantes des services lances ##
#utilisation de webmin pour mon poste
    $fwcmd allow tcp from 192.168.1.203 to me dst-port 10000 in via $pif setup keep-state
    $fwcmd allow tcp from me to any dst-port 25 via $pif setup keep-state

# ssh
case ${sshd_enable} in
[Yy][Ee][Ss])
    #$fwcmd allow tcp from 192.168.1.203 to me dst-port 22 in via $pif setup keep-state
    $fwcmd allow tcp from any to me dst-port 22 in via $pif setup keep-state
    ;;
esac

# apache
case ${apache22_enable} in
[Yy][Ee][Ss])
    $fwcmd allow tcp from any to me dst-port 80 in via $pif setup keep-state
    $fwcmd allow tcp from any to me dst-port 443 in via $pif setup keep-state
    ;;
esac

# ntp
case ${ntpdate_enable} in
[Yy][Ee][Ss])
    $fwcmd pass udp from me to any 123 keep-state
    ;;
esac

# refuser et logger tout le reste
$fwcmd deny log all from any to any

[modifier] Vérification du bon fonctionnement

Voilà, une foi le fichier de règle créé, il suffit de recharger le fichier rc.conf

root@freebsd#shutdown now

On affiche les règles avec cette commande

root@freebsd#ipfw -ad list
00100    96  100030 allow ip from any to any via lo0
00200     0       0 deny ip from any to 127.0.0.0/8
00300     0       0 deny ip from 127.0.0.0/8 to any
00400     0       0 check-state
03000 14223 1889076 deny ip from any to 0.0.0.255:0.0.0.255 in via de0
03100     0       0 allow tcp from any to 192.168.1.254 dst-port 53 out via de0 setup keep-state
03200   746   86565 allow udp from any to 192.168.1.254 dst-port 53 out via de0 keep-state
03300     0       0 allow tcp from any to 192.168.1.254 dst-port 53 out via de0 setup keep-state
03400     0       0 allow udp from any to 192.168.1.254 dst-port 53 out via de0 keep-state
03500   361   61991 allow tcp from me to any out via de0 setup uid root keep-state
03600   456   68594 allow tcp from any to me dst-port 22 in via de0 setup keep-state
03700     6     256 allow tcp from any to me dst-port 80,443 in via de0 setup keep-state
03800     0       0 allow udp from me to any dst-port 123 keep-state
03900    14     716 deny log logamount 100 ip from any to any
65535     0       0 allow ip from any to any
## Dynamic rules (167):
...ici, les règles dynamiques
  • l'option -a permet d'afficher le nombre de fois ou la règle est appelée.
  • l'option -d permet d'afficher les règles dynamiques

Testez votre firewall avec une autre machine en faisant un petit scan avec nmap par exemple :

root@freebsd(alt)#nmap -v -sV -O 192.168.1.185