Verwenden Sie IP-Tabellen oder die Nullroute, um ungefähr 1 Million IP-Adressen auf eine schwarze Liste zu setzen?


22

Ich bin auf eine Situation gestoßen, in der ein Client einen Satz von knapp 1 Million einzelnen IP-Adressen (keine Subnetze) auf die schwarze Liste setzen muss und die Netzwerkleistung ein Problem darstellt. Ich würde zwar vermuten, dass IPTables-Regeln eine geringere Auswirkung auf die Leistung haben als Routen, aber das ist nur eine Vermutung.

Hat jemand einen soliden Beweis oder eine andere Rechtfertigung für die Bevorzugung von IPTables oder Null-Routing als Lösung für die Sperrung langer Listen von IP-Adressen? In diesem Fall ist alles automatisiert, so dass die Benutzerfreundlichkeit eigentlich kein Problem darstellt.

EDIT 26-Nov-11

Nach einigen Tests und Entwicklungen scheint keine dieser Optionen funktionsfähig zu sein. Es scheint, dass sowohl Routensuchen als auch Iptables den Regelsatz linear durchsuchen und einfach zu lange brauchen, um so viele Regeln zu verarbeiten. Auf moderner Hardware verlangsamt das Speichern von 1 Million Elementen in einer Iptables-Blacklist den Server auf etwa 2 Dutzend Pakete pro Sekunde. IPTables und Null-Routen sind also aus.

ipsetWie von Jimmy Hedman empfohlen, wäre das großartig, außer dass Sie nicht mehr als 65536 Adressen in einem Set verfolgen können. Daher kann ich nicht einmal versuchen, es zu verwenden, es sei denn, jemand hat irgendwelche Ideen.

Anscheinend ist die einzige Lösung, um diese vielen IPs zu blockieren, eine indizierte Suche in der Anwendungsschicht. Ist das nicht so


Mehr Informationen:

In diesem Fall blockiert der Anwendungsfall den Zugriff einer Liste mit IP-Adressen, die als "bekannte Straftäter" eingestuft wurden, auf statische Inhalte auf einem Webserver. FWIW: Das Blockieren durch Apache Deny fromist ebenso langsam (wenn nicht sogar langsamer) wie das Ausführen eines linearen Scans.


Zu Ihrer Information: Die endgültige Lösung bestand darin, Apaches mod_rewrite in Verbindung mit einer Berkeley-DB-Map zu verwenden, um Lookups für die Blacklist durchzuführen. Aufgrund der Indizierung der Berkeley-DBs konnte die Liste mit der Leistung O (log N) skaliert werden.


5
Ist ipset ( ipset.netfilter.org ) nicht eher weniger darauf ausgelegt, diese Art von Problem zu lösen?
Jimmy Hedman

@ JimmyHedman: Sie sollten das eine Antwort machen. Und dann fügen Sie einen Vorschlag zum Benchmark hinzu, indem Sie alles auf 3 Arten machen :)
MikeyB

Ich bin neugierig, ob Sie ein bisschen mehr Informationen darüber geben können, welches Problem Sie lösen möchten. Vielleicht ist das Blockieren von 1M-IP-Adressen nicht der richtige Weg, um das Problem zu beheben?
SpacemanSpiff

Es wäre sehr hilfreich zu wissen, warum Sie so viele Adressen blockieren und ob Sie INPUT- oder FORWARD-Datenverkehr filtern möchten.
Juliano

Hier können Sie sehen, wie ipset iptables-Regeln etwa 11x schneller als reguläre iptables-Regeln erstellt. daemonkeeper.net/781/mass-blocking-ip-addresses-with-ipset Hoffe, dass diese Hilfe.
Alien Torres

Antworten:


15

Versuchen Sie, iptables zu verwenden und einen mehrstufigen Baum zu erstellen, um die Anzahl der Suchvorgänge zu verringern.

iptables -N rules_0_0_0_0_2
iptables -N rules_64_0_0_0_2
iptables -N rules_128_0_0_0_2
iptables -N rules_192_0_0_0_2
iptables -N rules_0_0_0_0_4
iptables -N rules_16_0_0_0_4

iptables -A INPUT -p tcp --dport 80 -s 0.0.0.0/2 -j rules_0_0_0_0_2
iptables -A INPUT -p tcp --dport 80 -s 64.0.0.0/2 -j rules_64_0_0_0_2
iptables -A INPUT -p tcp --dport 80 -s 128.0.0.0/4 -j rules_128_0_0_0_2
iptables -A INPUT -p tcp --dport 80 -s 192.0.0.0/4 -j rules_192_0_0_0_2

iptables -A rules_0_0_0_0_2 -s 0.0.0.0/4 -j rules_0_0_0_0_4
iptables -A rules_0_0_0_0_2 -s 16.0.0.0/4 -j rules_16_0_0_0_4

und so weiter - Hinzufügen von Verschachtelungsebenen; Natürlich brauchen Sie eine automatische Methode zum Erstellen der Regeln und sollten Ketten nur für die Netzwerke haben, in denen Sie einen oder mehrere Täter haben. Auf diese Weise können Sie die Anzahl der Suchvorgänge erheblich reduzieren, und ich denke, das könnte der Fall sein eigentlich arbeiten.


Dies hört sich so an, als ob es funktionieren könnte, wodurch die zeitliche Komplexität der Suche nach Firewall-Regeln von O (n) auf O (log n) reduziert und effektiv ein Suchbaum in iptables erstellt wird.
Per von Zweigbergk

Wenn Sie sich für diesen Weg entscheiden, wäre es wahrscheinlich nützlich, einen Algorithmus zu verwenden, um einen ausgeglichenen binären Suchbaum aus der Liste der IP-Adressen zu erstellen und dann einfach die Struktur dieses Suchbaums als Satz von IPtables-Regeln auszugeben.
Per von Zweigbergk

@Per von Zweigbergk - in der Tat ... oder beschneiden Sie den Baum einfach frühzeitig, ohne dass Sie tiefer suchen müssen. Obwohl das Laden dieser gottlosen Menge an Regeln viel Zeit in Anspruch nehmen wird.
pQd

Dies ist ein sehr guter Ansatz. Natürlich ist ein wenig Verarbeitung erforderlich, aber ich denke, das ist die richtige Idee.
Tyler

3
@pQd Nach früheren Ausfällen mit iptables et al. implementierte ich eine Lösung in Apache unter Verwendung einer RewriteMap mit Berkeley-Datenbank. Aber mein schnellster Mechanismus, der iptables in einer Schleife verwendet, lud ungefähr 100 Regeln pro Sekunde, während iptables-restore den gesamten Satz in ungefähr 4 Sekunden erledigte. Dies ist ein erstklassiger Desktop-Computer. Der RewriteMap-Mechanismus hat einen nicht nachweisbaren geringen Einfluss auf die Leistung.
tylerl

11

Genau dafür ipsetist.

Von seiner Website http://ipset.netfilter.org/ :

Wenn du möchtest

  • Speichern Sie mehrere IP-Adressen oder Portnummern und vergleichen Sie diese auf einen Schlag mit der Sammlung von iptables.
  • iptables-Regeln dynamisch anhand von IP-Adressen oder Ports ohne Leistungseinbußen aktualisieren;
  • Drücken Sie komplexe, auf IP-Adressen und Ports basierende Regelsätze mit einer einzigen iptables-Regel aus und profitieren Sie von der Geschwindigkeit der IP-Sätze

Dann ist ipset vielleicht das richtige Werkzeug für Sie.

Es wurde von Jozsef Kadlecsik, einem Mitglied des Netfilter-Kernteams, geschrieben (der auch das REJECT-Ziel geschrieben hat). Das ist also die beste Wahl, die ich mir vorstellen kann.

Es ist sogar in den aktuellen Kerneln enthalten.


Soweit ich gesehen habe, ist ipset bei 65.000 IP-Adressen top. Gibt es einen Settyp, der 1 Millionen Einträge verarbeiten kann?
tylerl

7
Wenn Sie den Settyp hash: ip verwenden, können Sie eine sehr große Anzahl von Adressen haben. Ich habe 1000000 ausprobiert und die Leistung war ziemlich gut. Wenn Sie eine -m state --state ESTABLISHED-Regel einrichten, bevor Sie Ihren Satz überprüfen, können Sie sicherstellen, dass Sie den Satz nur bei neuen Verbindungen überprüfen, was die Leistung bei der Verarbeitung einer großen Anzahl von Paketen erhöhen würde.
Matthew Ife

Erwähnenswert ist jedoch, dass die Speichernutzung eines IPSets mit 1M-Adressen langsam zunimmt. Laut diesem Beitrag auf der Netfilter-Mailingliste beträgt H * 40byte + (N/4 + N%4) * 4 * element sizedie aktuelle Formel für die IPSet-Hash-Größe für 2015 ungefähr 64 MB für 1 MB Adressen in einem Hash mit 1,5 Mio. Slots. Mit der Apache / Berkdb-Lösung werden die Daten auf der Festplatte gespeichert und nur die Seiten der aktiven Adressen geladen.
M Conrad

5

Ich habe das selbst nicht getestet, aber als ich Ihre Problembeschreibung hörte, dachte ich sofort " pf" (wie von OpenBSD).

pfhat das Konzept von Adresstabellen, die genau das sind, wonach Sie suchen.

Nach einigen sehr flüchtigen Nachforschungen, die ich angestellt habe, scheint dies das Potenzial zu haben, besser als zu skalieren ipset. Gemäß dem Kapitel zu Laufzeitoptionen in den häufig gestellten Fragen (FAQ) von PF werden standardmäßig 1.000 Tabellen mit insgesamt 200.000 Einträgen in allen Tabellen unterstützt. (100.000, wenn das System über einen physischen Speicher von <100 MB verfügt). Dies lässt mich glauben, dass es sich zumindest lohnt, zu versuchen, dies zu testen, um festzustellen, ob es auf einer nützlichen Ebene funktioniert.

Natürlich gehe ich davon aus, dass Sie Ihre Server unter Linux betreiben, sodass Sie eine separate Firewall-Box benötigen, auf der ein Betriebssystem mit pf (wie OpenBSD oder FreeBSD) ausgeführt wird. Möglicherweise können Sie auch den Durchsatz verbessern, indem Sie auf jede Art von Stateful Packet Filtering verzichten.


Das Konvertieren der Serverarchitektur des Clients in BSD ist keine Option. Zumindest über den Tellerrand hinaus denken.
Tyler

2
Sie müssten nicht die gesamte Serverarchitektur auf BSD konvertieren, es würde ausreichen, eine Firewall zu erstellen, die vor den realen Server gestellt wird. (Einfach genug, um in einer VM zu tun.)
Per von Zweigbergk

2

Haben Sie mit einem FIB_TRIE anstelle von FIB_HASH untersucht.

FIB_TRIE sollte für Ihre Präfixzählungen viel besser skaliert werden. (/ 32s Null-Routen sind immer noch Präfixe, nur sehr spezifisch)

Möglicherweise müssen Sie Ihren eigenen Kernel kompilieren, um ihn zu verwenden, aber es hilft.

FIB_TRIE Hinweise


2

Für die Nachwelt: Laut ipsetDokumentation ist die Standardgröße eines Sets 65536, dies kann durch Optionen geändert werden.

maxelem Dieser Parameter gilt für den Befehl create aller Hash-Typ-Sets. Es definiert die maximale Anzahl von Elementen, die in der Menge gespeichert werden können, Standard 65536. Beispiel:ipset create test hash:ip maxelem 2048.

Ich habe dies hier eingestellt, da ich noch keinen Kommentar abgeben kann.


1

Einige hilfreiche Hinweise für alle, die in Zukunft auf dieses Problem stoßen:

Analysieren Sie zunächst keinen Verkehr, den Sie nicht benötigen. Wenn Sie beispielsweise den TCP-Verkehr blockieren, filtern Sie nur die SYN-Pakete. Auf diese Weise treffen Sie den Filter nur einmal pro Verbindung. Sie können verwenden, -m statewenn Sie möchten, aber die Verbindungsverfolgung hat ihren eigenen Overhead, den Sie möglicherweise vermeiden möchten, wenn die Leistung ein Problem darstellt.

Zweitens dauert es lange, eine Million Regeln in iptables abzulegen: mehrere Minuten. Wenn Sie so viele Entitäten nachverfolgen müssen, sollten Sie sie wahrscheinlich außerhalb von Netfliter aufbewahren. Die schiere Größe des Regelsatzes macht einen Unterschied.

Drittens ist das Ziel, lineare Scans zu vermeiden; Leider sind sowohl iptables als auch iproute2 von Natur aus linear. Sie können Ihre Regeln im Binärbaumstil in eine große Anzahl von Ketten aufteilen, wodurch die Anzahl der Regeln, die Sie konsultieren müssen, begrenzt wird. Trotzdem ist iptables für diese Problemgröße nicht gut geeignet. Es wird funktionieren , aber es ist eine Verschwendung von wertvollen Ressourcen.

Viertens und vor allem ist es keine schlechte Idee, die Arbeitslast auf den Benutzerbereich zu verlagern. Auf diese Weise können Sie Ihren eigenen engen Code schreiben oder eine Standardlösung verwenden, die auf Ihre Problemstellung abgestimmt ist. Wie bereits erwähnt, bestand meine eigene Lösung darin, BDB-Lookups zu verwenden, die über das mod_rewrite-System von apache ausgelöst wurden. Dies hatte den zusätzlichen Vorteil, nur eine Suche pro Sitzung auszulösen, und zwar erst, nachdem eine gültige Anfrage eingereicht wurde. In diesem Fall war die Leistung extrem schnell und die Kosten für die Sperrliste waren nahezu vernachlässigbar.

Sie können ähnliche Benutzerbereichsmanipulationen mit iptables ausführen, indem Sie das -j QUEUEZiel in Verbindung mit verwenden libnetfilter_queue. Dieses Tool ist leistungsstark, einfach und schlecht dokumentiert. Ich würde empfehlen, so viel wie möglich aus so vielen Quellen zu lesen, wie Sie finden können, da im Internet viele interessante Materialien verstreut sind, die nicht Teil einer offiziellen Dokumentation sind.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.