Ограничение скорости в сети, но разрешить пакетную передачу по TCP-соединению до ограничения

8

У нас есть маршрутизатор Cisco, который позволяет ограничивать скорость (они называют это политикой), но разрешает пакетную передачу для каждого TCP-соединения. Например, мы можем ограничить пропускную способность в 50 Мбит, но ограничение не будет наложено, пока не будет передано 4 мегабайта. Это применяется для каждого TCP-соединения.

Есть ли способ сделать это в Linux? Кроме того, есть ли недостатки такого решения? В случае, если это кому-либо полезно, команда Cisco для установки пакетной передачи является третьим параметром команды полиции, которая запускается в соответствии с картой политик (по крайней мере, на нашем ASA 5505).

Цель этого состоит в том, чтобы позволить серверу использовать пакетную передачу 95/5 и обслуживать веб-страницы как можно быстрее для обычных пользователей, но уменьшить шансы на пакетную передачу более чем на 5% времени (например, при выполнении сервер-сервер). передача или загрузка больших файлов с веб-сайта). Я понимаю, что с помощью DDoS-атаки, которая продолжалась слишком долго, это может быть не решением, но по разным причинам это не является проблемой.

sa289
источник

Ответы:

6

Это выполнимо в Linux с iptablesи tc. Вы настраиваете iptables для MARKпакетов в соединении, где было передано некоторое количество байтов. Затем вы используете tcэти помеченные пакеты в классе в порядке очереди, чтобы ограничить пропускную способность.

Одна сложная часть заключается в ограничении соединения как для загрузки, так и для загрузки. tcне поддерживает формирование трафика входа. Вы можете обойти это, формируя выход на интерфейсе, обращенном к вашему веб-серверу (который будет формировать загрузку на ваш веб-сервер), и формируя выход на интерфейсе, обращенном к вашему вышестоящему провайдеру (который будет формировать загрузку с вашего веб-сервера). Вы на самом деле не формируете входной (загрузочный) трафик, так как не можете контролировать скорость отправки данных вышестоящим провайдером. Но формирование интерфейса, обращенного к вашему веб-серверу, приведет к тому, что пакеты будут отброшены, а загрузчик сократит свое окно TCP, чтобы приспособиться к ограничению пропускной способности.

Пример: (предполагается, что это на маршрутизаторе на основе Linux, где интерфейс веб-сервера обращен, eth0а восходящий - eth1)

# mark the packets for connections over 4MB being forwarded out eth1
# (uploads from webserver)
iptables -t mangle -A FORWARD -p tcp -o eth1 -m connbytes --connbytes 4194304: --connbytes-dir both --connbytes-mode bytes -j MARK --set-mark 50

# mark the packets for connections over 4MB being forwarded out eth0
# (downloads to webserver)
iptables -t mangle -A FORWARD -p tcp -o eth0 -m connbytes --connbytes 4194304: --connbytes-dir both --connbytes-mode bytes -j MARK --set-mark 50

# Setup queuing discipline for server-download traffic
tc qdisc add dev eth0 root handle 1: htb
tc class add dev eth0 parent 1: classid 1:50 htb rate 50mbit

# Setup queuing discipline for server-upload traffic
tc qdisc add dev eth1 root handle 1: htb
tc class add dev eth1 parent 1: classid 1:50 htb rate 50mbit

# set the tc filters to catch the marked packets and direct them appropriately
tc filter add dev eth0 parent 1:0 protocol ip handle 50 fw flowid 1:50
tc filter add dev eth1 parent 1:0 protocol ip handle 50 fw flowid 1:50

Если вы хотите сделать это на самом веб-сервере, а не на маршрутизаторе Linux, вы все равно можете использовать части загрузки вышеупомянутого материала. Одним из примечательных изменений вы бы заменить FOWARDс OUTPUT. Для загрузки вам необходимо настроить дисциплину очередей, используя устройство «Промежуточный функциональный блок», или ifb. Короче говоря, он использует виртуальный интерфейс, так что вы можете рассматривать входящий трафик как выходной и формировать его оттуда с помощью tc. Более подробную информацию о том, как настроить, ifbможно найти здесь: /server/350023/tc-ingress-policing-and-ifb-mirroring.

Обратите внимание, что этот тип материала требует большой настройки для масштабирования. Непосредственная проблема заключается в том connbytes, что conntrackмодуль зависит от масштабируемых стен с большим количеством соединений. Я бы порекомендовал тяжелое нагрузочное тестирование.

Еще одна оговорка - это то, что это вообще не работает для UDP, так как оно не имеет состояния. Есть и другие способы решения этой проблемы, но похоже, что ваши требования касаются только TCP.

Кроме того, чтобы отменить все вышеперечисленное, сделайте следующее:

# Flush the mangle FORWARD chain (don't run this if you have other stuff in there)
iptables -t mangle -F FORWARD

# Delete the queuing disciplines
tc qdisc del dev eth0 root
tc qdisc del dev eth1 root
alienth
источник