iptables: Limit Maximum Connections per IP

Katsumi

Lt. Commander
Registriert
Sep. 2002
Beiträge
1.336
Hallo.

Ich habe einen kleinen privaten Server und suche einen Weg IPs mit zu vielen Verbindungen zu blocken. Die erste Frage die ich mir dann aber stellen muss.. was sind denn zu viele Verbindungen überhaupt? Gibt es dafür einen Richtwert? Gerade Googlebot und MSNBot sind ja nicht zimperlich beim crawlen.

Anstatt einen Apache Mod zu verwenden, kann man über iptables die Verbindung pro IP limitieren: http://www.cyberciti.biz/faq/iptables-connection-limits-howto/

/sbin/iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 20 -j REJECT --reject-with tcp-reset
In dem Beispiel werden pro IP 20 Verbindungen zugelassen. Alles darüber wird verworfen. Was genau heißt das in der Praxis, wenn man eine Seite aufruft mit vielen Grafiken/Ressourcen? Sieht man dann plötzlich nur die halbe Seite? ;)

Hat jemand damit Erfahrungen?
 
Falls der Browser zu viele parallele Verbindungen aufmacht und es bei einem Fehlschlag nicht nochmal versucht, fehlen dann die entsprechenden Resourcen, ja. Für einen Richtwert gilt eigentlich nur, ausprobieren. Allerdings ist es ein Unterschied, ob jemand seine IP alleine benutzt oder ob dutzende von Nutzern hinter einem Proxy sitzen.

Vielleicht macht es da mehr Sinn, die Verbindungen pro Sekunde zu limitieren und eben nicht, die Verbindungen insgesamt (oder beides irgendwie in Kombination).

Bei meinem Server habe ich das mit dem recent Modul gemacht, allerdings auch um Attacken auf den SSH Dienst zu erschweren. Ein paar Details dazu habe ich in meinem Blog niedergeschrieben:
https://www.ssl-id.de/www.killercow.de/blog/?p=29

Gerade bei Webseiten macht es wahrscheinlich auch Sinn, eine Art Burstrate mit einzurechnen. Ruft ein Benutzer eine Seite das erste mal auf, werden mit einem Mal nen Haufen Verbindungen aufgemacht, nachfolgende Seitenaufrufe begnügen sich dann aber wahrscheinlich mit einigen wenigen neuen Verbindungen.
 
Mir scheint, der Threaderöffner hat gar kein tatsächliches Problem mit zu vielen Verbindungen von einer IP sondern will nur limitieren, weil ihm das cool vorkommt.

20 ist gar nichts. Firefox macht z.B. in Standardeinstellung 6 Verbindungen auf. Schon der 4. Client aus dem gleichen NAT-Netz bekommt also TCP-Resets von so einem Server - komplett ohne Grund. Hinter der IP eines HTTP-Proxies verstecken sich oft _richtig_ _viele_ Clients. Warum sollte man die künstlich limitieren? Solange keine Probleme auftauchen, würde ich nur eine Maximalzahl gleichzeitiger Verbindungen für den Server konfigurieren, aber nichts in Abhängigkeit von der Quell-IP.
 
Ich habe auf dem Server leider seit 2-3 Wochen plötzlich von Zeit zu Zeit extrem Höhe CPU Last auf mySQL-Prozesse und finde den Grund dafür bisher nicht. Problem ist das auch Besucher davon betroffen sind und dann 20-30s Ladezeiten der Seite haben.

http://img1.picload.org/image/largcrp/mrtga.png
http://img4.picload.org/image/larpiol/mrtge.png
http://img4.picload.org/image/lalaoaa/mrtgx.png
http://img5.picload.org/image/lacdglc/mrtgz.png
http://picload.org/image/lacwrwi/mrtgu.png

http://img4.picload.org/image/lalacao/cpu-month.png

Ich habe centOS 6.5 mit Plesk 11.5.30. Ich lasse mir die Verbindungen anzeigen:
# netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort –n

Die ganzen access_log zu analysieren ist aufwendig, bisher habe ich dort nichts gefunden. Bisher bin ich so vorgegangen, dass ich die IPs in einem Zeitraum sammel und schaue wie oft die vor kommt. Ist aber schwer zu entscheiden was da IPs sind die "böse" sind.
awk -vDate=`date -d '4:30' +[%d/%b/%Y:%H:%M:%S` -vDate2=`date -d'5:30' +[%d/%b/%Y:%H:%M:%S` ' { if ($4 > Date && $4 < Date2) print $1}' access_log | sort |uniq -c |sort -n | tail

Auch die aktuellen mySQL Prozesse anschauen hat mir bisher nichts gebracht, allerdings muss man schon dann wohl auch genau treffen wenn überhaupt das Problem besteht und ich sitze jetzt nicht 24h vor dem einen Server. ^^°
# SHOW FULL PROCESSLIST;

Für Ideen bin ich offen. :)
 
Im access_log stehen zwar die Quell-IP drin, aber die sind nicht zu verwechseln mit einzelnen Verbindungen, da viele Clients über eine Verbindung unmittelbar nacheinander mehrere Requests absetzen.

Wenn 20-30s Ladezeiten auftreten, ist es durchaus sinnvoll, etwas zu limitieren. Nur was? In welchen Phasen traten denn die Probleme auf. Ich interpretiere die Grafiken so, daß die langen Ladezeiten zu Zeiten der Load-Spitzen auftraten. Das müßte man verifizieren. Es stimmt wahrscheinlich aber nicht zwingend. Also Antwortzeiten loggen und ebenfalls an MRTG verfüttern, um die Problemphasen sicher identifizieren zu können. Die rot markierten Load-Spitzen in den frühen Morgenstunden gehen jedenfalls zeitlich nicht mit vielen offenen Verbindungen einher. Nach Zahl irgendwelcher Verbindungen zu limitieren scheint deshalb keine naheliegende Lösung zu sein.

Man müßte sich anschauen, was für Load das überhaupt ist. Schau dir an, worauf die Prozesse warten: Wollen sie Rechnen (warten auf CPU) oder warten sie auf IO? Beides würde in deinem Load-mrtg IMHO identisch aussehen, hätte aber unterschiedliche Ursachen.

Ich habe von mysql (und dessen Analyse) wenig Plan. Wenn mysql der Problembär ist, muß jedenfalls eine sinnvolle Limitierung auf Basis des Betriebszustandes der mysql-Prozesse erfolgen. Es gilt ein passendes Kriterium zu finden, was "zu viel" ist. Wenn es zu viel wird, den Webserver 503 ausliefern lassen, bis "zu viel" nicht mehr gilt. Die Methode ist (von der produzierten Last) billig und den Clients wird gesagt "Ich lebe, kann dich aber gerade nicht bedienen. Versuchs später nochmal." statt auf TCP-Ebene Verbindungen zu resetten.
 
Zuletzt bearbeitet:
Hier ein Beispiel von heute morgen. Es wird von Tag zu Tag irgendwie schlimmer.
http://picload.org/image/laicgpi/martggau2t.png

Per netstat sieht man leider nichts....
# netstat -plan | grep :80 | awk {'print $5'} | rev | cut -d: --complement -f1 | rev | sort | uniq -c | sort -nk 1
10 79.195.181.*
10 80.140.86.*
10 84.63.242.*
11 188.106.92.*
11 79.219.35.*
11 84.179.99.*
11 93.197.127.*
13 188.104.41.*
13 84.162.38.*
15 78.34.203.*
15 79.229.219.*
21 89.244.151.*
22 93.181.45.*

Ich habe die access_log von gestern zwischen 6 und 12 Uhr ausgewertet.
Ich habe nur drei Domains (apache/nginx):

domain1/access_log

567 126.45.169.*
575 141.8.147.*
638 2003:*:ce37:1e01:dd43:7e6b:cd0d:3834
749 2003:*:861:9b01:588c:dfa5:2219:a99b
788 91.63.206.*
1058 84.59.230.*
1261 2a02:*:e880:87e0:dc17:2390:e10a:aabf
1328 89.186.147.*
1672 77.21.191.*
3113 80.226.24.*

domain1/proxy_access_log

368 85.212.29.*
401 213.23.227.*
408 91.63.206.*
411 2003:*:ce37:1e01:dd43:7e6b:cd0d:3834
513 2a02:*:e880:87e0:dc17:2390:e10a:aabf
559 2003:*:861:9b01:588c:dfa5:2219:a99b
604 89.186.147.*
877 84.59.230.*
1281 77.21.191.*
1606 80.226.24.*

domain2/access_log

4408 66.249.65.*
6679 78.54.185.*
10177 178.154.243.*
11265 66.249.65.*
11287 66.249.65.*
11424 66.249.65.*
18866 66.249.65.*
18955 66.249.65.*
19206 66.249.65.*
27972 141.8.147.*

domain2/proxy_access_log

1247 91.52.4.*
1252 5.147.100.*
1345 217.84.202.*
1362 91.50.17.*
1573 65.55.215.*
1807 217.225.227.*
2238 84.61.33.*
2551 78.54.185.*
8673 141.8.147.*
10146 178.154.243.*

domain3/access_log

2563 66.249.73.*
2617 66.249.73.*
2663 66.249.73.*
2677 66.249.73.*
2765 66.249.73.*
3043 66.249.73.*
5281 141.8.147.*
56793 66.249.65.*
56853 66.249.65.*
57440 66.249.65.*

domain3/proxy_access_log

4 5.10.83.*
4 5.10.83.*
4 65.55.215.*
4 66.249.65.*
5 141.8.147.*
5 144.76.23.*
5 5.10.83.*
9 204.11.108.*
9 66.249.65.*
10 208.115.113.*

Man müßte sich anschauen, was für Load das überhaupt ist. Schau dir an, worauf die Prozesse warten: Wollen sie Rechnen (warten auf CPU) oder warten sie auf IO? Beides würde in deinem Load-mrtg IMHO identisch aussehen, hätte aber unterschiedliche Ursachen.
Wie sieht man das?
 
Katsumi schrieb:
Wie sieht man das?
top und "ps ax" zeigen eine Spalte zum Prozessstatus:
'R'=running/runnable (rennt schon oder würde gern rennen, also wartet nur auf eine freie CPU)
'D'=deferred (wartet, daß der Kernel endlich mit Krimskrams fertig wird, in aller Regel gehts da um IO)

Siehe "man ps" unter "PROCESS STATE CODES". Was man üblicherweise als "Load" angezeigt bekommt (mit xload, w, uptime, top, ...) und was vermutlich auch dein MRTG als "CPU Load" anzeigt, ist die Summe der Zahlen der Prozesse dieser beiden Kategorien. (naja, grob jedenfalls)
 
Zuletzt bearbeitet:
Zurück
Oben