一:ebtables简介
ebtables和iptables类似,都是Linux系统下网络数据包过滤的配置工具。既然称之为配置工具,就是说过滤功能是由内核底层提供支持的,这两个工具只是负责制定过滤的rules.

ebtables即是以太网桥防火墙,以太网桥工作在数据链路层,ebtables来过滤数据链路层数据包。 2.6内核内置了ebtables,要使用它必须先安装ebtables的用户空间工具(ebtables-v2.0.8-2),安装完成后就可以使用ebtables来过滤网桥的数据包。

二、ebtables配置
ebtables的配置分为表、链和规则三级。
1. 表
表是内置且固定的,共有三种: filter, nat, broute,用-t选项指定。最常用的就是filter了,所以不设-t时默认就是这个表。nat用于地址转换,broute用于以太网桥。
2.  链
链有内置和自定义两种 。不同的表内置的链不同,这个从数据包的流程图中就可以看出来。所谓自定义的链也是挂接在对应的内置链内的,使用-j让其跳转到新的链中。
3. 规则
每个链中有一系列规则,每个规则定义了一些过滤选项。每个数据包都会匹配这些项,一但匹配成功就会执行对应的动作。

所谓动作,就是过滤的行为了。有四种,ACCEPT,DROP,RETURN和CONTINUE。常用的就是ACCEPT和DROP,

Ebtables使用规则如下:

ebtables [-t table] -[ADI] chain rule-specification [match-extensions] [watcher-extensions]

-t table :一般为FORWARD链。

-ADI:A添加到现有链的末尾;D删除规则链(必须指明规则链号);I插入新的规则链(必须指明规则链号)。

-P:规则表的默认规则的设置。不同的表有不同的规则。

-F:对所有的规则表的规则链清空。

-L:指明规则表。可加参数,--Lc,--Ln

-p:指明使用的协议类型,ipv4,arp等可选(使用时必选)详情见/etc/ethertypes

--ip-proto:IP包的类型,1为ICMP包,6为TCP包,17为UDP包,在/etc/protocols下有详细说明

--ip-src:IP包的源地址

--ip-dst:IP包的目的地址

--ip-sport:IP包的源端口

--ip-dport:IP包的目的端口

-i:指明从那片网卡进入

-o:指明从那片网卡出去
3:实例
这个实例来自ebtables的官网,ebtables实例。这个实例主要是结合ebtables和TC来实现对用户进行流量控制。
在实际的应用中,这种场景较常见。
基于MAC地址来对不同的网络宽带使用者进行流量控制。

Bridge configuration
------------- ifcfg-br0 -------------
DEVICE=br0
ONBOOT=no
BOOTPROTO=static
IPADDR=192.168.111.11
NETMASK=255.255.255.0

----------- bridge_up.sh --------------------
#!/bin/bash

ifdown eth0
ifdown eth1  //关闭网络中的网卡eth0和eth1.

ifconfig eth0 0.0.0.0 up
ifconfig eth1 0.0.0.0 up //开启eth0,eth1,但是没有给有效的IP地址。即没有IP地址。

brctl addbr br0 //使用brctl命令创建网桥br0

brctl addif br0 eth0
brctl addif br0 eth1 //将网络接口添加进网桥br0

ifconfig br0 up

----------- bridge_down.sh --------------------
#!/bin/bash
 
ifdown eth0
ifdown eth1
ifconfig br0 down
brctl delbr br0
The rate shaping part

We're usingTC to do the deed. This is my first attempt at this, so I may be doing some things wrong, especially with the TCcommands - BUT IT WORKS - so I figure, I'll fix it later. You can use ebtables -L --Lc to see your customer's usage. I dump this out hourly, adding the -Z option to zero the counters out, then have a perl script parse that output and dump it into a mysql table where I can make better use of it.

--------------------------- rateshape -----------------------
#!/bin/bash
#
#  All Rates are in Kbits, so in order to gets Bytes divide by 8
#  e.g. 25Kbps == 3.125KB/s
#
TC=/sbin/tc
EBTABLES=/sbin/ebtables   # Location of ebtables
 
cd /usr/local/bridge
 
tc_start() {
    $TC qdisc add dev eth0 root handle 1:0 cbq bandwidth 100Mbit avpkt 1000 mpu 64
    $TC qdisc add dev eth1 root handle 1:0 cbq bandwidth 100Mbit avpkt 1000 mpu 64
 在TC 中, 使用"major:minor"这样的句柄来标识队列和类别,其中major和minor都是数字。
对于队列来说,minor总是为0,即"major:0"这样的形式,也可以简写为"major: 比如,队列1:0可以简写为1:。需要注意的是,major在一个网卡的所有队列中必须是惟一的。对于类别来说,其major必须和它的父类别或父队列的major相同,而minor在一个队列内部则必须是惟一的(因为类别肯定是包含在某个队列中的)。举个例子,如果队列2:包含两个类别,则这两个类别的句柄必须是2:x这样的形式,并且它们的x不能相同, 比如2:1和2:2。
这里,命令中的"add 表示要添加,"dev eth0 表示要操作的网卡为eth0。
"root 表示为网卡eth0添加的是一个根队列。"handle 1: 表示队列的句柄为1:。"cbq 表示要添加的队列为cbq队列。
#Customer A
#Two MACs: 00:0D:BD:A4:E1:C8 and 00:20:78:B0:25:7D
#256kbps download speed
${TC} class add dev eth0 parent 1:0 classid 1:1 cbq rate 256KBit allot 1514 prio 1 avpkt 1000 bounded
${TC} filter add dev eth0 parent 1:0 protocol ip handle 1 fw flowid 1:1
${EBTABLES} -A FORWARD -d 00:0D:BD:A4:E1:C8 -j mark --set-mark 1 --mark-target ACCEPT
${EBTABLES} -A FORWARD -d 00:20:78:B0:25:7D -j mark --set-mark 1 --mark-target ACCEPT
#128kbps upload speed
${TC} class add dev eth1 parent 1:0 classid 1:1 cbq rate 128KBit allot 1514 prio 1 avpkt 1000 bounded
${TC} filter add dev eth1 parent 1:0 protocol ip handle 1 fw flowid 1:1
${EBTABLES} -A FORWARD -s 00:0D:BD:A4:E1:C8 -j mark --set-mark 1 --mark-target ACCEPT
${EBTABLES} -A FORWARD -s 00:20:78:B0:25:7D -j mark --set-mark 1 --mark-target ACCEPT

#Customer B
#MAC Address: 00:0D:BD:A4:D6:54
#800kbps download speed
${TC} class add dev eth0 parent 1:0 classid 1:2 cbq rate 800KBit allot 1514 prio 1 avpkt 1000 bounded
${TC} filter add dev eth0 parent 1:0 protocol ip handle 2 fw flowid 1:2
${EBTABLES} -A FORWARD -d 00:0D:BD:A4:D6:54 -j mark --set-mark 2 --mark-target ACCEPT
#64kbps upload speed
${TC} class add dev eth1 parent 1:0 classid 1:2 cbq rate 64KBit allot 1514 prio 1 avpkt 1000 bounded
${TC} filter add dev eth1 parent 1:0 protocol ip handle 2 fw flowid 1:2
${EBTABLES} -A FORWARD -s 00:0D:BD:A4:D6:54 -j mark --set-mark 2 --mark-target ACCEPT

#Customer C
#MAC Address: 00:0A:5E:22:D1:A3
#do not rate shape!
${EBTABLES} -A FORWARD -s 00:0A:5E:22:D1:A3 -j ACCEPT
${EBTABLES} -A FORWARD -d 00:0A:5E:22:D1:A3 -j ACCEPT

#Block anything we didn't specify above.
${EBTABLES} -A FORWARD -j DROP --log

#<my config has over 500 customers and over 1100 MAC addresses>
#Just keep incrementing the classid, handle, flowid, and mark values for each customer's
#individual speed queues.
}
 
tc_stop() {
 
    ./save_and_reset_counters
 
    ${EBTABLES} -F //将删除ebtables中定义的规则
 
    $TC qdisc del dev eth0 root
    $TC qdisc del dev eth1 root //删除在eth0和eth1上面定义的队列
}
 
tc_restart() {
 
    tc_stop
    sleep 1
    tc_start
}
 
tc_show() {
 //分别查看eth0和eth1上面定义的队列,类及过滤器。
    echo ""
    echo "eth0"
    $TC qdisc show dev eth0
    $TC class show dev eth0
    $TC filter show dev eth0
    echo ""
    echo "eth1"
    $TC qdisc show dev eth1
    $TC class show dev eth1
    $TC filter show dev eth1}//下面是shell脚本的case语句。case "$1" in
 
  start)
 
    echo -n "Starting bandwidth shaping: "
    tc_start
    echo "done"
    ;;
 
  stop)
 
    echo -n "Stopping bandwidth shaping: "
    tc_stop
    echo "done"
    ;;
 
  restart)
 
    echo -n "Restarting bandwidth shaping: "
    tc_restart
    echo "done"
    ;;
 
  show)
 
    tc_show
    ;;
 
  *)
 
    echo "Usage: rateshape {start|stop|restart|show}"
    ;;
 
esac