Begrenzen Sie die maximale Anzahl von Verbindungen pro IP-Adresse und die Anzahl neuer Verbindungen pro Sekunde mit iptables

37

Wir haben einen Ubuntu 12.04 Server mit httpd auf Port 80 und wir wollen einschränken:

  • die maximalen Verbindungen pro IP-Adresse zu httpd bis 10
  • die maximale Anzahl neuer Verbindungen pro Sekunde zu httpd bis 150

Wie können wir das mit iptables machen?

evachristine
quelle

Antworten:

48
iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 15 --connlimit-mask 32 -j REJECT --reject-with tcp-reset  

Dadurch werden Verbindungen über 15 von einer Quell-IP zurückgewiesen.

iptables -A INPUT -m state --state RELATED,ESTABLISHED -m limit --limit 150/second --limit-burst 160 -j ACCEPT  

Hierbei sind 160 neue Verbindungen (Pakete wirklich) zulässig, bevor das Limit von 150 neuen Verbindungen (Paketen) pro Sekunde angewendet wird.

Totti
quelle
1
Kann das oben Genannte so eingerichtet werden, dass es an allen Ports funktioniert, nicht nur an Port 80?
EminezArtus
1
Sind Sie sicher, dass dies per IP ist?
LatinSuD
2
Um diese Regel für alle Ports festzulegen, entfernen Sie einfach --dport 80.
Dan Pritts
5
Die zweite Regel funktioniert NICHT bei "neuen Verbindungen". Bestehende ("ESTABLISHED") Verbindungen sind davon ausdrücklich betroffen. Wenn Sie neue Verbindungen herstellen möchten, möchten Sie --state NEW. Sie könnten auch in Betracht ziehen, -m conntrack --ctstateanstelle von -m state --state. conntrack ist neu und verbessert gegen state.
Dan Pritts
2
der obige Kommentar zum Hinzufügen der 2. Regel zu NEWVerbindungen - tun Sie das nicht - es macht Ihre INPUTKette effektiv zu einem Standard accept!!!
Stuart Cardall
8

Sie möchten, dass die folgenden Regeln in Ihren iptables beide Anforderungen in Ihrer Frage beantworten:

iptables -t filter -I INPUT -p tcp --dport 80 -j ACCEPT

iptables -t filter -I INPUT -p tcp --dport 80 -m state \
  --state RELATED,ESTABLISHED -j ACCEPT

# Adjust "--connlimit-above NN" to limit the maximum connections per IP
#   that you need.
iptables -t filter -I INPUT -p tcp --syn --dport 80 -m connlimit \
  --connlimit-above 10 --connlimit-mask 32 -j DROP

# Adjust "--connlimit-above NNN" to the maximum total connections you
#   want your web server to support
iptables -t filter -I INPUT -p tcp --syn --dport 80 -m connlimit \
  --connlimit-above 150 -j DROP

Da wir -I (gemäß der OP-Anforderung) verwenden, müssen wir sie in umgekehrter Reihenfolge ausführen, um sie von unten nach oben zu "lesen".

Ich schlage auch vor, die Änderung von --connlimit-mask NN von 32 auf 24 zu berücksichtigen. Dadurch wird ein vollständiges Class-C-Netzwerk (max. 256 IP-Adressen im gleichen Bereich) auf 10 Verbindungen begrenzt. Sie können auch eine andere klassenlose Nummer wie 22 oder 30 verwenden, je nachdem, wie Ihr Dienst Ihrer Meinung nach verwendet wird.

Abhängig davon, wie sich der Client verhalten soll, können Sie auch "-j REJECT --reject-with tcp-reset" anstelle von "-j DROP" in den beiden obigen Regeln oder sogar nur in den max. 150 Verbindungen verwenden Regel.

Wenn Sie die Verbindung ABLEHNEN, zeigt der Browser oder die Software, die Port 80 verwendet, sofort den Status "Nicht verfügbar" an, aber die DROP-Option veranlasst den Client, einige Male zu warten und es erneut zu versuchen, bevor die Site als nicht verfügbar gemeldet wird. Ich neige dazu, mich selbst an den DROP zu lehnen, da er sich eher wie eine schlechte Verbindung als wie ein Offline-Server verhält.

Wenn das Verbindungslimit wieder unter 150 (oder 10) fällt, während es noch versucht, wird es schließlich zu Ihrem Server durchgeleitet.

Die Option REJECT verursacht jedoch einen Bruchteil des Datenverkehrs auf Ihrer Site, da DROP dazu führt, dass zusätzliche Pakete gesendet werden, während der Versuch wiederholt wird. Wahrscheinlich nicht so relevant.

Wenn Ihr Port 80-Datenverkehr andererseits Teil eines Clusters ist, teilt REJECT dem Cluster-Controller mit, dass er nicht aktiv ist, und beendet das Senden von Datenverkehr an ihn für die Dauer des Zeitlimits für Wiederholungsversuche.

Die RELATED, ESTABLISHED-Regel gibt es unter der Annahme, dass Ihre Standardregel den gesamten Datenverkehr blockiert (iptables -t filter -P INPUT DROP). Dies akzeptiert nur weitere Pakete, die zu akzeptierten Verbindungen gehören.

Außerdem weist --syn es an, auf die Pakete zu achten (oder diese zu zählen), die eine TCP-Verbindung herstellen.

Ian Macintosh
quelle
Vielen Dank, dass Sie sich die Details dieser Befehle angesehen haben.
Txyoji
Kann ich --connlimit-mask dazu bringen, nur diese bestimmte IP-Adresse und nicht einen ganzen Bereich zu blockieren?
Analog
Die --connlimit-Maske 32 ist eine einzelne Adressgrenze. Das heißt, es ist wie eine / 32-Netzmaske. Alles andere, wie 24, ist wie eine / 24-Netzmaske, wobei die unteren 8 Bits ignoriert werden.
Ian Macintosh
5

Sie müssen die connlimitModule verwenden, mit denen Sie die Anzahl der parallelen TCP-Verbindungen zu einem Server pro Client-IP-Adresse (oder Adressblock) beschränken können.

/sbin/iptables -I INPUT -p tcp --syn --dport 80 -m connlimit \
      --connlimit-above 10 -j DROP
Raman_Singh
quelle
Ich habe deine Antwort aktualisiert und hoffe, dass sie noch in Ordnung ist (warum wird "--syn" benötigt?). + Und wie wäre es mit der "Die maximale Verbindung pro Sekunde (Port 80, TCP) zu 150"? Danke!
Evachristine
--syn bedeutet, dass die Regel nur TCP-Pakete mit dem syn-Flag betrachtet - was bedeutet, dass neue Verbindungen bestehen. Sie könnten mit -m state --state NEW ungefähr dasselbe tun, aber dies ist wahrscheinlich schneller.
Dan Pritts