Скрипты для организации безлимита в разное время суток (VPN)

Форум для размещения материалов по реализации различных схем использования ПО, решению частых проблем и предупреждению частых ошибок
Закрыто
SOLDIER
Сообщения: 649
Зарегистрирован: Чт мар 16, 2006 18:07

Скрипты для организации безлимита в разное время суток (VPN)

Сообщение SOLDIER »

Дано:
UTM 5.2.1-005
ОС - Gentoo.
Пользователи подключаются по VPN (PPTP). Скорости безлимитных тарифов формируются при помощи радиус-апарметров, заданных в настройках тарифных планов. Ограничения вешаются на ppp-интерфейс пользователя, назначаемый ему после авторизации.
Возникла задача с 1.00 до 8.00 снимать ограничения трафика. Путём проб и допиливания баш-скрипта был рождён вот такой скрипт под названием 30-shape.sh (размещается в директории /etc/ppp/ip-up.d:

Код: Выделить всё

#!/bin/bash
# Script for shaping. SOLDIER.
# Rev 1.1. Changes for Night Unlimited (from 1.00 before 8.00).
if [ -f /var/run/radattr.$1 ]
   then
         DOWNSPEED=`/bin/awk  '/PPPD-Downstream-Speed-Limit/ {print $2}'  /var/run/radattr.$1`
         UPSPEED=`/bin/awk  '/PPPD-Upstream-Speed-Limit/ {print $2}'  /var/run/radattr.$1`
         IP=`/bin/awk  '/Framed-IP-Address/ {print $2}'  /var/run/radattr.$1`
         DATE=`date +%d/%m/%G-%H:%M:%S`
         HOUR=`date +%H`

    /sbin/tc qdisc del dev $1 root    > /dev/null
    /sbin/tc qdisc del dev $1 ingress > /dev/null

 ##### speed server->client
 if [ "$HOUR" -lt "01" ] OR [ "$HOUR" -gt "07" ]
        then
        if [ ["$DOWNSPEED" -gt "0"]
         then
           case $DOWNSPEED in
            824) DOWNSPEED=`expr $DOWNSPEED + 210`;;
            860) DOWNSPEED=`expr $DOWNSPEED + 2840`;;
            # было 700) DOWNSPEED=`expr $DOWNSPEED + 6110`;;
            700) DOWNSPEED=`expr $DOWNSPEED + 6150`;;
            600) DOWNSPEED=`expr $DOWNSPEED + 11450`;;
            # было 600) DOWNSPEED=`expr $DOWNSPEED + 11410`;;
            812) DOWNSPEED=`expr $DOWNSPEED + 2950`;;
            # было  812) DOWNSPEED=`expr $DOWNSPEED + 2910`;;
            *) k=1;;
            esac
                /sbin/tc qdisc add dev $1 root handle 1: htb default 30 r2q 1

                /sbin/tc class add dev $1 parent 1: classid 1:1 htb rate 100mbit burst 4k quantum 60000

                /sbin/tc class add dev $1 parent 1:1 classid 1:10 htb rate 80mbit burst 4k prio 10 quantum 60000
                /sbin/tc class add dev $1 parent 1:1 classid 1:20 htb rate ${DOWNSPEED}kbit burst 4k prio 20
 quantum 60000
                /sbin/tc class add dev $1 parent 1:1 classid 1:30 htb rate ${DOWNSPEED}kbit burst 4k prio 30
 quantum 60000

                /sbin/tc qdisc add dev $1 parent 1:10 handle 10: sfq perturb 10 quantum 1500
                /sbin/tc qdisc add dev $1 parent 1:20 handle 20: sfq perturb 10 quantum 1500
                /sbin/tc qdisc add dev $1 parent 1:30 handle 20: sfq perturb 10 quantum 1500

                /sbin/tc filter add dev $1 parent 1:0 protocol ip prio 10 u32 match ip src 10.10.10.10 flowid 1:10
                /sbin/tc filter add dev $1 parent 1:0 protocol ip prio 10 u32 match ip src 10.10.10.11 flowid 1:10
                /sbin/tc filter add dev $1 parent 1:0 protocol ip prio 10 u32 match ip src 192.168.100.100 flowid 1:10
                /sbin/tc filter add dev $1 parent 1:0 protocol ip prio 10 u32 match ip dst 10.10.10.10 flowid 1:10
                /sbin/tc filter add dev $1 parent 1:0 protocol ip prio 10 u32 match ip dst 10.10.10.11 flowid 1:10
                /sbin/tc filter add dev $1 parent 1:0 protocol ip prio 20 u32 match ip tos 0x10 0xff flowid1:20
                /sbin/tc filter add dev $1 parent 1:0 protocol ip prio 20 u32 match ip protocol 1 0xff flowid 1:20
                /sbin/tc filter add dev $1 parent 1: protocol ip prio 20 u32 match ip protocol 6 0xff match u8 0x05 0x0f at 0 match u160x0000 0xffc0 at 2 match u8 0x10 0xff at 33 flowid 1:20
        fi
    fi
##### speed client->server
    if [ "$HOUR" -lt "01" ] || [ "$HOUR" -gt "07" ]
       then
       if [ "$UPSPEED" -gt "0" ]
              then
              case $UPSPEED in
              910) UPSPEED=`expr $UPSPEED + 840`;;
              # было 910) UPSPEED=`expr $UPSPEED + 800`;;
              300) UPSPEED=`expr $UPSPEED + 3150`;;
              # было 300) UPSPEED=`expr $UPSPEED + 3100`;;
              500) UPSPEED=`expr $UPSPEED + 5550`;;
              # было 500) UPSPEED=`expr $UPSPEED + 5510`;;
              824) UPSPEED=`expr $UPSPEED + 2876`;;
              *) k=1;;
              esac
              burst=`echo $UPSPEED/100+2 | bc 2>/dev/null`
               /sbin/tc qdisc add dev $1 handle ffff: ingress
               /sbin/tc filter add dev $1 parent ffff: protocol ip prio 50 u32 match ip src 0.0.0.0/0 police rate ${UPSPEED}kbit burst ${burst}k mtu 12k drop flowid :1
       fi
      fi
       echo "$DATE :HOUR - $HOUR :Interface $1: IP-address: $IP, DOWNSPEED: $DOWNSPEED, UPSPEED: $UPSPEED" >> /var/log/pppd/speeds.log

fi

CASE нужен потому, что радиус-параметры (скорость в моём случае) некорректно передаются Радиусом НетАпа - значения больше 1000 не передаются - вернее, передаётся какая-то чушь. Поэтому вынужен был таким вот образом формировать нужные мне значения.
В скрипте сняты ограничения на внутренние файлопомойки (10.10.10.10, 10.10.10.11, 192.168.100.100). Возможно - там есть и что-то лишнее, а что-то сделано неоптимально - каждый волен переделывать под себя. :) Разумеется, снятие ограничения - это частный случай - при желании можно через else выставить свои ограничения. Возникает ещё один нюанс - если в час ночи пользователей можно "заинтересовать", чтобы они сами переподключались (чтобы выставились новые скорости на ppp-интерфейсе), то в 8 часов утра они уже будут не заинтересованы в этом. ;) Что очевидно. Поэтому вынужден был сделать вот такой вот скриптик (пока недопиленный, но логика, думаю, будет понятна. Его цель - вытащить из базы IP-адреса тех, у кого безлимитные тарифы, проверить кто из них на линии и сформировать файл. Через тот же while read можно потом по порядку давать команды на "опускания" соответвтсвующих интерфейсов (pppN) - до мая это доделаю. Код скрипта:

Код: Выделить всё

#!/bin/bash
DATE=`date +%d/%m/%G-%H:%M:%S`
echo "SELECT inet_ntoa( ip &4294967295 ) FROM ip_groups , users, service_links WHERE service_links.service_i
d IN ('63', '65', '67', '69') AND service_links.is_deleted !=1 and users.is_deleted!=1 and ip_groups.is_dele
ted != 1 AND service_links.account_id = users.basic_account AND users.login = ip_groups.uname" | mysql -N -u
 user -ppassword UTM5 > /var/log/pppd/list_IP.txt
rm -f /var/log/pppd/ppp.txt
cat list_IP.txt | (
 while read var ;
 do grep -s $var /var/run/* | grep rad | cut -f2 -d '.' | cut -f1 -d':' >> /var/log/pppd/ppp.txt;
 done
 )
 N=`wc -l ppp.txt | cut -f1 -d ' '`
echo "$DATE: Numbers of unlims online - $N">> /var/log/pppd/unlims.log
echo "Done!"
Выбираются 4 моих безлимитных тарифа. С ID=63, 65,67,69. Скрипт надо, естественно, запускать по крону. while для "опускания" интерфейсов добавлю позже. :)
Собственно - вот. Делюсь с коллегами своими наработками. Повторюсь - я не претендую, что всё сделал оптимально. :) Я не гуру в баше. Тем не менее, буду также рад услышать критику/исправления.

cjcrazy
Сообщения: 497
Зарегистрирован: Чт янв 20, 2005 21:54

Сообщение cjcrazy »

По второму скрипту:
Пользователей выключать не надо (создание лишних неудобств).
Нужно составлять список ip-интерфейсов, затем с ip бежать в базу биллинга, выяснять тариф, устанвленные ограничения и перерезать полосу на интерфейсах пизлимитчиков заново.

Соответственно, этот скрипт нужно выполнять столько раз в день, сколько ступенек запланировано.

SOLDIER
Сообщения: 649
Зарегистрирован: Чт мар 16, 2006 18:07

Сообщение SOLDIER »

cjcrazy писал(а):По второму скрипту:
Пользователей выключать не надо (создание лишних неудобств).
Нужно составлять список ip-интерфейсов, затем с ip бежать в базу биллинга, выяснять тариф, устанвленные ограничения и перерезать полосу на интерфейсах пизлимитчиков заново.
Дык ёлы-палы. :) Поясняю ещё раз. Скрипт выдирает как раз из базы список IP безлимитчиков, потом прогоняет ifconfig на предмет нахождения оных на линии, составляет список ppp-интерфейсов, на которых они находятся. Ну и предполагается ifconfig pppNNN down. Почему это необходимо я вроде бы тоже написал - насколько я знаю tc не позволяет менять скорость на уже работающем ppp-интерфейсе. Хотя не считаю себя большим знатоком tc. Вполне допускаю, что я неправ. :wink:

cjcrazy
Сообщения: 497
Зарегистрирован: Чт янв 20, 2005 21:54

Сообщение cjcrazy »

2SOLDIER, про ifconfig pppX down - спешу сообщить - интерфейс покладете, но не выключите (убъете). он может ещё дооолго в таком состоянии находиться. со стороны пользователя будет выглядеть как непонятная проблема: pppoe-подключение поднято, но трафик не бегает.

скорость на ppp менять легко:

Код: Выделить всё

/sbin/tc qdisc change dev....
работает (выдерга из рабочей системы).

убивать pppoe - гляньте в сторону ключика -k у pppoe (один из возможных вариантов).

куда смотреть сначала (в базу, либо на интерфейсы) - дело вкуса ;)

SOLDIER
Сообщения: 649
Зарегистрирован: Чт мар 16, 2006 18:07

Сообщение SOLDIER »

cjcrazy, про change - спасибо. Подумаю. Про "не выключите" - возможно Вы правы - проверю. Насчёт "долго" - не уверен.
Попутно - у меня pptp. Хотя это вряд ли имеет разницу.
ПысЫ: За "покладёте" отдельное спасибо. Лично от меня. :)

cjcrazy
Сообщения: 497
Зарегистрирован: Чт янв 20, 2005 21:54

Сообщение cjcrazy »

2SOLDIER, рад помочь. ;)

Закрыто