Значит так. Предполагается, что роутер (ASUS wl-500gP или совместимый) уже прошит олеговской прошивкой и проведена начальная настройка до rTorrent. Кроме того, должны стоять следующие утилиты: tail, head, awk, wget. Если чего из этого нет, то отправляемся на wl500g.info и настраиваем все, что нужно. Кроме того, понадобится утилита sudo, для того, чтобы скрипт смог работать под пользователем p2p, от имени которого стартует rTorrent.
Sudo
У меня rTorrent работает от имени пользователя p2p. Поскольку этот пользователь бесправный, то он не сможет запускать этот скрипт. Точнее скрипт он запустит, а вот обратиться к iptables - не сможет. Для того чтобы обойти эту неприятность и ставится sudo. Ставим:
ipkg install sudo
После установки, находим конфиг sudo (/opt/etc/sudoers) и правим его. Самый ПРАВИЛЬНЫЙ способ править конфиг sudo - это использовать утилиту visudo. Дело в том, что перед записью исправленного конфига visudo в начале проверяет его на корректность и если все нормально, то сохраняет его. А если находит ошибки - то не сохраняет. Итак, набираем в консоле:
visudo
Вот мой конфиг sudo. Строки которые я исправлял, отмечены красным:
# sudoers file.
#
# This file MUST be edited with the 'visudo' command as root.
# Failure to use 'visudo' may result in syntax or file permission errors
# that prevent sudo from running.
#
# See the sudoers man page for the details on how to write a sudoers file.
#
# Host alias specification
# User alias specification
# Cmnd alias specification
# Defaults specification
# Runas alias specification
# User privilege specification
# root ALL=(ALL) ALL
admin ALL=(ALL) ALL
# Uncomment to allow people in group wheel to run all commands
# %wheel ALL=(ALL) ALL
# Same thing without a password
# %wheel ALL=(ALL) NOPASSWD: ALL
# Samples
# %users ALL=/sbin/mount /cdrom,/sbin/umount /cdrom
# %users localhost=/sbin/shutdown -h now
p2p IGORROUTER = (admin) NOPASSWD: /usr/sbin/iptables
Defaults:p2p runas_default = admin
Defaults:admin runas_default = admin
Пользователя root я закомментарил, и добавил пользователя admin, аналогичного root.
Указал, что пользователь p2p может запускать на моем роутере (IGORROUTER) утилиту iptables без пароля.
Пользователем по умолчанию для p2p назначен admin. Также и для пользователя admin, назначен пользователь admin, иначе sudo пытается использовать пользователя root, которого нет. Узнать имя роутера можно при помощи hostname, например:
hostname
IGORROUTER
Кратко, команды, которые я использовал при правке конфига в visudo:
- клавиша <Insert> - перейти в режим редактирования;
- клавиша <Esc> - выйти из режима редактирования;
- ":w" - сохранить конфиг;
- ":q" - выйти из visudo;
- ":wq" - сохранить конфиг и выйти из visudo.
Скрипт rt-shaper.sh
Скрипт rt-shaper.sh предназначен для автоматической регилировки скачки/отдачи bittorrent-клиентом rTorrent в зависимости от наличия и количества трафика проходящего через роутер. Другими словами, если форвардного(проходящего через роутер на клиентов в вашей сети) трафика через роутер нет, то rTorrent, установленный на роутер, не ограничивается. Если же форвардный трафик есть, то скорость скачки/отдачи ограничивается. Более того, и скорость скачки, и скорость отдачи изменяется в заданном интервале в зависимости от количества форвардного трафика.
Я рекомендую скрипт ставить в отдельный каталог. У меня он стоит в /opt/etc/rt-shaper
На данный каталог нужно дать права пользователю p2p. У меня в качестве группы для каталога указана p2p и группе даны права на чтение(r), запись(w) и выполнение(x).
Далее, нужно место, где будут храниться значения, которые должны сохраняться между запусками скрипта. Поскольку, при каждом запуске скрипта, туда что-то пишется, лучше это место завести не на флешке, а на винте. У меня винт смонтирован в /home, а на нём я создал подкаталог var и ещё подкаталог rtorrent. Таким образом, путь к временным файлам имеет такой вид: /home/var/rtorrent
На него тоже нужно дать права на запись пользователю p2p.
Скрипт /opt/etc/rt-shaper/rt-shaper.sh
#!/bin/sh # Скрипт предназначения для автоматического ограничения rTorrent работающего на роутере # при обнаружении транзитного(форвардного) трафика через роутер. # Скорость(скорости upload'а и download'а) может варьироваться в заданном пределе в зависимости от # количества и поведения транзитного трафика. # С точки зрения rTorrent'а скрипт действует писсимистично, т.е.: # при присутсвии транзитного трафика rTorrent ограничевается быстрее, # чем это ограничение снимается при уменьшении транзитного трафика или его полном исчезновении # # Автор: Игорь (igor77777 on wl500g.info) # PATH=/opt/bin:/opt/sbin:/usr/bin:/sbin:/bin:/usr/sbin RTSHAPER=/opt/etc/rt-shaper VARCAT=/home/var/rtorrent LOGFILE=/opt/var/log/rt-shaper.log PIDUPWGET=$VARCAT/rtshaperupwget.pid PIDDLWGET=$VARCAT/rtshaperdlwget.pid # Если есть конфигурационный файл, то подключаем его min_uprate=10; # минимальный upload rate rTorrent в килобайтах. Скорость будет уменьшаться до него, но не ниже min_dlrate=10; # минимальный download rate rTorrent в килобайтах. Скорость будет уменьшаться до него, но не ниже step_rate=10; # шаг изменения rate в килобайтах max_uprate=50; # максимальный upload rate rTorrent в килобайтах. При появлении форвардного трафика будет выставлен именно он. При дальнейшем росте форвардного трафика rate будет уменьшаться вплоть для min_uprate max_dlrate=50; # максимальный download rate rTorrent в килобайтах. При появлении форвардного трафика будет выставлен именно он. При дальнейшем росте форвардного трафика rate будет уменьшаться вплоть для min_dlrate max_count_change_rate=5; # максимально колличество пропущенных изменений rate. После этого колличества rate будет изменен по любому interval_rate=5; # частота точнее интервал, в секундах, с которой дергается скрипт. Должен совпадать с тем, что указано в конфиге rTorrent enable_log=0; # признак ведения лога 0-не вести лог. 1-вести лог, 2-вести подробный лог, 3-лог с промежуточными переменными if [ -f $RTSHAPER/rt-shaper.conf ]; then . $RTSHAPER/rt-shaper.conf fi # первым делом проверяем, есть ли процессы wget порожденные скриптом # если есть, то скрипт дальше не выполняется if [ -e $PIDUPWGET -a -e $PIDDLWGET ]; then # файлы c pid'ами существуют hasexit=0 kill -0 $(cat $PIDDLWGET) >/dev/null 2>&1 res=$? [ $enable_log -gt 2 ] && echo "Search dlrate wget pid=$(cat $PIDDLWGET) res=$res. At " `date` >> $LOGFILE if [ $res -eq 0 ]; then hasexit=`expr $hasexit + 1` fi kill -0 $(cat $PIDUPWGET) >/dev/null 2>&1 res=$? [ $enable_log -gt 2 ] && echo "Search uprate wget pid=$(cat $PIDUPWGET) res=$res. At " `date` >> $LOGFILE if [ $res -eq 0 ]; then hasexit=`expr $hasexit + 1` fi if [ $hasexit -gt 0 ]; then [ $enable_log -gt 0 ] && echo "Find child wget. Script exit. At " `date` >> $LOGFILE exit 0 fi fi # установка upload rate rTorrent setuprate(){ _new_rate=$curr_uprate; if [ $_new_rate -ne 0 ]; then _new_rate="$_new_rate"k; fi _post_string="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\ <methodCall>\ <methodName>set_upload_rate</methodName>\ <params>\ <param>\ <value>\ <string>$_new_rate</string>\ </value>\ </param>\ </params>\ </methodCall>\ "; /opt/bin/wget -q --post-data="$_post_string" -O - http://127.0.0.1:80/RPC2 > /dev/null& pid=$! [ $enable_log -gt 2 ] && echo "Set uprate wget pid=$pid _post_string=$_post_string. At " `date` >> $LOGFILE echo $pid > $PIDUPWGET [ $enable_log -gt 0 ] && echo "set_upload_rate $_new_rate. At " `date` >> $LOGFILE } # установка download rate rTorrent setdlrate(){ _new_rate=$curr_dlrate; if [ $_new_rate -ne 0 ]; then _new_rate="$_new_rate"k; fi _post_string="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\ <methodCall>\ <methodName>set_download_rate</methodName>\ <params>\ <param>\ <value>\ <string>$_new_rate</string>\ </value>\ </param>\ </params>\ </methodCall>\ "; /opt/bin/wget -q --post-data="$_post_string" -O - http://127.0.0.1:80/RPC2 > /dev/null& pid=$! [ $enable_log -gt 2 ] && echo "Set dlrate wget pid=$pid _post_string=$_post_string. At " `date` >> $LOGFILE echo $pid > $PIDDLWGET [ $enable_log -gt 0 ] && echo "set_download_rate $_new_rate. At " `date` >> $LOGFILE } # Если файл с текущими значениями есть, то просто подключаем его if [ -f $VARCAT/curr_state ]; then . $VARCAT/curr_state else last=0; # последнее показание форвардного трафика last_delta=0; # последний объем трафика прошедший за измеряемый промежуток curr_uprate=0; # текущий upload rate curr_dlrate=0; # текущий download rate curr_state=0; # текущее состояние, если 0, то rtorrent не ограничивается count_change_rate_ups=0; # счетчик пропущенных изменений rate, по причине маленького отличия last_delta. После определенного колличества, все равно происходит изменение rate fi old_last=$last; old_last_delta=$last_delta; old_curr_uprate=$curr_uprate; old_curr_dlrate=$curr_dlrate; old_curr_state=$curr_state; old_count_chahge_rate_ups=$count_change_rate_ups; fwd=`sudo iptables -t filter -L FORWARD -v -x -n | tail -n 5 | head -n 1 | awk '{print($2)}'` # обрабатываем переполнение if [ $fwd -lt $last ]; then last=0; [ $enable_log -gt 1 ] && echo "Overflow counter forward byte. At " `date` >> $LOGFILE fi delta=0; change_uprate=0; change_dlrate=0; [ $enable_log -gt 2 ] && echo "fwd=$fdw last=$last. At " `date` >> $LOGFILE if [ $fwd -eq $last ]; then # форвардного трафика не было [ $enable_log -gt 2 ] && echo "curr_state=$curr_state. At " `date` >> $LOGFILE if [ $curr_state -gt 0 ]; then # если стоит ограничение, то снимаем его # но вначале определенное количество раз пропускаем [ $enable_log -gt 2 ] && echo "count_change_rate_ups=$count_change_rate_ups. At " `date` >> $LOGFILE if [ $count_change_rate_ups -ge $max_count_change_rate ]; then curr_state=0; last_delta=0; curr_uprate=0; curr_dlrate=0; count_change_rate_ups=0; change_uprate=1; change_dlrate=1; else [ $enable_log -gt 2 ] && echo "count_change_rate_ups++ =$count_change_rate_ups. At " `date` >> $LOGFILE count_change_rate_ups=`expr $count_change_rate_ups + 1`; fi fi else delta=`expr $fwd - $last`; last=$fwd; # если ограничения нет и появился форвардный трафик [ $enable_log -gt 2 ] && echo "curr_state=$curr_state delta=$delta. At " `date` >> $LOGFILE if [ $curr_state -eq 0 ]; then curr_state=1; curr_uprate=`expr $max_uprate - $step_rate`; curr_dlrate=`expr $max_dlrate - $step_rate`; count_change_rate_ups=0; change_uprate=1; change_dlrate=1; else # а вот если форвардный трафик уже был, то смотрим, прибавляется он или уменьшается # и в зависимости от этого дергаем скорость rtorrenta # кроме того, проверяется размер этого изменения, и изменяем, только если он больше определенной велечины [ $enable_log -gt 2 ] && echo "delta=$delta last_delta=$last_delta. At " `date` >> $LOGFILE if [ $delta -ge $last_delta ]; then # трафик прибавился uptrafic=`expr $delta - $last_delta`; # если прирост трафика больше половины шага уменьшения скорости для rTorrent [ $enable_log -gt 2 ] && echo "uptrafic=$uptrafic count_change_rate_ups=$count_change_rate_ups. At " `date` >> $LOGFILE if [ $uptrafic -ge `expr $step_rate '*' 1024 '*' $interval_rate / 2` -o $count_change_rate_ups -ge $max_count_change_rate ]; then # если текущая скорость uprate больше минимальной, то уменьшаем скорость ещё if [ $curr_uprate -gt $min_uprate ]; then curr_uprate=`expr $curr_uprate - $step_rate`; change_uprate=1; fi # если текущая скорость dlrate больше минимальной, то уменьшаем скорость ещё if [ $curr_dlrate -gt $min_dlrate ]; then curr_dlrate=`expr $curr_dlrate - $step_rate`; change_dlrate=1; fi if [ $change_uprate -eq 1 -o $change_dlrate -eq 1 ]; then curr_state=`expr $curr_state + 1`; fi count_change_rate_ups=0; [ $enable_log -gt 2 ] && echo "curr_uprate=$curr_uprate curr_dlrate=$curr_dlrate curr_state=$curr_state count_change_rate_ups=$count_change_rate_ups. At " `date` >> $LOGFILE else count_change_rate_ups=`expr $count_change_rate_ups + 1`; [ $enable_log -gt 2 ] && echo "count_change_rate_ups++ =$count_change_rate_ups. At " `date` >> $LOGFILE fi else # проходящий трафик уменьшился dltrafic=`expr $last_delta - $delta`; [ $enable_log -gt 2 ] && echo "dltrafic=$dltrafic count_change_rate_ups=$count_change_rate_ups. At " `date` >> $LOGFILE # если объем трафика уменьшился на щаг скорости для rTorrent if [ $dltrafic -ge `expr $step_rate '*' 1024 '*' $interval_rate` -o $count_change_rate_ups -ge $max_count_change_rate ]; then # если текущая скорость uprate больше минимальной, то уменьшаем скорость ещё if [ $curr_uprate -lt $max_uprate ]; then curr_uprate=`expr $curr_uprate + $step_rate`; change_uprate=1; fi # если текущая скорость dlrate больше минимальной, то уменьшаем скорость ещё if [ $curr_dlrate -lt $max_dlrate ]; then curr_dlrate=`expr $curr_dlrate + $step_rate`; change_dlrate=1; fi if [ $change_uprate -eq 1 -o $change_dlrate -eq 1 ]; then curr_state=`expr $curr_state - 1`; # при уменьшении трафика, не даем curr_state уйти в 0 if [ $curr_state -eq 0 ]; then curr_state=1; fi fi count_change_rate_ups=0; [ $enable_log -gt 2 ] && echo "curr_uprate=$curr_uprate curr_dlrate=$curr_dlrate curr_state=$curr_state count_change_rate_ups=$count_change_rate_ups. At " `date` >> $LOGFILE else count_change_rate_ups=`expr $count_change_rate_ups + 1`; [ $enable_log -gt 2 ] && echo "count_change_rate_ups++ =$count_change_rate_ups. At " `date` >> $LOGFILE fi fi fi fi [ $enable_log -gt 1 ] && echo "Previous forward trafic $last_delta, now forward trafic $delta, current state $curr_state, current upload rate $curr_uprate, current download rate $curr_dlrate. At " `date` >> $LOGFILE # если необходимо изменение rate, то вызываем соответствующие функции [ $change_uprate -eq 1 ] && setuprate [ $change_dlrate -eq 1 ] && setdlrate last=$fwd; last_delta=$delta; if [ $old_last -ne $last -o $old_last_delta -ne $last_delta -o $old_curr_uprate -ne $curr_uprate -o $old_curr_dlrate -ne $curr_dlrate -o $old_curr_state -ne $curr_state -o $old_count_chahge_rate_ups -ne $count_change_rate_ups ]; then echo -e "last=$last\nlast_delta=$last_delta\ncurr_uprate=$curr_uprate\ncurr_dlrate=$curr_dlrate\ncurr_state=$curr_state\ncount_change_rate_ups=$count_change_rate_ups\n" > $VARCAT/curr_state; [ $enable_log -gt 2 ] && echo "Exit script. last=$last last_delta=$last_delta curr_uprate=$curr_uprate curr_dlrate=$curr_dlrate curr_state=$curr_state count_change_rate_ups=$count_change_rate_ups. At " `date` >> $LOGFILE else [ $enable_log -gt 2 ] && echo "Exit script. No change temperary varables. $VARCAT/curr_state not save. At " `date` >> $LOGFILE fi exit 0
Строчки, которые нужно поменять под себя я выделил красным.
RTSHAPER= - каталог, в котором лежит сам скриптVARCAT= - каталог временных файлов
LOGFILE= - логфайл
В каталог /opt/etc/rt-shaper можно положить файл с настройками, которые будут использоваться в работе скрипта. Файл rt-shaper.conf
min_uprate=50; # минимальный upload rate rTorrent в килобайтах. Скорость будет уменьшаться до него, но не ниже
min_dlrate=10; # минимальный download rate rTorrent в килобайтах. Скорость будет уменьшаться до него, но не ниже
step_rate=10; # шаг изменения rate в килобайтах
max_uprate=70; # максимальный upload rate rTorrent в килобайтах. При появлении форвардного трафика будет выставлен именно он. При дальнейшем росте форвардного трафика rate будет уменьшаться вплоть для min_uprate
max_dlrate=50; # максимальный download rate rTorrent в килобайтах. При появлении форвардного трафика будет выставлен именно он. При дальнейшем росте форвардного трафика rate будет уменьшаться вплоть для min_dlrate
max_count_change_rate=5; # максимально количество пропущенных изменений rate. После этого количества rate будет изменен по любому
interval_rate=7; # частота точнее интервал, в секундах, с которой дергается скрипт. Должен совпадать с тем, что указано в конфиге rTorrent
enable_log=0; # признак ведения лога 0-не вести лог. 1-вести лог, 2-вести подробный лог, 3-лог с промежуточными переменными
Можно конфиг и не ложить, а задать все необходимые значения прямо в скрипте.
Параметры: min_uprate, min_dlrate, max_uprate, max_dlrate, step_rate - задаются в килобайтах. Т.е. сейчас, при наличии форвардного трафика скорость скачки будет гулять в интервале между 10 килобайтами и 50 килобайтами, а скорость отдачи между 50 килобайтами и 70 килобайтами с шагом в 10 килобайтами.
Параметр: interval_rate - должен совпадать с тем значением, которое будет указано для шедулера rTorrent, который будет запускать скрипт.
Подключение скрипта к rTorrent
Для подключения скрипта к rTorrent, нужно добавить одну строчку в конфиг rTorrent.
У меня конфиг rTorrent лежит в /opt/etc/rtorrent.conf
Добавляем туда строку:
schedule = rtshaper,15,7,execute=/opt/etc/rt-shaper/rt-shaper.sh
Здесь: 15 - задержка, в секундах, после которой rTorrent начнет запускать скрипт на выполнение. 7 - интервал, в секундах, с которым rTorrent будет запускать скрипт, должен совпадать с параметром interval_rate из rt-shaper.conf.
Вот собственно и все. Надеюсь, что я ни чего не пропустил.
Комментариев нет:
Отправить комментарий