web-dev-qa-db-fra.com

Comment puis-je gérer par programmation les règles iptables à la volée?

Je dois interroger les règles existantes, ainsi que pouvoir facilement ajouter et supprimer des règles. Je n'ai trouvé aucune API pour ce faire. Y a-t-il quelque chose qui me manque?

La solution la plus proche que j'ai trouvée est d'utiliser iptables-save | iptables-xml pour interroger et appeler manuellement la commande iptables elle-même pour ajouter/supprimer des règles. Une autre solution que j'ai envisagée consiste simplement à régénérer l'ensemble des règles de la base de données de mon application et à vider la chaîne entière, puis à la réappliquer. Mais je veux éviter cela car je ne veux pas supprimer de paquets - à moins qu'il n'y ait un moyen de le faire de manière atomique. Je me demande s'il y a une meilleure façon.

Une API en C serait formidable; cependant, comme je prévois de l'intégrer dans un programme suid autonome, les bibliothèques qui le font dans N'IMPORTE QUELLE langue sont également très bien.

39
Ycros

De la FAQ netfilter :

Malheureusement, la réponse est: non.

Maintenant, vous pourriez penser "mais qu'en est-il de libiptc?". Comme cela a été souligné à plusieurs reprises sur la ou les listes de diffusion, libiptc n'était [~ # ~] jamais [~ # ~] destiné à être utilisé comme une interface publique. Nous ne garantissons pas une interface stable, et il est prévu de la supprimer lors de la prochaine incarnation du filtrage de paquets Linux. libiptc est bien trop bas pour être utilisé raisonnablement de toute façon.

Nous sommes bien conscients qu'il y a un manque fondamental pour une telle API, et nous travaillons à améliorer cette situation. Jusque-là, il est recommandé soit d'utiliser system () soit d'ouvrir un tube dans stdin de iptables-restore. Ce dernier vous donnera de bien meilleures performances.

19
Eric Lathrop

Utiliser iptables-save et iptables-restore pour interroger et régénérer des règles est facilement le moyen le plus efficace de le faire. Autrefois, ces scripts étaient des scripts Shell, mais maintenant ce sont des programmes C qui fonctionnent très efficacement.

Cependant, je dois souligner qu'il existe un outil que vous pouvez utiliser pour faciliter la maintenance d'iptables. La plupart des ensembles de règles dynamiques sont en fait la même règle répétée plusieurs fois, comme:

iptables -A INPUT -s 1.1.1.1 -p tcp -m --dport 22 -j ACCEPT
iptables -A INPUT -s 2.2.2.0/24 -p tcp -m --dport 22 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 22 -j REJECT

Au lieu de remplacer ces règles à chaque fois que vous souhaitez modifier les ports qui peuvent accéder au port 22 (utile, par exemple, le détournement de port), vous pouvez utiliser des ipsets. Viz:

ipset -N ssh_allowed nethash
iptables -A ssh_allowed -m set --set ssh_allowed src -p tcp -m --dport 22 -j ACCEPT
ipset -A ssh_allowed 1.1.1.1
ipset -A ssh_allowed 2.2.2.0/24

Les ensembles peuvent contenir des adresses IP, des réseaux, des ports, des adresses Mac et avoir des délais d'expiration sur leurs enregistrements. (Vous avez toujours voulu ajouter quelque chose pendant juste une heure?).

Il existe même une méthode atomique pour échanger un ensemble avec un autre, donc une actualisation signifie créer un nouvel ensemble temporaire, puis l'échanger en tant que nom de l'ensemble existant.

12
Jerub

Vous pouvez envisager d'utiliser rfw qui est l'API REST pour iptables. Il sérialise les commandes iptables à partir de diverses sources potentiellement simultanées et exécute à distance iptables à la volée.

rfw est conçu pour les systèmes distribués qui essaient de mettre à jour les règles de pare-feu sur plusieurs boîtiers mais il peut également être exécuté sur une seule machine sur l'interface localhost. Ensuite, il permet d'éviter la surcharge SSL et d'authentification car il peut être exécuté sur HTTP simple dans ce cas.

Exemple de commande:

PUT /drop/input/eth0/11.22.33.44

ce qui correspond à:

iptables -I INPUT -i eth0 -s 11.22.33.44 -j DROP

Vous pouvez insérer et supprimer des règles ainsi que rechercher l'état actuel pour obtenir les règles existantes au format JSON:

GET /list/input

Avertissement: j'ai commencé ce projet. C'est open source sous la licence MIT.

9
Grzegorz Luczywo

Pour autant que je sache (bien qu'aucune référence ne semble le mentionner), iptables-restore Est atomique. À la fin, lorsque la ligne COMMIT est lue, iptables appelle iptc_commit Dans libiptc (que vous n'êtes pas censé utiliser dans une interface interne) , qui appelle ensuite setsockopt(SO_SET_REPLACE) avec vos nouveaux ensembles de règles.

Cela semble aussi atomique que possible: avec un seul appel de noyau. Cependant, des parties plus informées sont invitées à contester cela. :-)

Edit: je peux confirmer que votre description est correcte. iptables-restore Se fait comme une opération atomique dans le noyau.

Pour être encore plus spécifique l'opération "seulement" est atomique par CPU. Comme nous stockons l'intégralité du blob d'ensemble de règles par processeur (en raison des optimisations de cache).

4
Chris Jester-Young

Il n'y a délibérément pas d'API pour gérer ces règles. Vous n'êtes pas censé vouloir le faire. Ou quelque chose.

Si vous avez besoin de règles suffisamment dynamiques, vous vous souciez des performances de l'exécution de/sbin/iptables, il existe d'autres façons de le faire:

  • En utilisant quelque chose comme la correspondance "récente" ou la correspondance d'ensembles IP, vous pouvez ajouter/supprimer des adresses IP des listes noires/blanches sans modifier l'ensemble de règles.
  • Vous pouvez passer des paquets dans l'espace utilisateur pour le filtrage à l'aide de NFQUEUE
3
MarkR

Ce matin, je me suis réveillé pour découvrir que la Russie recevait une attaque par déni de service (DOS). Ils me frappaient à partir de dizaines de blocs IP. Ils doivent avoir eu un grand pool d'adresses IP ou une sorte de liste/service proxy. Chaque fois que je bloquais une adresse IP, une autre surgissait. Enfin, j'ai cherché un script et j'ai trouvé que j'avais besoin d'écrire ma propre solution. Ce qui suit est un peu agressif, mais ils exécutaient mon TOP LOAD LEVEL à plus de 200.

Voici un script rapide que j'ai écrit pour bloquer le DOS en temps réel.

cat  **"output of the logs"** | php ipchains.php **"something unique in the logs"**

==> PHP Script:

<?php

$ip_arr = array();

while(1)
{
   $line = trim(fgets(STDIN)); // reads one line from STDIN
   $ip = trim( strtok( $line, " ") );

   if( !array_key_exists( $ip, $ip_arr ) )
      $ip_arr[$ip] = 0;

   $regex = sprintf( "/%s/", $argv[1] );

   $cnt = preg_match_all( $regex, $line );

   if( $cnt < 1 ) continue;

   $ip_arr[$ip] += 1;

   if( $ip_arr[$ip] == 1  )
     {
//     printf( "%s\n", $argv[1] );
//     printf( "%d\n", $cnt );
//     printf( "%s\n", $line );

       printf( "-A BLOCK1 -s %s/24 -j DROP\n", $ip );

       $cmd = sprintf( "/sbin/iptables  -I BLOCK1  -d %s/24 -j DROP", $ip );
       system( $cmd );
     }
}

?>

Hypothèses:

1) BLOCK1 is a Chain already created. 
2) BLOCK1 is a Chain that is run/called from the INPUT CHAIN 
3) Periodically you will need to run "ipchains -S BLOCK1" and put output in /etc/sysconfig file. 
4) You are familiar with PHP 
5) You understand web log line items/fields and output.
2
Patrick

Ceci est un exemple d'utilisation de bash et iptables pour bloquer dynamiquement les pirates abusant de sshd sur CentOS. Dans ce cas, j'ai configuré sshd pour interdire la connexion par mot de passe (autorise les clés). Je regarde dans/var/log/secure pour les entrées de "Bye Bye", qui est la façon polie de sshd de dire f-off ...

IP=$(awk '/Bye Bye/{print $9}' /var/log/secure |
     sed 's/://g' |sort -u | head -n 1)

[[ "$IP" < "123" ]] || {

  echo "Found $IP - blocking it..." >> /var/log/hacker.log

  /sbin/iptables -A INPUT -s $IP -j DROP

  service iptables save

  sed -i "/$IP/d" /var/log/secure

}

Je lance cela en boucle toutes les secondes, ou minutes, ou tout ce qui me rend heureux. Je teste la valeur de $ IP pour vérifier qu'elle a trouvé une valeur utile, si c'est le cas j'invoque iptables pour la supprimer, et j'utilise sed pour purger le fichier journal de $ IP afin que l'entrée ne soit pas ajoutée à nouveau.

Je fais un peu de prétraitement (non illustré) pour mettre sur liste blanche certaines adresses IP importantes qui sont toujours valides et qui pourraient avoir eu des problèmes de connexion (en raison d'une erreur de l'utilisateur).

De temps en temps, je trie la liste des filtres iptables et en crée des plages IP (en utilisant un script différent - et une fois vérifiées, ce sont généralement des plages IP en provenance d'Inde, de Chine et de Russie). Ainsi, mon ensemble de règles de filtre iptables global reste entre 50 et 500 entrées; ipset n'améliore pas vraiment beaucoup sur une liste aussi courte.

1
Andrew

MarkR a raison, vous n'êtes pas censé faire ça. Le moyen le plus simple est d'appeler iptables à partir du script ou d'écrire la configuration iptables et de la "restaurer".

Si vous le souhaitez, lisez la source d'iptables. iptables utilise des correspondances et des tables comme objets partagés. Vous pouvez utiliser la source ou eux.

Le netfilter Linux possède également certains fichiers include sous/usr/include/netfilter *. Ce sont des fonctions de bas niveau. C'est ce qu'utilise iptables. C'est aussi proche d'une API que l'on peut obtenir sans iptables.

Mais cette API est "désordonnée". Gardez à l'esprit qu'il a été conçu pour être utilisé uniquement par iptables. Ce n'est pas très bien documenté, vous pouvez rencontrer des problèmes très spécifiques, l'API peut changer assez rapidement sans aucun avertissement, donc une mise à niveau cassera votre code, etc.

0
terminus