Ogranicz liczbę połączeń na adres IP i nowe połączenia na sekundę dzięki iptables

37

Mamy serwer Ubuntu 12.04 z httpd na porcie 80 i chcemy ograniczyć:

  • maksymalna liczba połączeń na adres IP do httpd do 10
  • maksymalna liczba nowych połączeń na sekundę do httpd do 150

Jak możemy to zrobić za pomocą iptables?

evachrystyna
źródło

Odpowiedzi:

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

Spowoduje to odrzucenie połączeń powyżej 15 z jednego źródłowego adresu IP.

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

W tym 160 nowych połączeń (tak naprawdę pakietów) jest dozwolonych przed zastosowaniem limitu 150 NOWYCH połączeń (pakietów) na sekundę.

Totti
źródło
1
Czy powyższe można skonfigurować tak, aby działało na wszystkich portach, nie tylko na porcie 80?
EminezArtus
1
Czy jesteś pewien, że dotyczy to adresu IP?
LatinSuD,
2
Aby ustawić tę regułę dla wszystkich portów, wystarczy usunąć --dport 80.
Dan Pritts
5
Druga reguła NIE działa na „nowych połączeniach”. Wyraźnie wpływa na istniejące połączenia („USTANOWIONE”). Aby wykonywać nowe połączenia, powinieneś - stan NOWOŚĆ. Możesz również rozważyć użycie -m conntrack --ctstatezamiast -m state --state. conntrack jest nowy i ulepszony w porównaniu do stanu.
Dan Pritts,
2
powyższy komentarz dotyczący dodawania drugiej reguły do NEWpołączeń - nie rób tego - skutecznie zamienia Twój INPUTłańcuch w domyślny accept!!!
Stuart Cardall
8

Chcesz, aby następujące reguły w iptables odpowiadały na oba wymagania w twoim pytaniu:

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

Ponieważ używamy -I (zgodnie z żądaniem PO), musimy to zrobić w odwrotnej kolejności, więc „przeczytaj” je od dołu do góry.

Sugeruję również rozważenie - zmiana NN -connlimit-mask z 32 na 24. Ograniczy to pełną sieć klasy C (maks. 256 adresów IP w tym samym zakresie) do 10 połączeń. Możesz także użyć dowolnego innego numeru bezklasowego, takiego jak 22 lub 30, w zależności od tego, w jaki sposób możesz skorzystać z usługi.

Również w zależności od tego, jak chcesz, aby klient się zachowywać, to może chcieć użyć „-j REJECT --reject-with tcp-reset” zamiast „-j DROP” w dwie reguły powyżej, lub nawet tylko w 150 Przyłącza max reguła.

Jeśli odrzucisz połączenie, przeglądarka lub oprogramowanie korzystające z portu 80 natychmiast pokaże stan „niedostępny”, ale opcja DROP spowoduje, że klient poczeka i spróbuje jeszcze kilka razy, zanim zgłosi witrynę jako niedostępną. Zwykle opieram się na DROP, ponieważ zachowuje się bardziej jak złe połączenie niż serwer offline.

Ponadto, jeśli limit połączenia spadnie z powrotem poniżej 150 (lub 10), gdy jest nadal ponawiany, w końcu przejdzie do twojego serwera.

Opcja ODRZUĆ spowoduje jednak o ułamek mniejszy ruch w witrynie, ponieważ DROP spowoduje wysłanie dodatkowych pakietów podczas ponownej próby. Prawdopodobnie nie wszystko, co istotne.

Z drugiej strony, jeśli ruch na porcie 80 jest częścią klastra, REJECT poinformuje kontroler klastra, że ​​jest wyłączony i przestanie wysyłać do niego ruch na czas oczekiwania.

Reguła POWIĄZANA, USTANOWIONA jest przy założeniu, że domyślną regułą jest blokowanie całego ruchu (iptables -t filtr -P WEJŚCIE DROP). To akceptuje tylko kolejne pakiety należące do akceptowanych połączeń.

Również --syn mówi, aby zwracał uwagę na (lub liczył) pakiety, które ustanawiają połączenie TCP.

Ian Macintosh
źródło
Dzięki za przejrzenie drobiazgów tych poleceń.
txyoji
Czy mogę uzyskać opcję --connlimit-mask, aby blokować tylko ten konkretny adres IP, a nie cały zakres?
Analog
--Connlimit-mask 32 jest limitem jednego adresu. To jest jak maska ​​sieci / 32. Cokolwiek mniej, np. 24, jest jak maska ​​sieci / 24, ignorując niższe 8 bitów.
Ian Macintosh
5

Musisz użyć connlimitmodułów, które pozwalają ograniczyć liczbę równoległych połączeń TCP do serwera na adres IP klienta (lub blok adresu).

/sbin/iptables -I INPUT -p tcp --syn --dport 80 -m connlimit \
      --connlimit-above 10 -j DROP
Raman_Singh
źródło
Zaktualizowałem twoją odpowiedź, mam nadzieję, że nadal jest OK (dlaczego potrzebne jest „--syn”?). + A co powiesz na „Maksymalne połączenie na sekundę (port 80, TCP) do 150”? Dziękuję Ci!
evachristine
--syn oznacza, że ​​reguła patrzy tylko na pakiety TCP z flagą syn - co oznacza nowe połączenia. Możesz zrobić mniej więcej to samo z opcją -m stan - stan NOWY, ale prawdopodobnie jest to szybsze.
Dan Pritts