Пользователь
0,0
рейтинг
20 мая 2011 в 11:48

Администрирование → Ограничиваем входящий и исходящий трафик в Linux из песочницы

В данной статье хочу рассказать, как я строил систему ограничения входящего и исходящего трафика в Linux.
Как и учет трафика, ограничение полосы пропускания в сети является очень важной задачей, хотя первое с каждым годом всё быстрее отходит на второй план, шейпинг трафика остается необходимой задачей каждого системного/сетевого администратора.

Какие есть способы ограничения трафика?

Для того, чтобы ответить на этот вопрос нужно определиться для чего этот трафик ограничивать вообще.
Взяв за основу мою сеть из, примерно, 50 рабочих мест, которые выходят в интернет через шлюз, под управлением ОС Ubuntu и некоторые из пользователей пользуются локальными ресурсами на этом сервере по протоколу SMB.
Моя цель ограничить пользователям скорость передачи данных в Интернет со справедливым разделением полосы пропускания между ними.

Исходя из моих задач, для ограничения полосы пропускания можно использовать следующие методы:
1. Ограничение с помощью прокси-сервера Squid.
Данный метод позволяет довольно гибко контролировать весь www,ftp трафик пользователей с возможностью гибкого ограничения скорости пропускания.
2. Использование traffic control из iproute2.
Очень гибкий и оптимальный метод ограничения трафика, но не предоставляющий контроля над WWW трафиком, как в предыдущем методе.
3. Конечно возможно ограничить скорость путём использования модуля –m limit для iptables – но считаю это неприемлемым.

В общем я решил остановиться на методе ограничения трафика с помощью пакета iproute2.

Что, где и как?

Как уже упоминал, я использую сервер: OS Ubuntu 10.04, ядро 2.6.32-30. В сервере 3 интерфейса: eth0 – внутренняя сеть, eth1 — провайдер 1, eth2 – провайдер 2.

Задача: ограничить скорость входящего и исходящего трафика пользователей с приоритезацией трафика по классам, исходя из некоторых условий. Локальный трафик не ограничивать.

Немного теории

Представим ситуацию, когда пользователь установил соединение с youtube.com и смотрит какой-нибудь ролик в HD-качестве. Основная часть трафика направляется от сервера, в данном случае youtube.com к пользователю. Учитывая, что весь трафик проходит через наш шлюз, мы можем повлиять на скорость передачи этого трафика путем установки шейпера трафика на интерфейсе внутренней сети.
Похожая ситуация происходит, когда пользователь загружает фотоотчет о проведенном отпуске, состоящий из 300 фотографий в разрешении 5000х3500 пикселей на какой-нибудь сервис хранения фотографий в интернете.

Естественно, что при отсутствии системы ограничения трафика этот пользователь займёт весь канал и остальным пользователям не будет предоставлена нормальная скорость работы с Интернет. Но мы не может ограничить скорость отправки данных пользователем на внешнем интерфейсе сервера, т.к. для доступа пользователей в Интернет используется NAT, а, учитывая, что шейпинг трафика выполняется после преобразования адресов, то на внешнем интерфейсе сервера уже не будет пакетов с внутренними адресами сети.

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

В теории управления трафиком мы можем ограничивать только исходящий трафик. Следовательно, трафик, который направляется к пользователю внутренней сети, будет исходящим относительно внутреннего интерфейса eth0, а трафик, направляющийся от пользователя внутренней сети – исходящим относительно внешнего интерфейса eth1.

Исходя из вышеизложенного, я ограничивал входящий к пользователю трафик на интерфейсе внутренней сети — eth0, а исходящий от пользователя трафик – на виртуальном интерфейсе ifb0.

Для того чтобы во время занятия пользователем всей полосы пропускания, ограниченной ему на шлюзе, для скачивания какого-нибудь большого объема данных и при этом мог нормально пользоваться ssh и чтобы у него работал ping – я использовал приоритезацию трафика.

Я расставил следующие приоритеты трафика:
  1. icmp
  2. udp,ssh
  3. tcp sport 80
  4. остальной неклассифицированный трафик

Чем ниже параметр – тем выше приоритет трафика.

Дисциплины, классы, фильтры

Как уже было мной отмечено, входящий к пользователям трафик будет ограничиваться на интерфейсе eth0, а исходящий от пользователей – на виртуальном интерфейсе ifb0.

Для инициализации интерфейса ifb0 нужно сначала загрузить модуль управления интерфейсом:
/sbin/modprobe ifb
После успешной загрузки модуля нужно включить интерфейс:
/sbin/ip link set dev ifb0 up
Затем, после того, как интерфейс будет поднят, нужно организовать переадресацию всего исходящего трафика от пользователей на этот интерфейс:
/sbin/tc qdisc add dev eth0 ingress
/sbin/tc filter add dev eth0 parent ffff: protocol ip u32 match u32 0 0 action mirred egress redirect dev ifb0

Теперь можно смело начинать строить классы и фильтры для входящего к пользователям трафика на интерфейсе eth0, а исходящего – на интерфейсе ifb0.

Для ограничения трафика используется следующий принцип:
  1. На интерфейсе создается, так называемый корневой обработчик очереди
  2. К этой дисциплине прикрепляется класс, который одержит информацию о максимальной пропускной способности данных, которые в этот класс попадут
  3. Добавляется фильтр, который, с помощью определенных параметров, относит каждый пакет к тому или иному классу

Классы могут быть вложенными. То есть, если класс 1: описывает максимальную пропускную способность в 1Мбит, то класс 1:1, который является его подклассом, не может превысить ограничения по скорости его родителя.

Ограничиваем входящий к пользователям трафик

Все манипуляции с трафиком будем проводить на интерфейсе eth0.

Для начала создадим корневой обработчик очереди на интерфейсе:
/sbin/tc qdisc add dev eth0 root handle 1: htb default 900

Тем самым мы привязали корневой обработчик очереди к интерфейсу eth0, присвоили ему номер 1: и указали на использование планировщика HTB с отправкой всего неклассифицированного трафика в класс с номером 900.

Затем создадим дочерний класс 1:1 с шириной канала, равной скорости интерфейса:
/sbin/tc class add dev eth0 parent 1: classid 1:1 htb rate 100Mbit burst 15k
Все последующие классы будут подклассами только что созданного нами класса. Это дает нам более точную приоритезацию и обработку скорости потока данных.

Создадим класс для локального трафика, адресом назначения или исходным адресом которого будет являться внутренний адрес сервера. Это нужно для удобства пользования ресурсами сервера, такими как SSH, SMB, FTP, WWW и так далее. Скорость, описанная классом – 50Mbit, но в случае, если скорость потока родительского класса не меньше 100Mbit, то разрешаем использовать 80Mbit, в качестве максимальной скорости передачи данных.
/sbin/tc class add dev eth0 parent 1:1 classid 1:10 htb rate 50Mbit ceil 80Mbit burst 15k

Далее создаем класс, скорость которого будет равно ширине полосы пропускания, которую нам предоставляет провайдер. В моем случае – это 15Mbit.
/sbin/tc class add dev eth0 parent 1:1 classid 1:100 htb rate 15Mbit burst 15k

Даже если провайдер предоставляет большую скорость, к примеру 18Mbit, я рекомендую снижать эту скорость для шейпера на 1-2 Mbit для более «мягкого» ограничения трафика.
Далее создадим класс, в который будут отправляться все пакеты данных, которые не попадут ни в один из созданных ранее классов.
/sbin/tc class add dev eth0 parent 1:1 classid 1:900 htb rate 56Kbit ceil 128Kbit

Для каждого пользователя я создавал отдельный подкласс, с выделенной полосой пропускания, а затем создавал подклассы этого класса для приоритезации трафика:
/sbin/tc class add dev eth0 parent 1:100 classid 1:101 htb rate 4Mbit ceil 6Mbit

Данной командой мы указали на создание класса с номером 1:101, который является подклассом класса с номером 1:100 и указали пропускную способность класса в 4Mbit, а в случае свободной полосу пропускания у родительского класса, разрешить максимальное прохождение данных по классу на скорости 6Mbit.

Далее создаем подклассы для приоритезации трафика:
# PRIO 1 -> icmp traffic - самый низкий приоритет
/sbin/tc class add dev eth0 parent 1:101 classid 1:102 htb rate 33kbit ceil 6Mbit prio 1
# PRIO 2 -> udp, ssh
/sbin/tc class add dev eth0 parent 1:101 classid 1:103 htb rate 33kbit ceil 6Mbit prio 2
# PRIO 3 -> tcp sport 80 – WWW трафик из мира
/sbin/tc class add dev eth0 parent 1:101 classid 1:104 htb rate 33kbit ceil 6Mbit prio 3
# PRIO 4 -> unclassified traffic – трафик, который не попал под условия, указанные в предыдущих классах
/sbin/tc class add dev eth0 parent 1:101 classid 1:105 htb rate 33kbit ceil 6Mbit prio 4


После создания классов пришло время создания фильтров, которые будут классифицировать трафик по определенным критериям.

Есть несколько способов классифицировать трафик.
Самые удобные из них – это u32 классификаторы, позволяющие классифицировать пакеты исходя из адреса назначения или отправителя, используемого протокола, номера порта и так далее, и классификаторы на основе меток iptables. Для использования последних необходимо сначала маркировать пакеты при помощи iptables в цепочке PREROUTING, на основе каких-либо условий, а затем при помощи tc направлять пакеты с соответствующей меткой в нужные классы.

Я предпочел использовать u32 классификатор.

Присваиваем icmp-трафику самый низкий приоритет и отправляем его в класс 1:102
/sbin/tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip dst 192.168.10.78 \
match ip protocol 1 0xff flowid 1:102


UDP и SSH трафик отправляем в класс 1:103
/sbin/tc filter add dev eth0 protocol ip parent 1:0 prio 2 u32 match ip dst 192.168.10.78 \
match ip protocol 17 0xff flowid 1:103
/sbin/tc filter add dev eth0 protocol ip parent 1:0 prio 2 u32 match ip dst 192.168.10.78 \
match ip protocol 6 0xff match ip sport 22 0xffff flowid 1:103


WWW-трафик, пришедший с tcp-порта 80 отправляем в класс 1:104
/sbin/tc filter add dev eth0 protocol ip parent 1:0 prio 3 u32 match ip dst 192.168.10.78 \
match ip protocol 6 0xff match ip sport 80 0xffff flowid 1:104


Трафик, не соответствующий ни одному из условий отправляем в класс 1:105
/sbin/tc filter add dev eth0 protocol ip parent 1:0 prio 4 u32 match ip dst 192.168.10.78 flowid 1:105

Приоритезация работает по такому принципу, что каждому классу выделяется по минимальной полосе пропускания с возможностью заимствования у родительского класса максимальной полосы пропускания, в зависимости от приоритета трафика, поэтому, если класс будет забит WWW-трафиком с tcp-порта 80, при прохождении icmp пакета с более низким приоритетом, чем у WWW-трафика, он будет пропущен вне очереди, учитывая его приоритет.

Ограничиваем исходящий трафик

Для ограничения исходящего от пользователей трафика выполняются такие же действия как и для входящего, только в ход идет виртуальный интерфейс ifb0. Также нужно изменить назначение следования трафика: вместо dst 192.168.10.78 – нужно указать src 192.168.10.78 соответственно.

Автоматизация и принцип работы скриптов

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

root@mixer:/etc/rc.d/shape# cat ./users
#CLIENT	IP	DOWN	CEIL	UP	CEIL	PROVIDER	ID
user1	192.168.10.78	1Mbit	2Mbit	1Mbit	4Mbit	mageal	10
user2	192.168.10.44	1Mbit	1Mbit	2Mbit	3Mbit	ukrtel	11


Файл представляет из себя поля, разделенный знаком табуляции либо пробелом со следующими значениями:
CLIENT – Имя пользователя. Нужно для удобства предоставления данных
IP – адрес пользователя в сети
DOWN – скорость потока данных к пользователю
CEIL – максимальная скорость входящего трафика к пользователю при доступности данной полосы у родительского класса
UP — скорость потока данных от пользователя
CEIL – то же, что и у CEIL для входящего трафика к пользователю
PROVIDER – какой из провайдеров используется для обслуживания запросов пользователя (при наличии нескольких)
ID – номер класса для пользователя. Подробнее о номерах классов ниже.
Также я использую несколько bash-скриптов.

root@steel:/etc/rc.d/shape# cat ./rc.shape

#!/bin/bash
. /etc/init.d/functions
/sbin/modprobe ifb
/sbin/ip link set dev ifb0 up

TC="/sbin/tc"
DEV_P1_DOWN="eth0"
DEV_P1_UP="ifb0"

stop(){
$TC qdisc del dev $DEV_P1_DOWN root
$TC qdisc del dev $DEV_P1_UP root
$TC qdisc del dev $DEV_P1_DOWN ingress
}
start(){
# Удаляем все обработчики на интерфейсе
$TC qdisc del dev $DEV_P1_DOWN root
$TC qdisc del dev $DEV_P1_UP root
$TC qdisc del dev $DEV_P1_DOWN ingress

## Перенаправляем весь исходящий от пользователей трафик на виртуальный интерфейс ifb0
$TC qdisc add dev $DEV_P1_DOWN ingress
$TC filter add dev $DEV_P1_DOWN parent ffff: protocol ip u32 match u32 0 0 action mirred egress redirect dev $DEV_P1_UP

# Подгружаем скрипты с описанием классов входящего и исходящего трафика

. /etc/rc.d/shape/rc.shape.down.classes
. /etc/rc.d/shape/rc.shape.up.classes

# Весь трафик, который следует на шлюз или от него ограничиваем в 50Мбит с максимумом в 80Мбит.
$TC filter add dev $DEV_P1_UP protocol ip parent 1:0 prio 1 u32 match ip dst 10.0.0.1 flowid 1:10
$TC filter add dev $DEV_P1_DOWN protocol ip parent 1:0 prio 1 u32 match ip src 10.0.0.1 flowid 1:10

# Подгружаем скрипт с описанием фильтров
. /etc/rc.d/shape/rc.shape.filters
}

case "$1" in
start)
start
;;
stop)
stop
;;
restart|reload)
start
;;
*)
msg_usage "${0##*/} {restart|start|stop}"
RETVAL=1
esac


Далее код, который подгружается:

Классы

root@steel:/etc/rc.d/shape# cat ./rc.shape.down.classes

#!/bin/bash
## DOWNLOAD CLASSES
##########################################################
# Создаем корневой обработчик очереди
$TC qdisc add dev $DEV_P1_DOWN root handle 1: htb default 900

# Описание классов для входящего к пользователям трафика
$TC class add dev $DEV_P1_DOWN parent 1: classid 1:1 htb rate 100Mbit burst 15k

# Локльный трафик (SERVER -> CLIENTS)
$TC class add dev $DEV_P1_DOWN parent 1:1 classid 1:10 htb rate 50Mbit ceil 80Mbit burst 15k

# Трафик от провайдера (SERVER -> CLIENTS)
$TC class add dev $DEV_P1_DOWN parent 1:1 classid 1:100 htb rate 15Mbit burst 15k

# Неклассифицированный трафик будет отправлен в этот класс (SERVER -> CLIENTS)
$TC class add dev $DEV_P1_DOWN parent 1:1 classid 1:900 htb rate 128Kbit ceil 128Kbit

root@steel:/etc/rc.d/shape# cat ./rc.shape.up.classes
#!/bin/bash

## UPLOAD CLASSES
#############################################################
# Создаем корневой обработчик очереди
$TC qdisc add dev ifb0 root handle 1: htb default 900

# Описание классов для исходящего от пользователей трафика
$TC class add dev ifb0 parent 1: classid 1:1 htb rate 100Mbit burst 15k
# Локальный трафик (CLIENTS -> SERVER)
$TC class add dev $DEV_P1_UP parent 1:1 classid 1:10 htb rate 50Mbit ceil 80Mbit burst 15k

# Трафик к провайдеру (CLIENTS -> SERVER)
$TC class add dev $DEV_P1_UP parent 1:1 classid 1:100 htb rate 5Mbit burst 15k
# Неклассифицированный трафик будет отправлен в этот класс (CLIENTS -> SERVER)
$TC class add dev $DEV_P1_UP parent 1:1 classid 1:900 htb rate 128Kbit ceil 128Kbit


И фильтры:

root@steel:/etc/rc.d/shape# cat ./rc.shape.filters
#!/bin/bash
# читаем построчно файл “users”
while read LINE
do
set -- $LINE
if [[ $1 =~ '^\#' ]]
then
continue
fi
################################################################
CLIENT_IP=$2
CLIENT_DOWN_RATE=$3
CLIENT_DOWN_CEIL=$4
################################################################
# DOWNSTREAM
#####################

# создаем отдельный подкласс для пользователя
$TC class add dev $DEV_P1_DOWN parent 1:100 classid 1:${8}1 htb rate $CLIENT_DOWN_RATE ceil $CLIENT_DOWN_CEIL

# PRIO 1 -> icmp traffic
$TC class add dev $DEV_P1_DOWN parent 1:${8}1 classid 1:${8}2 htb rate 33kbit ceil $CLIENT_DOWN_CEIL prio 1

# PRIO 2 -> udp, ssh
$TC class add dev $DEV_P1_DOWN parent 1:${8}1 classid 1:${8}3 htb rate 33kbit ceil $CLIENT_DOWN_CEIL prio 2

# PRIO 3 -> tcp sport 80
$TC class add dev $DEV_P1_DOWN parent 1:${8}1 classid 1:${8}4 htb rate 33kbit ceil $CLIENT_DOWN_CEIL prio 3

# PRIO 4 -> unclassified traffic
$TC class add dev $DEV_P1_DOWN parent 1:${8}1 classid 1:${8}5 htb rate 33kbit ceil $CLIENT_DOWN_CEIL prio 4

# фильтруем icmp-пакеты в ранее созданный нами класс для icmp-трафика с приоритетот 1
$TC filter add dev $DEV_P1_DOWN protocol ip parent 1:0 prio 1 u32 match ip dst $CLIENT_IP \
match ip protocol 1 0xff flowid 1:${8}2

# фильтрация udp
$TC filter add dev $DEV_P1_DOWN protocol ip parent 1:0 prio 2 u32 match ip dst $CLIENT_IP \
match ip protocol 17 0xff flowid 1:${8}3
# ssh
$TC filter add dev $DEV_P1_DOWN protocol ip parent 1:0 prio 2 u32 match ip dst $CLIENT_IP \
match ip protocol 6 0xff match ip sport 22 0xffff flowid 1:${8}3
# WWW, sport 80
$TC filter add dev $DEV_P1_DOWN protocol ip parent 1:0 prio 3 u32 match ip dst $CLIENT_IP \
match ip protocol 6 0xff match ip sport 80 0xffff flowid 1:${8}4
# самый высокий приоритет – трафику, не попавшему под предыдущие фильтры
$TC filter add dev $DEV_P1_DOWN protocol ip parent 1:0 prio 4 u32 match ip dst $CLIENT_IP flowid 1:${8}5

# UPSTREAM
#####################

CLIENT_UP_RATE=$5
CLIENT_UP_CEIL=$6

### ТАКИЕ ЖЕ ПРАВИЛА И ДЛЯ ИСХОДЯЩЕГО ТРАФИКА

$TC class add dev $DEV_P1_UP parent 1:100 classid 1:${8}1 htb rate $CLIENT_UP_RATE ceil $CLIENT_UP_CEIL
# PRIO 1 -> icmp traffic
$TC class add dev $DEV_P1_UP parent 1:${8}1 classid 1:${8}2 htb rate 1kbit ceil $CLIENT_UP_CEIL prio 1
# PRIO 2 -> udp, ssh
$TC class add dev $DEV_P1_UP parent 1:${8}1 classid 1:${8}3 htb rate 1kbit ceil $CLIENT_UP_CEIL prio 2
# PRIO 3 -> unclassified traffic
$TC class add dev $DEV_P1_UP parent 1:${8}1 classid 1:${8}4 htb rate 1kbit ceil $CLIENT_UP_CEIL prio 3
$TC filter add dev $DEV_P1_UP protocol ip parent 1:0 prio 1 u32 match ip src $CLIENT_IP \
match ip protocol 1 0xff flowid 1:${8}2
$TC filter add dev $DEV_P1_UP protocol ip parent 1:0 prio 2 u32 match ip src $CLIENT_IP \
match ip protocol 17 0xff flowid 1:${8}3
$TC filter add dev $DEV_P1_UP protocol ip parent 1:0 prio 2 u32 match ip src $CLIENT_IP \
match ip protocol 6 0xff match ip dport 22 0xffff flowid 1:${8}3
$TC filter add dev $DEV_P1_UP protocol ip parent 1:0 prio 3 u32 match ip src $CLIENT_IP flowid 1:${8}4

done < ./users


Данные скрипты нужно положить в один каталог, Выполнить:

chmod +x ./rc.shape

и затем

./rc.shape start

Я описал один из методов ограничения трафика. Утилита tc – очень мощная вещь в вопросах об ограничениях трафика. Рекомендую ознакомиться с документом: LARTC-HOWTO для более глубокого изучения данного вопроса.
Alexey S. Kuznetsov @BusTeR
карма
22,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Администрирование

Комментарии (52)

  • +8
    Следующая статья должна быть про imq и ifb, и про то, почему через них всё делается проще и удобнее. В частности, про то, что так проще контроллировать входящий от провайдера трафик, если локалок несколько, и контролировать трафик локалок, если провайдеров несколько.
    • +4
      Как раз работаю в этом направлении
      • –1
        Может лучше купить нормальный биллинг? который все это самое будет делать за вас? :)
        например pyzzle.isp
        • –1
          Как-то его слишком активно пиарят. Настораживает.
          Лично я остаюсь на самопиленном ABillS ;).
    • +1
      Поддерживаю. Про tc уже было несколько статей, а про imq/ifb — нет.
    • 0
      уже как 6 лет назад (когда работал админом) я делал как раз с помощью IMQ устройства ограничение для входящего трафика.

      В принципе система работала вполне себе, только все равно это в некотором роде танцы с бубнами, особенно в смысле подбора правильных цифр для бурстов и им подобным
  • +5
  • 0
    Тема очень актуальна и интересна. И еще вопрос: если нет необходимости классифицировать трафик по внутренним ip, то виртуальный интерфейс можно не создавать, а ограничивать прямо на eth1?
    • 0
      Можно ограничить весь egress трафик.
  • 0
    Статья из разряда «побольше бы таких».
    Жаль нет времени сейчас все внимательно прочитать и опробовать сразу.В мемориз!
  • +2
    Как же все сложно.

    Можно же использовать IPMARK + HTB — дел на 10 минут, производительность потрясающая. Пример использования здесь centos.alt.ru/?p=532.

    Либо поставить ipfw который позволяет в 3 строчки порезать трафик. Пример здесь centos.alt.ru/?p=505.

    Либо использовать надстройку над HTB SC которая использует либо flow классификатор либо u32 хэш фильтры и тоже показывает высокую производительность. Пример здесь centos.alt.ru/?p=504.

    • 0
      Я описал один из методов ограничения полосы пропускания и все подробно расписал.
      Ваши статьи тоже очень позновательны и, я уверен, что методы, описанные в них показывают высокую эффективность при работе.
    • +1
      да… без хеш фильтров никуда… на носу ipv6 ;)
      ipfw все же более для BSD, предпочитаю простоту и удобство, поэтому в качестве роутера freebsd(ipfw,vlan).
      а ipmark + htb удобна тем, что можно развести на несколько машин при высокой нагрузке ;)
    • НЛО прилетело и опубликовало эту надпись здесь
      • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      Тоже использую HTB.
  • –1
    Момент, а зачем какие-то виртуальные интерфейсы, когда ЕМНИП можно классифицировать входящие пакеты ещё до NAT? Вроде как что-то типо

    -t mangle -A POSTROUTING -o eth1 -s 192.168.0.0/24 -j CLASSIFY --set-class 0001:0002

    eth1 — исходящий интерфейс в мир, на котором висит SNAT в POSTROUTING. А потом уже например

    tc class add dev eth1 parent 1: classid 1:2 htb rate 128kbit

    Или я не прав?
    • 0
      Трафик можно резать только на интерфейсах. А их у человека два, потому пользователь при лимите, скажем, 2 мегабита мог бы получить 4: 2 на одном и 2 на втором.

      Поэтому трафик сначала прогоняется через ifb (все вместе, на оба направления) и там режется.
      • –1
        Так, стоп. Трафик всегда двунаправленный. Проще говоря для резки всегда надо ограничивать отдельно входящую и исходящую полосу на разных интерфейсах. И так собственно и делает автор. Входящая ограничивается элементарно — на внутреннем интерфейсе по IP получателя. Исходящая — соотв. на внешнем, но тут проблема — SNAT затирает адрес источника. Поэтому надо до SNAT классифицировать пакеты средствами iptables, и потом уже резать трафик средствами tc. И не надо никаких промежуточных виртуальных интерфейсов, единственное предназначение которых, насколько я понимаю, — «вешать» на них tc для работы с исходящим трафиком по IP отправителя.

        Есть, к слову, ещё IPMARK для тех же целей, но про него я как-то совсем ничего не знаю.
  • 0
    > Исходящая — соотв. на внешнем

    Именно, что на внешнем. А там их два.
    Если повесить tc shaper на оба — получается, что юзер может получить в два раза больше положенной полосы (шейпится ведь на обеих отдельно). Предназначение ifb здесь — зашейпить трафик до того, как он растечется по внешним интерфейсам.
    • 0
      Пардон, промахнулся. Это был ответ на habrahabr.ru/blogs/sysadm/119611/#comment_3913344.

      Заодно уж добавлю: возможность работать с адресом отправителя до SNAT — это скорее побочный эффект, использованный как приятная плюшка.
    • 0
      Ага, про два провайдера не заметил, обратил внимание только на то, что виртуальный интерфейс позиционируется как средство обхода проблемы SNAT. Да и в любом случае, даже с двумя провами виртуальный интерфейс только для резки трафика не нужен. Один клиент не сможет использовать одновременно два исходящих интерфейса никаким образом. Соотв. у вас будет какой-нибудь виртуальный bond интерфейс или какой-то другой способ объединения каналов. В любом случае с точки зрения исходящего трафика всегда будет только один внешний интерфейс, на который можно повесить tc.
      • 0
        Почему же не сможет? Вполне. Скажем, маршрут на 0.0.0.0/0 идет через один интерфейс, а на какой-нибудить IX или пиринг — через второй. Собстсвенно, у меня так сейчас и есть. Иногда даже пакеты улетают в один интерфейс, а ответ приходит из другого :).
        • 0
          Добавлю, чтобы понятней было: имеется в виду два разных L3-интерфейса, а не два L2, обьединенных в один, как Вы предположили.
        • 0
          Ну, это что-то жутко нетипичное) Тут может и надо городить какие-то виртуальные интерфейсы, в то время как обычно это совершенно не требуется.
          • 0
            Как раз-таки это жутко типичное. У больших маршрутизаторов явно больше, чем два интерфейса ;). У меня на бордере, например, 9 штук (специально зашел и посчитал).

            В этом-то, собственно, и состоит работа маршрутизатора — выбирать путь отправки пакета. Трафик резать и менеджерам вконтакте закрывать — вторичное.
            • 0
              У маршрутизаторов — безусловно. У шлюзов — уже нет. А режете же вы трафик не внутри корп. сети, а на шлюзе) И даже если они совмещены — активный канал между сетями в подавляющем большинстве случаев один и именно он и интересует, а всякие внутренние интерфейсы, VPN и прочее — это уже всё не в счёт, ибо составляет внутренние ресурсы сети. У меня по крайней мере всё именно так в сети на 5 удалённых офисов с хитрой топологией.
              • 0
                Шлюз — частный случай маршрутизатор.
  • –1
    Я не сетевик ни разу, поэтому немножко не понимаю. Подскажите пожалуйста, что провайдер выигрывает режа входящий из инета трафик? Ну в смысле пакеты ж отбрасываются или как? Т.е. допустим клиент с тарифом 1 мбит/с делает запрос и ответный пакет до шлюза провайдера доходит же не со скоростью 1 мбит/с а на полной? или я неправ?
    Еще раз сорри за глупый вопрос — трафик резал один раз в жизни, давно, и почти неправда :)
    • 0
      Передающая сторона подстраивается под это ограничение, т.е. уменьшает скорость до тех пор, пока пакеты не будут идти нормально. Выглядит это так, будто где-то по дороге узкий канал.

      Кстати, отбрасывает пакеты policer. Shaper же задерживает пакеты, пока не получится нужная скорость. Помогает избежать множества проблем.
      • 0
        Передающая сторона это тот сайт с которого я тащу инфу к примеру? А каким образом подстраивается? Не подскажите где этот механизм описан? Или хотя бы дайте ключевые слова, по которым искать, плиз.
  • +1
    ковырялся с tc довольно долго. Не получилось заводить ни по man tc ни по скриптам с многочисленных форумах.
    Есть такая очень хорошая вещь… как wondershaper.
    очень простое использование. ограничение по down/up.
    работает для ppp клиентов.
    • 0
      wondershaper хорош тем, что генерирует скрипт. Можно посмотреть, что и как оно делает :).
      Еще есть sc. Живет где-то на forum.nag.ru.
      • 0
        мне в короткие сроки надо было на сервере настроить ограничение полосы пропускания для ppp клиентов )) Пару ночей — и я уже почти отчаялся и хотел ставить фряху ( у меня на дебиане все работает ) в ней решаются такие задачи сравнительно просто.
        С tc намучался… вандершейпер — грамотная надстройка…
        единственное я заметил, что что-бы была реальная скорость 2 на 2 мегабита надо ставить слегка ( 2300-2400) завышенные параметры. Не знаю, почему… и это не служебный трафик. Так же есть приоритеты, например полностью забитый канал торрентами не мешает нормальному серфингу.
        • –1
          Если PPP — то Вам надо было на специализированные форумы сходить :). Например, довольно простой и эфективный скрипт есть тут: abills.net.ua/wiki/doku.php/abills:docs:linux:pppd_radattr:ru. Варианты посложнее — там же на форуме.
          • 0
            Вы не поверите. Я это изучал — не завелось. Так же как и скрипты с некоторых форумов. и абилс я рассматривал — что вообще ее поставить «из коробки». Так это вообще к мамонтам надо, которые коаксиал тянули)
            • 0
              Странно, у меня работает. Даже сейчас.
  • 0
    Хех, а я думал разборки с микротиком — сложно).
    Спасибо, познавательно.
    Сам все ж сделал выбор в пользу коробки, пока эмоции крайне положительные).
    • 0
      У Микротика своих проблем хватает. А так — да, неплохо.
  • 0
    > В теории управления трафиком мы можем ограничивать только исходящий трафик.

    на самом деле мы может ограничивать оба трафика на каждом интерфейсе. И хотя входящий при этом ограничивается не так ровно, как исходящий, получается небольшая «пила», но задача выполняется, паразитный трафик не занимает весь канал и не приводит к задержкам приоритетного трафика.
    • +1
      На небольших скоростях — надо ifb. А если уже считаются мегабитами (от 5 до 100), то смело можно делать ingress policer, заметно не будет. Я, например, давно уже так сделал.
      • 0
        Посмотрел в рабочий фильтр, действительно ingress policer.
        Все равно при максимальной загрузке видна пилообразность графика, он же размером tcp окна играется, что бы скорость выставить.
        Но в общем работает хорошо, приоритетный трафик никогда не лагал.
        • 0
          Ну, у меня задача несколько иная. У меня без QoS, просто шейпинг. Тарифы (это ISP) от 3 до 100 мегабит, всюду policer — разницы не заметно.
          А пилообразность… ну пусть себе будет :). Дискомфорта не создает.
          • 0
            Так QoS в большинстве случае бесполезен, так что только шейпером и живем.
        • 0
          Я думал, linux не умеет динамически менять размер окна.
          • 0
            ээ… там смысл в том, что мы задерживаем ack пакеты для tcp, что приводит к тому, что скользящее окно tcp на той стороне замедляет свое движение, как если бы между нами где-то был узкий канал.
            • 0
              А, в этом смысле.
          • 0
            А я всю жизнь думал, что винда не умеет. (:
            Как оказалось, 7 умеет.
  • –1
    На мой взгляд вся эта затея слишком крута для офиса даже из 50 машин

    Мне казаться будет достаточно сказать роутеру что все выдать по 1-2m на web и по 1-10m на smtp. Люди должны работать а не фото отчеты с отпуска выкладывать.
  • 0
    Спасибо за статью! Буду ждать дополнений!
  • 0
    Чувствуется что автор глубоко копнул тему — молодец. Я вот когда пришел на текущее место работы из всего зоопарка выбрал NeTAMS — не скажу что с ним нет проблем, но в данный момент он шейпит трафик и считает квоты для пользователей сети ISP, в котором я работаю. Иной раз тупо не хватает знаний и статистики — нарабатываю на ходу. :-)

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.