
Mais, pour être facilement modifiable, nous allons définir en plus quelques variables :
Ensuite, il nous faut charger les modules dont nous aurons besoin :
Suivant votre configuration, il peut être nécessaire de charger un autre module, pour en avoir la liste :
///////////////////////////////////////
|
| # (suite du script...) |
| $IPTABLES -P INPUT DROP |
| $IPTABLES -P OUTPUT DROP |
| $IPTABLES -P FORWARD DROP |
Pour ne pas être ennuyé, il faut tout autoriser pour ce qui est du traffic réseau local (sur 'lo' et '$INTERNAL_IF' aka: 'eth0') :
| # (suite du script...) |
| # "On accepte le traffic sur 'lo'" |
| $IPTABLES -A INPUT -i lo -j ACCEPT |
| $IPTABLES -A OUTPUT -o lo -j ACCEPT |
| $IPTABLES -A FORWARD -i lo -j ACCEPT |
| $IPTABLES -A FORWARD -o lo -j ACCEPT |
| # "On accepte le traffic sur le réseau local" |
| $IPTABLES -A INPUT -i $INTERNAL_IF -j ACCEPT |
| $IPTABLES -A OUTPUT -o $INTERNAL_IF -j ACCEPT |
| $IPTABLES -A FORWARD -i $INTERNAL_IF -j ACCEPT |
| $IPTABLES -A FORWARD -o $INTERNAL_IF -j ACCEPT |
Ceci n'est pas vraiment obligatoire.
Si vous ne regardez pas régulièrement les logs de votre mur pare feu, celui-ci a toutes les chances de devenir inefficace. Nous allons donc 'logguer' une partie des connections que nous refuserons
| # (suite du script...) |
| # On loggue les packets DROPés |
| $IPTABLES -A LOG_DROP -j LOG --log-prefix "[IPT] " |
| $IPTABLES -A LOG_DROP -j DROP |
Le mur pare feu peut aussi servir à partager la connection, pour cela il faut faire deux choses :
1. l'autoriser au niveau du noyau :
| # (suite du script...) |
| echo 1 > /proc/sys/net/ipv4/ip_forward |
| # (suite du script...) |
| $IPTABLES -A POSTROUTING -t nat -o $EXTERNAL_IF -j MASQUERADE/td> |
A partir de maintenant je vais vous donner des recettes de cuisine.
Tout d'abord, il faut savoir que vous pouvez au choix utiliser un numéro de port ou son nom dans le fichier /etc/services.
J'utiliserais, dans la mesure du possible, cette dernière solution. Je ne détaillerais pas tous les ports, si vous souhaitez utiliser un port que j'aurais omis, consultez /etc/services.
Dans ce fichier, vous constaterez que certains ports sont indiqués comme utilisant le protocol tcp, udp ou autre.
Pour autoriser ces protocols vous devrez changer le "-p tcp" par "-p udp" ou autre dans les exemples qui vont suivre.
Pour la plupart des connections, tout ce que je vais dire ici s'applique (exceptions notables : l'irc/dcc, le ftp/actif).
Pour autoriser les machines de votre réseau local (si le masquerading est activé) ainsi que votre serveur mur pare feu à se connecter à un port sur internet, il faut procéder de la maniére suivante (dans l'exemple j'autorise la connection au WEB : www):
| # (suite du script...) | |
| $IPTABLES -A INPUT -i $EXTERNAL_IF -p tcp --sport www -m state --state ESTABLISHED,RELATED -j ACCEPT | |
| $IPTABLES -A OUTPUT -o $EXTERNAL_IF -p tcp --dport www -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT |
| Chaque commande $IPTABLES doit être tapée sur une seule ligne depuis le $IPTABLES jusqu'au -j ACCEPT ou -j DENY (dans la suite...) |
| # (suite du script...) |
| $IPTABLES -A INPUT -i $EXTERNAL_IF -p tcp -m multiport --sports www,https -m state --state ESTABLISHED,RELATED -j ACCEPT | $IPTABLES -A OUTPUT -o $EXTERNAL_IF -p tcp -m multiport --dports www,https -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT/td> |
Pour autoriser les machines d'internet à se connecter à votre serveur local (dans l'exemple j'autorise la connection à votre serveur WEB : www):
| # (suite du script...) |
| $IPTABLES -A OUTPUT -o $EXTERNAL_IF -p tcp --sport www -m state --state ESTABLISHED,RELATED -j ACCEPT |
| $IPTABLES -A INPUT -i $EXTERNAL_IF -p tcp --dport www -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT |
Il existe des cas particuliers, ce sont les protocoles qui ouvrent plusieurs liaisons en même temps :
le DCC(pour irc), le ftp passif, les protocole vidéo (comme le h323).
Ils fonctionnent souvent (mais pas tous) sur le principe suivant : le client (vous) réclame quelque chose (un fichier) au serveur (le serveur ftp) ;
celui-ci répond à la demande en ouvrant une nouvelle connection (aléatoire en général : c'est ce qui nous pose problème, on ne sait pas quel port ouvrir) réseau sur le client (vous).
Pour ne pas ouvrir n'importe quel port (plus précisément, pour ne pas ouvrir TOUS les ports) pour être en mesure de répondre à la demande du serveur, il faut que nous soyons capable de "tracer" (to track en anglais) la provenance de la demande de connection pour être sur que la demande de connection provient d'une liaison que nous avons nous méme initié.
C'est le rôle du module "ip_conntrack" et de ses acolytes : "ip_conntrack_ftp" (pour le ftp) et "ip_conntrack_irc" pour l'irc.
Pour que cela (ce qui va suivre) fonctionne, il faut donc que ces modules soient chargés.
C'est ce que nous faisons au début du script, donc plus besoin de nous en occuper, si ce n'est pour autoriser les connections qui sont en relation avec celles déja établies sur les ports qui sont utilisés par irc et ftp
:
| # (suite du script...) |
| $IPTABLES -A OUTPUT -o $EXTERNAL_IF -p tcp --sport 1024:65535 --dport 1024:65535 -m state --state ESTABLISHED,RELATED -j ACCEPT |
| # (suite du script...) |
| $IPTABLES -A OUTPUT -o $EXTERNAL_IF -p tcp --sport 1024:65535 --dport 1024:65535 -m state --state NEW -j ACCEPT |
Pour l'instant, si vous avez ouvert quelques port, vous avez du remarquer que vous n'avez plus accès au ping. Nous allons remédier à cela
| :# (suite du script...) |
| $IPTABLES -A OUTPUT -p icmp -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT |
| $IPTABLES -A INPUT -p icmp -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT |
| # (suite du script...) |
| $IPTABLES -A INPUT -p icmp -m state --state RELATED,ESTABLISHED -j ACCEPT |
| $IPTABLES -A INPUT -p icmp -m state --state NEW -m limit --limit 10/min -j ACCEPT |
Il est un port que vous êtes obligé d'autoriser dans le sens 'réseau local' vers 'internet' : le port "domain" (aka: 53) en udp ET tcp.
Sinon vous serez dans l'impossibilité d'utiliser la résolution de nom (aka: l'identification d'un nom de domaine avec son IP)
.
Sinon, moi j'autorise, dans le sens 'reseau local' vers 'internet' en tcp :
|
* domain (obligatoire), * ftp, * ftp-data, * www, * https, * pop-3, * imap2, * imap3, * smtp, * ircd, * cvspserver , * rsync, * 7070 (realaudio), * 11371 (keyserver), * ssh, * 1441 (flux ogg de radio france) Et en udp : * domain (obligatoire), * 6970 et 7170 (realaudio) Et dans le sens : 'internet' vers 'reseau local' en tcp : * auth (accélère l'établissement de la connection à plein de serveurs irc) Rappel : tous ces noms de 'ports' se trouvent dans le fichier /etc/services |
our finir, on loggue tout via syslogd :
| $IPTABLES -A FORWARD -j LOG_DROP |
| $IPTABLES -A INPUT -j LOG_DROP |
| $IPTABLES -A OUTPUT -j LOG_DROP |
Il n'est en général pas nécessaire d'arrêter le mur pare feu,
mais, sait-on jamais ? Pour faire les tests, il est nécessaire de l'arrêter et de le redémarrer (parce que l'ordre des règles est important).
Voici un petit script pour arrêter le mur pare feu (celui qui est proposé ici,
il ne fonctionnera pas avec tous les murs de feu)
| #!/bin/sh |
| # Script d'arrêt du mur pare feu |
| # mettez ici l'emplacement d'iptables : |
| IPTABLES=/sbin/iptables |
| echo "On vide toutes les régles." |
| $IPTABLES -F INPUT |
| $IPTABLES -F OUTPUT |
| $IPTABLES -F FORWARD |
| $IPTABLES -t nat -F POSTROUTING |
| $IPTABLES -F LOG_DROP |
| $IPTABLES -X |
| $IPTABLES -P INPUT ACCEPT |
| $IPTABLES -P OUTPUT ACCEPT |
| $IPTABLES -P FORWARD ACCEPT |
Ce mur pare feu n'est certainement pas parfait,
mais j'espere qu'il vous permettra de mieux comprendre comment sont fabriqués les murs de feu que vous trouvez dans des scripts tous faits.