Les Firewalls à l'AUF

C'est quoi un parefeu

C'est un matériel ou un logiciel qui permet de filtrer les échanges d'informations entre plusieurs (>1) réseaux. Typiquement qu'est-ce qui a le droit d'entrer ou de ne pas entrer, qu'est-ce qui a le voir de sortir ou de ne pas sortir. Pour faire cela, il se sert des caractéristiques des flux de communications : Par exemple l'éméteur, le déstinataire, le portocole, les ports, etc.

Ce qu'il fait

Il filtre les échanges entres plusieurs interfaces réseaux. Ces réseaux pouvant être internes ou externes ;) Merci WillyManga

Ce qu'il ne fait pas

Protéger des virus, surveiller les communication à l'interne d'un réseau,

Iptables

C'est juste l'outil permettant de configurer le comportement de netfilter qui est en fait le service de filtrage qui est directement implémenté dans le noyeau linux. Netfilter permet d'intercepter et de manipuler les paquets réseaux sur une machine linux. Il prévoit certain points de contrôle (hooks) au niveau desquels diverses opérations (cibles) sont possibles.

Une règle est un ensemble de caractéristiques permettant de sélectionner des paquets (tests de concordance) et de leur appliquer une action (cible). Iptables permet de configurer le comportement de netfilter au niveau de ces "hooks" grâce à des options permettant de contrôler finement netfilter :

Option

Fonction

-L

Affiche toutes les règles de la chaîne indiquée

-F

Supprime toutes les règles de la chaîne. Si aucune chaîne n'est spécifiée, toutes celles de la table sont vidées

-N

Crée une nouvelle chaîne utilisateur avec le nom passé en paramètre

-X

Supprime la chaîne utilisateur. Si aucun nom n'est spécifié, toutes les chaînes utilisateur seront supprimées

-P

Modifie la politique par défaut de la chaîne (Celle qui est appliquée quand aucune règle n'est applicable). Il faut indiquer en plus comme paramètre la cible à utiliser.

-A

Ajoute une règle à la fin de la chaîne spécifiée

-I

Insère la règle avant celle indiquée. Cette place est précisée par un numéro qui fait suite au nom de la chaîne. La première porte le numéro 1. Si aucun numéro n'est indiqué, la règle est insérée au début

-D

Supprime une règle de la chaîne. Soit un numéro peut être précisé, soit la définition de la chaîne à supprimer (ses tests de concordance et sa cible)

-j

Indique l'action à effectuer (cible) pour la règle

-t

Indique la table sur laquelle va s'appliquer la règle. par défaut quand rien n'est indiqué, c'est sur filter

D'autres options sont disponibles et servent à caractériser les flux de communications à sélectionner et les actions à effectuer.

Fonctionnement de netfilter

La machine d'état (conntrack)

La machine d'état permet au sein de netfilter de suivre l'état des connexions et de pouvoir ainsi faire du filtrage dessus. Elle est accessible grâce à l'option "-m state --state" qui permet de spécifier l'état de la connexion. Les valeurs possible sont :

Les chaines

Plusieurs scénarios peuvent être envisagées pour un paquet sur un parefeu :

Quelque soit le cas de figure, un paquet doit traverser un certain nombre d'étapes avant d'être délivré. Les divers endroits où il est possible d'intercepter et de modifier sur un paquet sont les "hooks". Une chaine désigne la méthode de contrôle applicable en un "hook". Les chaines disponibles par défaut sont les suivantes :

Chaque paquet réseau, entrant ou sortant, traverse donc au moins une de ces chaînes. Au niveau de chaque chaine, un certain nombre d'actions est possible. Ces actions se trouvent regroupées en "tables"

Les tables

Netfilter définit un certain nombre d'actions possibles sur un flux de données. Ces actions peuvent être regroupées en 4 grandes catégories d'actions appellées "table". Ainsi :

Il existe d'autres cibles qui ne sont pas associées à une table particulière. C'est le cas de :

Passage dans les chaines

Trois cas de figures sont envisageables. Il est également possible de généraliser l'ordre de passage dans les tables. La table "raw" sera toujours rencontré avant "mangle" qui sera toujours rencontré si applicable avant "nat" qui sera toujours rencontré avant "filter" et ce au niveau de chaque chaine.

Expéditeur externe vers hôte local

Etapes

CHAINE

table

Commentaires

1

sur le câble

2

arrivée sur l'interface réseau

3

PREROUTING

raw

Cette chaîne sert normalement à modifier les paquets, i.e. changer les bits de TOS, etc.

4

Contrôle du code de connexion

5

PREROUTING

mangle

Modification des paquets

6

PREROUTING

nat

Ici on peut changer le destinataire d'un paquet : DNAT

7

Décision de routage

8

INPUT

mangle

Modification du paquet avant qu'il ne soit envoyé au processus de l'hôte

9

INPUT

filter

Filtrage du paquet. On le laisse passer ou pas

10

Livraison du paquet aux processus locaux

Hôte local vers destinataire externe

Etapes

CHAINE

table

Commentaires

1

Processus local

2

Décision de routage : Est-ce que le paquet doit sortir de la machine ou pas ?

3

OUTPUT

raw

Activation ou désactivation du traçage de connexion

4

Prise en charge par conntrack

5

OUTPUT

mangle

Modification des paquets

6

OUTPUT

nat

Translation d'adresse : DNAT, SNAT ou MASQUERADE sur les paquets sortants du parefeu

7

Décision de routage

8

OUTPUT

Filter

Filtrage du paquet. On le laisse passer ou pas

9

POSTROUTING

nat

On peut modifier l'adresse de l'expéditeur ici : SNAT

10

Interface réseau pour envoi

Expéditeur externe vers destinataire externe

Etapes

CHAINE

table

Commentaires

1

Média de transmission

2

Arrivée sur interface

3

PREROUTING

raw

Activation ou désactivation du traçage de connexion

4

Prise en charge par conntrack

5

PREROUTING

mangle

Modification des paquets

6

PREROUTING

nat

Modification de l'adresse du destinataire : DNAT

7

Décision de routage

8

FORWARD

mangle

Modification particulière des paquets avant la décision finale de routage

9

FORWARD

filter

Filtrage des paquets? Ils traversent ou pas

10

POSTROUTING

mangle

Dernière chance de modification du paquet avant son envoi

11

POSTROUTING

nat

Modification de l'adresse de l'expéditeur: SNAT ou MASQUERADE

12

Arrivée sur l'interface réseau

13

Expédition vers le destinataire

Types de configuration

Il existe 2 façons de voir la mise en place d'un pare-feu :

On ouvre tout et on ferme au cas par cas

Option dangereuse à mon avis personnel (C'est discutable). Elle consiste simplement à passer la cible de filter par défaut à ACCEPT sur INPUT, OUTPUT et FORWARD. C'est largement suffisant. Ensuite au fur et à mesure de la découverte des failles, on ferme. A mettre en place dans un environnement sécurisé.

On ferme tout et on ouvre au cas par cas

Option préférée. On en fait confiance qu'à ceux qu'on connait et encore. Cela se traduit par passer la cible de filter par défaut à REJECT ou DROP sur INPUT, OUTPUT et FORWARD. Ensuite on fait des ACCEPT au cas par cas en prenant soin de mettre le plus de descripteurs possibles.

Nous à l'AUF on a choisi la seconde méthode. Enfin ce n'est pas une obligation, mais plus une recommandation. Chacun est libre de faire ce qui lui est le plus simple dans son contexte.

Application des règles

Taper les règles à la main

Il est possible de taper les règles directement en ligne de commande les unes à la suite des autres au fur et à mesure. Mais dans ce cas, il faut faire attention à ne pas perdre la main à la suite de l'effacement des règles et de l'application de la cible par défaut "DROP" (voir un peu plus loin).

Faire un fichier de script

Il est également possible d'inscrire toutes les règles dans un fichier et de l'exécuter en une fois. C'est le ce cas qui est l'usage à l'AUF. Dans le second cas, le fichier est lu de façon séquentiel i.e. les paquets parcourent les règles dans l'ordre dans lequel ils sont inscrits dans le fichier et à moins d'instructions contraires, sont interceptés par la première règle dont les critères de sélection correspondent aux propriétés du paquet. Ainsi mettre une règle moins précise avant une autre plus précise empêche l'exécution de cette dernière. Exemple :

/sbin/iptables -p icmp -j ACCEPT
/sbin/iptables -p icmp -i eth0 -d xx.xx.xx.xx -j REJECT

Entrée dans cet ordre, la dernière règle ne sera jamais exécutée (les paquets à destination de la machine xx.xx.xx.xx ne seront jamais rejetées) car les paquets seront déjà interceptés par la première qui est une règle plus générale. Enfin, il est possible d'utiliser des variables comme dans des scripts shell classiques, ce qui simplifie drôlement la lecture du fichier et sa maintenance.

Configuration type

Now, quand on configurer son netfilter, il est bon de faire le bilan les types de trafic qui circulent et les services. Typiquement dans chaque CNF, nous avons une séparation du réseau en trois parties :

Les exemples suivant vont permettre de configurer notre parefeu qui est au coeur de tout cela. Nous fermerons tout et nous ouvrions au cas par cas

On établit le comportement par défaut

/sbin/iptables -P INPUT DROP
/sbin/iptables -P OUTPUT DROP
/sbin/iptables -P FORWARD DROP

Pour rappel si on bloque tout le trafic sur filter, rien ne passera même si on ne précise rien sur les autres tables. Ensuite, il faut toujours mettre ces règles avant toutes autres configurations, car cela permet de fixer le comportement par défaut et d'éviter de laisser passer des traffics indésirables avant que les règles particulières ne soient mises en application. Donc notre cas, on supprime tous les paquets sans notifications.

Effacements des anciennes règles en vigueur

/sbin/iptables -F
/sbin/iptables -X
/sbin/iptables -t nat -F
/sbin/iptables -t nat -X
/sbin/iptables -t mangle -F
/sbin/iptables -t mangle -X

On vide avec "-F" les chaines et avec "-X" les chaines personnelles que nous aurions pu créer. Comme cela on est vraiment sûr d'avoir fait le ménage. Par contre après ces règles, seuls les comportements pas défaut s'appliquent. En d'autres termes, tout est bloqué, tous les accès … y compris celui en cours ...

Autoriser les connexions établies

Ici on fait direcetement appel à la machine d'état. Si une connexion est déjà autorisée, où une connexion relative à une connexion établie alors, on l'accepte. C'est plus simple pour la suite comme dans le cas de protocoles comme FTP qui après que la connexion soit établie (sur le port 21 par exemple) peut ouvrir une nouvelle connexion sur un port aléatoire pour le transfert de données. ce qui s'avère problématique pour la gestion. D'un autre coté entrer ces règles en début de fichier permet de réduire le nombre de tests que le Netfilter doit effectuer avant d'intercepter ces types de paquet.

/sbin/iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
/sbin/iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
/sbin/iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT

"-m state --state" permet d'indiquer les états de connexions à sélectionner.

Configuration de ce qui entre et sort du FW

/sbin/iptables -A INPUT -i lo -j ACCEPT
/sbin/iptables -A OUTPUT -o lo -j ACCEPT

Il est à noter ici l'utilisation de "-i" (pour Input interface) et "-o" (pour Output interface) qui permet de sélectionner respectivement les interfaces en entrée et en sortie. "lo" désigne le loopback. Et puis sans cela, plus de connexions locales (login entre autres :D).

/sbin/iptables -A INPUT -p esp -j ACCEPT
/sbin/iptables -A OUTPUT -p esp -j ACCEPT
/sbin/iptables -A INPUT -p ah -j ACCEPT
/sbin/iptables -A OUTPUT -p ah -j ACCEPT

La directive "-p" permet d'autoriser des protocoles (tcp/udp/...)

/sbin/iptables -A INPUT -p icmp -m limit --limit 4/s -i eth0 -j ACCEPT
/sbin/iptables -A INPUT -p icmp -j ACCEPT
/sbin/iptables -A OUTPUT -p icmp -j ACCEPT

/sbin/iptables -A INPUT -p tcp --dport ssh -s [RESEAUAUF] -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport ssh -s [IPRTR] -j ACCEPT
/sbin/iptables -A INPUT -p tcp --dport ssh -s [IPRTL] -j ACCEPT

/!\ Notez l'utilisation avec la directive "--dport" d'un nom au lieu d'un numéro de port. Ce nom correspond au nom standardisé du service qui est sensé écouter sur ce port. La liste des noms de services et de leur port d'écoute est dans /etc/services

#DNS c'est très important en UDP et en TCP
/sbin/iptables -A OUTPUT -p udp --dport domain -j ACCEPT
/sbin/iptables -A OUTPUT -p tcp --dport domain -j ACCEPT
#Le web pour faire des requêtes apt
/sbin/iptables -A OUTPUT -p tcp --dport www -d [IPSQUID] -j ACCEPT
#On devrait pouvoir faire du ssh à partir du parefeu 
/sbin/iptables -A OUTPUT -p tcp --dport ssh -j ACCEPT
#Et le mail pour les alertes apticron mais uniquement à destination de notre serveur mail
/sbin/iptables -A OUTPUT -p tcp --dport smtp -d [IPMAIL] -j ACCEPT

Ce qui travaverse le parefeu

/sbin/iptables -A FORWARD -p icmp --icmp-type ping -m limit --limit 10/s -i eth0 -j ACCEPT
/sbin/iptables -A FORWARD -p icmp --icmp-type ping -j ACCEPT

/sbin/iptables -A FORWARD -s [IPBACKUP] -p tcp --dport rsync -j ACCEPT
/sbin/iptables -A FORWARD -s [IPBACKUP] -p tcp --dport ssh -j ACCEPT

/sbin/iptables -A FORWARD -p udp --dport domain -d [IPDNS] -j ACCEPT
/sbin/iptables -A FORWARD -p tcp --dport domain -d [IPDNS] -j ACCEPT

/sbin/iptables -A FORWARD -p tcp --dport smtp -d [IPMAIL] -j ACCEPT
/sbin/iptables -A FORWARD -p tcp --dport pop3 -d [IPMAIL] -j ACCEPT
/sbin/iptables -A FORWARD -p tcp --dport imap -d [IPMAIL] -j ACCEPT
/sbin/iptables -A FORWARD -p tcp --dport pop3s -d [IPMAIL] -j ACCEPT
/sbin/iptables -A FORWARD -p tcp --dport imaps -d [IPMAIL] -j ACCEPT
/sbin/iptables -A FORWARD -p tcp --dport smtps -d [IPMAIL] -j ACCEPT

/sbin/iptables -A FORWARD -p tcp --dport smtp -s [IPMAIL] -j ACCEPT
/sbin/iptables -A FORWARD -p tcp --dport smtps -s [IPMAIL] -j ACCEPT
/sbin/iptables -A FORWARD -p tcp --dport smtp -j LOG --log-prefix "SMTP-HORS-SERVEUR: " -m limit --limit 1/minute
/sbin/iptables -A FORWARD -p tcp --dport smtps -j LOG --log-prefix "SMTP-HORS-SERVEUR: " -m limit --limit 1/minute
/sbin/iptables -A FORWARD -p tcp --dport smtp -j REJECT
/sbin/iptables -A FORWARD -p tcp --dport smtps -j REJECT

Alors ici on note qu'on loggue la tentative d'envoi de mail par un autre serveur que le serveur smtp avant de mettre un reject.

/sbin/iptables -A FORWARD -p tcp --dport www -d [IPWEB] -j ACCEPT
/sbin/iptables -A FORWARD -p tcp --dport https -d [IPWEB] -j ACCEPT

/sbin/iptables -A FORWARD -i eth2 -s [IPPERSONNEL] -o ipsec+ -j ACCEPT

/!\ Ici il est intéressant de constater l'utilisation du "+" à la fin de "ipsec" qui permet de sélectionner toutes les interfaces dont le nom commencent par "ipsec".

/sbin/iptables -A FORWARD -d [IPVISIO] -j ACCEPT
/sbin/iptables -A FORWARD -s [IPVISIO] -j ACCEPT

# Le serveur proxy/cache doit pouvoir accéder à internet
# Il faut penser à rajouter tous les ports des protocoles qui sont proxysés
/sbin/iptables -A FORWARD -s [IPPROXY] -o eth0 -p tcp --dport www -j ACCEPT 
# Le serveur DNS doit pouvoir faire des requêtes sinon seuls les domaines locaux seront résolus
/sbin/iptables -A FORWARD -s [IPDNS] -o eth0 -p tcp --dport domain -j ACCEPT
# Le serveur de temps doit pouvoir se mettre à jour sur internet
/sbin/iptables -A FORWARD -s [IPNTP] -o eth0 -p tcp --dport ntp -j ACCEPT
# Le serveur nat doit pouvoir faire du ftp et du ftps vers des sites ftp pour les usagers qui en on besoin
/sbin/iptables -A FORWARD -s [IPNAT] -o eth0 -p tcp --dport ftp -j ACCEPT
/sbin/iptables -A FORWARD -s [IPNAT] -o eth0 -p tcp --dport ftps -j ACCEPT
# Les personnels également doit pouvoir aller où ils veulent  ...
/sbin/iptables -A FORWARD -s [IPPERSONNEL] -p tcp --dport ftp -j ACCEPT
/sbin/iptables -A FORWARD -s [IPPERSONNEL] -p tcp --dport ftps -j ACCEPT
/sbin/iptables -A FORWARD -s [IPPERSONNEL] -p tcp --dport http -j ACCEPT
/sbin/iptables -A FORWARD -s [IPPERSONNEL] -p tcp --dport https -j ACCEPT
/sbin/iptables -A FORWARD -s [IPPERSONNEL] -p tcp --dport pop -j ACCEPT
/sbin/iptables -A FORWARD -s [IPPERSONNEL] -p tcp --dport imap -j ACCEPT
/sbin/iptables -A FORWARD -s [IPPERSONNEL] -p tcp --dport pops -j ACCEPT
/sbin/iptables -A FORWARD -s [IPPERSONNEL] -p tcp --dport imaps -j ACCEPT
/sbin/iptables -A FORWARD -s [IPPERSONNEL] -p tcp --dport pop -j ACCEPT
# Pour le messenger jabber
/sbin/iptables -A FORWARD -s [IPPERSONNEL] -p tcp --dport 5222 -j ACCEPT
# Autoriser le forward de nos reseaux pour la redirections squid (voir plus bas)
/sbin/iptables -A FORWARD -s [IPPERSONNEL] -p tcp --dport 3128 -j ACCEPT

/sbin/iptables -A FORWARD -p tcp --dport ssh -s [IPRTL] -j ACCEPT

Les NATs et autres redirections squid

# Théoriquement le proxy ne doit pas avoir accès à l'intranet, donc exclure les paquets qui sont à destination de l'intranet
/sbin/iptables -t nat -A PREROUTING -d [RESEAUAUF] -p tcp --dport www -j RETURN
# Inutile d'activer le proxy pour les des communications à destination des machines de notre DMZ. Cette règle est pour les paquets sortant du pare-feu lui même /!\ les avis divergent ici !!
/sbin/iptables -t nat -A OUTPUT -d $IPDMZ -p tcp --dport www -j RETURN
# Enfin exclure le proxy lui même du processus. Cela ce fait grâce au RETURN qui l'empêche les paquets venant du proxy de continuer dans la table nat
/sbin/iptables -t nat -A PREROUTING -s [IPPROXY] -p tcp --dport www -j RETURN
# On redirige enfin tous les paquets DMZ allant vers internet sur le squid. /!\ On intervient avant que la décision de routage ne soit prise
/sbin/iptables -t nat -A PREROUTING -s [IPDMZ] -p tcp --dport www -j DNAT --to-destination [IPPROXY]:3128
# Permettre au personnel d'utiliser squid
/sbin/iptables -t nat -A PREROUTING -s [IPPERSONNEL] -p tcp --dport www -j DNAT --to-destination [IPPROXY]:3128
# Enfin pour le pare-feu lui même 
/sbin/iptables -t nat -A OUTPUT -p tcp --dport www -j DNAT --to-destination [IPPROXY]:3128
# Sans cette règles le proxy renverra les réponses directement aux serveurs de la DMZ qui la rejetteront. C'est possible de faire autrement en obligeant le proxy à renvoyer les requêtes venant de la DMZ au FW ou en sortant le proxy de la DMZ pour le mettre derrière le FW 
/sbin/iptables -t nat -A POSTROUTING -s [IPDMZ] -p tcp --dport 3128 -j SNAT --to-source [IPFW]

On remarque ici qu'on change la destination et le port de destination en même temps avec "-j DNAT --to-destination"

$IPT -t nat -A POSTROUTING -s [IPRPV] -o eth0 -j SNAT --to-source [IPFW]

Finalisation des règles

* Enfin, on bloque tout !!!

$IPT -A INPUT -j LOG --log-prefix "INPUT: "
$IPT -A INPUT -j REJECT

$IPT -A OUTPUT -j LOG --log-prefix "OUTPUT: "
$IPT -A OUTPUT -j REJECT

$IPTF -j LOG --log-prefix "FORWARD: "
$IPTF -j REJECT

-j LOG --log-prefix permet d'ajouter une entête avant l’évènement loggué

ZAO/Projets/DocumentationFW (dernière édition le 2014-11-10 12:45:18 par FranckKouyami)