Ограничение пропускной способности сетевого соединения в Linux
Оригинал: How to limit network bandwidth on Linux
Автор: Dan Nanni
Дата публикации: 26 января 2016 г.
Перевод: А. Панин
Дата перевода: 23 мая 2016 г.
Если в процессе работы с вашей системой Linux для настольных компьютеров вы нередко одновременно используете множество работающих с сетью приложений или разделяете пропускную способность своего домашнего сетевого соединения между несколькими компьютерами, вы наверняка хотите максимально контролировать использование ресурсов имеющегося сетевого соединения. В противном случае при загрузке файлов большого объема с помощью специализированного приложения ваша интерактивная сессия SSH может начать работать с большим замедлением или перестать работать вообще. Либо в процессе синхронизации директории большого объема с сервером Dropbox ваши домашние могут начать жаловаться на постоянные перерывы, возникающие в процессе просмотра видео из сети.
В данном руководстве я постараюсь описать два различных подхода к ограничению пропускной способности сетевого соединения в Linux.
Ограничение пропускной способности сетевого соединения на уровне приложения в Linux
Одним из инструментов для ограничения пропускной способности сетевого соединения, использующим интерфейс командной строки системы, является утилита под названием trickle . Trickle позволяет осуществлять шейпинг трафика, генерируемого любым из существующих приложений, путем «подгрузки» библиотеки с реализацией механизма сетевых сокетов и алгоритмов ограничения пропускной способности сетевого соединения в процессе запуска приложения. Преимущество утилиты trickle заключается в том, что она функционирует исключительно в пространстве пользователя, поэтому вам не понадобятся привилегии пользователя root для ограничения пропускной способности сетевого соединения на уровне какого-либо из приложений. Для совместимости с утилитой trickle приложение должно использовать интерфейс сетевых сокетов без статического связывания с соответствующей системной библиотекой. Утилита trickle может оказаться полезной тогда, когда вам нужно ограничить пропускную способность сетевого соединения на уровне приложения, которое не имеет аналогичного встроенного механизма.
Для установки trickle в Ubuntu, Debian и производных дистрибутивах следует использовать следующую команду:
Для установки trickle в дистрибутивах Fedora или CentOS/RHEL (с подключенным репозиторием EPEL) следует использовать следующую команду:
Утилита trickle используется следующим образом. Необходимо просто разместить вызов trickle (а также флаги и значения лимитов скоростей) перед командой, которую вы желаете исполнить.
С помощью данной команды устанавливаются заданные лимиты скоростей приема и передачи данных (в КБ/с) для приложения, запускаемого с помощью заданной команды.
Например, для установки ограничения максимальной скорости передачи данных для утилиты scp, равного 100 КБ/с, может использоваться следующая команда:
При желании вы можете установить ограничение максимальной скорости приема данных (равное, к примеру, 300 КБ/с) для вашего веб-браузера Firefox, создав специальный файл запуска приложения со следующей командой запуска:
Наконец, утилита trickle может запускаться в режиме демона и контролировать «общую» пропускную способность сетевого соединения для всех приложений, которые были запущены с помощью нее. Для запуска trickle в режиме демона (т.е., trickled) может использоваться следующая команда:
После того, как демон trickled начнет работу в фоновом режиме, вы можете запускать другие приложения с помощью утилиты trickle. Теперь, если вы запустите с помощью утилиты trickle одно приложение, его скорость приема данных будет ограничиваться 1000 КБ/с. Если же вы запустите с помощью утилиты trickle еще одно приложение, скорость приема данных каждого из этих приложений будет ограничиваться 500 КБ/с и так далее…
Ограничение пропускной способности сетевого соединения на уровне сетевого интерфейса в Linux
Еще один способ управления пропускной способностью вашего сетевого соединения заключается в установке лимитов скоростей приема и передачи данных на уровне сетевого интерфейса. Данный подход может оказаться полезным тогда, когда вы делите соединение с сетью Интернет с кем-либо еще. Как и в подавляющем большинстве случаев, в Linux есть необходимый для этого инструмент. Сценарий wondershaper предназначен для выполнения описанной задачи: он ограничивает пропускную способность сетевого соединения на уровне сетевого интерфейса.
На самом деле, wondershaper является простым сценарием командной оболочки, который использует утилиту tc для установки параметров шейпинга трафика и качества сетевого соединения на уровне заданного сетевого интерфейса. Шейпинг исходящего трафика осуществляется путем распределения пакетов по очередям с разными приоритетами, шейпинг входящего трафика — путем отбрасывания пакетов.
Фактически, список полезных функций сценария wondershaper не ограничивался добавлением возможности управления пропускной способностью для каждого из сетевых интерфейсов. Wondershaper также пытается максимально снизить задержки интерактивных сессий, таких, как SSH в процессе загрузки или передачи файлов больших объемов. Кроме того, он гарантирует, что при передаче файлов больших объемов (например, при синхронизации директорий с сервером Dropbox) не будет значительно снижаться скорость загрузки файлов и наоборот.
Для установки wondershaper в Ubuntu, Debian и производных дистрибутивах следует использовать следующую команду:
Для установки wondershaper в дистрибутиве Fedora или CentOS/RHEL (с подключенным репозиторием EPEL) следует использовать следующую команду:
Сценарий wondershaper используется следующим образом:
Например, для установки максимальных скоростей приема/передачи данных для сетевого интерфейса eth0, равных 1000 и 500 Кб/с соответственно, может использоваться следующая команда:
Вы можете удалить установленное ограничение пропускной способности сетевого интерфейса с помощью следующей команды:
Если вас интересует принцип работы сценария wondershaper, вы можете изучить его содержимое (/sbin/wondershaper).
Заключение
В данном руководстве я рассказал о двух различных вариантах ограничения пропускной способности сетевого соединения в системе Linux для настольных компьютеров, а именно, об ограничении пропускной способности сетевого соединения на уровне отдельных приложений и на уровне сетевых интерфейсов. Оба рассмотренных инструмента являются максимально простыми и позволяют быстро и просто организовать шейпинг ранее никоим образом не контролируемого сетевого трафика. Те из вас, кто желает узнать больше о способах ограничения пропускной способности сетевых соединений в Linux, могут ознакомиться со следующим руководством .
Источник
Ограничение скорости с помощью утилиты TC
Потребовалось мне как то ограничить пользователей по скорости выхода в интернет. В моем распоряжении был роутер на linux машине. Первое что пришло на ум — это прокси-сервер, но он не полностью удовлетворял потребностям, так как ограничивал только web-трафик и пользователи программками типа DC забивали весь канал. Стал искать дальше, какими средствами linux можно ограничить трафик. Нашел утилиту tc входящую в состав пакета iproute2. На сервере весь трафик пользователей натится(nat), eth0 — интерфейс который смотрит в интернет, eth1 — интерфейс локальной сети. Все ограничение трафика сделано на интерфейсе локальной сети.
1) # Удаляем настройки корневого класса
/sbin/tc qdisc del dev eth1 root
/sbin/tc qdisc del dev eth1 ingress
2) # Создаем корневой класс со скоростью общего входящего канала в 1000 mbit
/sbin/tc qdisc add dev eth1 root handle 1:0 cbq avpkt 1000 bandwidth 1000mbit
dev eth1 — это устройство, к которому мы подключаем дисциплину обработки очереди
root — указывает что это корневая дисциплина
handle 1:0 — задается дескриптор в форме старший номер:младший номер (допускается использовать «1:» — при этом подразумевается что младший номер равен 0)
cbq — указываем тип дисциплины обработки очереди
avpkt — определяет усредненный размер пакета. Для ethernet-интерфейсов можно считать его равным 1000 байт при MTU равном 1500 байтам.
Bandwidth — физическая пропускная способность нашего устройства
3) # Создаем корневой класс для исходящего канала
/sbin/tc qdisc add dev eth1 handle ffff: ingress
4) # Создаем класс с шириной канала 15200kbit
/sbin/tc bounded class add dev eth1 parent 1: classid 1:1 cbq rate 15200kbit allot 1500 prio 5 bounded isolated
classid — для classid младший номер должен быть уникальным. (то есть число после двоеточия)
rate — этот параметр задает ограничение полосы пропускания
prio — присваивает классам приоритеты — чем меньше значение, тем выше приоритет
bounded — обозначает что классу запрещается занимать свободную полосу пропускания других классов, настроенных с параметром sharing
isolated — обозначает что другие классы на смогут занять полосу этого класса, даже если она будет свободна
5) # Классифицируем трафик с помощью фильтров и направляем его в нужные классы
/sbin/tc filter add dev eth1 parent 1: protocol ip prio 16 u32 match ip dst 192.168.0.10 flowid 1:1
u32 — это классификатор, позволяющий классифицировать пакеты на основании их атрибутов
flowid — задает дескриптор класса, куда направляются пакеты соответствующие заданному фильтру
6) # Для более равномерного распределения пропускной способности между соединениями, присоединим к классу дисциплину обработки очереди SFQ
/sbin/tc qdisc add dev eth1 parent 1:1 sfq perturb 10
sfq — дисциплина для более равномерного распределения пропускной способности между соединениями
perturb — этот параметр задает интервал в секундах, через который происходит изменение функции
7) # Этой командой мы будем контролировать резкое увеличение трафика
/sbin/tc filter add dev eth1 parent ffff: protocol ip prio 50 u32 match ip src 192.168.0.10/32 police rate 15200Kbit burst 15564800 drop flowid 1:1
burst — контролирует реакцию на резкое увеличение трафика
C 4-го по 7-ой пункт выполняем для каждого ip-адреса
Посмотреть что получилось можно с помощью команды /sbin/tc -s qdisc ls dev eth1
Вот скрипт для двух IP-адресов с разной скоростью интернета:
/sbin/tc qdisc del dev eth1 root
/sbin/tc qdisc del dev eth1 ingress
/sbin/tc qdisc add dev eth1 root handle 1: cbq avpkt 1000 bandwidth 1000mbit
/sbin/tc qdisc add dev eth1 handle ffff: ingress
/sbin/tc class add dev eth1 parent 1: classid 1:1 cbq rate 15200kbit allot 1500 prio 5 bounded isolated
/sbin/tc filter add dev eth1 parent 1: protocol ip prio 16 u32 match ip dst 192.168.0.10 flowid 1:1
/sbin/tc qdisc add dev eth1 parent 1:1 sfq perturb 10
/sbin/tc filter add dev eth1 parent ffff: protocol ip prio 50 u32 match ip src 192.168.0.10/32 police rate 15200Kbit burst 15564800 drop flowid 1:1
/sbin/tc class add dev eth1 parent 1: classid 1:2 cbq rate 400kbit allot 1500 prio 5 bounded isolated
/sbin/tc filter add dev eth1 parent 1: protocol ip prio 16 u32 match ip dst 192.168.0.101 flowid 1:2
/sbin/tc qdisc add dev eth1 parent 1:2 sfq perturb 10
/sbin/tc filter add dev eth1 parent ffff: protocol ip prio 50 u32 match ip src 192.168.0.101/32 police rate 400Kbit burst 409600 drop flowid 1:2
Источник
Про Debian
Продолжаем мытарства с созданием идеальной платформы для продажи VDS на основе debian и KVM. Данная статья в принципе верна для любого дистрибутива, только пакетным менеджером воспользуйтесь правильно. И верна она не только для виртуализации, а вообще… Но мой шкурный интерес здесь именно в том, чтобы ограничить максимальную скорость сети для отдельно взятой VDSки.
Как обычно — предыстория. На днях заметил, что периодически скорость скачивания файлов с моей VDS падает. При том падает достаточно быстро и возвращается к нормальному состоянию так же быстро. На хосте — 7 виртуальных серверов, один из которых я использую для экспериментов, а 6 — сдаю знакомым в аренду. Расследование показало, что на одном из VDS размещается бэкап-хост для другого сервера. Было приятно увидеть, что файлы с него дёргались со скоростью аж 80 мбит в секунду, но оставлять 10 мбит всем остальным VDS, пусть и на короткий период? Нет, так не пойдёт.
Ковыряние в packages.debian.org вывело меня на очень простую и удобную утилиту — wondershaper. Я не вдавался в подробности того, как она работает, для меня важно то, что она работает. Собственно, как использовать:
wondershaper [ interface ] [ downlink ] [ uplink ] — устанавливает ограничение для интерфейса
wondershaper [ interface ] — показывает ограничение для интерфейса
wondershaper clear [ interface ] — удаляет ограничение для интерфейса
Теперь подробнее применительно к KVM. Для начала узнаем, какой интерфейс в текущий момент использует ненавистная для нас VDS с жутким потреблением bandwidth
Если вы использовали мой прошлый мануал ( /16 ) для настройки KVM, то сделаем следующее:
Debian:
# ps aux | grep vds10
root 3351 3.4 8.4 1685376 691888 ? Sl Jun16 1340:50 /usr/bin/kvm -S -M pc -m 1024 -smp 1 -name vds10 -monitor pty -boot c -drive file=/vms/vds10.img,if=ide,index=0,boot=on -drive file=/iso/debian-504-i386-CD-1.iso,if=ide,media=cdrom,index=2 -net nic,macaddr=54:52:00:38:00:fb,vlan=0 -net tap,fd=11,script=,vlan=0,ifname=vnet0 -serial pty -parallel none -usb -vnc 127.0.0.1:0 -k en-us
Если не использовали мой мануал… Ну во-первых, зря, во-вторых — вам всё равно нужно узнать интерфейс. Сделать это можно через virt-manager или отключая интерфейсы через iptables, пингуя нужную VDS.
Итак, в приведенной мной цитате из grep выше vds10 у нас бегает с интерфейсом vnet0. Начнём её жестоко мучать:
Debian:
# wondershaper vnet0 10000 10000
Мы выставили ограничение для интерфейса в 10000 кбит в секунду на download и 10000 на upload. К сожалению, я не разобрался, как указывать ограничения в мегабитах, но оно и не так важно.
# wondershaper vnet0
Этой командой вы можете посмотреть статистику по интерфейсу. Она большая и непонятная, но всё же)
Теперь мы стали добрыми и решили убрать ограничение для интерфейса (VDSки). Делаем
Debian:
# wondershaper vnet0 clear
Ограничение на интерфейс больше не распространяется.
Как ещё можно использовать wondershaper… Ну например, ограничивать суммарную скорость всех VDS на сервере, если они используют одно устройство bridge (wondershaper br0 100 100), чтобы у хоста оставалась гарантированная свободная полоса. Можно группировать VDSы на разные bridge (в одной из следующих статей расскажу как) и ограничивать им скорость по группам.
Ну и выводы.
Данный метод не защищает ни VDS, ни хост от инкапсуляции трафиком. Он не поможет пережить вам 200 мегабитный ddos одной из VDS.
Данный метод в общем-то полезен, только если вы желаете ограничить скорость исходящего трафика VDS. Ограничивать входящую скорость я не рекомендую.
Источник