1. Перво наперво нам нужно сделать раздачу инета на определённые ip-адреса нашей внутренней сети. Для этого в терминале:sudo su
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables-save > /etc/iptables.up.rules
echo "pre-up iptables-restore < /etc/iptables.up.rules" >> /etc/network/interfaces
apt-get install dnsmasq
в /etc/sysctl.conf:
net.ipv4.ip_forward=1
Это выпустит в Инет всю внутреннюю сеть.
Далее добавим правила форвардинга, чтобы вести учёт по айпи и чтобы пускать в сеть только тех, кто нам нужен.
Пропустим в Инет ip 192.168.0.101
iptables -A FORWARD -s 168.192.0.101 -i eth1 -j ACCEPT
iptables -A FORWARD -d 168.192.0.101 -o eth1 -j ACCEPT
Остальное закрываем
iptables -A FORWARD -o eth1 -j DROP
Для подсчёта трафика сервера, т.е. сколько сервак не перенаправил, а схавал сам.
iptables -A INPUT -i eth1 -j ACCEPT
iptables -A OUTPUT -o eth1 -j ACCEPT
2. В mysql создаём таблицу с полями:id (int)
ip (tinytext)
upload (int)
download (int)
timestamp (timestamp)
Все целочисленные типы – unsigned, у нас отрицательных значений быть не может.
3. Создадим скрипт для сбора данных и поместим его в ~/bin (ваше дело куда его пихать).#!/usr/bin/env python2
#-*- coding: UTF-8 -*-
# Created by Ramil ⚡ Thunde® ⚡ Minnigaliev
# March 2011 (update May 2011)
cmd = 'iptables -L -vnx'
import subprocess
PIPE = subprocess.PIPE
p = subprocess.Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE,
stderr=subprocess.STDOUT, close_fds=True)
data = p.stdout.read()
cmd = 'iptables -Z'
subprocess.Popen(cmd, shell = True)
import re, sys
arIP = re.findall("192\.168\.0\.[0-9]+",data)
arByte = re.findall("([0-9]+) ACCEPT",data)
import MySQLdb
db = MySQLdb.connect(host="127.0.0.1", user="user", passwd="", db="traffic", charset='utf8')
cursor = db.cursor()
i = 0
while (i < len(arIP)) :
ip = arIP[i]
up = int(arByte[i])
down = int(arByte[i + 1])
i = i + 2
if (up > 0 or down > 0):
sql = """INSERT INTO traffic.raw(ip, upload, download) VALUES ('%(ip)s', '%(up)s', '%(down)s')"""%{"ip":ip, "up":up, "down":down}
cursor.execute(sql)
## Трафик шлюза
gateway_up = re.findall("OUTPUT.+\n.+\n[^0-9]+[0-9]+[^0-9]+([0-9]+) ACCEPT",data)
gateway_down = re.findall("INPUT.+\n.+\n[^0-9]+[0-9]+[^0-9]+([0-9]+) ACCEPT",data)
gateway_up = int(gateway_up[0])
gateway_down = int(gateway_down[0])
if (gateway_up > 0 or gateway_down > 0):
sql = """INSERT INTO traffic.raw(ip, upload, download) VALUES ('%(ip)s', '%(up)s', '%(down)s')"""%{"ip":"192.168.0.200", "up":gateway_up, "down":gateway_down}
cursor.execute(sql)
db.commit()
db.close()
Дадим права на запуск
chmod +x python.py
добавить запуск скрипта в кроне
sudo crontab -e
*/1 * * * * sudo /home/thunder/bin/traffic.py
Раз в минуту скрипт будет запускаться и добавлять в БД информацию о трафике за минуту.
4. Для удобного считывания данных из БД создадим php-скрипт. Для работы которого требуется работающий веб-сервер, как настроить смотреть тутвеб-морда:
<style type="text/css">
table {
border-collapse: collapse;
}
td {
border: #b7b7b7 1px solid;
padding: 5px;
}
</style>
<p><h1>Трафик-полицай</h1></p>
<?php
/* Переменные для соединения с базой данных */
///////////////////////////////////////////////////////////////
$hostname = "localhost";
$username = "user";
$password = "";
$dbName = "traffic";
///////////////////////////////////////////////////////////////
/* Таблица MySQL, в которой хранятся данные */
$userstable = "raw";
/* создать соединение */
if (!mysql_connect($hostname,$username,$password)) {
echo(mysql_error());
die(mysql_error());
};
/* выбрать базу данных. Если произойдет ошибка - вывести ее */
if (!mysql_select_db($dbName)) {
echo(mysql_error());
die(mysql_error());
};
mysql_query("SET NAMES utf8;");
//==============================================================================
if($_SERVER['REMOTE_ADDR']!="127.0.0.1") : ?>
<p><h1 style="color: #ff0000">Недельный лимит трафика - 100 МБ</h1></p>
<p><h3>Т.е. в сутки должно быть в среднем 20 МБ, можно больше, но за неделю, чтоб не выходило больше недельного лимита</h3><p>
<? endif;
/////////////////////////////////////////////////////////////////////
$arCli = Array(
Array("192.168.0.1","Новый сервер"),
Array("192.168.0.220","Тест"),
...
);
/////////////////////////////////////////////////////////////////////
if (isset($_REQUEST['time1']) && isset($_REQUEST['time2'])) {
$time1 = $_REQUEST['time1'];
$time2 = $_REQUEST['time2'];
} else {
$time1 = date("Y-m-d 00:00:00", time());
$time2 = date("Y-m-d H:i:s", time());
}
?>
<form action="traffic.php" method="GET">
<input type="text" name="time1" value="<?= $time1 ?>" />
<input type="text" name="time2" value="<?= $time2 ?>" />
<input type="submit" value="Отправить">
</form>
<?
echo "<table><tr><td>№</td><td>IP</td><td>КТО</td><td>ОТДАНО (МБ)</td><td>ПОЛУЧЕНО (МБ)</td><td>СУММА</td></tr>";
$total_up = 0;
$total_down = 0;
$i = 1;
foreach($arCli as $cli) :
$IP = $cli[0];
if (($_SERVER['REMOTE_ADDR']!="127.0.0.1")&&($_SERVER['REMOTE_ADDR']!=$IP)) {continue;}
echo "<tr><td>".$i++."</td><td>$cli[0]</td><td>$cli[1]</td>";
$sql = mysql_query("SELECT *
FROM $userstable
WHERE `ip` = '$IP'
AND `timestamp` > '$time1'
AND `timestamp` < '$time2';"
);
$up = 0;
$down = 0;
while ($row = mysql_fetch_array($sql)) :
$up += $row['upload'];
$down += $row['download'];
endwhile;
$total_up += $up;
$total_down += $down;
echo "<td>".round($up/1024/1024,3)."</td><td>".round($down/1024/1024,3)."</td><td>".round(($up+$down)/1024/1024,3)."</td></tr>";
endforeach;
echo "<tr><td colspan=3>ВСЕГО</td><td>".round($total_up/1024/1024,3)."</td><td>".round($total_down/1024/1024,3)."</td><td>".round(($total_up+$total_down)/1024/1024,3)."</td></tr>";
echo "</table>";
?>
В данном скрипте нужно поправить:
$hostname = "localhost";
$username = "user";
$password = "";
$dbName = "traffic";
и
$arCli = Array(
Array("192.168.0.1","Новый сервер"),
Array("192.168.0.220","Тест"),
...
);
под себя.
после чего сможем увидеть