LINUX.ORG.RU

Ограничение трафика на порт


1

2

Здравствуйте, имеется сервер ОС Debian. Задача состоит следующим, ограничить порты на траффик. Много гуглил, читал. Решил использовать iptables+quota . Т.к биллинговых систем, нет подходящих.. Суть такова, порты открываются на внешнюю сеть, мы даем им ограничение в заданном количестве трафика, нужно сделать так чтобы трафик считал за месяц, а при его достижении лимита(входящего так и исходящего), блокировал этот порт.

Пример такой: iptables -A INPUT -p tcp --dport 80 -m quota --quota 52428800 -j ACCEPT

iptables -A INPUT -p tcp --dport 80 -j DROP

Но не совсем понятно, как ограничить его по времени, и после блокировать.. Просьба знающих объяснить, спасибо за внимание!



Последнее исправление: trowke (всего исправлений: 1)

Создаёшь квоту на определённый объём данных, следующим правилом правилом DROP/REJECT и раз в месяц по крону сбрасываешь цепочки/счётчики.

ИМХО, если уж пользуешь крон, проще наваять скрипт/пару скриптов для сбора статистики (iptables -nvxL и парсить вывод) и включения/выключения по условию.

nickleiten ★★★
()
Ответ на: комментарий от trowke

1. Создаём скрипт для старта нашей системы (его можно в rc.local прописать), например /opt/quotas/rc.quotas-start:

#!/bin/sh

DROOT="/opt/quotas";

LIST="$DROOT/_list";

cat $LIST | while read L;do
    N=`echo $L|awk '{print $1}'`;
    T=`echo $L|awk '{print $2}'`;
    P=`echo $L|awk '{print $3}'`;

    iptables -N quota_$N;
    iptables -A quota_$N -p $T --dport $P -j ACCEPT;
    iptables -I INPUT -j quota_$N;
done
Для удобства обрамляем наши таблицы именем с префиксом quota_* Также можно слегка автоматизировать это дело, вынеся параметры правил в отдельный файл, в котором будем указывать размер квоты и для какого порта применять, например, /opt/quota/_list:
web   tcp   80   52428800
ssh   tcp   22   12800000
Думаю, с этим всё понятно. Можно ещё накалякать скрипт убирающий весь этот мусор из iptables (для остановки этих правил), например /opt/quotas/rc.quotas-stop:
#!/bin/sh

DROOT="/opt/quotas";

LIST="$DROOT/_list";

cat $LIST | while read L;do
    N=`echo $L|awk '{print $1}'`;
    iptables -D INPUT -j quota_$N;
    iptables -F quota_$N;
    iptables -X quota_$N;
done


2. Создаём скрипт, собирающий статистику, например /opt/quotas/traff-cron.sh:

#!/bin/sh

DROOT="/opt/quotas";

YEAR=`date +%Y`;
MON=`date +%m`;
DAY=`date +%d`;
TIME=`date +%H:%M`;

LIST="$DROOT/_list";

cat $LIST | while read L;do
    N=`echo $L|awk '{print $1}'`;
    TRAFF=`iptables -Z -xnvL $N|head -n3|tail -n1|awk '{print $2}'`;
    if [ ! -d "$DROOT/$N" ];then mkdir -p "$DROOT/$N"; fi
    if [ ! -d "$DROOT/$N/$YEAR" ];then mkdir -p "$DROOT/$N/$YEAR"; fi
    FULLDIR="$DROOT/$N/$YEAR/$MON";
    if [ ! -d "$FULLDIR" ];then mkdir -p "$FULLDIR"; fi
    
    echo "$TIME  $TRAFF" >>$FULLDIR/$DAY;
    if [ -e "$FULLDIR/_traffic" ];then
        OLDMONTRAFF=`cat $FULLDIR/_traffic`;
        NEWMONTRAFF=`expr $OLDMONTRAFF + $TRAFF`;
        echo $NEWMONTRAFF > $FULLDIR/_traffic
    else
        echo $TRAFF > $FULLDIR/_traffic;
    fi
done
Тут всё просто, берём все таблицы с префиксом quota_ и в цикле каждую обрабатываем (берем кол.-во байт из iptables, создаём поддиректории согласно дате сбора статистики если таковых не имеется и считаем трафик помесячно, годовые я не реализовывал, т.к. там всё то же самое за исключением пути хранения файла, пусть будет домашним заданием).
3. Теперь самое интересное - скрипт, который будет включать/выключать. Путь будет /opt/quotas/styx-cron.sh
#!/bin/sh

DROOT="/opt/quotas";

YEAR=`date +%Y`;
MON=`date +%m`;
DAY=`date +%d`;
TIME=`date +%H:%M`;

LIST="$DROOT/_list";

cat $LIST | while read L;do
    N=`echo $L|awk '{print $1}'`;

    FULLDIR="$DROOT/$N/$YEAR/$MON";
    if [ -d "$FULLDIR" ];then 
        if [ -e "$FULLDIR/_traffic" ];then
            Q=`echo $L|awk '{print $4}'`;
            T=`echo $L|awk '{print $2}'`;
            P=`echo $L|awk '{print $3}'`;
            MTRAFF=`cat $FULLDIR/_traffic`;
            if [ "$MTRAFF" -ge "$Q" ];then
                iptables -F quota_$N;
                iptables -A quota_$N -p $T --dport $P -j DROP
            fi
        fi
    fi
    
done
Берём список, проверяем есть ли хоть какая-то статистика в виде директории текущего месяца, есть ли файл с трафиком за весь месяц и проверяем числа из файла с квотой, при превышении лимита - убираем старые правила из таблицы и добавляем DROP.
4. Осталась автоматизация, то есть файл crontab. Назовём его /opt/quotas/quotas.crontab:
*/1 * * * * /opt/quotas/traff-cron.sh
*/5 * * * * /opt/quotas/styx-cron.sh
0 0 1 * * /opt/quotas/rc.quotas-stop.sh && /opt/quotas/rc.quotas-start.sh
Собственно всё ясно - раз в минуту собираем урожай из циферок, раз в пять минут проверяем пора ли отключать и раз в месяц рестарт всей системы.

И не збываем в rc.local прописать файлы /opt/quotas/rc.quotas-start и обязательно crontab /opt/quotas/quotas.crontab

nickleiten ★★★
()
Ответ на: комментарий от nickleiten

Спасибо большое, за подробную инструкцию. Но при просмотре всей цепочки, iptables -L -n , не могу обноружить заданную мной категорию порта 80, с 50 мб трафика..

А вот если я на прямик добовляю правила: iptables -A INPUT -p tcp --dport 80 -m quota --quota 52428800 -j ACCEPT

то все видно в цепочке.. подскажите как быть, спасибо!

trowke
() автор топика
Ответ на: комментарий от trowke

Там есть просто правило ACCEPT с указанными криетриями, оно нам нужно для счётчика трафика. А включением/выключением занимаются отдельные скрипты. В моём примере -m quota не используется вообще.

nickleiten ★★★
()
Ответ на: комментарий от nickleiten

т.е смотрите, допустим мне нужно открыть порт 22 для ssh добовляю правила:

iptables -A INPUT -p tcp --dport 22 -m quota --quota 52428800 -j ACCEPT

после чего идем в /opt/quota/_list и добовляем в файл ssh tcp 22 12800000

и тогда оно начнет считать? видимо я не все понимаю :(

trowke
() автор топика
Ответ на: комментарий от trowke

Ничего добавлять не надо. Скрипты сами всё добавляют согласно _list - почитайте внимательно rc.quota-start

nickleiten ★★★
()
Ответ на: комментарий от trowke

В смысле сами ручками iptables трогать не надо, вы редактируете _list и рестартуете rc.quote-stop;rc.quote-start - они сами сгенерируют нужные правила.

nickleiten ★★★
()

Если всё-таки так горите желанием использовать -m quota, то решение немного упрощается, но теряется возможность сбора статистики.
1. Создаём файлы /opt/quota/_list:

web   tcp   80   52428800
ssh   tcp   22   12800000
Первый столбец - имя таблицы, второй - протокол [tcp/udp], третий - порт, четвёртый - квота в байтах
2. Создаём файл /opt/quota/rc.quotas-start:
#!/bin/sh

DROOT="/opt/quotas";

LIST="$DROOT/_list";

cat $LIST | while read L;do
    N=`echo $L|awk '{print $1}'`;
    T=`echo $L|awk '{print $2}'`;
    P=`echo $L|awk '{print $3}'`;
    Q=`echo $L|awk '{print $4}'`;
    iptables -N quota_$N;
    iptables -A quota_$N -p $T --dport $P -m quota --quota $Q -j ACCEPT;
    iptables -A quota_$N -p $T --dport $P -j DROP
    iptables -I INPUT -j quota_$N;
done
В этом варианте, создаются таблицы с цепочками прохождения, пока квота не переполнена будет выполняться условие ACCEPT, если нет, то след. правило в iptables будет отбрасівать пакеты (DROP)
3. Создаём файл /opt/quota/rc.quotas-stop
#!/bin/sh

DROOT="/opt/quotas";

LIST="$DROOT/_list";

cat $LIST | while read L;do
    N=`echo $L|awk '{print $1}'`;
    iptables -D INPUT -j quota_$N;
    iptables -F quota_$N;
    iptables -X quota_$N;
done
Файл аналогичен первому примеру, простоая очистка таблиц и удаление правил.
4. Теперь создаём /opt/quota/quotas.crontab:
0 0 1 * * /opt/quota/rc.quotas-stop && /opt/quota/rc.quotas-start
Именно эта строка сбрасывает раз в месяц счётчики.

Этот вариант проще, и как раз выполняет всё, что вы хотите без дополнительных усилий. Никаких манипуляций с вашей стороны не требуется в плане добавления правил вручную - всё генерируется скриптами, указанными выше. Необходимо только добавить в /etc/rc.local такие строки:

/opt/quota/rc.quotas-start
crontab /opt/quota/quotas.crontab
Если в вашем /etc/rc.local есть строка exit 0, то эти строки нужно добавить до этого самого exit 0.

nickleiten ★★★
()
Ответ на: комментарий от nickleiten

скажите возможно ли с вами как-то связаться icq\ skype ?

trowke
() автор топика
Ответ на: комментарий от nickleiten

как в первом так и во втором способе, видно через вывод iptables -L -n только одно правила это web с 80 портом, что идет после него, молчек.. Давайте свяжемся, обговорим работу, которую я хочу сделать, а вы скажите свою сумму, т.к я ценю чужой труд.

trowke
() автор топика
Ответ на: комментарий от trowke

В скайпе редко бываю, jabber/xmpp включен всегда, когда я за компьютером. Скайп сейчас включил - всё есть в профиле.

nickleiten ★★★
()
Ответ на: комментарий от trowke

В связи с некоторыми опечатками в путях (/opt/quota и /opt/quotas) скрипты немного коряво работают, но работают - только что проверил и собрал всё воедино. Стучитесь в скайп/джаббер, я всю ночь на связи.

nickleiten ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.