概要
本篇博文根据RYU控制的官方文档RYU book第九章FIREWALL,第一部分Example of operation of a single tenant(IPv4)形成,其余三部分大同小异.按照文档上的内容进行实践,并说明了实践过程中存在的问题,指出了文档中不合理的地方.以下所有的rest api的调用都是在firefox上利用restclient插件进行,这样比直接调用curl命令更加直观.
A single tenant(iPv4)
实验拓扑
创建实验环境
mininet创建拓扑
1 | mininet@mininet-vm:~$ sudo mn --topo single,3 --mac --controller=remote |
设置openflow1.3
在ovs交换机s1上设置使用openflow1.31
2mininet@mininet-vm:~$ ovs-vsctl set Bridge s1 protocols-OpenFlow13
ovs-vsctl: Bridge does not contain a column whose name matches "protocols-OpenFlow13"
上面是按照文档上的命名,但这样做会报错,查看该命令的帮助文档,即
man ovs-vsctl
发现一下信息:1
2
3
4
5
6OpenFlow Version
Configure bridge br0 to support OpenFlow versions 1.0, 1.2, and
1.3:
ovs-vsctl set bridge br0 protocols=openflow10,open‐
flow12,openflow13
于是将该命令改为:1
2mininet@mininet-vm:~$ sudo ovs-vsctl set Bridge s1 protocols=OpenFlow13
mininet@mininet-vm:~$
启动控制器
1 | mininet@mininet-vm:~/ryu/ryu/app$ sudo ryu-manager rest_firewall.py |
设置初始状态
默认情况下,所有的通信都是禁止的,查看交换机的状态
1 | [ |
这是因为有一个最高优先级的流表,丢弃所以数据包:1
2
3
4
5
6mininet@mininet-vm:~$ sudo ovs-ofctl -O openflow13 dump-flows s1
OFPST_FLOW reply (OF1.3) (xid=0x2):
cookie=0x0, duration=2.571s, table=0, n_packets=0, n_bytes=0, priority=65534,arp actions=NORMAL
cookie=0x0, duration=2.571s, table=0, n_packets=0, n_bytes=0, priority=65535 actions=drop
cookie=0x0, duration=2.571s, table=0, n_packets=0, n_bytes=0, priority=0 actions=CONTROLLER:128
mininet@mininet-vm:~$
所以必须先enable交换机:
http://localhost:8080/firewall/module/enable/0000000000000001
1 | [ |
再次查看交换机状态:
1 | [ |
接着试试h1 ping h2,因为访问规则没有设置,所以这个时候,数据包会被阻塞.
1 | [FW][INFO] dpid=0000000000000001: Blocked packet = ethernet(dst='00:00:00:00:00:02',ethertype=2048,src='00:00:00:00:00:01'), ipv4(csum=56630,dst='10.0.0.2',flags=2,header_length=5,identification=18800,offset=0,option=None,proto=1,src='10.0.0.1',tos=0,total_length=84,ttl=64,version=4), icmp(code=0,csum=53393,data=echo(data='\xfa\x85\xa4V\x00\x00\x00\x00\xb6G\x08\x00\x00\x00\x00\x00\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./01234567',id=2934,seq=1),type=8) |
增加规则
允许h1, h2互ping
为了让h1和h2之间能互相ping通,需要设置两条规则,如图:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29curl -X POST -d ’{"nw_src": "10.0.0.1/32", "nw_dst": "10.0.0.2/32", "nw_proto":
"ICMP"}’ http://localhost:8080/firewall/rules/0000000000000001
[
{
"switch_id": "0000000000000001",
"command_result": [
{
"result": "success",
"details": "Rule added. : rule_id=1"
}
]
}
]
curl -X POST -d ’{"nw_src": "10.0.0.2/32", "nw_dst": "10.0.0.1/32", "nw_proto":
"ICMP"}’ http://localhost:8080/firewall/rules/0000000000000001
[
{
"switch_id": "0000000000000001",
"command_result": [
{
"result": "success",
"details": "Rule added. : rule_id=2"
}
]
}
]
在交换机s1上查看流表信息:1
2
3
4
5
6
7mininet@mininet-vm:~$ sudo ovs-ofctl -O openflow13 dump-flows s1
OFPST_FLOW reply (OF1.3) (xid=0x2):
cookie=0x1, duration=14.573s, table=0, n_packets=0, n_bytes=0, priority=1,icmp,nw_src=10.0.0.1,nw_dst=10.0.0.2 actions=NORMAL
cookie=0x2, duration=6.237s, table=0, n_packets=0, n_bytes=0, priority=1,icmp,nw_src=10.0.0.2,nw_dst=10.0.0.1 actions=NORMAL
cookie=0x0, duration=151.7s, table=0, n_packets=0, n_bytes=0, priority=65534,arp actions=NORMAL
cookie=0x0, duration=151.7s, table=0, n_packets=0, n_bytes=0, priority=0 actions=CONTROLLER:128
mininet@mininet-vm:~$
可见这个时候除了h1, h2之间的ping包外,其它数据包都将转向控制器.
允许h2, h3之间所以的IP数据包通信
允许h2, h3之间所有的IP数据包进行通信,需要增加两条规则,如下图:
具体如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27curl -X POST -d ’{"nw_src": "10.0.0.2/32", "nw_dst": "10.0.0.3/32"}’ http://
localhost:8080/firewall/rules/0000000000000001
[
{
"switch_id": "0000000000000001",
"command_result": [
{
"result": "success",
"details": "Rule added. : rule_id=3"
}
]
}
]
curl -X POST -d ’{"nw_src": "10.0.0.3/32", "nw_dst": "10.0.0.2/32"}’ http://
localhost:8080/firewall/rules/0000000000000001
[
{
"switch_id": "0000000000000001",
"command_result": [
{
"result": "success",
"details": "Rule added. : rule_id=4"
}
]
}
]
查看此时交换机s1的流表规则:1
2
3
4
5
6
7
8
9mininet@mininet-vm:~$ sudo ovs-ofctl -O openflow13 dump-flows s1
OFPST_FLOW reply (OF1.3) (xid=0x2):
cookie=0x3, duration=116.689s, table=0, n_packets=0, n_bytes=0, priority=1,ip,nw_src=10.0.0.2,nw_dst=10.0.0.3 actions=NORMAL
cookie=0x4, duration=108.073s, table=0, n_packets=0, n_bytes=0, priority=1,ip,nw_src=10.0.0.3,nw_dst=10.0.0.2 actions=NORMAL
cookie=0x1, duration=645.369s, table=0, n_packets=0, n_bytes=0, priority=1,icmp,nw_src=10.0.0.1,nw_dst=10.0.0.2 actions=NORMAL
cookie=0x2, duration=637.033s, table=0, n_packets=0, n_bytes=0, priority=1,icmp,nw_src=10.0.0.2,nw_dst=10.0.0.1 actions=NORMAL
cookie=0x0, duration=782.496s, table=0, n_packets=0, n_bytes=0, priority=65534,arp actions=NORMAL
cookie=0x0, duration=782.496s, table=0, n_packets=0, n_bytes=0, priority=0 actions=CONTROLLER:128
mininet@mininet-vm:~$
阻塞h2,h3之间icmp数据包
上面步骤允许h2,h3之间所以IP数据包通信,且优先级为1,这里要阻塞h2,h3之间的icmp数据包,可下发两条规则,且设为更高的优先级.如下:
具体操作如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29curl -X POST -d ’{"nw_src": "10.0.0.2/32", "nw_dst": "10.0.0.3/32", "nw_proto
": "ICMP", "actions": "DENY", "priority": "10"}’ http://localhost:8080/firewall/rules
/0000000000000001
[
{
"switch_id": "0000000000000001",
"command_result": [
{
"result": "success",
"details": "Rule added. : rule_id=5"
}
]
}
]
curl -X POST -d ’{"nw_src": "10.0.0.3/32", "nw_dst": "10.0.0.2/32", "nw_proto
": "ICMP", "actions": "DENY", "priority": "10"}’ http://localhost:8080/firewall/rules
/0000000000000001
[
{
"switch_id": "0000000000000001",
"command_result": [
{
"result": "success",
"details": "Rule added. : rule_id=6"
}
]
}
]
查看流表规则:1
2
3
4
5
6
7
8
9
10
11mininet@mininet-vm:~$ sudo ovs-ofctl -O openflow13 dump-flows s1
OFPST_FLOW reply (OF1.3) (xid=0x2):
cookie=0x3, duration=2528.497s, table=0, n_packets=0, n_bytes=0, priority=1,ip,nw_src=10.0.0.2,nw_dst=10.0.0.3 actions=NORMAL
cookie=0x4, duration=2519.881s, table=0, n_packets=0, n_bytes=0, priority=1,ip,nw_src=10.0.0.3,nw_dst=10.0.0.2 actions=NORMAL
cookie=0x5, duration=73.716s, table=0, n_packets=0, n_bytes=0, priority=10,icmp,nw_src=10.0.0.2,nw_dst=10.0.0.3 actions=CONTROLLER:128
cookie=0x1, duration=3057.177s, table=0, n_packets=0, n_bytes=0, priority=1,icmp,nw_src=10.0.0.1,nw_dst=10.0.0.2 actions=NORMAL
cookie=0x6, duration=33.389s, table=0, n_packets=0, n_bytes=0, priority=10,icmp,nw_src=10.0.0.3,nw_dst=10.0.0.2 actions=CONTROLLER:128
cookie=0x2, duration=3048.841s, table=0, n_packets=0, n_bytes=0, priority=1,icmp,nw_src=10.0.0.2,nw_dst=10.0.0.1 actions=NORMAL
cookie=0x0, duration=3194.304s, table=0, n_packets=0, n_bytes=0, priority=65534,arp actions=NORMAL
cookie=0x0, duration=3194.304s, table=0, n_packets=0, n_bytes=0, priority=0 actions=CONTROLLER:128
mininet@mininet-vm:~$
确认规则
查看已经下发规则
> curl http://localhost:8080/firewall/rules/0000000000000001
1 | [ |
规则图
根据下发的规则,有如下示意图:
测试规则
h1 ping h2
规则设置允许h2,h3之间的icmp数据包,所以通信正常:1
2
3
4
5
6
7
8
9
10mininet> h1 ping h2 -c 3
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=1.03 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.349 ms
64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=0.054 ms
--- 10.0.0.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 0.054/0.479/1.034/0.410 ms
mininet>
h1,h2其它数据通信
h1,h2只能进行icmp相关的通信,比如进行http通信,将被阻塞:1
2
3
4
5
6mininet> h1 wget http://10.0.0.2
--2016-01-24 06:16:11-- http://10.0.0.2/
Connecting to 10.0.0.2:80... ^C
mininet>
[FW][INFO] dpid=0000000000000001: Blocked packet = ethernet(dst='00:00:00:00:00:02',ethertype=2048,src='00:00:00:00:00:01'), ipv4(csum=2706,dst='10.0.0.2',flags=2,header_length=5,identification=7208,offset=0,option=None,proto=6,src='10.0.0.1',tos=0,total_length=60,ttl=64,version=4), tcp(ack=0,bits=2,csum=11391,dst_port=80,offset=10,option='\x02\x04\x05\xb4\x04\x02\x08\n\x00`\x91\x94\x00\x00\x00\x00\x01\x03\x03\t',seq=3941373599,src_port=33179,urgent=0,window_size=29200)
h2 ping h3
h2,h3之间icmp数据是阻塞的,无法通信:1
2
3
4
5
6
7
8
9mininet> h2 ping h3
PING 10.0.0.3 (10.0.0.3) 56(84) bytes of data.
^C
--- 10.0.0.3 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2014ms
mininet>
[FW][INFO] dpid=0000000000000001: Blocked packet = ethernet(dst='00:00:00:00:00:03',ethertype=2048,src='00:00:00:00:00:02'), ipv4(csum=51515,dst='10.0.0.3',flags=2,header_length=5,identification=23913,offset=0,option=None,proto=1,src='10.0.0.2',tos=0,total_length=84,ttl=64,version=4), icmp(code=0,csum=10841,data=echo(data='\x1e\xde\xa4V\x00\x00\x00\x00\x1f\x85\t\x00\x00\x00\x00\x00\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./01234567',id=8983,seq=3),type=8)
h3 wget http://10.0.0.2:8080
h2,h3之间除了icmp外,其它ipv4数据包通信正常.
这里可以python自带的包建立简单的web服务器,用来测试是否能正常通信
> h2 python -m SimpleHTTPServer 8080
1 | mininet> h2 python -m SimpleHTTPServer 8080 & |
可见通信正常.
删除规则
#### 删除rule5和rule5
即取消对h2,h3的icmp数据包的限制:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27curl -X DELETE -d ’{"rule_id": "5"}’ http://localhost:8080/firewall/rules
/0000000000000001
[
{
"switch_id": "0000000000000001",
"command_result": [
{
"result": "success",
"details": "Rule deleted. : ruleID=5"
}
]
}
]
curl -X DELETE -d ’{"rule_id": "6"}’ http://localhost:8080/firewall/rules
/0000000000000001
[
{
"switch_id": "0000000000000001",
"command_result": [
{
"result": "success",
"details": "Rule deleted. : ruleID=6"
}
]
}
]
删除后的示意图
h2 ping h3
删除后,h2,h3之间icmp数据包通信成功:1
2
3
4
5
6
7
8
9
10
11
12
13
14mininet> h2 ping h3
PING 10.0.0.3 (10.0.0.3) 56(84) bytes of data.
64 bytes from 10.0.0.3: icmp_seq=19 ttl=64 time=0.375 ms
64 bytes from 10.0.0.3: icmp_seq=20 ttl=64 time=0.066 ms
64 bytes from 10.0.0.3: icmp_seq=21 ttl=64 time=0.067 ms
64 bytes from 10.0.0.3: icmp_seq=22 ttl=64 time=0.066 ms
64 bytes from 10.0.0.3: icmp_seq=23 ttl=64 time=0.064 ms
64 bytes from 10.0.0.3: icmp_seq=24 ttl=64 time=0.065 ms
64 bytes from 10.0.0.3: icmp_seq=25 ttl=64 time=0.062 ms
^C
--- 10.0.0.3 ping statistics ---
25 packets transmitted, 7 received, 72% packet loss, time 23999ms
rtt min/avg/max/mdev = 0.062/0.109/0.375/0.108 ms
mininet>
总结
通过这章内容的时间,大概了解了RYU控制器firewall即防火墙的使用方法.