概要
本篇博文根据RYU控制的官方文档RYU book第九章FIREWALL,第一部分Example of operation of a single tenant(IPv4)形成,其余三部分大同小异.按照文档上的内容进行实践,并说明了实践过程中存在的问题,指出了文档中不合理的地方.以下所有的rest api的调用都是在firefox上利用restclient插件进行,这样比直接调用curl命令更加直观.
A single tenant(iPv4)
实验拓扑
创建实验环境
mininet创建拓扑
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
mininet@mininet-vm:~$ sudo mn --topo single,3 --mac --controller=remote *** Creating network *** Adding controller Unable to contact the remote controller at 127.0.0.1:6633 *** Adding hosts: h1 h2 h3 *** Adding switches: s1 *** Adding links: (h1, s1) (h2, s1) (h3, s1) *** Configuring hosts h1 h2 h3 *** Starting controller c0 *** Starting 1 switches s1 ... *** Starting CLI: mininet> |
设置openflow1.3
在ovs交换机s1上设置使用openflow1.3
1 2 |
mininet@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 6 |
OpenFlow 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 2 |
mininet@mininet-vm:~$ sudo ovs-vsctl set Bridge s1 protocols=OpenFlow13 mininet@mininet-vm:~$ |
启动控制器
1 2 3 4 5 6 7 8 9 10 |
mininet@mininet-vm:~/ryu/ryu/app$ sudo ryu-manager rest_firewall.py loading app rest_firewall.py loading app ryu.controller.ofp_handler instantiating app None of DPSet creating context dpset creating context wsgi instantiating app rest_firewall.py of RestFirewallAPI instantiating app ryu.controller.ofp_handler of OFPHandler (2413) wsgi starting up on http://0.0.0.0:8080/ [FW][INFO] dpid=0000000000000001: Join as firewall. |
设置初始状态
默认情况下,所有的通信都是禁止的,查看交换机的状态
1 2 3 4 5 6 |
[ { "status": "disable", "switch_id": "0000000000000001" } ] |
这是因为有一个最高优先级的流表,丢弃所以数据包:
1 2 3 4 5 6 |
mininet@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 2 3 4 5 6 7 8 9 |
[ { "switch_id": "0000000000000001", "command_result": { "result": "success", "details": "firewall running." } } ] |
再次查看交换机状态:
1 2 3 4 5 6 |
[ { "status": "enable", "switch_id": "0000000000000001" } ] |
接着试试h1 ping h2,因为访问规则没有设置,所以这个时候,数据包会被阻塞.
1 2 |
[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 29 |
curl -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 7 |
mininet@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 27 |
curl -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 9 |
mininet@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 29 |
curl -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 11 |
mininet@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 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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
[ { "access_control_list": [ { "rules": [ { "priority": 1, "dl_type": "IPv4", "nw_dst": "10.0.0.3", "nw_src": "10.0.0.2", "rule_id": 3, "actions": "ALLOW" }, { "priority": 1, "dl_type": "IPv4", "nw_dst": "10.0.0.2", "nw_src": "10.0.0.3", "rule_id": 4, "actions": "ALLOW" }, { "priority": 10, "dl_type": "IPv4", "nw_proto": "ICMP", "nw_dst": "10.0.0.3", "nw_src": "10.0.0.2", "rule_id": 5, "actions": "DENY" }, { "priority": 1, "dl_type": "IPv4", "nw_proto": "ICMP", "nw_dst": "10.0.0.2", "nw_src": "10.0.0.1", "rule_id": 1, "actions": "ALLOW" }, { "priority": 10, "dl_type": "IPv4", "nw_proto": "ICMP", "nw_dst": "10.0.0.2", "nw_src": "10.0.0.3", "rule_id": 6, "actions": "DENY" }, { "priority": 1, "dl_type": "IPv4", "nw_proto": "ICMP", "nw_dst": "10.0.0.1", "nw_src": "10.0.0.2", "rule_id": 2, "actions": "ALLOW" } ] } ], "switch_id": "0000000000000001" } ] |
规则图
测试规则
h1 ping h2
规则设置允许h2,h3之间的icmp数据包,所以通信正常:
1 2 3 4 5 6 7 8 9 10 |
mininet> 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 6 |
mininet> 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 9 |
mininet> 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 2 3 4 5 6 7 8 9 10 11 12 13 |
mininet> h2 python -m SimpleHTTPServer 8080 & mininet> h3 wget http://10.0.0.2:8080 --2016-01-24 06:27:12-- http://10.0.0.2:8080/ Connecting to 10.0.0.2:8080... connected. HTTP request sent, awaiting response... 200 OK Length: 1600 (1.6K) [text/html] Saving to: 'index.html' 0% [ ] 0 --.-K/s 100%[======================================>] 1,600 --.-K/s in 0s 2016-01-24 06:27:12 (305 MB/s) - 'index.html' saved [1600/1600] mininet> |
可见通信正常.
删除规则
#### 删除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 27 |
curl -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 14 |
mininet> 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即防火墙的使用方法.