Умный шейпер
В домашней сети время от времени появляется от одного до пяти компьютеров одновременно, каждый из которых имеет доступ в Интернет. Стационарные машины подключены по проводам, а ноутбук и два нетбука цепляются через Wi-Fi роутер. Так уж вышло, что мой компьютер под управлением Linux Ubuntu 10.04, чаще всего бывает включен. ПК честно служит для всех файлопомойкой, а для меня — медиасервером и менеджером закачек с HTTP, FTP и BitTorrent. Весь входящий канал, как правило, забивается, отчего другие пользователи сети не в состоянии спокойно посерфить странички.
Почесал голову и написал небольшой shell-скрипт, устанавливающий ограничение, которое надо было всякий раз активировать вручную при крике отца «Эй! Ты опять качаешь что-то?» и снимать, когда он уходил спать. Так продолжалось несколько месяцев, пока мне не нужно было уезжать из города.
Конечно, можно составить особое расписание по будним и выходным дням и заставлять ОС ограничивать / восстанавливать скорость на сетевом интерфейсе в определённый час. (Или вовсе выключать / включать компьютер) Вроде всё хорошо, но может быть и так, что родные и не захотят быть в сети в это время. Получается, действия будут напрасны. Пришло на ум написать «умный шейпер»: некоторую программу, которая с заданной периодичностью будет проверять появление новых хостов в нашей домашней сети, изменение которых должно будет фиксироваться. На основе собранных данных скрипт должен будет анализировать и изменять правила.
Регулировать скорость будет wondershaper, сканировать объекты в локальной сети — утилита nmap, следить за расписанием — планировщик cron, а выполнять действия — интерпретатор Bash. Для пользователей Debian-подобных операционных систем все приложения доступны в репозиториях.
Создадим файл /bin/clshaper и установим права на исполнение (chmod +x).
Обозначим переменные:
DEFAULT_HOSTS — количество хостов по-умолчанию. В моём случае, это число равно двум, поскольку кроме меня в сети есть ещё и ADSL-модем.
INTERFACE — имя сетевого интерфейса. Узнать его можно с помощью команды ifconfig.
D_SPEED, U_SPEED — скорость загрузки и отдачи соответственно.
TMP_DIR — каталог для размещения временных файлов. Потребуется для хранения информации о «старых» хостах.
TMP_FILE — имя временного файла.
1 2 3 4 5 6 7 | #!/bin/bash DEFAULT_HOSTS=2 INTERFACE="eth1" D_SPEED=512 U_SPEED=512 TMP_DIR="/tmp/" TMP_FILE="tmp_nmap_scan.txt" |
Произведём сканирование сети на предмет наличия в них хостов и выделим из строки их количество.
8 9 | NMAP_STRING=$(nmap -sP 192.168.1.0/24 | grep "Nmap done"); NMAP_HOSTS=$(echo "$NMAP_STRING" | egrep -o '\(.+\)' | egrep -o '[0-9]'); |
Узнаём: существует ли наш файл во временном каталоге. Если он ещё не был создан, то сделаем это.
10 11 12 13 14 15 | TMP_FILE_EXIST=$(ls "$TMP_DIR" | grep "$TMP_FILE"); if [ ! "$TMP_FILE_EXIST" ] then touch "$TMP_FILE" && chmod 0777 "$TMP_FILE" && echo "$NMAP_HOSTS" > "$TMP_FILE" fi cd "$TMP_DIR"; |
Выделяем «старое» количество хостов из файла.
16 | FILE_HOSTS=$(cat "$TMP_FILE"); |
Выполняем проверку. Если количество хостов было изменено на значение DEFAULT_HOSTS, то выполняем изменение правил. Если ограничения однажды были установлены, то они будут сняты, и наоборот. Выполненные изменения записываем во временный файл.
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | if [ "$NMAP_HOSTS" != "$FILE_HOSTS" ] then if [ "$NMAP_HOSTS" = "$DEFAULT_HOSTS" -o "$FILE_HOSTS" = "$DEFAULT_HOSTS" ] then LIMIT=$(wondershaper $INTERFACE | grep "bounded"); if [ "$LIMIT" ] wondershaper clear $INTERFACE notify-send "Скорость восстановлена" echo "Все правила были очищены" else wondershaper $INTERFACE $D_SPEED $U_SPEED notify-send "Скорость ограничена" echo "Скорость была ограничена" fi echo "$NMAP_HOSTS" > "$TMP_FILE"; fi fi |
Сохраним файл и нам остаётся только добавить в /etc/crontab следующую строчку, чтобы заставить скрипт выполняться каждые 10 минут. Перезапустите демон cron и наслаждайтесь.
*/10 * * * * root /bin/clshaper