Искать по блогу

Рубрики

Архив записей

Умный шейпер

В домашней сети время от времени появляется от одного до пяти компьютеров одновременно, каждый из которых имеет доступ в Интернет. Стационарные машины подключены по проводам, а ноутбук и два нетбука цепляются через 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

Оставить мнение



*