Мы — долго запрягаем, быстро ездим, и сильно тормозим.
www.lissyara.su —> статьи —> FreeBSD —> подсчёт трафика —> ng_ipacct + squid

Подсчёт траффика с помощью ng_ipacct

Автор: arksu.


Итак начнем =). Возникла задача точно считать ВЕСЬ трафик с максимальной детализацией. Полез в инет искать готовые решения. Нашел кучу:
SAMS
NETAMS
SARG
IPACCT
и другие...

Но неустравивал функционал систем. Не гибко, проблемы с установкой, конфигурированием, трудно "подстраивать под себя". И решил искать альтернативу и делать "что-то свое". Скажу сразу что получилась связка ng_ipacct+squid+парсер логов+авторизатор+nginx+mysql и куча служебных скриптов для работы всей системы. Я назвал ее АСУТ (Автоматизированная система управления трафиком)

Часть 1. Общее описание системы
Начнемс. система состоит из нескольких модулей:
1. pf (файрволл с предустановленными правилами которые применяются по таблицам)
2. squid (прокси сервер с прописанной конфигурацией доступа и ACLами которые читаются из файлов)
3. mysql (база данных для хранения логов, пользователй, правил доступа, прав пользователей и другой не менее важной информации)
4. pfstat (формирование графиков, анализ работы роутера в целом)
5. nginx (чрезвычайно быстрый веб сервер с поддержкой FastCGI)
6. php, php-cgi (обработка php скриптов)
7. daemontools, ucspi-tcp (инструменты для создания tcpserver'а и демонизации процесса + ведение логов)
8. php скрипты (описывающие работу системы в целом - авторизация, управление системой, координация работы всех остальных модулей)

Ставим следующие порты, если их еще нет в системе:
/usr/ports/databases/mysql51-client
/usr/ports/databases/mysql51-server
/usr/ports/lang/php5
/usr/ports/lang/php5-extensions
/usr/ports/databases/phpmyadmin
/usr/ports/www/squid
/usr/ports/net-mgmt/ng_ipacct
/usr/ports/sysutils/daemontools
/usr/ports/sysutils/ucspi-tcp
/usr/ports/security/ipsec-tools
/usr/ports/sysutils/pfstat
/usr/ports/www/nginx-devel

И эти больше для удоства отладки и администрирования:
/usr/ports/sysutils/pftop
/usr/ports/security/sudo

Про установку и настройку MySQL, phpMyAdmin, nginx рассказывать не буду - на сайте полно информации.

Основной каталог с которым будет вестись вся работа: я назвал так - /var/asut (название не принципиально, просто потом нужно учитывать при последующем конфигурировании, у меня на каталог завязано многое
mkdir /var/asut

Часть 2. Установка ng_ipacct

Что такое ng_ipacct? Это NETGRAPH модуль ядра который представляет из себя TEE ноду NETGRAPH, перехватывает все пакеты проходящие через указанный интерфейс, суммирует байты по адресам и протоколам, хранит все это в памяти, и по сигналу скидывает собранные данные в файл. Так как это модуль ядра то сбор данных практически не сказывается на работе системы. Мне не удалось заметить сколь либо ощутимой загрузки средненького целерона даже при трафике 100 Мбит через интерфейс =)

Предварительно пересобираем ядро со следующими опциями:
options         NETGRAPH
options         NETGRAPH_ETHER
options         NETGRAPH_SOCKET
options         NETGRAPH_TEE

ставим:
cd /usr/ports/net-mgmt/ng_ipacct
make install clean

Оставляем опции по умолчанию
Тут можно добавить: в руководствах рекомендуют при каждой следующей пересборке ядра ставить ng_ipacct снова т.к. это все таки модуль ядра и пересборке он удаляется, но исходя из личного опыти после пересборки ядрая я забывал ставить ng_ipacct и тем не менее его модуль загружался и он работал.

Далее правим конфиг /usr/local/etc/ng_ipacct.conf
# указываем интерфейс на котором считать трафик
# не забываем менять bce1 во всем конфиг файле, еще ниже встречается несколько раз
ng_ipacct_interfaces="bce1"
ng_ipacct_modules_load="YES"
ng_ipacct_modules_list="ng_ipacct"

ng_ipacct_default_ether_start='
        mkpeer %%iface%%: tee lower right
        name %%iface%%:lower %%iface%%_tee
        connect %%iface%%: lower upper left

        mkpeer %%iface%%_tee: ipacct right2left %%iface%%_in
        name %%iface%%_tee:right2left %%iface%%_ip_acct
        connect %%iface%%_tee: %%iface%%_ip_acct: left2right %%iface%%_out
'

ng_ipacct_default_ether_stop='
        shutdown %%iface%%_ip_acct:
        shutdown %%iface%%_tee:
        shutdown %%iface%%:
'

ng_ipacct_bpf_ether_start='
        mkpeer %%iface%%: tee lower right
        name %%iface%%:lower %%iface%%_tee
        connect %%iface%%: lower upper left

        mkpeer %%iface%%_tee: bpf right2left %%iface%%_in
        name %%iface%%_tee:right2left %%iface%%_bpf
        connect %%iface%%_tee: right2left left2right %%iface%%_out

        mkpeer %%iface%%_bpf: ipacct %%iface%%_match_in %%iface%%_in
        name %%iface%%_bpf:%%iface%%_match_in %%iface%%_ip_acct
        connect %%iface%%_bpf: %%iface%%_ip_acct: %%iface%%_match_out %%iface%%_out
'

ng_ipacct_bpf_ether_stop='
        shutdown %%iface%%_ip_acct:
        shutdown %%iface%%_bpf:
        shutdown %%iface%%_tee:
        shutdown %%iface%%:
'


ng_ipacct_bce1_dlt="EN10MB"      # required line; see ipacctctl(8)
# 10000 записей будет хранится в памяти. чем больше RAM тем больше можно ставить значение
# из личного опыта 10000 записей при сбросе дампа 
# каждые 2 минуты хватает даже при больших нагрузках канала
# в том случае если будет превышено значение и все 10000 будут заполнены 
# все лишние записи просто не будут учитыватся и статистика "пропадет"
ng_ipacct_bce1_threshold="10000" # '5000' by default
ng_ipacct_bce1_verbose="yes"     # 'yes' by default
ng_ipacct_bce1_start=${ng_ipacct_default_ether_start}
ng_ipacct_bce1_stop=${ng_ipacct_default_ether_stop}

# указываем на имя скрипта для сброса лога
ng_ipacct_bce1_checkpoint_script="/var/asut/ipacct.sh bce1"

содержимое скрипта /var/asut/ipacct.sh
этот скрипт заставляет ng_ipacct сбросить собранную статистику в файл лога
#!/bin/sh
IPACCTCTL="/usr/local/sbin/ipacctctl"
IFACE=$1
# каталог куда скидывать лог файл
DIR=/var/asut/ipacct

if [ ! -e "$DIR" ]; then
   mkdir $DIR
fi

NAME="ng_ipacct.log"

$IPACCTCTL ${IFACE}_ip_acct:$IFACE checkpoint
$IPACCTCTL ${IFACE}_ip_acct:$IFACE show >> $DIR/$NAME
$IPACCTCTL ${IFACE}_ip_acct:$IFACE clear

/usr/bin/tail -1 $DIR/$NAME | /usr/bin/fgrep exceed

Для того чтобы заставить ng_ipacct сбрасывать дамп теперь нужно выполнить команду
/usr/local/etc/rc.d/ng_ipacct checkpoint

Вот пример лога
192.168.0.1     1245    34.12.32.34     22      6       199     8428
192.168.0.1     1462    12.12.12.12     22      6       18      772
192.168.0.1     1458    13.13.13.13     22      6       112     4688
192.168.0.1     1731    12.12.23.23     110     6       2       88
192.168.0.1     1464    45.23.12.12     22      6       18      824
192.168.0.1     333     192.168.0.1     333     6       13      760
45.23.12.12     22      192.168.0.1     1245    6       351     105260
45.23.12.12     22      192.168.0.1     1462    6       19      11632
45.23.12.12     22      192.168.0.1     1458    6       191     49240
34.12.123.4     110     192.168.0.1     1731    6       1       48
12.45.33.12     22      192.168.0.1     1464    6       20      13544
192.168.0.1     333     192.168.0.1     333     6       18      2228

столбцы слева нпараво:
адрес источника
порт источника
адрес получателя
порт получателя
номер протокола (описываются в /etc/protocols)
пакетов
байт

Все! Осталось добавить в /etc/rc.conf
echo '
ng_ipacct_enable="YES"
' >> /etc/rc.conf

Часть 3. Подготовка базы данных

#!/bin/sh
# создаем файл лога (если ведем логи)
touch /var/log/mysql.log

# меняем права доступа (ОБЯЗАТЕЛЬНО!!!)
chown mysql:wheel /var/log/mysql.log
chmod 640 /var/log/mysql.log

# создаем базу
/usr/local/bin/mysql_install_db
# меняем права доступа к каталогу (ОБЯЗАТЕЛЬНО!!!)
chown -R mysql:mysql /var/db/mysql

# врубаем мускул
echo 'mysql_enable="YES"' >> /etc/rc.conf
/usr/local/etc/rc.d/mysql-server start
# ставим свой пароль на рута в базе данных
mysqladmin -u root password 'my_pass'

Создаем таблицы в MySQL (предварительно создав базу):
CREATE DATABASE `asut` ;

USE `asut`;

CREATE TABLE IF NOT EXISTS `config` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` text NOT NULL,
  `param` text NOT NULL,
  `descr` text NOT NULL,
  `admin_level` int(2) NOT NULL,
  PRIMARY KEY (`id`)
) ;

INSERT INTO `config` (`id`, `name`, `param`, `descr`, `admin_level`) VALUES
(1, 'pf_table', 'allow_all', 'доступ администраторов (неограничен)', 500),
(2, 'pf_table', 'allow_icq', 'разрешить протокол ICQ', 2),
(3, 'squid_table', 'allow_all', 'полный доступ везде (неограничен ничем)', 500),
(5, 'squid_table', 'allow_normal',
'доступ для директоров (ограничения по порно сайтам и баннерам)', 10),
(6, 'squid_table', 'allow_work',
'доступ для обычных работников (ограничены порносайты,
баннеры, одноклассники, маил.ру и другие', 2),
(7, 'pf_table', 'allow_rdp', 'доступ RDP (3389)', 2),

CREATE TABLE IF NOT EXISTS `locks` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` text NOT NULL,
  PRIMARY KEY (`id`)
);

CREATE TABLE IF NOT EXISTS `log` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `mess` text NOT NULL,
  `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
);

CREATE TABLE IF NOT EXISTS `log_config` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `class` text NOT NULL,
  `message` text NOT NULL,
  `date` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ;

CREATE TABLE IF NOT EXISTS `ng_log` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `ip` text NOT NULL,
  `port` int(11) NOT NULL,
  `proto` text NOT NULL,
  `pkts_in` int(11) NOT NULL,
  `bytes_in` int(11) NOT NULL,
  `pkts_out` int(11) NOT NULL,
  `bytes_out` int(11) NOT NULL,
  `time` bigint(20) NOT NULL,
  PRIMARY KEY (`id`)
);

CREATE TABLE IF NOT EXISTS `rules` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `config_id` int(11) NOT NULL,
  PRIMARY KEY (`id`)
);

CREATE TABLE IF NOT EXISTS `squid_log` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `time` bigint(20) NOT NULL,
  `url` text NOT NULL,
  `site` text NOT NULL,
  `size` int(11) NOT NULL,
  PRIMARY KEY (`id`)
);

CREATE TABLE IF NOT EXISTS `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `login` text NOT NULL,
  `pass` text NOT NULL,
  `ip` char(16) NOT NULL,
  `last_keepalive` bigint(20) NOT NULL,
  `type` varchar(6) NOT NULL DEFAULT 'user',
  `enabled` int(1) NOT NULL DEFAULT '1',
  `day_quota` int(11) NOT NULL,
  `month_quota` int(11) NOT NULL,
  `fullname` text NOT NULL,
  `desc` text NOT NULL,
  `admin_level` int(2) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
);

CREATE TABLE IF NOT EXISTS `user_rights` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `name` varchar(20) NOT NULL,
  PRIMARY KEY (`id`)
);

Часть 4. Конфигурируем SQUID

squid уже стоит. Выполняем команду для создания каталога под кэш
squid -z

Правим конфиг SQUID, /usr/local/etc/squid/squid.conf:
# указываем какой интерфейс слушать
http_port 192.168.222.1:3128
# ошибки писать по-русски :)
# мы же заботимся о наших юзерах, мало кто из которых знает инглиш))
error_directory /usr/local/etc/squid/errors/Russian-1251
acl QUERY urlpath_regex cgi-bin \?
no_cache deny QUERY
cache_mem 16 MB
ftp_user anonymous@ass.com

acl all src 0.0.0.0/0.0.0.0

# тут указываем из каких файлов брать адреса клиентов которым разрешено то или иное
acl allow_all src "/var/asut/squid_conf/allow_all"
acl normal src "/var/asut/squid_conf/allow_normal"
acl work src "/var/asut/squid_conf/allow_work"

# тут указываем файлы с фильтрами содержимиого  
# одноклассники и прочие нехорошие вещи
acl notwork url_regex "/var/asut/squid_conf/notwork" 
# баннеры. мы ведь не хотим увеличения трафика из-за ненужных баннеров :)
acl banner url_regex "/var/asut/squid_conf/banner" 
# действительно рабочие сайты - возможно что-то будет
# резатся вышеописанными фильтрами, тут добавляем исключения
acl true_work url_regex "/var/asut/squid_conf/true_work" 

# запрещаем скачивать видео, музыку и тд и тп
acl bigfiles url_regex \.avi$ \.mpeg$ \.mpg$ \.exe$ \.mov$ \.iso$ \.nrg$ \.mpe$ \.mp3$ \.wmv$

acl manager proto cache_object
acl localhost src 127.0.0.1/255.255.255.255

# порты по которым будет пускать прокся
acl SSL_ports port 443 563
acl Safe_ports port 80             # http
acl Safe_ports port 21             # ftp
acl Safe_ports port 443            # https, snews
acl Safe_ports port 50000-65535    # ftp ports
acl CONNECT method CONNECT

http_access allow manager localhost
http_access deny manager

# Deny requests to unknown ports
http_access deny !Safe_ports

# Deny CONNECT to other than SSL ports
http_access deny CONNECT !SSL_ports

# описываем политики доступа
http_access allow true_work all
http_access allow allow_all
http_access deny bigfiles all
http_access deny banner all
http_access allow normal
http_access deny notwork all
http_access allow work

http_access allow localhost
http_access deny all
icp_access allow all
access_log /usr/local/squid/logs/access.log squid

Часть 5. Конфигурируем pfstat

Файл /etc/pfstat.conf (не забываем заменить vr0 на ваш ВНЕШНИЙ интерфейс)
collect 1 = interface "vr0" pass bytes in ipv4 diff
collect 2 = interface "vr0" pass bytes out ipv4 diff
collect 3 = interface "vr0" block bytes in ipv4 diff
collect 4 = interface "vr0" block bytes out ipv4 diff

image "/var/asut/www/pfstat/hour_ext.jpg" {
        from 300 minutes to now
        width 980 height 300
        left
                graph 1 bps "in" "bits/s" color 0 192 0 filled,
                graph 2 bps "out" "bits/s" color 0 0 255
        right
                graph 3 "block in" "p/s" color 255 0 0,
                graph 4 "block out" "p/s" color 192 192 0
}
image "/var/asut/www/pfstat/day_ext.jpg" {
        from 1 days to now
        width 980 height 300
        left
                graph 1 bps "in" "bits/s" color 0 192 0 filled,
                graph 2 bps "out" "bits/s" color 0 0 255
        right
                graph 3 "block in" "p/s" color 255 0 0,
                graph 4 "block out" "p/s" color 192 192 0
}

collect  9 = global states inserts  diff
collect 10 = global states removals diff
collect 11 = global states searches diff

image "/var/asut/www/pfstat/pfstat-states.jpg" {
        from 1 days to now
        width 980 height 300
        left
                graph 9 "inserts" "states/s" color 0 192 0 filled,
                graph 10 "removals" "states/s" color 0 0 255
        right
                graph 11 "searches" "states/s" color 255 0 0
}
collect 15 = global counters match          diff
collect 17 = global counters fragment       diff
collect 22 = global counters congestion     diff
collect 23 = global counters ip-option      diff
collect 24 = global counters proto-cksum    diff
collect 25 = global counters state-mismatch diff

image "/var/asut/www/pfstat/pfstat-errors.jpg" {
        from 1 days to now
        width 980 height 300
        left
                graph 17 "frag" "/s" color 192 0 192,
                graph 22 "cong" "/s" color 0 192 192,
                graph 23 "iopt" "/s" color 0 0 255,
                graph 24 "csum" "/s" color 192 192 0,
                graph 25 "mism" "/s" color 255 0 0
        right
                graph 15 "match" "/s" color 0 192 0
}

Создаем каталог под логи
mkdir /var/log/pfstat

И добавляем в крон
# crontab -u root -e

# раз в минуту собираем статистику интфрейса в лог файл
*   * * * *  /usr/local/bin/pfstat -q -d /var/log/pfstat/pfstat -c /etc/pfstat.conf
# раз в 5 минут генерируем графические отчеты
*/5 * * * *  /usr/local/bin/pfstat -p -d /var/log/pfstat/pfstat -c /etc/pfstat.conf

Часть 6. Конфигурируем nginx

Для корректной работы phpmyadmin через nginx
mv /usr/local/www/phpMyAdmin /usr/local/www/phpmyadmin

Файл /usr/local/etc/nginx/nginx.conf
user  nobody;
worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    gzip  on;
    server {
        listen       80;
        server_name  localhost;
        #charset koi8-r;

        location / {
            root   /usr/local/www/nginx;
            index  index.php index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/local/www/nginx-dist;
        }
######################################################################################
        location ~* /www/.*\.php$ {
            root   /var/asut;
            fastcgi_pass   127.0.0.1:1026;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /var/asut/$fastcgi_script_name;
            include        fastcgi_params;
        }
        location ~* /www/ {
                root   /var/asut;
                index  index.php index.html index.htm;
        }
######################################################################################
        location ~* /phpmyadmin/.*\.php$ {
            root   /usr/local/www;
            fastcgi_pass   127.0.0.1:1026;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /usr/local/www$fastcgi_script_name;
            include        fastcgi_params;
        }
        location ~* /phpmyadmin/ {
                root   /usr/local/www;
                index  index.php index.html index.htm;
        }
######################################################################################
    }
}

создаем файл /usr/local/etc/rc.d/php-cgi и пишем в него (спасибо Nikll за подсказку)
#!/bin/sh
#
# PROVIDE: php_fastcgi
# REQUIRE: DAEMON
# BEFORE:  LOGIN
# KEYWORD: shutdown

. /etc/rc.subr

name="php_fastcgi"
rcvar=`set_rcvar`

load_rc_config $name

: ${php_fastcgi_enable="NO"}
: ${php_fastcgi_user="www"}
: ${php_fastcgi_bindaddr="127.0.0.1"}
: ${php_fastcgi_bindport="9000"}
: ${php_fastcgi_children="5"}
: ${php_fastcgi_max_requests="1000"}
: ${php_fastcgi_allowed_env=""}

export PHP_FCGI_CHILDREN=${php_fastcgi_children};
export PHP_FCGI_MAX_REQUESTS=${php_fastcgi_max_requests};

command="/usr/local/bin/php-cgi";
command_args="-q -b ${php_fastcgi_bindaddr}:${php_fastcgi_bindport} &";
pidfile="/var/run/${name}.pid";

_allowed_env="ORACLE_HOME PATH USER PHP_FCGI_CHILDREN \
PHP_FCGI_MAX_REQUESTS FCGI_WEB_SERVER_ADDRS";
_allowed_env="${_allowed_env} ${php_fastcgi_allowed_env}";

start_precmd="${name}_start_precmd";
start_postcmd="ps -U ${php_fastcgi_user} -o \
  'pid,command'|grep ${command}|head -1|awk . '{print \$1}' > ${pidfile}";

php_fastcgi_start_precmd()
{
   export USER=${php_fastcgi_user};
   E=
   for i in ${_allowed_env}; do
       eval _val="\$$i";
       if [ "${_val}_x" != "_x" ]; then
           eval _add="$i=$_val";
           E="${E} ${_add}";
       fi
   done
   command="env - ${E} ${command}";
}

load_rc_config $name;

run_rc_command "$1";

Меняем права на файл
chmod +x /usr/local/etc/rc.d/php-cgi

И добавляем в /etc/rc.conf
nginx_enable="YES"

php_fastcgi_enable="YES"
php_fastcgi_user="www"
php_fastcgi_bindaddr="127.0.0.1"
php_fastcgi_bindport="1026"
php_fastcgi_children="5"
php_fastcgi_max_requests="1000"
php_fastcgi_allowed_env=""

Часть 7. Конфигурируем daemontools
создаем рабочие каталоги
mkdir -p /var/asut/supervise/server/log
mkdir -p /var/asut/log/

файл /var/asut/supervise/server/run
#!/bin/sh

exec /usr/local/bin/softlimit -m 100000000 \
/usr/local/bin/tcpserver -v -c 200 0 888 /var/asut/server.php 2>&1

желательно вместо 0 ставить адрес внутреннего интерфейса

файл /var/asut/supervise/server/log/run
#!/bin/sh
PATH=/var/qmail/bin:/usr/local/bin:/usr/bin:/bin
export PATH
exec multilog t s100000 n20 /var/asut/log/server.log 2>&1

в /etc/rc.conf добавляем строки:
svscan_enable="YES"
svscan_servicedir="/var/asut/supervise"

Часть 8. Настраиваем pf.

примерный конфиг /etc/pf:
int_if="bce1"
ext_if="bce0"
#=============================================================

web_ports="{80, 443}"
lans="{192.168.0.0/24}"

set skip on lo0
set skip on gif0
set skip on $int_if

table <allow_all>       persist file "/etc/pf_conf/allow_all"
table <allow_icq>       persist file "/etc/pf_conf/allow_icq"
table <allow_rdp> 		persist file "/etc/pf_conf/allow_rdp"

no nat on $ext_if from any to any port $web_ports
nat pass on $ext_if proto {tcp, udp, icmp} from <allow_all> to any -> $ext_if
nat pass on $ext_if proto tcp from <allow_icq> to any port {5190} -> $ext_if
nat pass on $ext_if proto tcp from <allow_rdp> to any port 3389 -> $ext_if

# допустим надо сделать проброс портов извне на какую-то машину в локалке
rdr pass on $ext_if proto tcp from 111.111.111.111 to $ext_if port 4001 -> 192.168.0.1 port 3389

pass out on $ext_if from $ext_if to any
pass out on $ext_if inet proto tcp from $ext_if to any port $web_ports keep state
pass on $ext_if inet proto icmp all

#ssh
pass in on $ext_if inet proto tcp from any to $ext_if port 22 keep state

#web acces
pass in on $ext_if inet proto tcp from 111.111.111.111 to $ext_if port 80

#mysql_access
pass in on $ext_if inet proto tcp from 222.222.222.222 to $ext_if port 3306

Часть 9. Сердце системы. Исполняемые скрипты.

Файл /var/asut/server.php
Данный скрипт описывает работу сервера авторизации. Написан на php. Работает по принципу Telnet, передача между клиентом и сервером идет в текстовом режиме в UTF8 кодировке (чтобы подружить Windows м UNIX)
Сервер авторизации
файл скачан размер размещён примечание
auth_server.rar
1209 1.7kb 2008-09-16 Сервер авторизации АСУТ

Файл /var/asut/global.php. Обновляет конфиги файрволла и прокси сервера, обеспечивает квотирование. Хорошо прокомментирован. :)
Центральный скрипт
файл скачан размер размещён примечание
global.rar
1196 3.3kb 2008-09-16 Центральный скрипт

Клиент авторизации. Написан на Delphi, писал на 2007, по идее должен компилится на любой. Зависимость от JVCL
файл скачан размер размещён примечание
client.rar
1108 904.3kb 2008-09-16 Клиент авторизации

Файл /var/asut/reconfigure.php - скрипт реконфигурирования (запускается по таймеру каждые 2 минуты)
#!/usr/local/bin/php
<?php
include('global.php');
reconfigure(0);
?>

добавляем в крон
chmod +x /var/asut/reconfigure.php
crontab -u root -e
*/2     *       *       *       *       root    /var/asut/reconfigure.php

Веб интерфейс для работы с системой. Формирование отчетов и другое. Положить все файлы в папку /var/asut/www
файл скачан размер размещён примечание
www.rar
1179 24.6kb 2008-09-16 Веб морда к АСУТ

Часть 10. Заключение. Механизмы работы.
в разработке... дописываю (устал писать)



размещено: 2008-09-12,
последнее обновление: 2009-03-04,
автор: arksu


Cancer, 2008-09-14 в 14:17:56

Вопросик а как же будет рубать пользователей за превышение трафика?

arksu, 2008-09-14 в 22:23:37

я сделал отдельный сервер авторизации на php. и авторизация либо по домену. либо по паролю логину. либо по айпи. можно в принципе любую авторизацию замутить. все ограничивается только фантазией.
статья в разработке.... все опишу ;)

kolobok, 2008-09-15 в 4:47:35

Чтоб не ругался:
root: /etc/rc: WARNING: can not load kld module netgraph
kernel: module_register: module ng_ether already exists!
kernel: Module ng_ether failed to register: 17
root: /etc/rc: WARNING: can not load kld module ng_ether
Нужно убрать netgraph и ng_ether
ng_ipacct_modules_list
Ибо ядро, видимо, уже собрано с ними.

arksu, 2008-09-15 в 8:42:05

kolobok - ты прав. ядро уже собрано с этими опциями. просто я не вдавался в суть этих ошибок ибо и с ними все прекрасно работает. сейчас обновлю статью
спасибо за замечание =)

www2, 2008-09-16 в 8:02:45

Судя по всему ng_acct похож на ng_netflow, только для netflow нужна ещё программа-коллектор.

В netflow есть такая штука как аггрегация информации за определённый период времени. Коллектор из комплекта flow-tools умеет скидывать потоки в двоичные файлы, в MySQL, в PostgreSQL.

Во flow-tools есть программы для фильтрации, аггрегации и построения отчётов из двоичных фалов. Если складывать в БД - возможности обработки вообще практически безграничные.

greg_b, 2008-09-16 в 9:09:38

В принципе неплохо, ждем продолжения. Надо ж в реалии потестить.

opt1k, 2008-09-16 в 11:06:19

вот мне squid нравиться за возмоэность ntlm аутентификации. Вот бы считалку трафика с ntlm

arksu, 2008-09-16 в 11:09:16

терпение! и только терпение!
я пошел дальше и сделал смешанную авторизацию. по логин-паролю, по доменной учетке, по айпи, можно и по MACу сделать (все ограничивается фантазией)
и эту авторизацию завязал на файрволл и squid.
скоро допишу....

XeNoN, 2008-09-16 в 13:14:20

Маленький совет, полезный при работе с netgraph и для устранения неполадок. Команда ngctl dot генерирует диаграмму связей netgraph узлов  в dot формате graphviz, т.е можно наглядно посмотреть, что и как соединяется.

tms, 2008-09-18 в 12:42:34

у мне какие-то непонятки c ng_ipacct - он установлен на шлюзе с ipfw NAT и в логе есть только данные по траффику с IP внешнего интерфейса. А как мне увидеть еще и траффик внутренних IP?

arksu, 2008-09-18 в 14:39:44

tms, ты считаешь трафик на внешнем интерфейсе. укажи в конфиге ng_ipacct считать трафик на внутреннем - тогда ты будешь видеть кто куда лазил из локалки

tms, 2008-09-18 в 18:26:28

считать на внутреннем интерфейсе тоже не очень правильно - часть траффика в счетчик вообще не попадет... замкнутый круг какой-то.

Aldaron, 2008-09-22 в 20:33:52

Хорошая статья, попробуем сделать все с pf. Пытался с ipfw - ничего не получилось. Хотя дело не в файрволле, у меня с самим нетграфом дикие косяки были. Мож со второго захода получится )

arksu, 2008-09-23 в 14:00:37

с ipfw делается аналогично, надо создать правила с привязкой на таблицы, их грузить из файлов, а файлы указать в скрипте global.php
и там же изменить команду на перезагрузку правил

Aldaron, 2008-09-24 в 10:56:20

Это я понимаю) Я с самим ng_ipacct намучился, не смг его прикрутить

arksu, 2008-09-24 в 10:59:25

можете по вопрсоам обращаться в аську: 232-455

sofinan, 2008-10-27 в 14:36:54

Пытался настроить по статье, но где то на середине устал бороться и решил сделать по своему.Срубил все что ниже ng_ippact, написал парсер лога терь пытаюсь прикрутить к lightsquid)))))Пока нихуя не получается)

Zar, 2008-10-29 в 9:14:28

2lissyara

слушай, а если в предыдущих статьях trafd & mysql и ipacctd

взять скрипт получения трафика и заюзать его для получения трафика из ng_ipacct все же отработает? структура же лога выгрузки одинакова?

Zar, 2008-10-29 в 11:34:28

все сделал, так что можно не отвечать :)
все работает, надо будет только замерить и потестить насколько корректно :)

Zar, 2008-11-24 в 7:39:12

Народ, подскажите... как уменьшить колличество логов для ng_ippact ?
а то у меня тестовый сервер в холостую за месяц БД мускла 150метров... и столько же log.txt

когда если сравнивать с traffd то у меня за год база мускля ~700Мб

подскажите выход? :)

arksu, 2008-11-24 в 13:37:03

в данный момент я занимаюсь этой проблемой
что сделано:
1. переписан на 100% авторизатор
2. переписан сервер авторизации
3. оптимизирована структура БД
4. много изменений в админке

что планируется:
1. сделать скрипт инсталяции БД и админки
2. дописать админку (редактироание прав пользователейи и тд и тп)

flint, 2008-11-24 в 13:49:17

а здесь это появиться?!

arksu, 2008-11-24 в 14:48:01

появится. возможно выложу на свой сайт.
либо напишу статью по новой

opt1k, 2008-12-04 в 17:55:21

автор, спасибо тебе большое, пиши ещё, статья интересная и актуальная

copypaiste, 2008-12-05 в 7:40:27

Очень интересный и нужный проект. Удачи автору! ;)

E-Wind, 2009-01-17 в 16:07:53

Просто загоняет трафик в БД

В Конфиге

ng_ipacct_fxp0_checkpoint_script="/root/scripts/ng_ipacct.sh fxp0"

Дамп:

--
— Структура таблицы `traffic_fxp0`
--

CREATE TABLE IF NOT EXISTS `traffic_fxp0` (
 `src_ip` varchar(15) NOT NULL,
 `src_port` int(11) NOT NULL,
 `dst_ip` varchar(15) NOT NULL,
 `dst_port` int(11) NOT NULL,
 `protocol` int(11) NOT NULL,
 `packets` int(11) NOT NULL,
 `bytes` int(11) NOT NULL,
 `unixtime` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

Скрипт -  ng_ipacct.sh

#!/bin/sh
IPACCTCTL="/usr/local/sbin/ipacctctl"
IFACE=$1

$IPACCTCTL ${IFACE}_ip_acct:$IFACE checkpoint
$IPACCTCTL ${IFACE}_ip_acct:$IFACE show | awk '{print "INSERT INTO `dbs_system`.`traffic_'$IFACE'` (`src_ip`,`src_port`,`dst_ip`,`dst_port`,`protocol`,`packets`,`bytes`,`unixtime`) VALUES (\""$1"\",\""$2"\",\""$3"\",\""$4"\",\""$5"\",\""$6"\",\""$7"\",\""$8"\"); "}' | /usr/local/bin/mysql -u <ПОЛЬЗОВАТЕЛЬ БД> -p<ПАРОЛЬ К БД> dbs_system
$IPACCTCTL ${IFACE}_ip_acct:$IFACE clear

Можно сделать лучше )

arksu, 2009-01-19 в 7:12:56

вся система переписана "от" и "до", развитие продолжается. просто пока не созрел выложить сюда. времени не хватает.
система используется для реальной работы в реальной компании в сети филиалов как файрволл, прокси, учет трафика, авторизатор, впн, и еще много функций...

Cancer, 2009-01-19 в 11:21:39

А скрины можно увидеть ?

opt1k, 2009-01-19 в 12:41:49

товарищ arksu, молимся на вас, ждём, ждём доменную ntlm авторизацию

arksu, 2009-01-19 в 16:37:07

объясню почему нет привязки на домен...
система "псевдо" привязана к домену. т.е. юзеры заносятся в эту базу и в домен. и логины должны совпадать буква в букву.
как работает:
запускается авторизатор на клиентской тачке. проверяет как выполнен вход пользователя в систему - либо вход в домен, либо локальный вход. если в домен - авторизатор выясняет в какой домен был вход, отправляет на сервер, если домен совпал с доменом который прописан в конфиге на сервере - клиент выясняет под каким логином вошел юзер,
если совпал логин с логином на сервере - считается что вход юзера в систему успешен. т.е. он авторизовался и можно прописать ему его правила
если же вход локальный - авторизатор еще спрашивает и пароль. и отправляет это на сервер, ну а потом если все ок - авторизует
ПОЧЕМУ? зачем именно так. домен не всегда и везде работает безглючно. особенно когда филиалов 20+ и доменов раскиданых по России столько же. чтобы не ловить глюков винды была сделана именно такая схема работы. юезров можно всегда импортировать в эту базу. или настроит автоматический импорт, можно авторизовать юзеров которых нет в домене (временные пользователи, гости) или которые приезжают из других филиалов (говорить что надо строить доменное дерево не надо...жалко трафик да и опять же глюкавость....)

arksu, 2009-01-19 в 16:40:00

Опять же по повду доменной авторизации... система написана на основе модульной структуры. т.е. в принципе можно прикрутить что угодно. не нарушая общей структуры.
на данный момент с "псевдо" авторизацией система работает как часы уже полгода. возможно в будущем я напишу сам. или возможно кому-то будет интересно и он напишет сам - в данном случае лучше связатся со мной, и я подскажу как и что делать...
www.ark.su

arksu, 2009-01-19 в 16:45:28

опять же к вопросу о домене.... =)
сеть филиалов на виндовых доменах работает с 2006 года...
за это время были не раз подвисания домена. когда нажимаешь с клиентской тачки вход в систему - а он думает долгоооо-долгооооооо и только потом начинает логинится.
т.е. глючит именно запрос в лдап домена или что-то еще.... но это происходть с завидной регулярность. поэтому желания разбиратся что там и как мало... лично мне проще было отвязать полсностю систему от домена. а те функции которые авторизатор испльзует для выяснения логина и домена - оттестированы и не глючат (работают быстро, используя ресурсы только локального компьютера, без обращений к домену)

arksu, 2009-01-19 в 16:48:27

чет меня проперло прям))))))

можно поставить самбу, настроить керберос на фре. и юзать функции самбы для авторизации, в принципе не трудно, и работать будет как часы)
но! имхо я сплю спокойнее когда знаю что на винду в этой системе НЕ ЗАВЯЗАНО вообще ничего! =) и никаких проблем с лицензированием не возникнет в принципе.
как говорица: не придирессии

jek, 2009-03-03 в 18:01:08

Исправьте строку

номер протокола (описываются в /etc/services)

на

номер протокола (описываются в /etc/protocols)

arksu, 2009-03-04 в 8:52:17

спасибо за замечание. запарился...

opt1k, 2009-05-22 в 8:07:25

ув. arksu недолго думая взял для своей бакалаврской работы тему учёта трафика на предприятии. Хочу использовать ваши наработки включая скрипты, естественно ссылку на статью оставлю :) Не против ли вы?
И вроде бы всё понятно на 1ый взгляд, но если вдруг будут вопросы, можно будет с вами связаться? я доставать особо не буду, ибо во многом уже разобрался по вашей статье :) Я бы хотел докрутить всё таки НТЛМ(в инете видел примеры на тех же дельфях) или даже может церберов.
Спасибо!

arksu, 2009-05-22 в 13:36:26

ув. opt1k, на данный момент система сильно изменена в сравнеии с тем что описано в статье. со свободным временем стало получше - выложу всю обновленную систему в течение месяца. и напишу статью.

а пока небольшие отрезки:

1. Авторизатор
решил уйти от постоянного TCP соединения, минусы:
при перезагрузке сервиса авторизации все коннекты рвутся, все пользователи становятся неавторизованными, лишний трафик, держатся постоянные соединения на стороне сервера - нагрузка на стек, еще один "дополнительный" демон - сложность в настройке
подумал-подумал и решил сделать как во всех "взрослых" современных нагруженных проектах - работа по HTTP
на сервере есть скрипт auth.php к которому обращается клиент и передает параметры через POST запрос. через него же осуществляется keepalive
что нам это дало:
избавились от отдельного демона. ниче дополнительно конфигурить не надо, nginx прекрасно справляется
за счет nginx+php-fpm+eaccelerator - высокое быстродействие

продолжение следует.......

adre, 2009-12-14 в 7:54:58

где продолжение?

arksu, 2009-12-14 в 12:25:20

на продолжение не хватает сил ))))
уже полгода...

vasilek, 2011-09-16 в 21:58:55

Что-то я не допонял, зачем тут squid, если на него не заворачивают трафик? Как ему(squid'у) приснится?

arksu, 2011-10-28 в 2:32:03

у клиентов руками в браузерах прописана прокся
у нас стоял виндовый домен. мы через политики домена всем настроили разом.
и резали намертво 80 порт. так что либо прокся - либо сидишь без http

если делать \"прозрачный\" прокси - скрывался айпи клиента (на тот момент не знал как решить) сейчас понимаю что можно было решить и прозрачное проксирование......
опыт приходит со временем)

Nologin, 2013-04-03 в 16:32:20

День добрый, так что со статьей? Она уже обновлена под текущий применяемый вами билд или все еще как изначально было написано?



 

  Этот информационный блок появился по той простой причине, что многие считают нормальным, брать чужую информацию не уведомляя автора (что не так страшно), и не оставляя линк на оригинал и автора — что более существенно. Я не против распространения информации — только за. Только условие простое — извольте подписывать автора, и оставлять линк на оригинальную страницу в виде прямой, активной, нескриптовой, незакрытой от индексирования, и не запрещенной для следования роботов ссылки.
  Если соизволите поставить автора в известность — то вообще почёт вам и уважение.

© lissyara 2006-10-24 08:47 MSK

Время генерации страницы 0.0824 секунд
Из них PHP: 61%; SQL: 39%; Число SQL-запросов: 81 шт.
Исходный размер: 113511; Сжатая: 21766