Squid Lightsquid ограничение трафика

squid-lightsquidБывают ситуации, когда нужно лимитировать количество трафика для пользователей сети. Это можно сделать при помощи proxy сервера squid и анализатора логов lightsquid.

Подробно об установке squid можно почитать в этой статье, об установке lightsquid вот в этой. В основе написания статьи использовался материал из этой публикации.

Идея заключается в том, что в конфигурационном файле squid мы добавим новый acl, членам которого мы запретим доступ в интернет. Информацию о превысивших лимит пользователях мы будем брать из отчетов lightsquid. Добавлением превысивших лимит пользователей в запрещающий acl будет заниматься созданный нами скрипт. Периодичность выполнения скрипта будет определена в планировщике.

Добавим в  /etc/squid/squid.conf запрещающие acl

# nano /etc/squid/squid.conf

# Description authentication schemes
. . .
acl no_quota url_regex -i "/etc/squid/db/no_quota_url.txt"
acl banusers proxy_auth_regex -i "/etc/squid/db/user_deny.txt"
. . .
http_access deny manager
http_access allow banusers no_quota
http_access deny banusers all
deny_info ERR_QUOTA all
http_access allow internet
http_access allow localhost
http_access deny all
. . .

Важно определить запрещающие acl после описания доступных схем аутентификации, иначе squid вылетит в следующую ошибку

Warning: empty ACL: acl banusers proxy_auth_regex -i "/etc/squid/db/user_deny.txt"
Can't use proxy auth because no authentication schemes are fully configured.
FATAL: ERROR: Invalid ACL: acl banusers proxy_auth_regex -i "/etc/squid/db/user_deny.txt"

acl no_quota предназначен для добавления сайтов, которые будут доступны при превышении  квоты. Он заполняется руками.

# mkdir /etc/squid/db
# echo "4skill.ru" > /etc/squid/db/no_quota_url.txt

acl banusers заполняется по средствам скрипта и содержит список, превысивших лимит пользователей. Он создается автоматически.

ERR_QUOTA это шаблон HTML страницы, выводимой пользователю, при превышении квоты. Эту страницу нужно создать руками

# nano /usr/share/squid/errors/templates/ERR_QUOTA

<html><head>
<meta type="copyright" content="Copyright (C) 1996-2015 The Squid Software Foundation and contributors">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Превышен лимит</title>
<style type="text/css"><!--
%l

body
:lang(fa) { direction: rtl; font-size: 100%; font-family: Tahoma, Roya, sans-serif; float: right; }
:lang(he) { direction: rtl; }
--></style>
</head><body id="%c">
<div id="titles">
<h1>ПРЕВЫШЕН ЛИМИТ</h1>
<h2>Запрошенный URL не может быть получен</h2>
</div>
<hr>

<div id="content">
<p>При получении URL <a href="%U">%U</a> произошла следующая ошибка</p>

<blockquote id="error">
<p><b>Вы превысили месячный лимит на интеренет.</b></p>
</blockquote>

<p>Система контроля доступа не позволяет выполнить ваш запрос сейчас. Обратитесь к вашему администратору.</p>

<p>Администратор Вашего кэша: <a href="mailto:%w%W">%w</a>.</p>
<br>
</div>

<hr>
<div id="footer">
<p>Создано %t на %h (%s)</p>
<!-- %c -->
</div>
</body></html>

Добавим папку для скрипта

mkdir /etc/squid/traf_limit

Создадим в /etc/squid/traf_limit скрипт traf_limit.pl

# nano /etc/squid/traf_limit/traf_limit.pl

#!/usr/bin/perl
# Довесок на LightSquid Project (c) 2004-2005 Sergey Erokhin aka ESL
# Скрипт создает файл user_deny для ограничения Интернета по трафику
# Автор: Иван Лонин loninia@apksouz.ru 2008 год

use File::Basename;

# Не очень хорошо напрямую писать путь к конфигурационному файлу, но не
# хотелось sh-файл для сron делать

require "/etc/squid/traf_limit/config";

#($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)= localtime(time);
@dat=localtime(time);
$year =1900+$dat[5];
$month=1 + $dat[4];
if ($month<10){
    $month="0".$month
}
$filter="$year$month";

#print "$log_path/$filter*\n";
@daylist=glob("$log_path/$filter*");

foreach $daypath (sort @daylist) {

  open FF,"<$daypath/.total";
  $totaluser=<FF>;chomp $totaluser;$totaluser=~s/^user: //;
  $totalsize=<FF>;chomp $totalsize;$totalsize=~s/^size: //;

while (<FF>) {

    ($user,$size,$hit)=split;
    $h{$user}{size}+=$size;
    $h{$user}{hit}+=$hit;
  }
  close FF;
}
#
$cummulative=0;
open RES,">$res_file";
print RES "# файл содержит пользователей, превысивших квоту.\
# автоматически переписывается скриптом traf_limit.pl\n";

foreach $user (sort {$h{$b}{size}<=>$h{$a}{size}} keys %h) {
    $all4user=$h{$user}{size}/1024/1024;
    if ($vip_user{$user}{size} > 0) {
        $limit=$vip_user{$user}{size};
    }else{
        $limit=$all_limit;
    }
    if ($all4user >= $limit) {
        print RES "$user\n";
#        print "$h{$user}{size}\n";
    };
}

Добавим права на запуск

# chmod +x /etc/squid/traf_limit/traf_limit.pl

Добавим конфигурационный файл для скрипта

# nano /etc/squid/traf_limit/config

#!/usr/bin/perl
# путь к логам lightsquid
$log_path="/var/lib/lightsquid/report";

# Файл, в который пишутся пользователи, превысившие лимит
$res_file="/etc/squid/db/user_deny.txt";

# Лимит трафика в мегабайтах
$all_limit=3000;

# Привилегированные пользователи с повышенным или пониженным
# лимитом для каждого пользователя строка формата:
# $vip_user={<имя_пользователя}{size}=<лимит_в_мегабайтах>;
$vip_user{"192.168.1.100"}{size}=7000;
$vip_user{user1}{size}=7000;

В данном примере лимит составляет 3GB в месяц.

Добавим выполнение скрипта в планировщик

# nano /etc/cron.d/lightsquid
. . .
30 * * * * root [ -x /usr/share/lightsquid/lightparser.pl ] && /usr/share/lightsquid/lightparser.pl
0 * * * * root /etc/squid/traf_limit/traf_limit.pl && /usr/sbin/squid -k reconfigure > /dev/null 2>&1

Запуск скрипта traf_limit.pl имеет смысл только после формирования отчета lightsquid скриптом lightparser.pl. Это нужно учитывать при формировании расписания в планировщике.

Простой способ лимитирования суточного трафика

В отчетах lightsquid присутствует колонка «Превысили». В данную секцию попадают пользователи, суточный трафик которых превысил значение параметра в /etc/lightsquid/lightsquid.cfg

#user maximum size per day limit (oversize)
$perusertrafficlimit = 500*1024*1024;

В примере выше указан лимит в 500МБ.

Создадим скрипт /etc/lightsquid/over_limit.sh

# nano /etc/lightsquid/over_limit.sh

#!/bin/sh

unset path
path=/var/lib/lightsquid/report/$(date +%Y%m%d)

cut -f 1 /var/lib/lightsquid/report/$(date +%Y%m%d)/.overuser > /etc/squid/db/user_deny.txt
/usr/sbin/squid -k reconfigure

exit 0

Добавим права на запуск

# chmod +x /etc/lightsquid/over_limit.sh

Данный скрипт будет записывать в запрещающий acl пользователей из колонки «Превысили».

Добавим скрипт в планировщик

# nano /etc/cron.d/lightsquid
. . .
30 * * * * root [ -x /usr/share/lightsquid/lightparser.pl ] && /usr/share/lightsquid/lightparser.pl
#0 * * * * root /etc/squid/traf_limit/traf_limit.pl && /usr/sbin/squid -k reconfigure > /dev/null 2>&1
0 * * * * root /etc/lightsquid/over_limit.sh > /dev/null 2>&1

Squid Lightsquid ограничение трафика: 4 комментария

  1. Павел

    Спасибо, интересная и полезная статья, интересно будет поэкспериментировать с /etc/squid/traf_limit/config. На самом деле есть некий челендж, заставить в Lightsquid грузиться группы из определенного контейнера AD. И вот для этих групп задавать лимиты. То есть в Lightsquid определить лимиты для пользователей внутри каждой группы. А дальше все по вашей статье.

    1. Андрей Автор записи

      Обновил статью Lightsquid Ubuntu Server 16.04 на тему авто заполнения файла групп для lightsquid. Правда группы добавляются не из названия OU, а из атрибута department.

  2. Игорь

    Андрей, не подскажите, столкнулись со следующей проблемой, traf_limit.pl, похоже некорректно отрабатывает учетные записи содержащие символ — (тире). При превышении $all_limit, пользователь с прописанным индивидуальным лимитом $vip_user, записывается в файл user_deny.txt У пользователей, имя которых не содержит — (тире), скрипт отрабатывает корректно, индивидуальные лимиты применяются.
    С уважением,

    1. Андрей Автор записи

      Добрый день!
      Сейчас воспроизвел описанную ситуацию. В /etc/squid/traf_limit/config указал пользователя user-name1 с лимитом в 12 МБ

      $vip_user{user-name1}{size}=12;

      Далее запустил сам скрипт

      /etc/squid/traf_limit/traf_limit.pl

      После проработки скрипта, пользователь записался в user_deny.txt

      # cat /etc/squid/db/user_deny.txt
      # файл содержит пользователей, превысивших квоту.
      # автоматически переписывается скриптом traf_limit.pl
      cl1$
      user1
      user-name1

      После запуска

      /usr/sbin/squid -k reconfigure

      Пользователь user-name1 потерял доступ в интернет.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *