Configurer un firewall avec ipchains |
||
|
Cette page n'a pas pour objet de vous présenter une configuration sécurisée infaillible, ce serait un brin prétentieux, elle a plus pour but de présenter la mise en place d'une protection suffisamment simple et efficace pour stopper au moins 90% des attaques. On peut en effet considérer que plus de 90% des attaques sont l'action d'apprentis hackers, le pourcentage restant étant l'action d'hackers "professionnels" (si tenter qu'on puisse leur préter ce terme), de toute façon si vous êtes un simple particulier, il y a peu de risque que vous soyez un jours une victime de cette dernière catégorie, ça n'a rien de très prestigieux...
L'exemple de configuration des règles de filtrage d'ipchains s'applique à une arborescence type Red Hat (et donc Mandrake).
NOTE: Je prépare un script pour ceux qui ont une connection permanente (ADSL, câble), un peu de patience.
Ipchains est un outil disponible sur linux qui permet de filtrer les paquets, en fait celui-ci est plus ou moins intégré au noyau (supérieur à 2.2.X), pour l'installation je vous conseille de vous reporter au ipchains-HOWTO.
NOTE: Pour plus d'info sur la notion de paquet se reporter à mon cours réseau.
Les points d'entrée sortie pour les paquets sur le poste linux
sont appelés interfaces, la liste des interfaces est:
- carte réseau pour le réseau interne (eth0),
- interface loopback (ou lo en abrégé), c'est
une interface réseau virtuelle, tout paquet envoyé d'un processus
local à un autre processus local passe par cette interface,
- interface réseau externe, c'est l'interface réseau
créé lors d'une connexion par PPP (ppp0),
- interface réseau "remote", c'est l'interface réseau
créé par le FAI lors d'une connexion, caractérisée
par une adresse IP dynamique (pas forcément la même à
chaque connexion).
Il existe un certain nombre de possibilités pour le chemin que
peut suivre un paquet, voici quelques exemples:
- le paquet arrive sur la carte réseau (eth0) pour aller
sur une machine du réseau local, il passe par la chaîne input
en empruntant l'interface eth0, il est transmis s'il convient à
la chaîne forward, et passe en final par la chaîne output
qui décidera si le paquet peut repartir par l'interface eth0,
- le paquet arrive sur la carte réseau (eth0) pour rester
en local, on passe par la chaîne input, puis le paquet est
transmis en local (chaîne forward),
- le paquet est envoyé en local pour aller sur une machine du
réseau local (eth0), on passe par la chaîne forward
de transmission puis par la chaîne output en empruntant l'interface
eth0,
- le paquet est crée en local et reste en local (cas de processus
locaux), le paquet passe la chaîne input en utilisant l'interface
lo,
et transmis (chaîne forward), pour aller ensuite à
la chaîne output toujours en utilisant l'inteface
lo,
- le paquet arrive sur la carte réseau (eth0) pour aller
sur le net, le paquet passe par la chaîne input en utilisant
l'interface eth0, est transmis à la chaîne forward,
puis passe par la chaîne output en utilisant l'interface externe
(ppp0),
- le paquet arrive du net (ppp0) pour aller sur le réseau
local, le paquet passe par la chaîne input en utilisant l'interface
ppp0,
est transmis par la chaîne forward, puis passe par la chaîne
output
en utilisant l'interface réseau interne (eth0),
Voilà et j'en oublie sûrement d'autres, vous voyez que
les configurations pour le passage des paquets peuvent être multiples,
dans la configuration d'ipchains, vous devez veiller à ne
pas oublier un cas.
Les options dont nous allons nous servir pour ipchains sont les suivantes:
-P (Policy) pour changer la police d'une chaîne
(ACCEPT, DENY, REJECT),
-L (List) lister les règles d'une chaîne
ainsi que la police,
-F supprimer les règles d'une chaîne (la police
n'est pas supprimée),
-A (Add) rajoute une nouvelle règle à une
chaîne,
Pour les autres options reportez vous toujours au ipchains-HOWTO voire au man d'ipchains. Nous n'allons pas créer d'autres chaînes, les chaînes existantes sont largement suffisantes, nous n'allons que modifier leur police et rajouter des règles. La syntaxe pour modifier la police est la suivante:
ipchains -F input REJECT
Dans cet exemple la police de la chaîne input sera REJECT, c'est à dire qu'on rejette tous les paquets entrants (et qu'on avertit l'expéditeur). La syntaxe pour rajouter une règle est la suivante
ipchains -A chaîne -i interface -s source -d destination -j police
Ce qui signifie que les paquets provenant de l'expéditeur source en passant par l'interface interface à destination de destination seront traités suivant la police de la chaîne (police). Les différentes syntaxes sont:
Pour les chaînes par défaut:
- input
-output
- forward
Pour l'interface:
- eth0 (interface interne)
- ppp0 (interface externe)
- adresse IP dynamique (interface remote)
- lo (interface loopback)
Pour la source ou la destination, la syntaxe est la suivante:
- 0.0.0.0/0 pour spécifier n'importe quelle adresse
- 192.168.13.0/24 un poste du sous réseau 192.168.26.X
- 192.168.13.1/32 la machine d'adresse IP 192.168.13.1
Pour la police:
- ACCEPT
- DENY
- REJECT
Ce qui nous donne dans l'exemple suivant:
ipchains -A input -i ppp0 -s 192.168.13.0/24 -d 0.0.0.0/0 -l -j REJECT
Toute machine se faisant passer pour une machine du réseau local (source 192.168.13.0/24) voulant aller n'importe où (destination 0.0.0.0/0) en passant par l'interface externe ppp0 est rejetée (REJECT). On a mis en place ici une protection "anti-spoofing" pour éviter que quelqu'un se fasse passer pour une des machines de votre réseau privé masqueradisé.
Vous pouvez spécifier aussi un protocole particulier à filtrer en rajoutant -p protocol (du style -p ICMP), par défaut s'il n'y a rien c'est que la règle concerne tous les protocoles réseaux.
#!/bin/bash
# l'argument 4 correspond à l'adresse IP dynamique donnée
par le FAI,
# qu'on appelera interface "remote"
EXTIP=$4
# définition de l'interface externe, généralement
on passe par ppp0
EXTINT="ppp0"
# définition de l'interface interne, dans le cas d'une carte
réseau unique
# c'est eth0
INTINT="eth0"
# définition du sous réseau utilisé en interne
# mettez ici le type d'adresse que vous utilisez
INTNET="192.168.13.0/24"
########################################################################################
#
définition des règles pour la chaîne input
#
########################################################################################
# on part tout d'abord d'une situation saine, c'est à dire
qu'on efface d'abord toutes
# les règles, et qu'on rejette tout ce qui arrive y compris
les paquets venant du réseau interne
# dans un premier temps on supprime toutes les règles
/sbin/ipchains -F input
# puis on redéfinit la police (on rejette tout en entrée)
/sbin/ipchains -P input REJECT
# on redéfinit maintenant les règles pour la chaîne input
# les machines du réseau local INTNET ont le droit d'aller
# n'importe où en passant par l'interface INTINT (eth0)
/sbin/ipchains -A input -i $INTINT -s $INTNET -d 0.0.0.0/0 -j ACCEPT
# maintenant les machines se faisant passer pour une machine du réseau
local
# sont rejetées si elles tentent de passer par l'interface
externe EXTINT pour aller sur le net
# c'est une protection "anti spoofing" (se faire passer pour un
autre)
# option log (-l) activée
/sbin/ipchains -A input -i $EXTINT -s $INTNET -d 0.0.0.0/0 -l -j
REJECT
# n'importe quelle machine passant par l'interface
# EXTINT (ppp0) a le droit d'aller sur l'interface remote
(la machine elle-même)
# en gros les paquets venants du net pourront arriver sur votre
machine
# (nécessaire pour surfer par exemple)
/sbin/ipchains -A input -i $EXTINT -s 0.0.0.0/0 -d $EXTIP/32 -j
ACCEPT
# on autorise à aller sur le net n'importe quelle machine
passant par l'interface loopback
# on autorise ici tous les données local vers local (quelque
soit la source ou la destination spécifiée)
/sbin/ipchains -A input -i lo -s 0.0.0.0/0 -d 0.0.0.0/0 -l -j ACCEPT
# n'importe quelle machine essayant de passer par une
# autre interface que lo, eth0, ppp0 et interface remote pour aller
sur le net est rejetée
# option log activée
/sbin/ipchains -A input -s 0.0.0.0/0 -d 0.0.0.0/0 -l -j REJECT
########################################################################################
#
définition des règles pour le chaîne output
#
########################################################################################
# on efface toutes les règles pour la chaîne output
/sbin/ipchains -F output
# on redéfinit la police, on rejette tout ce qui veut sortir
/sbin/ipchains -P output REJECT
#on redéfinit maintenant les règles pour la chaîne output
# n'importe quelle machine allant sur le réseau interne en
passant par l'interface réseau interne est acceptée
/sbin/ipchains -A output -i $INTINT -s 0.0.0.0/0 -d $INTNET -j ACCEPT
# toute machine voulant aller sur le réseau local en passant
par l'interface externe est rejetée
# option log activée
/sbin/ipchains -A output -i $EXTINT -s 0.0.0.0/0 -d $INTNET -l -j
REJECT
# une machine se faisant passer pour un poste du réseau local
pour aller sur le net en passant par
# l'interface externe est rejetée
# option log activée
/sbin/ipchains -A output -i $EXTINT -s $INTNET -d 0.0.0.0/0 -l -j
REJECT
# tout paquet venant de l'interface remote (la machine elle-même)
peut aller sur le
# net en passant par l'interface remote est accepté
/sbin/ipchains -A output -i $EXTINT -s $EXTIP/32 -d 0.0.0.0/0 -j
ACCEPT
# tout ce qui passe par l'interface loopback est valid
# concerne les données qui circulent localement
/sbin/ipchains -A output -i lo -s 0.0.0.0/0 -d 0.0.0.0/0 -j ACCEPT
# tout le reste est rejeté (ce qui ne passe pas par eth0,
ppp0, lo, ou l'interface remote)
# option log activée
/sbin/ipchains -A output -s 0.0.0.0/0 -d 0.0.0.0/0 -l -j REJECT
########################################################################################
#
définition des règles pour la chaîne forward
#
########################################################################################
# on efface toutes les règles de la chaîne forward
/sbin/ipchains -F forward
# on redéfinit la police, on transmet rien du tout (on supprime)
/sbin/ipchains -P forward DENY
# on redéfinit les règles pour la chaîne forward
# Les paquets provenant du réseau interne vers n'importe où
en passant par l'interface externe ppp0
# sont transmis et masqueradisés ( l'adresse IP de l'expéditeur)
est caché
/sbin/ipchains -A forward -i $EXTINT -s $INTNET -d 0.0.0.0/0 -j
MASQ
# Toutes les autres sortes de transmission sont interdites
# option log activée
/sbin/ipchains -A forward -s 0.0.0.0/0 -d 0.0.0.0/0 -l -j REJECT
# fin de la partie firewall
# suite du fichier /etc/ppp/ip-up
NOTES:
- Par rapport à la configuration simple de l'ip masquerade,
il n'est plus nécessaire de rajouter les lignes de configuration
d'ipchains dans /etc/rc.d/rc.local
- Pour que ça marche assurez vous que le champ FORWARD_IPV4
est à Yes dans le fichier /etc/sysconfig/network.
[root@tavel marcel]# ipchains -L input
Chain input (policy REJECT):
target
prot opt
source
destination
ports
ACCEPT all
------ 192.168.13.0/24
anywhere
n/a
REJECT all
----l- 192.168.13.0/24
anywhere
n/a
ACCEPT all
------ anywhere
ppp66-brest.libertysurf.fr n/a
ACCEPT all
----l- anywhere
anywhere
n/a
REJECT all
----l- anywhere
anywhere
n/a
- target correspond au traitement à appliquer à
la règle
- prot pour protocole
- opt pour options (?)
- source on voit l'adresse du réseau interne
- destination on voit à la troisième ligne l'adresse
IP dynamique (le nom en fait)
- ports à n/a parce qu'on n'en spéficie
pas de particulier
Le résultat de ipchains -L forward
[root@tavel marcel]# ipchains -L forward
Chain forward (policy DENY):
target prot
opt
source
destination
ports
MASQ all
------ 192.168.13.0/24
anywhere
n/a
REJECT all
----l- anywhere
anywhere
n/a
Et de ipchains -L output
[root@tavel marcel]# ipchains -L output
Chain output (policy REJECT):
target
prot opt
source
destination
ports
ACCEPT all
------ anywhere
192.168.13.0/24 n/a
REJECT all
----l- anywhere
192.168.13.0/24 n/a
REJECT all
----l- 192.168.13.0/24
anywhere
n/a
ACCEPT all
------ ppp66-brest.libertysurf.fr anywhere
n/a
ACCEPT all
------ anywhere
anywhere
n/a
REJECT all
----l- anywhere
anywhere
n/a
Maintenant le fichier de log de ipchains est /var/log/messages, voici un exemple de ce qu'on peut y trouver:
Feb 26 20:51:44 tavel kernel: Packet log: output REJECT eth0 PROTO=6 192.168.13.11:1101 216.10.15.227:80 L=60 S=0x00 I=5687 F=0x0000 T=64 SYN (#6)
- ouput nom de la chaîne,
- REJECT résultat de la règle,
- eth0 interface utilisée par le paquet,
- PROTO=6, le paquet utilise le protocole 6 soit TCP
(pour avoir la liste des protocoles et leur numéro, voir le fichier
/etc/protocols),
- 192.168.13.11 adresse de l'expéditeur du paquet,
- :1101 le numéro du port expéditeur est 1101,
- 216.10.15.227 adresse du destinataire,
- :80 c'est le numéro du port de destination, ça
correspond au serveur http,
- L=60 le paquet a une longueur totale de 60 octets,
- S=0x00, champ Type Of Service (voir ipchains-HOWTO),
- I=5687 identificateur quelconque (?),
- F=0x0000 concerne une histoire de fragments, (voir l'ipchains-HOWTO),
- T=64 durée de vie du paquet, à chaque hop, c'est
à dire, à chaque routage, on soustrait 1 à ce chiffre,
quand on arrive à 0, le paquet est supprimé,
-(#6) numéro de la règle.
Une fois déconnectée je vous conseille de virer toutes les règles, car sinon ça va remplir /var/log/messages inutilement, voici à quoi pourrait ressembler /etc/ppp/ip-down.
# !/bin/bash
# /etc/ppp/ip-down
# début de la partie firewall
/sbin/ipchains -F input
/sbin/ipchains -P input ACCEPT
/sbin/ipchains -F output
/sbin/ipchains -P output ACCEPT
/sbin/ipchains -F forward
/sbin/ipchains -P forward ACCEPT
# fin de la partie firewall
# suite du fichier
ipchains -A output -d 234.121.45.55/32 -j REJECT
On a vu qu'on pouvait spécifier le type du protocole concerné par la règle de filtrage, les protocoles possibles sont udp, tcp et icmp. Ca nous donne ça par exemple:
ipchains -A input -s $INTNET-d 0.0.0.0/.0 -p tcp -j ACCEPT
On autorise les paquets utilisant le procotole réseau TCP provenant de machines de notre réseau interne à aller n'importe où.
Tout service réseau (telnet, ftp, http,
...) est identifié par un numéro de port, par ailleurs celui-ci
utilise soit le protocole UDP soit le protocole TCP (si ce
n'est pas les deux)(voir encore une fois le cours réseau pour plus
de détail), par exemple le service telnet a pour numéro
23
et utilise le protocole TCP. Vous trouverez dans le fichier
/etc/services
la liste exhaustive des services réseau avec leur numéro
ainsi que le protocole rattaché.
Avec ipchains on peut donc préciser une règle
sur un service réseau particulier, ainsi:
ipchains -A input -i $EXTINT -s 0.0.0.0/0 -p TCP -d $EXTIP/32 23 -j REJECT
Interdit tout paquet provenant de l'interface externe à se diriger vers le port 23 (telnet) de votre machine connectée. A noter qu'au lieu de mettre 23, vous auriez pu tout bêtement mettre telnet, ipchains assimile les numéros de port avec leur dénomination dans /etc/services.
NOTE: Une bonne lecture le Firewall-HOWTO.
ATTENTION: N'ayant pas le câble je n'ai pas pu tester son efficacité, à vous de me le dire.
Tout d'abord écrivait ce fichier /etc/rc.d/init.d/rc.firewall
#!/bin/bash
# script pour la mise en place des règles de firewall
# pour les câbles en poste isolé (carte réseau
sur eth0)
# ou en réseau interne (carte réseau sur eth1)
# détermination de l'adresse IP donné par le câble
EXTIP="`/sbin/ifconfig eth0|grep inet|awk '{print $2}'|awk -F":"
'{print $2}'`"
# définition de l'interface externe, généralement
on passe par eth0
# pour les câbles
EXTINT="eth0"
# définition de l'interface interne, dans le cas d'une deuxième
# carte réseau (eth1)
# à commenter si poste isolé
INTINT="eth1"
# si vous avez un réseau local
# mettez l'adresse de votre réseau utilisé en interne
# à commenter si poste isolé
INTNET="192.168.13.0/24"
#######################################################################################
# définition des règles pour la chaine input
########################################################################################
# on part tout d'abord d'une situation saine, c'est à dire
qu'on efface d'abord
# toutes
# les règles, et qu'on rejette tout ce qui arrive y compris
les paquets venant
# du réseau interne
# dans un premier temps on supprime toutes les règles
/sbin/ipchains -F input
# puis on redéfinit la police (on rejette tout en entrée)
/sbin/ipchains -P input REJECT
# on redéfinit maintenant les règles pour la chaîne
input
# les machines du réseau local INTNET ont le droit
d'aller
# n'importe où en passant par l'interface INTINT (eth1)
# à commenter si poste isolé
/sbin/ipchains -A input -i $INTINT -s $INTNET -d 0.0.0.0/0 -j ACCEPT
# maintenant les machines se faisant passer pour une machine du
réseau local
# sont rejetées si elles tentent de passer par l'interface
externe EXTINT pour
# aller sur le net
# c'est une protection "anti spoofing" (se faire passer pour un
autre)
# option log (-l) activée
# à commenter si poste isolé
/sbin/ipchains -A input -i $EXTINT -s $INTNET -d 0.0.0.0/0 -l -j
REJECT
# n'importe quelle machine passant par l'interface
# EXTINT (eth0) a le droit d'aller sur l'interface remote
(la machine
# elle-même)
# en gros les paquets venants du net pourront arriver sur votre
machine
# (nécessaire pour surfer par exemple)
/sbin/ipchains -A input -i $EXTINT -s 0.0.0.0/0 -d $EXTIP/32 -j
ACCEPT
# on autorise à aller sur le net n'importe quelle machine
passant par
# l'interface loopback
# on autorise ici tous les données local vers local (quelque
soit la source ou
# la destination spécifiée)
/sbin/ipchains -A input -i lo -s 0.0.0.0/0 -d 0.0.0.0/0 -l -j ACCEPT
# n'importe quelle machine essayant de passer par une
# autre interface que lo, eth0, eth1 et interface remote pour aller
sur le net
# est rejetée
# option log activée
/sbin/ipchains -A input -s 0.0.0.0/0 -d 0.0.0.0/0 -l -j REJECT
########################################################################################
#
définition des règles pour le chaîne output
########################################################################################
# on efface toutes les règles pour la chaîne output
/sbin/ipchains -F output
# on redéfinit la police, on rejette tout ce qui veut sortir
/sbin/ipchains -P output REJECT
#on redéfinit maintenant les règles pour la chaîne
output
# n'importe quelle machine allant sur le réseau interne en
passant par
# l'interface réseau interne est acceptée
# à commenter si poste isolé
/sbin/ipchains -A output -i $INTINT -s 0.0.0.0/0 -d $INTNET -j ACCEPT
# toute machine voulant aller sur le réseau local en passant
par l'interface
# externe est rejetée
# option log activée
# à commenter si poste isolé
/sbin/ipchains -A output -i $EXTINT -s 0.0.0.0/0 -d $INTNET -l -j
REJECT
# une machine se faisant passer pour un poste du réseau local
pour aller sur le
# net en passant par
# l'interface externe est rejetée
# option log activée
# à commenter si poste isolé
/sbin/ipchains -A output -i $EXTINT -s $INTNET -d 0.0.0.0/0 -l -j
REJECT
# tout paquet venant de l'interface remote (la machine elle-même)
peut aller
# sur le
# net en passant par l'interface remote est accepté
/sbin/ipchains -A output -i $EXTINT -s $EXTIP/32 -d 0.0.0.0/0 -j
ACCEPT
# tout ce qui passe par l'interface loopback est valid
# concerne les données qui circulent localement
/sbin/ipchains -A output -i lo -s 0.0.0.0/0 -d 0.0.0.0/0 -j ACCEPT
# tout le reste est rejeté (ce qui ne passe pas par eth0,
eth1, lo, ou
# l'interface remote)
# option log activée
/sbin/ipchains -A output -s 0.0.0.0/0 -d 0.0.0.0/0 -l -j REJECT
########################################################################################
#
définition des règles pour la chaîne forward
########################################################################################
# on efface toutes les règles de la chaîne forward
/sbin/ipchains -F forward
# on redéfinit la police, on transmet rien du tout (on supprime)
/sbin/ipchains -P forward DENY
# on redéfinit les règles pour la chaîne forward
# Les paquets provenant du réseau interne vers n'importe
où en passant par
# l'interface externe eth0
# sont transmis et masqueradisés ( l'adresse IP de l'expéditeur)
est caché
# à commenter si poste isolé
/sbin/ipchains -A forward -i $EXTINT -s $INTNET -d 0.0.0.0/0 -j
MASQ
# Toutes les autres sortes de transmission sont interdites
# option log activée
/sbin/ipchains -A forward -s 0.0.0.0/0 -d 0.0.0.0/0 -l -j REJECT
On met les droits 755 à ce fichier.
chmod 755 /etc/rc.d/init.d/firewall
Une fois que vous êtes connectés vous pouvez lancer les règles de rc.firewall, en lançant en tant que root simplement le script. L'idéal est de le lancer automatiquement, pour cela vous pouvez très bien le lancer à la fin du fichier /etc/rc.d/rc.local.