Je suis tombé sur une situation où un client doit mettre sur liste noire un ensemble d'un peu moins d'un million d'adresses IP individuelles (pas de sous-réseaux), et les performances du réseau sont une préoccupation. Bien que je suppose que les règles IPTables auraient moins d'impact sur les performances que les routes, ce n'est qu'une conjecture.
Quelqu'un a-t-il des preuves solides ou une autre justification pour favoriser IPTables ou le routage nul comme solution pour mettre sur liste noire les longues listes d'adresses IP? Dans ce cas, tout est automatisé, donc la facilité d'utilisation n'est pas vraiment un problème.
EDIT 26-Nov-11
Après quelques tests et développements, il semble qu'aucune de ces options ne soit réalisable. Il semble que les recherches d'itinéraire et iptables effectuent des recherches linéaires dans l'ensemble de règles et prennent tout simplement trop de temps pour traiter ces nombreuses règles. Sur le matériel moderne, mettre 1M d'éléments dans une liste noire iptables ralentit le serveur à environ 2 douzaines de paquets par seconde. Les IPTables et les routes nulles sont donc sortis.
ipset
, comme recommandé par Jimmy Hedman, serait génial, sauf qu'il ne vous permet pas de suivre plus de 65536 adresses dans un ensemble, donc je ne peux même pas essayer de l'utiliser à moins que quelqu'un n'ait des idées.
Apparemment, la seule solution pour bloquer autant d'IP consiste à effectuer une recherche indexée dans la couche application. N'est-ce pas?
Plus d'information:
Dans ce cas, le cas d'utilisation empêche une liste d'adresses IP de "contrevenants connus" d'accéder à du contenu statique sur un serveur Web. FWIW, le blocage via Apache Deny from
est tout aussi lent (sinon plus) car il effectue également un balayage linéaire.
FYI: La solution de travail finale consistait à utiliser le mod_rewrite d'apache en conjonction avec une carte berkeley DB pour effectuer des recherches sur la liste noire. La nature indexée des bases de données berkeley a permis à la liste d'évoluer avec les performances O (log N).
Réponses:
essayez d'utiliser iptables et de créer une arborescence à plusieurs niveaux pour réduire le nombre de recherches.
et ainsi de suite - ajout de niveaux d'imbrication; évidemment, vous aurez besoin d'un moyen automatique de construire les règles et vous devriez avoir des chaînes uniquement pour les réseaux où vous avez un ou plusieurs délinquants - de cette façon, vous pouvez réduire le nombre de recherches qui doivent être faites de manière assez significative et je pense que cela pourrait fonctionne réellement.
la source
C'est exactement pour ça
ipset
.Depuis son site Web http://ipset.netfilter.org/ :
Si tu veux
alors l'ipset peut être l'outil approprié pour vous.
Il est écrit par un membre de l'équipe de base de Netfilter, Jozsef Kadlecsik (qui a également écrit la cible REJECT), c'est donc le meilleur choix auquel je puisse penser.
Il est même inclus dans les noyaux récents.
la source
H * 40byte + (N/4 + N%4) * 4 * element size
d'environ 64 Mo pour 1M d'adresses dans un hachage de 1,5 m. L'utilisation de la solution apache / berkdb stocke les données sur disque et ne charge que les pages des adresses actives.Je n'ai pas testé cela moi-même, mais quand j'ai entendu la description de votre problème, j'ai immédiatement pensé "
pf
" (comme d'OpenBSD).pf
a le concept de tables d'adresses qui peut être juste ce que vous cherchez.Selon certaines recherches très sommaires que j'ai faites, il semblerait que cela puisse évoluer mieux que
ipset
. Selon le chapitre de la FAQ de PF sur les options d'exécution, prêt à l'emploi sans réglage, pf prend en charge un total de 1 000 tables, avec un total de 200 000 entrées sur toutes les tables par défaut. (100 000 si le système a une mémoire physique <100 Mo). Cela m'amène à croire qu'il vaut au moins la peine d'essayer de tester cela pour voir s'il fonctionne à un niveau utile.Bien sûr, je suppose que vous exécutez vos serveurs sous Linux, vous devez donc disposer d'un pare-feu séparé exécutant un système d'exploitation avec pf (comme OpenBSD ou FreeBSD). Vous pouvez également améliorer le débit en supprimant tout type de filtrage de paquets avec état.
la source
Avez-vous étudié l'utilisation d'un FIB_TRIE au lieu de FIB_HASH.
FIB_TRIE devrait évoluer beaucoup mieux pour le nombre de préfixes. (Les routes nulles / 32s sont toujours des préfixes, juste très spécifiques)
Vous devrez peut-être compiler votre propre noyau pour l'utiliser, mais cela aide.
FIB_TRIE Notes
la source
Pour la postérité: selon les
ipset
documents, la taille par défaut d'un ensemble est 65536, cela peut être modifié par les options.Je mets ceci ici car je ne peux pas encore commenter.
la source
Quelques notes utiles pour tous ceux qui tomberont sur ce problème à l'avenir:
Tout d'abord, n'analysez aucun trafic dont vous n'avez pas besoin. Si vous bloquez le trafic TCP, par exemple, ne filtrez que les paquets SYN, de cette façon vous n'appuyez sur le filtre qu'une seule fois par connexion. Vous pouvez l'utiliser
-m state
si vous le souhaitez, mais le suivi des connexions a sa propre surcharge que vous pouvez éviter si les performances sont un problème.Deuxièmement, mettre un million de règles dans iptables prend beaucoup de temps: plusieurs minutes. Si vous avez besoin de suivre autant d'entités, vous feriez probablement mieux de les garder hors de Netfliter. La taille même de l'ensemble de règles fait une différence.
Troisièmement, l'objectif est d'éviter les balayages linéaires; mais malheureusement, iptables et iproute2 sont intrinsèquement linéaires. Vous pouvez diviser vos règles en style arbre binaire en un grand nombre de chaînes, ce qui limite le nombre de règles que vous devez consulter, mais même quand même, iptables n'est pas bien adapté à cette taille de problème. Cela fonctionnera , mais c'est un gaspillage de ressources précieuses.
Quatrièmement et surtout, pousser votre charge de travail vers l'espace utilisateur n'est pas une mauvaise idée. Cela vous permet d'écrire votre propre code serré ou d'utiliser une solution standard adaptée à votre ensemble de problèmes. Ma propre solution à ce problème, comme mentionné, était d'utiliser des recherches BDB déclenchées par le système mod_rewrite d'Apache. Cela avait l'avantage supplémentaire de déclencher une seule recherche par session, et uniquement après qu'une demande valide avait été soumise. Dans ce cas, les performances étaient extrêmement rapides et le coût de la liste de blocage était presque négligeable.
Vous pouvez effectuer une manipulation similaire de l'espace utilisateur avec iptables en utilisant la
-j QUEUE
cible conjointement aveclibnetfilter_queue
. Cet outil est puissant, simple et mal documenté. Je recommanderais de lire autant que possible à partir d'autant de sources que vous pouvez trouver, car il y a beaucoup de documents intéressants dispersés sur le Web qui ne font partie d'aucune documentation officielle.la source