RYU控制器的firewall功能(转)

概要

本篇博文根据RYU控制的官方文档RYU book第九章FIREWALL,第一部分Example of operation of a single tenant(IPv4)形成,其余三部分大同小异.按照文档上的内容进行实践,并说明了实践过程中存在的问题,指出了文档中不合理的地方.以下所有的rest api的调用都是在firefox上利用restclient插件进行,这样比直接调用curl命令更加直观.

A single tenant(iPv4)

实验拓扑

art

创建实验环境

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.

设置初始状态

默认情况下,所有的通信都是禁止的,查看交换机的状态

http://localhost:8080/firewall/module/status

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."
    }
  }
]

再次查看交换机状态:

http://localhost:8080/firewall/module/status

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通,需要设置两条规则,如图:
rule

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数据包进行通信,需要增加两条规则,如下图:
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数据包,可下发两条规则,且设为更高的优先级.如下:
block icmp h2 h3
具体操作如下:

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"
  }
]

规则图

根据下发的规则,有如下示意图:
confirm

测试规则

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"
      }
    ]
  }
]

删除后的示意图

delete confirm

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即防火墙的使用方法.

猜你喜欢

转载自blog.csdn.net/neo233/article/details/80635474
今日推荐