У нас на шлюзе (FeeBSD) в качестве фаирвола используется PF, когда возникла необходимость учета и анализа трафика в качестве инструмента был выбран ng_ipacct.
Конфигурация ng_ipacct
Установка из портов стандартная, и конфиг с небольшими изменениями
# $FreeBSD: ports/net-mgmt/ng_ipacct/files/ng_ipacct.conf,v 1.6 2008/06/03 10:40:16 skv Exp $
#
# Please read and meditate on netgraph(4), ipacctctl(8) and ngctl(8).
# Enable ng_ipacct (i.e. enable run startup script "ng_ipacct.sh")
ng_ipacct_enable="YES"
# Enable kernel modules loading.
# On "ng_ipacct.sh start" all kernel modules specified
# in ${ng_ipacct_modules_list} will be loaded.
# Note: on "ng_ipacct.sh stop" only "ng_ipacct" will be unloaded.
ng_ipacct_modules_load="YES"
# Netgraph can load required ng_* modules automatically on the hook creation
# - except for "ng_ether". Generally, modules preloading is recommended.
# Do not add to this list modules which are statically compiled into kernel.
#ng_ipacct_modules_list="netgraph ng_ether ng_cisco ng_socket ng_tee ng_ipacct"
ng_ipacct_modules_list="ng_ipacct"
# List of monitored interfaces. For each interface additional vars must be
# specified in corresponding variables 'ng_ipacct_IFACE_*'.
# See examples below.
ng_ipacct_interfaces="rl1 rl0"
# Default start/stop scripts.
#
# Single quotes are required to preserve newlines.
# '%%iface%%' will be automatically expanded with a relevant interface.
# This feature should be applied to use indentical rules
# for similar interfaces.
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%%:
'
# Configuration for 'rl1_ip_acct' node:
ng_ipacct_rl1_dlt="EN10MB" # required line; see ipacctctl(8)
ng_ipacct_rl1_threshold="15000" # '5000' by default
ng_ipacct_rl1_verbose="yes" # 'yes' by default
ng_ipacct_rl1_start=${ng_ipacct_default_ether_start}
ng_ipacct_rl1_stop=${ng_ipacct_default_ether_stop}
ng_ipacct_rl1_checkpoint_script="/usr/bin/ipacct.sh rl1"
ng_ipacct_rl0_dlt="EN10MB" # required line; see ipacctctl(8)
ng_ipacct_rl0_threshold="15000" # '5000' by default
ng_ipacct_rl0_verbose="yes" # 'yes' by default
ng_ipacct_rl0_start=${ng_ipacct_default_ether_start}
ng_ipacct_rl0_stop=${ng_ipacct_default_ether_stop}
ng_ipacct_rl0_checkpoint_script="/usr/bin/ipacct.sh rl0"
Настройка cron
В crontab добавляем запуск скидывания статистики каждые 10 мин.:*/10 * * * * root /usr/local/etc/rc.d/ng_ipacct checkpoint
Скрипт, который обрабатывает статистику, задается сдесь:
ng_ipacct_rl1_checkpoint_script="/usr/bin/ipacct.sh rl1"
ng_ipacct_rl0_checkpoint_script="/usr/bin/ipacct.sh rl0"
Вывод статистики
Код скрипта, основной задачей которого является скидывание файлов статистики на ftp сервер:#!/bin/sh
IPACCTCTL="/usr/local/sbin/ipacctctl"
WPUT="/usr/local/bin/wput"
FTPHOST="hostname"
FTPUSER="username"
FTPPASS="password"
IFACE=$1
DIR="/var/log/ipacct"
TMP=$DIR
PREFIX=$(date +%Y%m%d%H%M)
NAME="ng_ipacct_$1.log"
$IPACCTCTL ${IFACE}_ip_acct:$IFACE checkpoint
$IPACCTCTL -n ${IFACE}_ip_acct:$IFACE show >> $DIR/$NAME
$IPACCTCTL ${IFACE}_ip_acct:$IFACE clear
sleep 3
/usr/bin/tail -1 $DIR/$NAME | /usr/bin/fgrep exceed
NEW_FILE=$TMP/$PREFIX-$NAME
mv $DIR/$NAME $NEW_FILE
if [ -f $NEW_FILE ]; then
$WPUT --tries=5 --basename=$TMP $NEW_FILE ftp://$FTPUSER:$FTPPASS@$FTPHOST
if [ $? = 0 ]; then
rm $NEW_FILE
fi
fi
Сохранение статистики трафика интерфейса в MySQL
Обработка проводится на дрогом хосте скриптом на php (запускается в консоли), при этом данные сохраняются в mysql:#!/usr/bin/php
<?php
ini_set('memory_limit', '128M');
require_once 'settings.php';
require_once 'functions.php';
require_once 'Ftp.php';
start_timer('main');
abs_mysql_connect($cfg['db_host'], $cfg['db_user'], $cfg['db_pass'], $cfg['db_name']);
$ftp=new Abs_Ftp($cfg['ftp_user'], $cfg['ftp_pass'], $cfg['ftp_host']);
$ftp_files=$ftp->nlist();
foreach ($ftp_files as $ftp_file)
{
if ($ftp_file==="." or $ftp_file==="..") {
continue;
}
$tmp_file=$cfg['tmp'].'/'.$ftp_file;
try {
//читаем файл с сервера
$ftp->get($tmp_file, $ftp_file);
debug_print("Process $ftp_file \n");
$i=0;
$info=fname_to_info($ftp_file);
$time=$info["time"];
$if=$info["if"];
if (is_null($if)) {
continue;
}
$file=fopen($tmp_file, "r");
abs_mysql_query("START TRANSACTION");
$sql="INSERT INTO `if_$if` (`time`, `from_ip`, `from_port`, `to_ip`, `to_port`, `proto`, `byte`) VALUES ";
$i=0;
$count=0;
$fill_sql=false;
while (!feof ($file)) {
$i=$i+1;
$count=$count+1;
$line=parse_raw_str(fgets($file));
$from_ip=$line['from_ip'];
$from_port=$line['from_port'];
$to_ip=$line['to_ip'];
$to_port=$line['to_port'];
$proto=$line['proto'];
$byte=$line['byte'];
if (!is_null($byte) and $byte!==0) {
$sql.=" ('$time', '$from_ip', '$from_port', '$to_ip', '$to_port', '$proto', '$byte' ), ";
$fill_sql=true;
}
if ($i % 50===0 and $fill_sql){
$i=0;
$sql=substr($sql, 0, -2);
$sql.=" ON DUPLICATE KEY UPDATE `byte`=`byte`+VALUES(`byte`);";
abs_mysql_query($sql);
print_progress($count);
$sql="INSERT INTO `if_$if` (`time`, $if_name `from_ip`, `from_port`, `to_ip`, `to_port`, `proto`, `byte`) VALUES ";
$fill_sql=false;
}
}
if ($i!==0 and $fill_sql) {
$sql=substr($sql, 0, -2);
$sql.=" ON DUPLICATE KEY UPDATE `byte`=`byte`+VALUES(`byte`);";
abs_mysql_query($sql);
print_progress($count);
}
abs_mysql_query('COMMIT');
fclose($file);
//удаляем файл
$ftp->delete($ftp_file);
unlink($tmp_file);
debug_print("\nSaved $time : $if ($count) \n");
} catch (Exception $e) {
debug_print("Error in file $ftp_file \n");
}
}
Комментариев нет:
Отправить комментарий