iptables a une page de manuel bien détaillée (man iptables
),
si tu veux de détails en particulier. Si tu es familier avec ipchains
tu devrais simplement regarder a
Différences entre iptables et ipchains; ils sont vraiment similaires.
Il y a plusieurs choses que tu peux faire avec iptables
.
Tu commences avec trois chaines de départ INPUT
, OUTPUT
et FORWARD
que tu ne peux pas effacer. Regardons les opérations pour
administrer les chaines:
Il y a plusieurs manières de manipuler une règles dans une chaine:
iptables peut ètre un module, appelé (`iptable_filter.o'), qui devrait
ètre automatiquement chargé quand tu lances iptables
. Il peut
aussi ètrte compilé dans le noyau.
Avant qu'aucune commende n'ait été effectuée, ( attention: certaines distributions lanceront iptables dans leurs scripts d'initialisation), il n'y a pas de règles dans aucune des chaines par défaut (`INPUT', `FORWARD' et `OUTPUT'), toutes les chaines ont une règle par défaut de ACCEPT. Tu peux changer la règle par defaut de la chaine FORWARD en specifiant l'option `forward=0' au module iptable_filter.
C'est le pain et le beurre du filtrage de paquets; manipuler des règles. plus communément, tu utiliseras probablement les commandes d'ajout (-A) et d'effacement (-D). Les autres (-I pour insérer et -R pour remplacer) sont de simples extensions de ces concepts.
Chaque règle spécifie des conditions que le paquet doit remplir, et que faire si le paquet les remplis (une `cible'). Par exemple, tu voudrais laisser tomber tous les paquets ICMP qui viennent de l'adresse IP 127.0.0.1. Donc dans ce cas les conditions sont que le protocole soit icmp et que l'adresse source soit 127.0.0.1. Notre cible est `DROP'.
127.0.0.1 est l'interface `loopback', que tu auras mème si tu n'as pas de connection réseau réelle. Tu peux utiliser la commande `ping' pour generer de tels paquets (elle envoie simplement un ICMP de type 8 (echo request) auquel tout les hotes devraient répondre avec un icmp de type 0 (echo reply) ). Cela est utile pour tester.
# ping -c 1 127.0.0.1
PING 127.0.0.1 (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.2 ms
--- 127.0.0.1 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.2/0.2/0.2 ms
# iptables -A INPUT -s 127.0.0.1 -p icmp -j DROP
# ping -c 1 127.0.0.1
PING 127.0.0.1 (127.0.0.1): 56 data bytes
--- 127.0.0.1 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss
#
Tu peux voir que le 1er ping a fonctionné (le `-c 1' dit a ping de n'envoyer qu'un seul paquet).
Ensuite nous ajoutons (-A) al la chaine `INPUT', une règle spécifiant que pour les paquest venant de 127.0.0.1 (`-s 127.0.0.1') avec le protocole ICMP (`-p icmp') nous devons sauter vers la cible DROP (`-j DROP').
Ensuite nous testons notre règle, en utilisant le second ping. Il y aura une pause avant que le programme ne stoppe parce qu'il attendra une réponse qui ne viendra jamais.
Nous pouvons effacer une règle de deux facons. Premièrement, comme nous savons que c'est la seule règle dans la chaine INPUT, on peut utiliser un effacement avec le nombre, comme:
# iptables -D INPUT 1
#
Pour effacer la règle numéro 1 dans la chaine INPUT.
La seconde facon est un miroir de la commande -A, remplacer -A par -D. C'est utile quand tu as une chaine complexe et que tu ne veux pas les compter pour trouver que c'est la règle 37 que tu veux effacer. Dans ce cas , on utiliserait:
# iptables -D INPUT -s 127.0.0.1 -p icmp -j DROP
#
La syntaxe de la commande -D doit avoir exactement les mèmes options
que celles de -A (ou -I ou -R). Si il y a plusieurs règles identiques
dans la mème chaine, le première seulement sera effacée.
Nous avons vu l'utilisation de `-p' pour specifier le protocole, et de `-s' pour specifier la source, mais il y a d'autres options que tu peux utiliser pour specifier les caractéristiques d'un paquet. Ce qui suit est une liste exhaustive.
Les adresses IP source (`-s', `--source' ou `--src') et destination (`-d',`--destination' ou `--dst') peuvent ètre specifiées de 4 façons. La facon la plus commune est d'utiliser le nom complet, comme `localhost' ou `www.linuxhq.com'. La seconde facon est de specifier l'adresse IP comme `127.0.0.1'.
Les troisièmes et quatrièmes facons permettent de specifier un groupe d'IPs, comme `199.95.207.0/24' ou `199.95.207.0/255.255.255.0'. Elles specifient toutes deux les adresses de 199.95.207.0 a 199.95.207.255 inclus; les nombres après le `/' disent quelle partie des adresses IP a de la signification. `/32' ou `/255.255.255.255' est le défaut (correspond a toutes les adresses IP). Pour specifier toutes les adresses IP `/0' peut ètre utilisé, comme dans:
[ NOTE: `-s 0/0' is redundant here. ]
# iptables -A INPUT -s 0/0 -j DROP
#
C'est rarement utilisé, comme l'effet ci dessus est le mème que de ne pas specifier l'option `-s' du tout.
Beaucoup d'options comme `-s' (ou `--source' ) et `-d' (`--destination') peuvent avoir leurs arguments précédés de `!' ( pronnoncé `NOT') pour correspondre aux adresses PAS égales a celles données. Par exemple `-s ! localhost' correspond a tout paquet qui ne vient pas de localhost.
Le protocole peut ètre spécifié avec `-p' ( ou `--protocol'). Le protocole peut ètre un nombre (si tu connais les valeurs numériques de protocole IP) ou un nom pour les cas spéciaux `TCP', `UDP' ou `ICMP'. La casse n'a pas d'importance, `tcp' marche aussi bien que `TCP'.
Le nom du protocole peut ètyre préfixé d'un `!', pour l'inverser, comme `-p ! TCP' pour speciofier les paquets qui ne sont pas TCP.
Les options `-i' (ou `--in-interface') et `-o' (ou `--out-interface')
spécifient le nom d'une interface a laquelle le paquet doit
correspondre. Une interface est l'appareil physique par lequel le paquet
arrive (`-i') ou sort (`-o'). Tu peux utiliser ifconfig
pour voir
les interfaces qui sont `up' (p.e., qui fonctionnent pour le moment).
Les paquets qui traversent la chaine INPUT
n'ont pas encore
d'interface de sortie donc, une règle utilisant `-o' -o dans cette
chaine ne conviendra pas, les paquets traversant la chaine OUTPUT
n'ont pas d'interface d'entrée, donc toute règle utilisant `-i' dans cette
chaine ne correspondra jamais.
Seuls les paquets traversant la chaine FORWARD
on une interface
d'entrée et de sortie.
Il est parfaitement légal de specifier une interface qui n'existe pas;
la règle ne conviendra pas jusqu'a ce que l'interface soit `up'.
C'est vraiment utile pour les lignes PPP ( habituellement l'interface
ppp0
) et ses semblables.
Un cas special est un nom d'interface se terminant par `+' qui conviendra a
toutes les interface ( qui existent déja ou pas) qui commencent par ces lettres.
Par exemple, pour specifier une règle qui convient a toutes les interfaces PPP,
on utilisera l'ioption -i ppp+
.
Le nom de l'interface peut ètre précédé par un `!' pour convenir a un paquet qui n'appartient pas a l'interface spécifiée.
Parfois un paquet est trop large pour rentrer dans la ligne de transmission (NdT: oui, je sais les traductions sont parfois foireuses). Quand ca arrive, le paquet est divisé en fragments, et envoyé comme de multiples paquets. Le récepteur réassemble ces fragments pour reconstruire le paquet entier.
Le problème avec les fragments c'est que le fragment initial a son en-tète complète (IP + TCP, UDP et ICMP) a examiner mais que les paquets suivants ont seulement quelques morceaux de l'en-tète (IP sans les champs de protocole). Donc regarder a l'intérieur des fragments suivants a la recherche d'en-tètes de protocoles ( comme c'est fait pour les extensions TCP,UDP et ICMP) n'est pas possible.
Si tu utilises le suivi de connection ou le NAT, alors tout les fragments seront recollés avant qu'ils n'arrivent au code de filtrage de paquets, donc tu n'auras pas a t'occuper des fragments.
Autrement il est important de comprendre comment les fragments sont traités
par les règles de filtrage. Toute règle de filtrage qui demande des infomations
qu'on a pas ne conviendra pas. Ca veut dire que le premier fragment est
traité comme tout autre paquet, mais que le secon,d et suivants ne le seront pas.
Donc une règle -p TCP --sport www
(qui specifie loe port source `www')
ne conviendra jamais a un fragment (autre que le premier fragment).
L'opposé est aussi valable -p TCP --sport ! www
.
Sinon, tu peux specifier une règle pour les seconds fragments et suivants , en utilisant l'option `-f' (ou `--fragment'). Il est aussi légal de spécifier une règle qui ne s'applique pas aux secondes fragments et suivants, en précédant `-f' avec `!'.
Habituellement il est sécurisant de laisser passer les seconds fragments et suivants, comme le filtrage sera fait sur le premier, et empèchera le réassemblement sur la machine cible; mais des bugs ont été trouvés qui permettent de crasher la machine simplement en lui envoyant des fragments.
Note: les paquets malformés (TCP, UDP et ICMP qui sont trop courts pour que le code de firewalling lise les ports ou le code ICMP et le type) sont DROP quand de telles combinaisons sont tentées, comme les fragments TCP qui commencent a la position 8.
Comme exemple, la règle suivante va laisser tomber tout les fragments qui vont vers 192.168.1.1:
# iptables -A OUTPUT -f -d 192.168.1.1 -j DROP
#
iptables
est extensible, ce qui veut dire que
le noyau et le programme iptables peuvent ètre étendus pour avoir de nouvelles
capacités.
Quelques unes de ces extensions sont standard, et d'autres sont plus exotiques. Elles peuvent ètre créées par d'autres personnes et distribuées séparément auc utilisateurs.
Les extensions au noyau sont normalment situées dans le répretoire des modules du kernel comme /lib/modules/2.3.15/net. Elles sont chargées a la demande si ton kernel a été compilé avec CONFIG_KMOD, donc tu n'as pas besion de les insérer a la main.
Les extensions au programme iptables sont des librairies partagées qui sont generallement situées dans /usr/local/lib/iptables/, malgré qu'une distribution puisse les mettre dans /lib/iptables ou /usr/lib/iptables.
Les extensions sont de deux types: nouvelles correspondances et nouvelles cibles; nous parlerons des nouvelles cibles ci-dessous. Quelques protocoles offrent aussi de nouveaux tests: pour le moment TCP, UDP et ICMP.
Pour ceux ci tu pourras specifier les nouveaux tests sur la ligne de commande après l'option `-p', qui va charger l'extension. Pour specifier de nouveaux tests, utilises l'option `-m' pour charger l'extension, après quoi l'extension est disponible.
Pour obtenir de l'aide sur une extension, utilises l'option pour la charger (`-p', `-j' ou `-m') suivi de `-h' ou `--help', p.e.:
# iptables -p tcp --help
#
Les extensions TCP sont automatiquement chagées si `-p tcp' est spécifié. Elles permettent les options suivantes (aucune d'entre elles ne convient aux fragments).
Suivi d'un `!'optionnel, ensuite 2 chaines de caractères de drapeaux, te permet de filtrer des drapeaux TCP spécifiques. La première chaine de drapeaux est le masque: une liste de drapeaux que tu veux examiner. La deuxième chaine de drapeaux dit lequel doit ètre présent. Par exemple:
# iptables -A INPUT --protocol tcp --tcp-flags ALL SYN,ACK -j DENY
Ceci indique que tout les drapeux doivent ètre examinés (`ALL' est synomime de `SYN,ACK,FIN,RST,URG,PSH'), mais seulement SYN et ACK doivent ètre présents. Il y a aussi l'argument `NONE' qui veut dire pas de drapeaux.
Précédé optionnelement d'un `!', c'est une raccourci pour `--tcp-flags SYN,RST,ACK SYN'.
suivi d'un `!' optionnel, ensuite soit un port TCP seul, ou un bloc de ports. Les ports peuvent ètre des noms de ports, listés dans /etc/services, ou des nombres. Les blocs son soit 2 noms de ports séparés par `:', ou (pour specifier plus grand que ou égal a) un port avec un `:' ajouté, ou (pour specifier plus petit que ou égal a) un port précédé de `:'.
est synonime de `--source-port'.
et
sont les mèmes qu'au dessus, ils spécifient juste la destination plutot que la source qui convient.
suivi d'un `!' optionnel ou d'un nombre, convient a un paquet qui a une option TCP qui équivaut a ce nombre. Un paquet qui n'a pas une en-tète TCP complète est laissé tombé automatiquement si un essai est fait pour examiner ses options TCP.
Il est parfois utile d'autoriser les connections TCP dans un sens mais pas dans l'autre. Par exemple, tu pourrais vouloir autoriser les connections vers un serveur WWW externe, mais pas les connections a partir de ce serveur.
L'approche naive serait de bloquer les paquets TCP venant du serveur. Malheureusement, les connections TCP on besion d'avoir des paquets qui vont dans les deux sens pour fonctionner.
La solution estd e bloquer seulement les paquets qui sont utilisés pour demander une connection. Ces paquets sont appelés des paquets SYN (ok, techniquement ce sont des paquets avec le drapeux SYN et pas de drapeaux FIN et ACK, mais nous les appelons paquets SYN pour faire plus court). En déniant seulement ces paquets, nous pouvons stopper les tentatives de connections.
Le drappeau `--syn' est utilisé pour cela: il est seulement valide pour les règles qui spécifient TCP comme protocole. Par exemple, pour specifier un essai de connection de la part de 192.168.1.1:
-p TCP -s 192.168.1.1 --syn
Ce drapeau peut ètre spécifié en le précédant de `!', qui veut dire tout les paquets sauf ceux d'initiation de connection.
Ces extensions sont automatiquements chargées si `-p udp' est spécifié. Elles donnent les options `--source-port', `--sport', `--destination-port' et `--dport' comme détaillé pour le tcp ci-dessus.
Ces extensions sont automatiquements chargées si `-p icmp' est spécifié. Elles donnent seulement une seule nouvelle option:
suivi d'un `!' optionnel, et ensuite un nom de type icmp (pe. `host-unreachable'), ou un type numérique (pe. `3'), ou un type et un code numérique séparés par un `/' (pe. `3/3'). Une liste de type icmp disponibles est donnée en utilisant `-p icmp --help'.
Les autres extensions dans le package netfilter sont des extensions de démonstration, qui (si installées) peuvent ètre invoquées avec l'option `-m'.
Ce module doit ètre spécifié explicitement avec `-m mac' ou `--match mac'. Il est utilisé pour concorder a des adresses Ethernet (MAC) de paquets qui arrivent, et est seulement utile pour convenir avec des paquets traversant les chaines INPUT et PREROUTING. Il donne une seule option:
suivi d'un `!' optionnel, ensuite une adresse ethernet en notation hexa séparée par `:', pe `--mac-source 00:60:08:91:CC:B7'.
Ce module doit ètre spécifié explicitement avec `-m limit' ou `--match limit'. Il est utilisé pour limiter la vitesse de concordance, comme pour specifier des messages de log. Il conviendra seulement a un certain nombre de fois pas seconde ( par défaut 3 concordances par heure, avec une réserve de 5). Il prends deux arguments optionnels:
suivi d'un nombre; spécifie le nombre maximum de concordances allouées par seconde. Le nombre peut specifier les unités explicitement, en utilisant `/second', `/minute', `/hour' ou `/day', ou une partie (donc `5/second' est le mème que `5/s').
suivi d'un nombre, inndique la réserve maximale avant d'atteindre la limite ci-dessus.
Cette concordance peut souvent ètre utilisée avec la cible LOG pour effectuer du logging limité en débit. Pour comprendre comment cela fonctionne on va regarder a la règle suivante, qui logge les paquets avec les paramètres de limite par défaut:
# iptables -A FORWARD -m limit -j LOG
La première fois que cette règle est atteinte, le paquet sera loggé; en fait comme la réserve est de 5, les 5 premiers paquets seront loggés. Après cela, 20 minutes passeront avant qu'un paquet ne soit loggé par cette règle, sans tenir compte du nombre de paquets qui l'atteigne. Aussi, chaque 20 minutes qui passe sans concorder avec un paquet, un paquet de la réserve sera regagné; si aucun paquet n'atteint la règle pendant 100 minutes, la réserve sera complètement rechargée; on est revenu au point de départ.
Note: tu ne peux pas créer de règle avec un temps de recharge de plus de 59 heures, donc si tu configures un débit moyen de 1 par jour, alors le débit de réserve doit ètre inférieur a 3.
Tu peux aussi utiliser ce module pour eviter les déniement de service (DoS) avec un débit supérieur pour augmenter la vitesse de réaction.
Protection syn-flood:
# iptables -A FORWARD -p tcp --syn -m limit --limit 1/s -j ACCEPT
Test de ports furtif:
# iptables -A FORWARD -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s -j ACCEPT
Ping de la mort:
# iptables -A FORWARD -p icmp --icmp-type echo-request -m limit --limit 1/s -j ACCEPT
Ce module fonctionne comme "une porte a hystérésis", comme montré dans le graphe qui suit.
débit (pkt/s)
^ .---.
| / DoS \
| / \
limite de DoS -|.....:.........\.......................
= (limit * | /: \
limit-reserve) | / : \ .-.
| / : \ / \
| / : \ / \
Fin de DoS -|/....:..............:.../.......\..../.
= limite | : :`-' `--'
-------------+-----+--------------+------------------> temps (s)
LOGIQUE =>concord.| pas concord. | concord.
On dit un paquet par seconde avec une réserve de 5 paquets mais, les paquets commences a arriver a 4/s pendant 3 secondes puis recommencent après 3 autres secondes
<--Flood 1--> <---Flood 2--->
Total ^ Ligne __-- YNNN
Paquets| Débit __-- YNNN
| mum __-- YNNN
10 | Maxi __-- Y
| __-- Y
| __-- Y
| __-- YNNN
|- YNNN
5 | Y
| Y Key: Y -> Règle concorde
| Y N -> Règle concorde pas
| Y
|Y
0 +--------------------------------------------------> Temps (secondes)
0 1 2 3 4 5 6 7 8 9 10 11 12
Tu peux voir que les 5 premiers paquets sont autorisés a depasser la limite de un paquet par seconde, ensuite lla limite entre en jeu. Si il y a une pause, un autre bloc est autorisé, mais pas au dessus de la limite maximum configurée par la règle (1 paquet par seconde après que la première réserve soit usée).
Ce module essaye de concorder les caractéristiques variées du créateur du paquet, pour les paquets générés locallement. Il est seulement valide pour la chaine OUTPUT, et mème comme cela, certains paquets (comme les réponses de ping ICMP) n'auront pas de possesseur, et donc ne concorderont jamais.
Concorde si le paquet a été créé par un processus qui a le user id effectif (numérique) donné.
Concorde si le paquet a été créé par un processus qui a le group id effectif (numérique) donné.
Concorde si le paquet a été créé par un processus qui a le process donné.
Concorde si le paquet a été créé par un processus qui a le groupe de session donné.
Ce module expérimental doit ètre spécifié explicitement avec `-m unclean ou `--match unclean'. Il effectue des vérifications sanitaires aléatoires et variées sur les paquets. Ce module n'a pas été testé, et ne devrait pas ètre utilisé comme une fonction de sécurité (il rend peut-ètre les choses plus mauvaises si il a des bugs lui-mème). Il n'a pas d'options.
Le critère le plus utile est fourni par l'extension `state' qui interprète l'analyse de suivi de connection du module `ip_conntrack'. Il est fortement recommendé.
Specifier `-m state' permet une option additionelle `--state', qui est une liste séparée par des virgules d'états qui conviennent ( les `!' indiquent les états qui ne conviennent pas. Ces états sont:
Un paquet qui engendre une nouvelle connection.
Un paquet qui appartient a une connection existante (p.e., une qui a eu des paquets de réponse).
Un paquet qui est relaté a, mais pas partie de, une connection existante, comme une erreur ICMP, ou ( avec le module ftp chargé), un paquet qui etablit une connection de données ftp.
Un paquet qui ne peut ps ètre identifié pour n'importe quelle raison: ceci inclus le manque de mémoire et les erreurs icmp qui ne correspondent a aucune connection connue. Générallement, ces paquets doivent ètre laissé tombés.
Maintenant nous connaissons les examens que nous pouvons faire sur un paquet, nous avons besoin de trouver une facon de dire quoi faire de ces paquets qui correspondent a nos tests. Ceci est appelé la cible d'une règle.
Il y a deux cibles simples compilées: DROP et ACCEPT. Nous les avons déja rencontrées. Si une règle correspond a un paquet et que la cible est une de celles ci, les règles suivantes ne sont pas consultées: le sort du paquet a été décidé.
Il y a deux autres types de cibles que celles qui sont compilées: les extensions et les chainnes créées par l'utilisateur.
Une propriété puissante que iptables
hérite de ipchains
est la possibilité pour l'utilisateur de créer de nouvelles chaines, en
addition aux qui existent déja (INPUT, FORWARD et OUTPUT). Par convention
les chaines utilisateur sont en minuscule pour les distinguer, nous décrirons
comment créer des chaines utilisateur dans
Opérations sur une Chaine Entière ci-dessous).
Quand un paquet concorde a une règle dont la cible est une chaine utilisateur, le paquet commence a traverser les règles dans la chaine utilisateur. Si cette chaine ne décide pas du sort du paquet, alors une fois que la traversée de cette chaine est terminée, la traversée reprend sur la règle suivante de la chaine courante.
Il est temps pour un peu plus d'art ASCII. Considérons deux chaines: INPUT
(la chaine par defaut) et test
(une chaine utilisateur).
`INPUT' `test'
---------------------------- ----------------------------
| Règle1: -p ICMP -j DROP | | Règle1: -s 192.168.1.1 |
|--------------------------| |--------------------------|
| Règle2: -p TCP -j test | | Règle2: -d 192.168.1.1 |
|--------------------------| ----------------------------
| Règle3: -p UDP -j DROP |
----------------------------
Considérons un paquet TCP venant de 192.168.1.1, allant a 1.2.3.4. Il
entre dans la chaine INPUT
, et est testé par la règle1 - pas de concordance.
La règle2 concorde et sa cible est test
, donc la règle suivante examinée
est le debut de la chaine test
. La règle1 de test
concorde mais ne
spécifie pas de cible, donc la règle suivante est examinée, la règle2.
Ca ne concorde pas, nous avons atteint la fin de la chaine test
.
Nous retournons a la chaine INPUT
ou nous venons d'examiner la règle2,
donc nous examinons la règle3, qui ne concorde pas d'avantage.
Donc la traversée du paquet est:
v __________________________
`INPUT' | / `test' v
------------------------|--/ -----------------------|----
| Règle1 | /| | Règle1 | |
|-----------------------|/-| |----------------------|---|
| Règle2 / | | Règle2 | |
|--------------------------| -----------------------v----
| Règle3 /--+___________________________/
------------------------|---
v
Les chaines utilisateurs peuvent sauter dans d'autres chaines utilisateur (mais ne fais pas de boucles: tes paquet seront laissés tomber si ils sont dans une boucle).
L'autre type de cible est une extension. Une extension de
cible consiste en un module du noyau, et une extension optionnele à
iptables
pour permettre de nouvelles options sur la ligne
de commande. Il y a plusieurs extensions dans la distribution netfilter:
Ce module permet de logger les paquets qui concordent. Il donne plusieurs options additionelles:
Suivi d'un nombre de niveau ou d'un nom. Les noms valides sont (non sensible a la casse) `debug', `info', `notice', `warning', `err', `crit', `alert' and `emerg', correspondent aux nombres 7 à 0. Voir la page de manuel de syslog.conf pour une explication de ces niveaux.
Suivi d'une chaine de caractères 30 caractères maximum, ce message est envoyé au début du message de log, pour lui permettre d'ètre identifier uniquement.
Ce module est le plus utile après une cible limit, pour ne pas saturer les logs.
Ce module a les mèmes effets que `DROP', excepté que l'envoyeur recoit un message d'erreur ICMP `port unreachable'. Notes que le message d'erreur ICMP n'est pas envoyé si (voir RFC 1122):
REJECT peut aussi prendre une option `--reject-with' qui altère le type du paquet de réponse utilisé: voir la page de manuel.
Il y a 2 cibles speciales compilées: RETURN
et
QUEUE
.
RETURN
a le mème effet que de tomber a la fin d'une chaine:
pour une règle dans une chaine compilée, la police de la chaine est
exécutée. Pour une règle dans une chaine utilisateur, la traversée continue
dans la chaine précédente, juste après la règle qui a sauté sur cette chaine.
QUEUE
est une cible spéciale, met les paquets en queue pour les
traiter en espace utilisateur. Pour que ca soit utile, deux composants
supplémentaires sont requis:
Ce qui suit est un exemple rapide de comment utiliser iptables pour mettre des paquets en queue pour les traiter en espace utilisateur:
# modprobe iptable_filter
# modprobe ip_queue
# iptables -A OUTPUT -p icmp -j QUEUE
Avec cette règle, les paquets ICMP sortants générés locallement (comme créés par
exemple avec ping) sont passés au module ip_queue, qui ensuite essaye de délivrer
les paquets a une application utilisateur. Si aucune application n'est la pour
prendre les paquets, ils sont laissés tomber.
Pour écrire une application utilisateur, utilises l'API libipq. Elle est distribuée avec iptables. du code d'exemple peut ètre trouvé avec les outils de la suite de tests (p.e. redirect.c) en CVS.
Le status de ip_queue peut ètre vérifié via:
/proc/net/ip_queue
La longueur maximale de la queue (le nombre de paquets délivrés à
l'espace utilisateur sans verdict retourné) peut ètre controllé via:
/proc/sys/net/ipv4/ip_queue_maxlen
La valeur par défaut de la longueur maximum de la queue est 1024. Une fois
que cette limite est atteinte, les nouveaux paquets seront laissés tomber
jusqu'a ce que la longueur de la queue tombe en dessous de la limite.
LEs protocoles bien faits comme le TCP interprètent les paquets laissés tombés
comme une congestion, et réagiront positivement lorsque la queue se remplit.
De toutes facons, des expériences doivent ètre faites pour determiner la
longueur de queue maximale pour une situation donnée si la valeur par
défaut est trop petite.
Une propriété utile de iptables
est la possibilité de
groupper des règles dans des chaines. Tu peux appeler les chaines
comme tu veux, mais je recommendes les minuscules pour eviter la confusion
avec les chaines compilées et les cibles. les noms de chaines peuvent
ètre de 31 caractères maximum.
Créons une nouvelle chaine. Parce que je suis imaginatif je l'appelerai
test
. Nous utilisons l'option `-N' ou `--new-chain':
# iptables -N test
#
C'est si simple. Maintenant tu peux mettre des règles dedans comme détaillé au dessus.
Effacer une chaine est simple aussi, en utilisant l'option `-X' ou `--delete-chain'. Pourquoi `-X'? Ben, toutes les bonnes règles étaient prises.
# iptables -X test
#
Il y a quelques restrictions pour effacer une chaine: elles doit ètre vide (voir Vider une Chaine dessous) et elle ne doit pas ètre la cible d'une table. Tu ne peux pas effacer une des chaines compilées.
Si tu ne spécifie pas de chaine, toutes les chaines utilisateur seront effacées, si possible.
Il y a une facon simple d'effacer toutes les règles d'une chaine, en utilisant la commande `-F' (or `--flush').
# iptables -F forward
#
Si tu ne spécifie pas de chaine, alors toutes les chaines seront vidées.
Tu peux lister toutes les règles d'une chaine en utilisant la commande `-L' (or `--list').
Le `refcnt' listé pour chaque chaine utilisateur est le nombre de règles qui ont cette chaine pour cible. Il doit ètre a zero (et la chaine doit ètre vide) avant que cette chaine soit effacée.
Si le nom de la chaine est omis, toutes les chaines sont listées, mème les chaines vides.
Il ya trois options qui peuvent accompagner `-L'. Le `-n' (numérique)
qui est vraiment utile car il évite a iptables
d'essayer de résoudre
les adresses IP, qui ( si tu utilises des DNS comme la pluspart des gens)
causera de larges délais si ton DNS n'est pas configuré convenablement,
ou tu as filtré les requètes DNS. Il cause aussi les ports TCP et UDP
comme des nombres en non des noms.
L'option `-v' te montre tout les détails des règles, comme les compteurs de paquets et d'octets, les comparaisons TOS, et les interfaces. Sinon ces valeurs sont omises.
Notes que les compteurs de paquets et d'octets sont écris en utilisant les suffixes `K', `M' ou `G' pour 1000, 1,000,000 et 1,000,000,000 respectivement. Utiliser `-x' (expansion des nombres) écrit les nombres complets sans importance avec leur grandeur.
Ilk est utile de pouvoir remettre els compteurs a zéro. Ca peut ètre fait avec l'option `-Z' (ou `--zero').
Le problème avec cette approche est que parfois tu as besoin de savoir la valeur des compteurs juste avant de les remettre a zero. Dans l'exemple du dessus, quelques paquets pourraient passer entre les commandes `-L' et `-Z'. Pour cette raison, tu peux utiliser `-L' et `-Z' ensembles, pour remettre les compteurs a zero en les lisant.
Nous avons parlé de ce qui arrive quand un paquet arrive a la fin d'une
chaine compilée quand nous avons discuté comment un paquet traversait
les chaines plus tot. Dans ce cas, la police de la chaine détermine
le sort du paquet. Seules les chaines compilées (INPUT
, OUTPUT
et
FORWARD
) ont des polices, a cause que si un paquet tombe a la fin
d'une chaine utilisateur, la traversée reprend a la chaine précédente.
La police peut ètre soit ACCEPT
ou DROP
.