Иногда возникает необходимость ограничивать скорость пользователей, подключающихся к PPTP-серверу. В этой статье будет показано как можно это организовать.
Итак. Допустим что у вас есть PPTP-сервер подобный этому и мы хотим ограничить скорость подключения для каждого пользователя некоторой величиной. Допустим 256k. Заодно выделим гарантированные полосы пропускания для определённых видов трафика.
Для этого создадим скрипт /etc/ppp/ip-up.d/shaper следующего содержания:
#!/bin/sh
# Интерфейс
IFACE=${1}
# Ширина канала
LIMIT="256kbit"
# Гарантированная полоса для http и https
LIMIT_1="64kbit"
# Гарантированная полоса для smtp и dns
LIMIT_2="32kbit"
tc qdisc add dev ${IFACE} root handle 1: htb default 30
# Задаём верхний порог на интерфейсе
tc class add dev ${IFACE} parent 1: classid 1:1 htb rate ${LIMIT} burst 4k
# Создаём "трубу" с гарантированной полосой пропускания LIMIT_1
tc class add dev ${IFACE} parent 1:1 classid 1:10 htb rate ${LIMIT_1} burst 4k
tc qdisc add dev ${IFACE} parent 1:10 handle 10: sfq perturb 1
# Создаём "трубу" с гарантированной полосой пропускания LIMIT_2
tc class add dev ${IFACE} parent 1:1 classid 1:20 htb rate ${LIMIT_2} ceil ${LIMIT} burst 4k
tc qdisc add dev ${IFACE} parent 1:20 handle 20: sfq perturb 1
# "Труба" по умолчанию. Полоса пропускания динамически меняется от 16k до всей ширины канала.
tc class add dev ${IFACE} parent 1:1 classid 1:30 htb rate 16kbit ceil ${LIMIT} burst 4k
tc qdisc add dev ${IFACE} parent 1:30 handle 30: sfq perturb 1
# Кладём http и https в трубу с гарантированной полосой LIMIT_1
tc filter add dev ${IFACE} protocol ip parent 1:0 prio 1 u32 match ip sport 80 0xffff flowid 1:10
tc filter add dev ${IFACE} protocol ip parent 1:0 prio 1 u32 match ip sport 443 0xffff flowid 1:10
# Кладём smtp и dns в трубу с гарантированной полосой LIMIT_2
tc filter add dev ${IFACE} protocol ip parent 1:0 prio 1 u32 match ip sport 25 0xffff flowid 1:20
tc filter add dev ${IFACE} protocol ip parent 1:0 prio 1 u32 match ip sport 53 0xffff flowid 1:20
Когда к PPTP-серверу подключается пользователь, для него создаётся новый PPP-интерфейс и выполняются скрипты из директории /etc/ppp/ip-up.d. В том числе и этот скрипт, который ограничит скорость на интерфейсе.
Усложним задачу. Допустим что некоторым пользователям нужно ограничивать скорость в других пределах. Тогда придётся усовершенствовать скрипт, добавив к нему возможность читать файл конфигурации и действовать в соответствии с ним.
Файл конфигурации сохраним как /etc/shaper.conf и он будет иметь следующий вид:
192.168.0.1:512kbit:128kbit:32kbit 192.168.0.2:128kbit:64kbit:32kbit
Т.е. в каждой строке будет ip-адрес пользователя, ограничение скорости и гарантированные полосы для http и других видов трафика. Всё это разделено двоеточиями.
В этом случае скрипт примет вид:
#/bin/sh
# Параметры по умолчанию:
# Ширина канала
DEF_LIMIT="256kbit"
# Гарантированная полоса для http и https
DEF_LIMIT_1="64kbit"
# Гарантированная полоса для smtp и dns
DEF_LIMIT_2="32kbit"
# Файл конфигурации
CFG_FILE="/etc/shaper.conf"
# Интерфейс
IFACE=${1}
# IP клиента
LOCAL=${4}
# Читаем настройки:
LIMIT=`grep ${LOCAL}: ${CFG_FILE} | cut -d ':' -f2`
LIMIT_1=`grep ${LOCAL}: ${CFG_FILE} | cut -d ':' -f3`
LIMIT_2=`grep ${LOCAL}: ${CFG_FILE} | cut -d ':' -f4`
# Если какой-то параметр пустой - устанавливаем в значение по умолчанию:
if [ -z ${LIMIT} ]; then
LIMIT=${DEF_LIMIT}
fi
if [ -z ${LIMIT_1} ]; then
LIMIT_1=${DEF_LIMIT_1}
fi
if [ -z ${LIMIT_2} ]; then
LIMIT_2=${DEF_LIMIT_2}
fi
tc qdisc add dev ${IFACE} root handle 1: htb default 30
# Задаём верхний порог на интерфейсе
tc class add dev ${IFACE} parent 1: classid 1:1 htb rate ${LIMIT} burst 4k
# Создаём "трубу" с гарантированной полосой пропускания LIMIT_1
tc class add dev ${IFACE} parent 1:1 classid 1:10 htb rate ${LIMIT_1} burst 4k
tc qdisc add dev ${IFACE} parent 1:10 handle 10: sfq perturb 1
# Создаём "трубу" с гарантированной полосой пропускания LIMIT_2
tc class add dev ${IFACE} parent 1:1 classid 1:20 htb rate ${LIMIT_2} ceil ${LIMIT} burst 4k
tc qdisc add dev ${IFACE} parent 1:20 handle 20: sfq perturb 1
# "Труба" по умолчанию. Полоса пропускания динамически меняется от 16k до всей ширины канала.
tc class add dev ${IFACE} parent 1:1 classid 1:30 htb rate 16kbit ceil ${LIMIT} burst 4k
tc qdisc add dev ${IFACE} parent 1:30 handle 30: sfq perturb 1
# Кладём http и https в трубу с гарантированной полосой LIMIT_1
tc filter add dev ${IFACE} protocol ip parent 1:0 prio 1 u32 match ip sport 80 0xffff flowid 1:10
tc filter add dev ${IFACE} protocol ip parent 1:0 prio 1 u32 match ip sport 443 0xffff flowid 1:10
# Кладём smtp и dns в трубу с гарантированной полосой LIMIT_2
tc filter add dev ${IFACE} protocol ip parent 1:0 prio 1 u32 match ip sport 25 0xffff flowid 1:20
tc filter add dev ${IFACE} protocol ip parent 1:0 prio 1 u32 match ip sport 53 0xffff flowid 1:20
Вобщем-то всё. Более подробно про управление скоростью можно прочитать в LARTC HowTo.
Ссылки по теме:

spir 2008-05-06 18:30:07 (#)
tc qdisc add dev $DEVICE handle ffff: ingress
tc filter add dev $DEVICE parent ffff: protocol ip prio 50 u32 match ip src 0.0.0.0/0 police rate ${UP}Kbit burst $DOWN drop flowid :1