IPTABLES - предельная скорость определенного входящего IP

103

Я не хочу ограничивать стоимость конкретной услуги. Моя цель - ограничить тариф только на основе входящего IP-адреса. Например, используя псевдо-правило:

john.domain.local (192.168.1.100) can only download from our httpd/ftp servers at "10KB/s" (instead of 1MB/s)

Как я могу оценить ограничение использования IPTables на основе входящих IP-адресов?

Джеймс
источник

Ответы:

165

IPTables не предназначен для такой работы, где для анализа этих решений необходимо проанализировать множество пакетов. IPTables - частично ответ, хотя!

Реальный ответ на это - удивительные и недостаточно используемые средства управления трафиком в Linux. Обратите внимание, что, если вы будете знать, что происходит, вы можете потерять сетевое соединение с машиной! Вы были предупреждены!

Предполагая, что eth0 является исходящим устройством, вам необходимо создать очередь управления трафиком на основе классов, которая по умолчанию будет выводить большую часть трафика через «быструю» очередь и помещать определенный список людей в «медленную» очередь.

Прелесть этого в том, что вы можете создать ситуацию, при которой вы разрешаете много исходящего трафика медленному пользователю, если переопределяющий класс не хочет пропускную способность, но этот пример этого не делает (всегда будет предоставлять 10 Кбит / с для медленных пользователей). Система очередей будет выглядеть примерно так:

                         Inbound traffic
                              +
                              |
                              |
                              v
                     +------------------+
                     |   Class 1:1      |
                     |------------------|
                     |  Root (all flows)|
                     |       100mbit    |
                     +-----+-----+------+
                           |     |
                           |     |
                           |     |
                           |     |
                           |     |
          +----------+     |     |     +----------+
          |    1:11  +-----+     +-----+    1:12  |
          |----------|                 |----------|
          | Default  |                 | Slow     |
          |100mb-80kb|                 |   80kb   |
          +----------+                 +----------+

Для этого сначала нужно настроить дисциплину очередей в ядре. Следующее сделает это за вас .. вы должны запустить это как один целый скрипт

#!/bin/bash
tc qdisc add dev eth0 parent root handle 1: hfsc default 11
tc class add dev eth0 parent 1: classid 1:1 hfsc sc rate 100mbit ul rate 100mbit
tc class add dev eth0 parent 1:1 classid 1:11 hfsc sc rate 99920kbit ul rate 100000kbit
tc class add dev eth0 parent 1:1 classid 1:12 hfsc sc rate 80kbit ul rate 80kbit

tc qdisc add dev eth0 parent 1:11 handle 11:1 pfifo
tc qdisc add dev eth0 parent 1:12 handle 12:1 pfifo

Значение по умолчанию 11 важно, так как оно сообщает ядру, что делать с не классифицированным трафиком.

После этого вы можете настроить правило iptables для классификации пакетов, соответствующих определенным критериям. Если вы планируете включить много-много людей в это медленное правило, правило ipset является более подходящим (я думаю, оно должно быть доступно на rhel6).

Итак, создайте базу данных ipset для сопоставления с ...

ipset create slowips hash:ip,port

Затем создайте правило iptables для сопоставления.

iptables -t mangle -I OUTPUT -m set --match-set slowips dst,src -j CLASSIFY --set-class 1:12

Это указывает ядру, что если вы сопоставите IP-адрес назначения с исходным портом из набора, классифицируйте его в медленную очередь, которую вы настроили с контролем трафика.

Теперь, наконец, всякий раз, когда вы хотите замедлить IP-адрес, вы можете использовать команду ipset, чтобы добавить ip в набор, такой как этот:

ipset add slowips 192.168.1.1,80
ipset add slowips 192.168.1.1,21
...

Вы можете проверить его работу с помощью команды "tc -s class show dev eth0", и вы увидите там статистику, указывающую, что пакеты перенаправляются в медленную очередь.

Обратите внимание, что единственным реальным недостатком является выживание перезагрузок. Я не думаю, что есть какие-либо сценарии инициализации, доступные для создания ipsets из дампов при перезагрузке (и они также должны быть созданы до правил iptables), и я уверен, что нет сценариев init для сброса правил управления трафиком при перезагрузке. Если вас это не беспокоит, вы можете просто воссоздать все это, вызвав скрипт в rc.local.

Мэтью Ифе
источник
3
Ну, я не могу отблагодарить тебя достаточно. Это очень наглядно и очень информативно. Позже я понял, что знание TC будет необходимо, и с тех пор я начал изучать это. Еще раз спасибо!
Джеймс
Ох, а что касается потери связи. Прежде чем перейти с моего VPS на хост-компьютер, я проверяю, что у меня отключена конфигурация. Также у меня есть VPN-доступ к частной сети на ETH0. Я буду работать только над ETH1, поэтому в теории у меня не будет проблем. Но предупреждение слышно!
Джеймс
2
Я не могу сказать вам, сколько раз я читал подобные уроки, это первое, что имело смысл
RC1140
5
В качестве идентификатора, как правило, более уместно использовать ограничение ресурсов, подобное этому, в контрольных группах (опять же, также возможно, а также недоиспользуемо и потрясающе), поскольку вы можете определить ограничения для каждого приложения для процессора, памяти, ввода-вывода и сети в централизованном хранилище политик. ». Но до сих пор не видел такой вопрос, чтобы предложить ответ.
Мэтью Иф
2
Если вам не нравится tcсинтаксис, вы можете попробовать tcng, который добавляет немного более удобный язык, который генерирует tcкоманды. Я любил это в сценариях оболочки: echo '... multi line tcng configuration ...' | tcng | sh.
Маттиас Вадман
5

Это так же просто, как принять правило ограничения скорости и добавить -sпереключатель. -sПереключателя соответствует входящих IP - адресов. Например, iptables -A INPUT -s 1.1.1.1а затем закончите с вашим предпочтительным методом ограничения скорости для этого правила.

Wesley
источник
Спасибо за ваш быстрый ответ. К сожалению, моя главная проблема - вторая половина. Я изучил --limit и не видел ничего, что позволяло бы мне ограничивать, основываясь на КБ / с - в каком направлении вы можете указать мне?
Джеймс
1
@ Джеймс Я бы вернулся к тебе, но мне пришлось выйти в дом друга. Только что вернулся, и я вижу, что MIfe проделал большую работу. =)
Уэсли