Frage Verwenden Sie IPtables oder Nullroute, um etwa 1 Million IP-Adressen auf die schwarze Liste zu setzen?


Ich bin auf eine Situation gestoßen, in der ein Client eine Menge von knapp 1 Million einzelner IP-Adressen (keine Subnetze) auf die schwarze Liste setzen muss, und die Netzwerkleistung ist ein Problem. Während ich vermuten würde, dass IPTables-Regeln weniger Auswirkungen auf die Performance haben als Routen, ist das nur eine Vermutung.

Verfügt jemand über stichhaltige Beweise oder eine andere Rechtfertigung dafür, entweder IPTables oder Null-Routing als Lösung für die schwarze Liste langer IP-Adresslisten zu bevorzugen? In diesem Fall ist alles automatisiert, daher ist die Benutzerfreundlichkeit kein Problem.

EDIT 26-Nov-11

Nach einigen Tests und Entwicklungen scheint es, dass keine dieser Optionen praktikabel ist. Es scheint, dass sowohl Routensuchen als auch Iptables lineare Suchvorgänge durch den Regelsatz durchführen und einfach zu lange dauern, um diese vielen Regeln zu verarbeiten. Auf moderner Hardware verlangsamen 1M-Einträge in einer iptables-Blacklist den Server auf etwa 2 Dutzend Pakete pro Sekunde. Also IPTables und Null-Routen sind out.

ipset, wie von Jimmy Hedman empfohlen, wäre großartig, außer dass es dir nicht erlaubt, mehr als 65536 Adressen in einem Set zu verfolgen, also kann ich es nicht einmal versuchen, es zu benutzen, außer jemand hat irgendwelche Ideen.

Offensichtlich ist die einzige Lösung zum Blockieren dieser vielen IPs eine indizierte Suche in der Anwendungsschicht. Ist das nicht so?


Mehr Informationen:

Der Anwendungsfall in diesem Fall ist das Blockieren einer "bekannten Täter" -Liste von IP-Adressen vom Zugriff auf statische Inhalte auf einem Webserver. FWIW, Blockierung durch Apache Deny from ist ebenso langsam (wenn nicht mehr so) wie es auch einen linearen Scan macht.


FYI: Endgültige Arbeitslösung war Apache mod_rewrite in Verbindung mit einer Berkeley-DB-Karte, um Lookups gegen die Blacklist zu tun. Die indexierte Natur der Berkeley DBs erlaubte eine Skalierung der Liste mit O (log N) Performance.


21
2017-11-25 22:31


Ursprung


Ist nicht ipset (ipget.netfilter.de) weniger entworfen, um mit dieser Art von Problem umzugehen? - Jimmy Hedman
@JimmyHedman: Du solltest das eine Antwort geben. Und dann füge einen Vorschlag hinzu, um es auf alle 3 Arten zu benchmarken :) - MikeyB
Ich bin neugierig, wenn Sie ein wenig mehr Informationen darüber geben können, welches Problem Sie lösen möchten? Vielleicht ist das Blockieren von 1M-IP-Adressen nicht die Lösung des Problems? - SpacemanSpiff
Es würde viel helfen zu wissen, warum Sie diese vielen Adressen blockieren möchten und ob Sie den INPUT- oder FORWARD-Verkehr filtern wollen. - Juliano
Hier können Sie sehen, wie ipset iptables-Regeln etwa 11x schneller als reguläre iptables-Regeln macht. daemonkeeper.net/781/mass-blocking-ip-addresses-with-ipset Ich hoffe das hilft. - Alien Torres


Antworten:


Verwenden Sie iptables, und erstellen Sie einen mehrstufigen Baum, 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 einen automatischen Weg, die Regeln zu erstellen, und Sie 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 Nachschlagewerke, die sehr wichtig sein müssen, reduzieren tatsächlich arbeiten.


15
2017-11-26 22:38



Das hört sich so an, als ob es funktionieren könnte, wodurch die Zeitkomplexität der Firewallregelsuche von O (n) nach O (log n) effektiv reduziert wird, wodurch effektiv ein Suchbaum in iptables aufgebaut wird. - Per von Zweigbergk
Wenn Sie sich für diese Route entscheiden, ist es wahrscheinlich nützlich, einen Algorithmus zu verwenden, um eine ausgewogene binäre Suchstruktur aus der Liste der IP-Adressen zu erstellen und dann die Struktur dieser Suchstruktur einfach als Satz von IPtables-Regeln zu speichern. - Per von Zweigbergk
@Per von Zweigbergk - in der Tat ... oder einfach den Baum früh abschneiden, wo man keine tieferen Lookups machen muss. Obwohl das Laden dieser gottlosen Menge an Regeln viel Zeit in Anspruch nimmt. - pQd
Dies ist ein sehr guter Ansatz. Offensichtlich erfordert es etwas Bearbeitung, aber es ist die richtige Idee, denke ich. - tylerl
@pQd nach vorherigen Fehlern mit iptables et al., implementierte ich eine Lösung in Apache mit a RewriteMap mit Berkeley-Datenbank. Aber mein mein schnellster Mechanismus, der iptables in einer Schleife verwendet, hat ungefähr 100 Regeln pro Sekunde geladen, während iptables-restore das ganze in ungefähr 4 Sekunden getan hat. Dies ist auf einem Top-of-the-Line-Desktop-Computer. Der RewriteMap-Mechanismus hat eine nicht nachweisbar geringe Auswirkung auf die Leistung. - tylerl


Das ist genau was ipset ist für.

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

Wenn du möchtest

  • speichert mehrere IP-Adressen oder Portnummern und gleicht sie auf einen Schlag mit der Sammlung von iptables ab;
  • Aktualisieren Sie iptables-Regeln dynamisch gegen IP-Adressen oder Ports ohne Leistungseinbußen.
  • Geben Sie komplexe IP-Adressen und Ports-basierte Regelsätze mit einer einzigen iptables-Regel aus und profitieren Sie von der Geschwindigkeit von IP-Sets

dann kann ipset das richtige Werkzeug für Sie sein.

Es wurde von Jozsef Kadlecsik, einem Netfilter-Kernteam-Mitglied, geschrieben (der auch das REJECT-Ziel geschrieben hat), so dass dies die beste Wahl ist, die ich mir vorstellen kann.

Es ist sogar in den letzten Kernel enthalten.


10
2017-11-26 09:10



Soweit ich gesehen habe, ist IPSet bei 65k IP-Adressen. Gibt es einen Settyp, der 1M Einträge verarbeiten kann? - tylerl
Wenn Sie den Typ hash: ip set verwenden, können Sie sehr viele Adressen haben. Ich habe 1000000 probiert und die Leistung war ziemlich gut. Wenn Sie vor dem Überprüfen Ihres Satzes eine -m -State -State-ESTABLISHED-Regel einrichten, können Sie sicherstellen, dass Sie nur die Einstellung für neue Verbindungen überprüfen, die die Leistung beim Umgang mit einer großen Anzahl von Paketen erhöhen würde. - Matthew Ife
Erwähnenswert ist jedoch, dass die Speicherauslastung eines IP-Sets mit 1M-Adressen immer größer wird. Gemäß diesen Beitrag auf der Netfilter Mailingliste Die aktuelle 2015 Formel für die IP-Hash-Größe ist H * 40byte + (N/4 + N%4) * 4 * element size was etwa 1M-Adressen in einem 1,5-m-Slot-Hash ergibt. Die Verwendung der Apache / Berkdb-Lösung speichert die Daten auf der Festplatte und lädt nur die Seiten der aktiven Adressen. - M Conrad


Ich habe das selbst nicht getestet, aber als ich deine Problembeschreibung gehört habe, dachte ich sofort "pf"(wie von OpenBSD).

pf hat das Konzept von Adresstabellen was genau das ist, wonach du suchst.

Nach einigen sehr oberflächliche Forschung, die ich getan habe, scheint es, dass dies das Potenzial hat, besser zu skalieren als ipset. Gemäß das PF FAQ's Kapitel zu Laufzeitoptionenout of the box ohne tuning unterstützt pf insgesamt 1.000 tabellen mit insgesamt 200.000 einträgen über alle tabellen hinweg. (100.000, wenn das System <100 MB physischen Speicher hat). Dies lässt mich glauben, dass es zumindest einen Versuch wert ist, dies zu testen, um zu sehen, ob es auf irgendeiner nützlichen Ebene funktioniert.

Natürlich nehme ich an, dass Sie Ihre Server unter Linux betreiben, also müssten Sie eine separate Firewall-Box haben, auf der ein Betriebssystem mit PF läuft (wie OpenBSD oder FreeBSD). Sie können möglicherweise auch den Durchsatz verbessern, indem Sie auf jegliche Art von Paketfilterung verzichten.


5
2017-11-26 22:42



Die Server-Architektur des Clients in BSD zu konvertieren, ist nicht wirklich eine Option. Ich denke aber zumindest aus der Schublade. - tylerl
Sie müssten nicht die gesamte Serverarchitektur in BSD konvertieren, es wäre ausreichend, eine Firewall zu erstellen, die vor den echten Server gestellt wird. (Einfach genug in einer VM zu tun.) - Per von Zweigbergk


Haben Sie eine FIB_TRIE anstelle von FIB_HASH untersucht?

FIB_TRIE sollte für deine Präfixzahlen viel besser skalieren. (/ 32s Nullrouten sind immer noch Präfixe, nur sehr spezifisch)

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

FIB_TRIE Hinweise


2
2017-11-26 23:53





Für die Nachwelt: nach ipset Docs die Standardgröße eines Satzes ist 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 im Set gespeichert werden können, standardmäßig 65536. Beispiel: ipset create test hash:ip maxelem 2048.

Ich stelle das hier her, da ich noch nichts sagen kann.


1
2017-11-14 19:53





Einige hilfreiche Hinweise für jeden, der in Zukunft über dieses Problem stolpert:

Analysieren Sie zunächst keinen Datenverkehr, den Sie nicht benötigen. Wenn Sie zum Beispiel TCP-Datenverkehr blockieren, filtern Sie nur die SYN-Pakete. Auf diese Weise treffen Sie den Filter nur einmal pro Verbindung. Sie können verwenden -m state Wenn Sie möchten, aber das Verbindungs-Tracking hat einen eigenen Overhead, den Sie möglicherweise vermeiden möchten, wenn die Leistung ein Problem darstellt.

Zweitens dauert es einige Minuten, eine Million Regeln in iptables zu setzen. Wenn Sie diese vielen Entitäten nachverfolgen müssen, sollten Sie sie besser aus Netfliter heraushalten. Die schiere Größe des Regelsatzes macht einen Unterschied.

Drittens ist das Ziel, lineare Scans zu vermeiden; aber leider sind sowohl iptables als auch iproute2 von Natur aus linear. Sie können Ihre Regeln aus dem Binärbaum-Stil in eine große Anzahl von Ketten aufteilen, was die Anzahl der Regeln begrenzt, die Sie konsultieren müssen, aber selbst für diese Problemgröße ist iptables nicht geeignet. Es wird funktionieren, aber es ist eine Verschwendung wertvoller Ressourcen.

Viertens, und am wichtigsten, ist es keine schlechte Idee, die Arbeitslast auf den Benutzer zu übertragen. So können Sie Ihren eigenen engen Code schreiben oder eine Standardlösung verwenden, die auf Ihre Problemstellung abgestimmt ist. Meine eigene Lösung für dieses Problem war, wie erwähnt, die Verwendung von BDB-Lookups, die durch das mod_rewrite-System von Apache ausgelöst wurden. Dies hatte den zusätzlichen Vorteil, dass nur eine Suche pro Sitzung ausgelöst wurde, und erst nachdem eine gültige Anfrage gesendet wurde. In diesem Fall war die Leistung extrem schnell und die Kosten der Blockliste waren fast vernachlässigbar.

Sie können ähnliche Benutzerbereichsmanipulationen mit iptables durchführen, indem Sie die -j QUEUE Ziel in Verbindung mit libnetfilter_queue. Dieses Tool ist leistungsstark, einfach und schlecht dokumentiert. Ich würde empfehlen, so viel wie möglich von so vielen Quellen wie möglich zu lesen, da es viel interessantes Material im Internet gibt, das nicht Teil einer offiziellen Dokumentation ist.


0
2017-09-19 04:40