Назад | Перейти на главную страницу

как ограничить пропускную способность загрузки для каждого пользователя в Linux?

Может ли кто-нибудь предоставить tc команда для ограничения скорости загрузки для каждого пользователя в Debian Lenny?

Я обнаружил, что для маркировки пакетов для каждого пользователя с помощью iptables я могу использовать следующую команду

iptables -t mangle -A OUTPUT -p tcp -m owner --uid-owner testuser -j MARK --set-mark 500

но я понятия не имею, как использовать tc

Обновить

выполнив следующие команды, мне удалось ограничить пропускную способность загрузки тестового пользователя до 10 Мбит

iptables -t mangle -N HTB_OUT
iptables -t mangle -I POSTROUTING -j HTB_OUT
iptables -t mangle -A HTB_OUT -j MARK --set-mark 30
iptables -t mangle -A HTB_OUT -m owner --uid-owner testuser -j MARK --set-mark 10

tc qdisc replace dev eth0 root handle 1: htb default 30
tc class replace dev eth0 parent 1: classid 1:1 htb rate 10Mbit burst 5k
tc class replace dev eth0 parent 1:1 classid 1:10 htb rate 10Mbit ceil 10Mbit
tc qdisc replace dev eth0 parent 1:10 handle 10: sfq perturb 10
tc filter add dev eth0 parent 1:0 prio 0 protocol ip handle 10 fw flowid 1:10

Теперь проблема в том, что я не хочу ограничивать пропускную способность FTP тестового пользователя, но, выполнив указанные выше команды, скорость FTP также ограничена 10 Мбит.

С уважением

Я вижу пару очевидных проблем с вашей конфигурацией htb.

Во-первых, у вас нет ручки 1:30, и вы должны, учитывая default 30. Возможно вы имели в виду default 1? При этом весь трафик будет привязан к classid 1: 1, если правило не прикрепляет трафик к другому классу.

Во-вторых, вам нужно установить свою ставку в классе самого высокого уровня htb 1: 1 на что-то разумное и меньшее, чем ваша линейная скорость. Например, если скорость вашей линии составляет 100 Мбит, скорость должна составлять 90% от: 90 Мбит. Некоторые рекомендуют более консервативные настройки, например, 75% линейной скорости; Я играю в опасную игру на 90%, и у меня все работает нормально - уменьшите, если вы заметите потерянные пакеты или неправильное распределение полосы пропускания. Последнее указывает на буферизацию восходящего потока.

В-третьих, ваш класс с ограниченной скоростью должен быть настроен с rate установите на гарантированную полосу пропускания, которую вы хотите выделить классу и ceil установите максимальный уровень, который вы позволите пользователю. Например, предположим, что вы хотите предоставить тестирующему пользователю 400 Кбит гарантированной полосы пропускания, но если линия в противном случае неактивна, позвольте ей вырасти до скорости линии. Устанавливать rate 400kbit и ограничьтесь тем, что вы указали как 1: 1. Если вы не устанавливаете ceil, по умолчанию используется рейтинг.

В-четвертых, для достижения вашей цели по исключению ftp-трафика вам нужно будет использовать connmark вместо просто mark. В противном случае ваше связанное соединение для передачи данных не будет должным образом освобождено от --set-mark 10. Коннмарк правильно выберет связанные соединения.

Я предлагаю следующие (непроверенные!) Правила в голове:

# flush rules out of postrouting so you're not constantly inserting during testing.
iptables -t mangle -F POSTROUTING
iptables -t mangle -X HTB_OUT

# The use of RETURN here is to fall out of our user chain and hit 
# -j CONNMARK --save-mark in the POSTROUTING chain.
iptables -t mangle -N HTB_OUT
iptables -t mangle -A HTB_OUT -j MARK --set-mark 30
iptables -t mangle -A HTB_OUT -p tcp --dport 21 -j MARK --set-mark 30
iptables -t mangle -A HTB_OUT -m mark ! --mark 0 -j RETURN
iptables -t mangle -A HTB_OUT -m owner --uid-owner testuser -j MARK --set-mark 10
iptables -t mangle -A HTB_OUT -m mark ! --mark 0 -j RETURN

iptables -t mangle -A POSTROUTING -j CONNMARK --restore-mark
iptables -t mangle -A POSTROUTING -m mark ! --mark 0 -j ACCEPT
iptables -t mangle -A POSTROUTING -j HTB_OUT
iptables -t mangle -A POSTROUTING -j CONNMARK --save-mark

Тогда для tc что-то вроде следующего:

# set a script variable that will represent our line-rate minus some change
CAPRATE=90Mbit
CAP_SUB_400=89Mbit

# clear our qdisc settings for eth0 so we're starting from a clean slate.
tc qdisc del dev eth0 root

tc qdisc add dev eth0 root handle 1: htb default 20
tc class add dev eth0 parent 1: classid 1:1 htb rate ${CAPRATE} burst 5k
# this is our capped class:
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 400kbit ceil ${CAPRATE}
# this is our default, catch-all class:
tc class add dev eth0 parent 1:1 classid 1:20 htb rate ${CAP_SUB_400} ceil ${CAPRATE}
tc qdisc add dev eth0 parent 1:10 handle 10: sfq perturb 10
tc qdisc add dev eth0 parent 1:20 handle 20: sfq perturb 10

tc filter add dev eth0 parent 1:0 prio 0 protocol ip handle 10 fw flowid 1:10

Что нужно помнить: сумма всего rates для непосредственных потомков любого родителя не должен превышать родительский rate Когда-либо. Я здесь немного схитрил и округлил 1:20 до 89 Мбит вместо 89600 Кбит. Вы можете недооценивать, но никогда не должны переоценивать.

правила iptables оцениваются Для того, чтобы. Если ваша политика допускает это, наиболее часто встречающиеся совпадения должны отображаться первыми; при условии, что большая часть этого устраняется правилами POSTROUTING перед входом в цепочку HTB_OUT, но это хорошее практическое правило.

Так зачем SFQ ... это все равно что помешивать горшок. SFQ пытается предоставить каждому соединению (на самом деле, паре конечных точек) справедливую долю пропускной способности, затем каждую секунду возмущения он снова перемешивает вещи, на случай, если слишком много соединений окажется в одной внутренней корзине (что возможно из-за того, как хешируется сделано на src / dst / portpair). Для получения дополнительной информации проверьте lartc или страницу руководства tc-sfq.

iptables -A OUTPUT -m conntrack --connbytes from:to --connbytes-mode packets/bytes/avgpkt -m owner --uid-owner owner -J DROP

Другие возможности -m connlimit -m hashlimit