Обмежте максимум з'єднань на IP-адресу та нових підключень на секунду за допомогою iptables


37

У нас є сервер Ubuntu 12.04 з httpd на порту 80 і ми хочемо обмежити:

  • максимальне з'єднання на IP-адресу до httpd до 10
  • максимум нових з'єднань за секунду до httpd до 150

Як ми можемо це зробити за допомогою iptables?

Відповіді:


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

Це відхилить з'єднання вище 15 з одного IP-джерела.

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

У цьому 160 нових з'єднань (пакетів дійсно) дозволено до застосування межі 150 НОВИХ з'єднань (пакетів) в секунду.


1
Чи можна вказане вище налаштувати для роботи на всіх портах, а не лише на портах 80?
ЕмінезАрт

1
Ви впевнені, що це за IP?
LatinSuD

2
Щоб встановити це правило для всіх портів, просто видаліть --dport 80.
Dan Pritts

5
Друге правило НЕ працює на "нових з'єднаннях". Він явно впливає на існуючі ("Встановлені") з'єднання. Щоб зробити нові з'єднання, ви хочете - держава НОВА. Ви можете також розглянути можливість використання -m conntrack --ctstateзамість -m state --state. conntrack є новим та вдосконаленим проти штату.
Дан Прітц

2
коментар вище для додавання 2-го правила до NEWз'єднань - не робіть цього - це ефективно перетворює вашу INPUTланцюг у дефолт accept!!!
Стюарт Кардалл

8

Ви хочете, щоб наступні правила у ваших iptables відповідали на обидва вимоги у вашому запитанні:

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

Оскільки ми використовуємо -I (відповідно до запиту ОП), ми повинні робити їх у зворотному порядку, тому "читаємо" їх знизу вгору.

Я також пропоную розглянути можливість змінення NN --connlimit-mask з 32 на 24. Це обмежить повну мережу класу C (максимум 256 IP-адрес у тому ж діапазоні) до 10 підключень. Ви також можете використовувати будь-яке інше безкласове число, наприклад 22 або 30, залежно від того, як ви вважаєте, що послуга може бути використана.

Також в залежності від того, як ви хочете, щоб клієнт себе, ви , можливо , захочете використовувати «-j REJECT --reject-з TCP-скидання» замість «-j DROP» в два вище правила, або навіть тільки в 150 з'єднань макс правило.

Якщо Ви відхилите підключення, браузер або програмне забезпечення, що використовує порт 80, одразу покажуть статус "недоступний", але параметр DROP змусить клієнта кілька разів зачекати і повторити спробу перед тим, як повідомити про сайт як недоступний. Я, як правило, схиляюся до DROP, оскільки він поводиться більше як поганий зв’язок, ніж офлайн-сервер.

Крім того, якщо ліміт підключення знизиться нижче 150 (або 10), поки він ще намагається, він, нарешті, перейде на ваш сервер.

Опція REJECT призведе до частки менше трафіку на ваш сайт, оскільки DROP призведе до того, що він надсилатиме додаткові пакети під час повторного повторного завантаження. Напевно, не все так актуально.

Якщо з іншого боку, трафік вашого порта 80 є частиною кластера, то REJECT скаже контролеру кластера, що він знижений, і припинить надсилати йому трафік на час його витримки.

Правило, пов'язане з встановленим, існує за умови, що ваше правило за замовчуванням блокує весь трафік (iptables -t фільтр -P INPUT DROP). Це просто приймає нові пакети, що належать до прийнятих з'єднань.

Також --syn каже йому звернути увагу на (або підрахувати) пакети, які встановлюють TCP-з'єднання.


Дякуємо за проходження деталей цих команд.
txyoji

Чи можу я отримати --connlimit-mask лише для блокування цієї конкретної IP-адреси, а не всього діапазону?
Аналог

--Connlimit-mask 32 - це обмеження однієї адреси. Тобто це як / 32 мережна маска. Що-небудь менше, як 24, це як маска / 24, ігноруючи нижні 8 біт.
Іван Макінтош

5

Вам потрібно використовувати connlimitмодулі, які дозволяють обмежити кількість паралельних підключень TCP до сервера за IP-адресою клієнта (або блоком адреси).

/sbin/iptables -I INPUT -p tcp --syn --dport 80 -m connlimit \
      --connlimit-above 10 -j DROP

Я оновив вашу відповідь, сподіваюся, це все одно гаразд (для чого потрібен "--син"?). + А як щодо "Максимальне з'єднання в секунду (порт 80, tcp) до 150"? Дякую!
евахристин

--syn означає, що правило дивиться лише на пакети TCP із прапором syn - це означає нові з'єднання. Ви можете зробити приблизно те ж саме з -m станом - state NEW, але це, мабуть, швидше.
Dan Pritts
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.