linux ip流量,[原]在Linux路由网关下查看客户端IP的实际流量

相信不少朋友都知道,使用Linux搭建路由网关,提供nat上网服务是非常简单的事情,而且性能也不错。但现在p2p的工具很多,有时候带宽会被这些工具在无意中就占满了(例如:使用迅雷、BT下载等)。这时候,总希望看看到底是谁在占用带宽。这样的工具有很多,如ntop、bandwidthd、iftop、IPTraf、MRTG等等,它们也提供了非常方便的图形监控界面,操作也非常简单。可惜,它们都有一些缺点,像实时性不够、IP流量分散、需要使用Web来查看等,恰好这些就是好我需要的。

为此,我利用iptables的统计功能,编写了一个小脚本来实现要求。(原想用Perl的Net::Pcap模块的对数据包解码统计的,但既然有现成的,为什么不用呢?)O(∩_∩)O哈哈~

一、查看网卡流量

首先,可能我们需要查看的是服务器上总的网卡流量。这个Linux提供了很好的数据:

引用

# cat /proc/net/dev

Inter-|   Receive                                                |  Transmit

face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed

lo:10020933   79976    0    0    0     0          0         0 10020933   79976    0    0    0     0       0          0

eth0:3274190272 226746109 438150 858758 369237     0          0         0 2496830239 218418052    0    0    0     0       0          0

sit0:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0

tun0:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0

tun1:    4675      51    0    0    0     0          0         0     8116      48    0    0    0     0       0          0

tun2:   51960     562    0    0    0     0          0         0   249612    3077    0    0    0     0       0          0

ppp0:4163571679 12086605    0    0    0     0          0         0 3089285665 15934370    0    0    0     0       0          0

这是网络启动后,通过服务器上各网卡的总流量,但不是很直观。(受排版影响,不太好看)

这里,提供一个小工具:他。使用非常简单:

引用

# sh flow.sh

Usage: flow.sh

e.g. flow.sh eth0 2

# sh flow.sh ppp0 2

IN: 232 KByte/s   OUT: 30 KByte/s

IN: 230 KByte/s   OUT: 38 KByte/s

IN: 241 KByte/s   OUT: 30 KByte/s

给出您要监控的网卡设备,然后是间隔时间,即会告诉您该设备的流量。

二、查看客户端IP实际流量的原理

接下来,进入我们的正题。除了通过上述脚本可以查看到网卡的实际流量外,我们该如何查看每个客户端的单独流量呢?先说说原理吧。

1、iptables设置

该过程最主要的就是利用了iptables的统计功能。

当我们用iptables实现nat转发后,所有的数据包要出去,必须要通过这台网关服务器,也就是说,我们只要在上面监控即可。并且,这些数据包都会经过iptables的FORWARD chain。这时,我们只要给iptables加上下述语句:

# iptables -I FORWARD -s 192.168.228.200 -j ACCEPT

# iptables -I FORWARD -d 192.168.228.200 -j ACCEPT

那么,通过192.168.228.200(客户端)经该服务器路由网关转发出去的数据包就会记录在iptables FORWARD chain中。

如:

引用

# iptables -v -n -x -L FORWARD

Chain FORWARD (policy DROP 5 packets, 351 bytes)

pkts      bytes target     prot opt in     out     source               destination

2834533 360907743 ACCEPT     all  --  *      *       192.168.228.200      0.0.0.0/0

3509528 3253144061 ACCEPT     all  --  *      *       0.0.0.0/0            192.168.228.200

这样,我们通过一些简单的运算,就可以得到实际的流量:

引用

# iptables -L -v -n -x|grep '192.168.228.200';sleep 3;iptables -L -v -n -x|grep '192.168.228.200'

2872143 365711591 ACCEPT     all  --  *      *       192.168.228.200      0.0.0.0/0

3555831 3297100630 ACCEPT     all  --  *      *       0.0.0.0/0            192.168.228.200

2872750 365777302 ACCEPT     all  --  *      *       192.168.228.200      0.0.0.0/0

3556591 3297814562 ACCEPT     all  --  *      *       0.0.0.0/0            192.168.228.200

# echo '(3297814562-3297100630)/1024/3'|bc

232

# echo '(365777302-365711591)/1024/3'|bc

21

原理就是这么简单。

※ 注意,FORWARD chain记录的流量中,不经过该网关转发的流量不会记录。也就是说,若你从该服务器上直接下载,流量是记录在INPUT和OUTPUT chain,而不是FORWARD中的。要统计那些数据,方法是相同的。

三、脚本

1、源码

$SEC是间隔的时间,时间太短误差比较大;$ZERO决定是否显示没变化IP。同时,显示被屏蔽的IP地址。

#!/usr/bin/perl -w

# Date:2009-03-12

# Author:HyphenWang

# Version:1.0

use strict;

my $IPTABLES_CMD="iptables -v -n -x -L FORWARD";

my $SEC="3";

my $ZERO="0";

my (%first_input,%first_output);

my (%second_input,%second_output);

my %ban_ip;

sub get_ipflow {

my ($ip_input,$ip_output)=@_;

for my $line (`$IPTABLES_CMD`) {

my @columns = split(/\s+/,$line);

$ip_input->{$columns[-1]}=$columns[2] if ($columns[3] eq "ACCEPT" and $columns[-1] =~ m/192\.168\.228\.\d+/);

$ip_output->{$columns[-2]}=$columns[2] if ($columns[3] eq "ACCEPT" and $columns[-2] =~ m/192\.168\.228\.\d+/);

$ban_ip{$columns[-1]}=1 if ($columns[3] eq "DROP" and $columns[-1] =~ m/192\.168\.228\.\d+/);

$ban_ip{$columns[-2]}=1 if ($columns[3] eq "DROP" and $columns[-2] =~ m/192\.168\.228\.\d+/);

}

}

get_ipflow(\%first_input,\%first_output);

sleep $SEC;

get_ipflow(\%second_input,\%second_output);

print "Now is ".localtime()."\n";

print "-"x53,"\n";

print "IP Address\t\tIn Flow Rate\tOut Flow Rate\n";

for (keys %first_input) {

if ($ZERO != 1) {

if (defined $second_input{$_} and defined $second_output{$_} and int(($second_input{$_}-$first_input{$_})/1024/$SEC) == 0) {

next;

}

}

if (defined $second_input{$_} and defined $second_output{$_}) {

printf ("%s\t\t%.fKB\t\t%.fKB\n",$_,($second_input{$_}-$first_input{$_})/1024/$SEC,($second_output{$_}-$first_output{$_})/1024/$SEC);

}

}

print "-"x53,"\n";

print "Banned IP Address:\n";

for (keys %ban_ip) {

print "$_\n";

}

2、结果

◎ ZERO为非1的情况

引用

# perl ipflow.pl

Now is Thu Mar 12 18:35:10 2009

-----------------------------------------------------

IP Address              In Flow Rate    Out Flow Rate

192.168.228.212         277 KByte/s     27 KByte/s

192.168.228.200         40 KByte/s      16 KByte/s

-----------------------------------------------------

Banned IP Address:

192.168.228.50

◎ ZERO为1的情况

引用

# perl ipflow.pl

Now is Thu Mar 12 18:36:21 2009

-----------------------------------------------------

IP Address              In Flow Rate    Out Flow Rate

192.168.228.219         0 KByte/s       0 KByte/s

192.168.228.150         0 KByte/s       0 KByte/s

192.168.228.153         0 KByte/s       0 KByte/s

192.168.228.215         0 KByte/s       0 KByte/s

192.168.228.212         220 KByte/s     27 KByte/s

192.168.228.200         14 KByte/s      9 KByte/s

192.168.228.154         0 KByte/s       0 KByte/s

192.168.228.220         0 KByte/s       0 KByte/s

192.168.228.99          0 KByte/s       0 KByte/s

192.168.228.216         0 KByte/s       0 KByte/s

192.168.228.211         0 KByte/s       0 KByte/s

192.168.228.155         0 KByte/s       0 KByte/s

192.168.228.218         21 KByte/s      1 KByte/s

192.168.228.30          0 KByte/s       0 KByte/s

192.168.228.221         0 KByte/s       0 KByte/s

-----------------------------------------------------

Banned IP Address:

192.168.228.50

本地下载:四、进阶

既然能捕获到每个客户端的实际流量,就可以根据实际流量执行tc或iptables的操作。例如流量大于200KB/s则限速,或暂时断开该IP。我准备进一步完善该脚本。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值