Linux网络IP记帐

时间:2020-01-09 10:41:23  来源:igfitidea点击:

如何知道在我的ppp0网络或eth0 Internet链接上传输了多少数据?
如何按地址(例如123.1.2.3和123.1.2.4)设置IP记帐?
如何为每个Apache虚拟域设置IP记帐?
如何通过服务端口(http,smtp)和协议(tcp,udp,icmp)设置计费?
如何记录每台客户端计算机正在使用的流量?

您不必安装任何特殊的东西。

Linux内核附带IP记帐,它是iptables的一部分。
它是Linux防火墙软件的一部分。
在防火墙级别,您可以过滤流量并配置IP记帐。

Linux内核收集了大量有关网络流量的信息,这些信息可用于IP记帐。
您也可以使用第三方软件。

拓扑图

Internet/ISP router
    //
      //         +-----------------+      +---------+
        //   eth1| Linux firewall  |      | LAN     |
          //-----+ (Gateway)       +------+ Servers |
                 | 192.168.1.254   |eth0  | Users   |
                 +-----------------+      +---------+

(网关IP记帐)

192.168.1.254是一台基于CentOS的Linux计算机,它是Internet的网关。
它的作用是:

  • 路由器
  • 交通整形装置
  • 防火墙功能
  • " FORWARD"链上的IP记帐
ISP port 1000MBps (Enterprise rack)
    //
      //         +------------+      +---------+
        //   eth1| Linux LB0  |      | Apache1 |
          //-----+------------+------+---------+
                 | Linux LB1  |eth0  | Apache2 |
                 +------------+      +---------+
                   Firewall          | Mysql1  |
                   123.1.2.1         +---------+
                   123.1.2.2         | Mysql2  |
                   123.1.2.3         +---------+
                                     | memcache|
                                     +---------+

上面的设置很复杂,并且托管在企业Java应用程序的本地ISP(机架空间)上:

  • lb0和lb1基于RHEL的软件负载平衡器。这两个服务器充当IP故障转移设备,防火墙和反向代理软件,以加快后端速度。 IP记帐在INPUT和OUTPUT链上配置了三个VIP(123.1.2.1、123.1.2.2和123.1.2.3)
  • 123.1.2.1、123.1.2.2和123.1.2.3:虚拟IP地址(VIP)在lb0和lb1之间移动以提供服务可用性。
  • Apache {1,2,3..N},Mysql {1,2}:用于存储数据,文件和Java应用程序的实际服务器。

警告!如果执行不正确,这些示例可能会阻止您的网络访问。

IP记帐需要对端口,服务,协议和网络概念有基本的了解。
本常见问题解答中列出的大多数操作是在假设它们将由运行bash或任何其他现代shell的root用户执行的前提下编写的。
所有示例都在RHEL或CentOS Linux下进行了测试;但应该可以在其他任何现代发行版下使用。

基于iptables的IP计费

您需要使用iptables(IPv4)或ip6tables(IPv6)来设置,维护和检查Linux内核中的数据包筛选器规则表。
可以定义几个不同的表。
每个表包含许多内置链,也可能包含用户定义的链。
您可以使用用户定义的链来设置IP记帐规则。
要查看您当前的iptables配置,请执行:

# iptables -L -n

要列出所有规则,请使用上面的命令。
您需要传递-v选项,它将显示其他信息:

  • 接口名称(例如eth1)。
  • 规则选项(如果有)。
  • TOS口罩。
  • 数据包和字节计数器,后缀为K,M或G。
# iptables -L -n -v

输出示例:

Chain INPUT (policy ACCEPT 73860 packets, 95M bytes)
pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     udp  --  virbr0 *       0.0.0.0/0            0.0.0.0/0           udp dpt:53 
    0     0 ACCEPT     tcp  --  virbr0 *       0.0.0.0/0            0.0.0.0/0           tcp dpt:53 
    0     0 ACCEPT     udp  --  virbr0 *       0.0.0.0/0            0.0.0.0/0           udp dpt:67 
    0     0 ACCEPT     tcp  --  virbr0 *       0.0.0.0/0            0.0.0.0/0           tcp dpt:67 

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     all  --  *      virbr0  0.0.0.0/0            192.168.122.0/24    state RELATED,ESTABLISHED 
    0     0 ACCEPT     all  --  virbr0 *       192.168.122.0/24     0.0.0.0/0           
    0     0 ACCEPT     all  --  virbr0 virbr0  0.0.0.0/0            0.0.0.0/0           
    0     0 REJECT     all  --  *      virbr0  0.0.0.0/0            0.0.0.0/0           reject-with icmp-port-unreachable 
    0     0 REJECT     all  --  virbr0 *       0.0.0.0/0            0.0.0.0/0           reject-with icmp-port-unreachable 

Chain OUTPUT (policy ACCEPT 54182 packets, 5660K bytes)
pkts bytes target     prot opt in     out     source               destination

请注意数据包和字节列。

步骤1:创建用户定义的链

创建新的用户定义链以设置IP记帐的语法如下:

# iptables -N INET_OUT

# iptables -N INET_IN

上面的命令创建了一个新的用户定义链,称为INET_OUT,以跟踪传出流量。

INET_IN可用于跟踪传入流量。

步骤2:设置IP记帐

您需要按如下所示追加INET_IN和INET_OUT:

# iptables -A FORWARD -j INET_IN

# iptables -A FORWARD -j INET_OUT

FORWARD用于通过服务器路由的数据包,即您的Linux服务器充当路由器(见
网关IP记帐)。
您可以为INPUT和OUTPUT链追加以下内容:

# iptables -A INPUT -j INET_IN

# iptables -A OUTPUT -j INET_OUT

步骤3:查看IP记帐数据

执行以下命令:

# iptables -L -v -n

要仅查看传出IP记帐数据:

# iptables -v -n -L INET_OUT

输出示例:

Chain INET_OUT (1 references)
pkts bytes target     prot opt in     out     source               destination         
2472  405K            all  --  any    any     example.com          anywhere            
  17M   16G            all  --  any    any     lan.local            anywhere

example.com生成405k字节,而lan.local生成16G传出流量。

按地址设置IP记帐

假设您有以下三个域,并且希望跟踪每个域的出站流量和入站流量:

  • example.com 123.1.2.1
  • example.net 123.1.2.2
  • example.org 123.1.2.3

您需要在shell提示符下输入以下命令,或将其添加到shell/perl脚本中:

# /sbin/iptables -N INET_OUT

# /sbin/iptables -N INET_IN

# /sbin/iptables -A INPUT -j INET_IN

# /sbin/iptables -A OUTPUT -j INET_OUT

# /sbin/iptables -A INET_IN -d 123.1.2.1

# /sbin/iptables -A INET_IN -d 123.1.2.2

# /sbin/iptables -A INET_IN -d 123.1.2.3

# /sbin/iptables -A INET_OUT -s 123.1.2.1

# /sbin/iptables -A INET_OUT -s 123.1.2.2

# /sbin/iptables -A INET_OUT -s 123.1.2.3

# /sbin/service iptables save

要查看传入的IP统计信息,请执行:

# /sbin/iptables -v -n -L INET_IN

输出示例:

Chain INET_IN (1 references)
pkts bytes target     prot opt in     out     source               destination         
  16M 2086M            all  --  any    any     anywhere             example.com
6141K 1319M            all  --  any    any     anywhere             www.example.net
  30M 4657M            all  --  any    any     anywhere             example.org

要查看外发IP统计信息,请执行:

# /sbin/iptables -v -n -L INET_OUT

输出示例:

Chain INET_OUT (1 references)
pkts bytes target     prot opt in     out     source               destination         
2472  405K            all  --  any    any     example.com          anywhere            
  17M   16G            all  --  any    any     www.example.net      anywhere            
5165K 2399M            all  --  any    any     example.org          anywhere

通过服务端口进行IP记帐

要收集eth1链接上承载的数据的端口80(http),443(https),22(SSH),143(imap),25(SMTP),53(dns)卷统计信息,请执行:

### create a new set of chains ###
# /sbin/iptables -N INET_IN_PORT
# /sbin/iptables -N INET_OUT_PORT

### ATTACH them (USE FORWARD for gateway systems) ###
# /sbin/iptables -A INPUT -j INET_IN_PORT
# /sbin/iptables -A OUTPUT -j INET_OUT_PORT

### Set up rules for INPUT ###
# /sbin/iptables -A INET_IN_PORT -i eth1 -p tcp --dport 80
# /sbin/iptables -A INET_IN_PORT -i eth1 -p tcp --dport 443
# /sbin/iptables -A INET_IN_PORT -i eth1 -p tcp --dport 25
# /sbin/iptables -A INET_IN_PORT -i eth1 -p tcp --dport 143
# /sbin/iptables -A INET_IN_PORT -i eth1 -p tcp --dport 53
# /sbin/iptables -A INET_IN_PORT -i eth1 -p udp --dport 53
# /sbin/iptables -A INET_IN_PORT -i eth1 -p tcp --dport 22

### Set up rules for OUTPUT ###
# /sbin/iptables -A INET_OUT_PORT -o eth1 -p tcp --sport 80
# /sbin/iptables -A INET_OUT_PORT -o eth1 -p tcp --sport 443
# /sbin/iptables -A INET_OUT_PORT -o eth1 -p tcp --sport 25
# /sbin/iptables -A INET_OUT_PORT -o eth1 -p tcp --sport 143
# /sbin/iptables -A INET_OUT_PORT -o eth1 -p tcp --sport 53
# /sbin/iptables -A INET_OUT_PORT -o eth1 -p udp --sport 53
# /sbin/iptables -A INET_OUT_PORT -o eth1 -p tcp --sport 22
# /sbin/service iptables save

要查看统计信息,请执行:

# iptables -L INET_IN_PORT -v -n

# iptables -L INET_OUT_PORT -v -n

按协议进行IP计费

在eth1上为tcp,udp和icmp协议设置IP记帐:

# /sbin/iptables -N INET_IN_PROTOCOL

# /sbin/iptables -N INET_OUT_PROTOCOL

### ATTACH them (USE FORWARD for gateway systems) ###

# /sbin/iptables -A INPUT -j INET_IN_PROTOCOL

# /sbin/iptables -A OUTPUT -j INET_OUT_PROTOCOL

### Match tcp, udp and icmp ###

# /sbin/iptables -A INET_IN_PROTOCOL -i eth1 -m tcp -p tcp

# /sbin/iptables -A INET_IN_PROTOCOL -i eth1 -m udp -p udp

# /sbin/iptables -A INET_IN_PROTOCOL -i eth1 -m icmp -p icmp

# /sbin/iptables -A INET_OUT_PROTOCOL -o eth1 -m tcp -p tcp

# /sbin/iptables -A INET_OUT_PROTOCOL -o eth1 -m udp -p udp

# /sbin/iptables -A INET_OUT_PROTOCOL -o eth1 -m icmp -p icmp

### save them (redhat and friends only) ###

# /sbin/service iptables save

要查看统计信息,请执行:

# iptables -L INET_OUT_PROTOCOL -v -n

# iptables -L INET_IN_PROTOCOL -v -n

如何查看数据包和字节计数器的精确值?

使用-x选项:

# iptables -L {Chain-Name-Here} -x

# iptables -L INET_IN_PORT -v  -x

# iptables -L INET_IN_PORT -v -x -n

输出示例:

Chain INET_IN_PORT (1 references)
    pkts      bytes target     prot opt in     out     source               destination         
  274688 45080261            tcp  --  eth1   any     anywhere             anywhere            tcp dpt:http 
      17     1517            tcp  --  eth1   any     anywhere             anywhere            tcp dpt:https 
       0        0            tcp  --  eth1   any     anywhere             anywhere            tcp dpt:ssh 
       0        0            udp  --  eth1   any     anywhere             anywhere            udp dpt:snmp 
       3      228            udp  --  eth1   any     anywhere             anywhere            udp dpt:ntp

如何删除数据包和字节计数器?

使用-Z选项:

# iptables -L {CHAIN-NAME-HERE} -Z

# iptables -L INET_IN_PORT -Z

验证相同,执行:

# iptables -L INET_IN_PORT -vnx

如何实时查看IP计费(带宽流量)?

您可以定期执行iptables,使用watch命令以全屏显示输出,如下所示:

# watch iptables  -n -v  -L INET_OUT -n

# watch -n 1 iptables -v  -L INET_IN

输出示例:

Portwise IP统计

Linux Apache IP记帐

请注意,我已经从上述输出中删除了域名。

按协议进行的外发IP计费

如何在重新启动后保存和还原计数器?

要保存计数器,请使用以下命令:

# iptables-save -c > /path/to/iptables.rules

# iptables-restore -c 

You can add iptables-restore command to /etc/rc.local or write a sys v style script (recommended):
#!/bin/sh
#
# save-restore-iptables-counter
#
# chkconfig:  2345 08 92
# description:  Save and restore iptables counters
# processname: none
# Note: See how to use this script :
# http://www.theitroad.local/faq/linux-configuring-ip-traffic-accounting/
# Source function library.
. /etc/init.d/functions
 
# Source networking configuration.
. /etc/sysconfig/network
 
# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0
 
path="/etc/sysconfig/iptables.rules.counter"
_restorecmd="/sbin/iptables-restore"
_savecmd="/sbin/iptables-save"
prog="save-restore-iptables-counter"
 
start() {
    echo -n $"Starting $prog: "
    $_restorecmd -c < "$path"
    retval=$?
    return $retval
}
 
stop() {
    echo -n $"Stopping $prog: "
    $_savecmd -c > "$path"
    retval=$?
    return $retval
}
 
restart(){
	stop
	start
}
 
 
case "" in
    start)
        start;;
    stop)
        stop;;
    restart)
        restart;;
    *)
        echo $"Usage: 
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [2027:704756]
:INET_IN - [0:0]
:INET_OUT - [0:0]
:INET_IN_PORT - [0:0]
:INET_OUT_PORT - [0:0]
:INET_IN_PROTOCOL - [0:0]
:INET_OUT_PROTOCOL - [0:0]
:RH-Firewall-1-INPUT - [0:0]
-A INPUT -j INET_IN
-A INPUT -j INET_IN_PORT
-A INPUT -j INET_IN_PROTOCOL
-A INPUT -j RH-Firewall-1-INPUT
-A FORWARD -j RH-Firewall-1-INPUT
-A OUTPUT -j INET_OUT
-A OUTPUT -j INET_OUT_PORT
-A OUTPUT -j INET_OUT_PROTOCOL
 
# IP accounting apache
-A INET_IN -d 123.1.2.1
-A INET_OUT -s 123.1.2.1
 
# Port wise ip accouting 
-A INET_IN_PORT -i eth0 -p tcp -m tcp --dport 80
-A INET_OUT_PORT -o eth0 -p tcp -m tcp --sport 80
 
# protcol wise ip accouting
-A INET_IN_PROTOCOL -i eth0 -m tcp -p tcp
-A INET_IN_PROTOCOL -i eth0 -m udp -p udp
-A INET_IN_PROTOCOL -i eth0 -m icmp -p icmp
-A INET_OUT_PROTOCOL -o eth0 -m tcp -p tcp
-A INET_OUT_PROTOCOL -o eth0 -m udp -p udp
-A INET_OUT_PROTOCOL -o eth0 -m icmp -p icmp
 
# Unlimited to lo
-A RH-Firewall-1-INPUT -i lo -j ACCEPT
 
# ICMP
-A RH-Firewall-1-INPUT -i eth0 -p icmp --icmp-type echo-reply -j ACCEPT
-A RH-Firewall-1-INPUT -i eth0 -p icmp --icmp-type destination-unreachable -j ACCEPT
-A RH-Firewall-1-INPUT -i eth0 -p icmp --icmp-type time-exceeded -j ACCEPT
 
# ICMP ping reply
-A RH-Firewall-1-INPUT -i eth0 -p icmp --icmp-type echo-request -j ACCEPT
 
# Drop spoof
-A RH-Firewall-1-INPUT -i eth0 -s 10.0.0.0/8 -j LOG --log-prefix "IP DROP SPOOF A: "
-A RH-Firewall-1-INPUT -i eth0 -s 10.0.0.0/8 -j DROP
 
-A RH-Firewall-1-INPUT -i eth0 -s 172.16.0.0/12 -j LOG --log-prefix "IP DROP SPOOF B: "
-A RH-Firewall-1-INPUT -i eth0 -s 172.16.0.0/12 -j DROP
 
-A RH-Firewall-1-INPUT -i eth0 -s 192.168.0.0/16 -j LOG --log-prefix "IP DROP SPOOF C: "
-A RH-Firewall-1-INPUT -i eth0 -s 192.168.0.0/16 -j DROP
 
-A RH-Firewall-1-INPUT -i eth0 -s 224.0.0.0/4 -j LOG --log-prefix "IP DROP MULTICAST D: "
-A RH-Firewall-1-INPUT -i eth0 -s 224.0.0.0/4 -j DROP
 
-A RH-Firewall-1-INPUT -i eth0 -s 224.0.0.0/5 -j LOG --log-prefix "IP DROP SPOOF E: "
-A RH-Firewall-1-INPUT -i eth0 -s 224.0.0.0/5 -j DROP
 
-A RH-Firewall-1-INPUT -i eth0 -s 127.0.0.0/8 -j LOG --log-prefix "IP DROP LOOPBACK "
-A RH-Firewall-1-INPUT -i eth0 -s 127.0.0.0/8 -j DROP
 
# Drop INVALID packets immediately
-A INPUT -i eth0 -p ALL -m state --state INVALID -j LOG --log-prefix "IP DROP INVALID "
-A INPUT -i eth0 -p ALL -m state --state INVALID -j DROP
 
-A INPUT -i eth0 -p tcp ! --syn -m state --state NEW -j LOG --log-prefix "IP DROP SYN "
-A INPUT -i eth0 -p tcp ! --syn -m state --state NEW -j DROP
 
-A INPUT -i eth0 -p tcp --tcp-flags ALL NONE -j LOG --log-prefix "IP DROP TCPFLAGS:1 "
-A INPUT -i eth0 -p tcp --tcp-flags ALL NONE -j DROP
 
-A INPUT -i eth0 -p tcp --tcp-flags ALL ALL -j LOG --log-prefix "IP DROP TCPFLAGS:2 "
-A INPUT -i eth0 -p tcp --tcp-flags ALL ALL -j DROP
 
-A INPUT -i eth0 -p tcp --tcp-flags ALL FIN,URG,PSH -j LOG --log-prefix "IP DROP TCPFLAGS:3 "
-A INPUT -i eth0 -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
 
-A INPUT -i eth0 -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j LOG --log-prefix "IP DROP TCPFLAGS:4 "
-A INPUT -i eth0 -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
 
-A INPUT -i eth0 -p tcp --tcp-flags SYN,RST SYN,RST -j LOG --log-prefix "IP DROP TCPFLAGS:5 "
-A INPUT -i eth0 -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
 
-A INPUT -i eth0 -p tcp --tcp-flags SYN,FIN SYN,FIN -j LOG --log-prefix "IP DROP TCPFLAGS:6 "
-A INPUT -i eth0 -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
 
-A INPUT -i eth0 --fragment -p ICMP -j LOG --log-prefix "IP DROP ICMP FRAGMENT "
-A INPUT -i eth0 --fragment -p ICMP -j DROP
 
 
# Open port and other stuff
-A RH-Firewall-1-INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A RH-Firewall-1-INPUT -s 0/0 -i eth0 -p udp -m state --state NEW -m udp --dport 53 -j ACCEPT
-A RH-Firewall-1-INPUT -s 124.1.2.3 -i eth0 -p udp -m state --state NEW -m udp --dport 161 -j ACCEPT
-A RH-Firewall-1-INPUT -s 124.1.2.3 -i eth0 -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A RH-Firewall-1-INPUT -s 0/0 -i eth0 -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A RH-Firewall-1-INPUT -s 0/0 -i eth0 -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
-A RH-Firewall-1-INPUT -s 0/0 -i eth0 -p tcp -m state --state NEW -m tcp --dport 53 -j ACCEPT
-A RH-Firewall-1-INPUT -s 0/0 -i eth0 -p tcp -m state --state NEW -m tcp --dport 25 -j ACCEPT
-A RH-Firewall-1-INPUT -s 0/0 -i eth0 -p tcp -m state --state NEW -m tcp --dport 143 -j ACCEPT
-A RH-Firewall-1-INPUT -s 0/0 -i eth0 -p tcp -m state --state NEW -m tcp --dport 110 -j ACCEPT
 
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited
 
COMMIT
#end
{start|stop|restart}" exit 3 esac

示例Redhat/CentOS/Fedora特定的配置文件-/etc/sysconfig/iptables

iptables -N YOUR-CHAIN-HERE
iptables -A FORWARD -j YOUR-CHAIN-HERE
iptables -A YOUR-CHAIN-HERE -d IP-ADDRESS
iptables -A YOUR-CHAIN-HERE -s IP-ADDRESS
iptables -A YOUR-CHAIN-HERE -i ppp0 -p tcp -m tcp  --sport PORT
iptables -A YOUR-CHAIN-HERE -o ppp0 -p tcp -m tcp  --dport PORT
iptables -A YOUR-CHAIN-HERE -i ppp0 config-options-as-per-requirements

语法总结

对网关系统IP记帐使用以下语法:

iptables -N YOUR-INPUT-CHAIN-HERE
iptables -N YOUR-OUTPUT-CHAIN-HERE
iptables -A INPUT -j YOUR-INPUT-CHAIN-HERE
iptables -A OUTPUT -j YOUR-OUTPUT-CHAIN-HERE
iptables -A YOUR-INPUT-CHAIN-HERE -d IP-ADDRESS
iptables -A YOUR-OUTPUT-CHAIN-HERE -s IP-ADDRESS
iptables -A YOUR-CHAIN-HERE -i eth1 config-options-as-per-requirements

对专用服务器角色或复杂的托管解决方案使用以下语法:

##代码##