Skip to content

Instantly share code, notes, and snippets.

@rsarai
Last active June 28, 2019 02:14
Show Gist options
  • Save rsarai/bf37688edb43961a67ee8fd7cf29eb39 to your computer and use it in GitHub Desktop.
Save rsarai/bf37688edb43961a67ee8fd7cf29eb39 to your computer and use it in GitHub Desktop.

Ryu Firewall

Topology

Commands

  • On an usual terminal
$ sudo mn --topo single,3 --mac --switch ovsk --controller remote -x
*** 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
*** Running terms on localhost:10.0
*** Starting controller
*** Starting 1 switches
s1

*** Starting CLI:
mininet>
  • On switch: s1 (root):
$ ovs-vsctl set Bridge s1 protocols=OpenFlow13
  • On controller: c0 (root):
$ ryu-manager ryu.app.rest_firewall
loading app ryu.app.rest_firewall
loading app ryu.controller.ofp_handler
instantiating app None of DPSet
creating context dpset
creating context wsgi
instantiating app ryu.app.rest_firewall of RestFirewallAPI
instantiating app ryu.controller.ofp_handler of OFPHandler
(2210) wsgi starting up on http://0.0.0.0:8080/

Changing in the initial state

  • Immediately after starting the firewall, it was set to disable status to cut off all communication. Enable it with the following command.
mininet> pingall
*** Ping: testing ping reachability
h1 -> X X
h2 -> X X
h3 -> X X
*** Results: 100% dropped (0/6 received)
  • On Node: c0 (root): mininet> xterm c0
# curl -X PUT http://localhost:8080/firewall/module/enable/0000000000000001
  [
    {
      "switch_id": "0000000000000001",
      "command_result": {
        "result": "success",
        "details": "firewall running."
      }
    }
  ]

# curl http://localhost:8080/firewall/module/status
  [
    {
      "status": "enable",
      "switch_id": "0000000000000001"
    }
  ]

Check ping communication from h1 to h2. Since access permission rules are not set, communication will be blocked.

  • host: h1:
# ping 10.0.0.2
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
^C
--- 10.0.0.2 ping statistics ---
20 packets transmitted, 0 received, 100% packet loss, time 19003ms

Packets that are blocked are output to the log.

Adding a Rule

Add a rule to permit pinging between h1 and h2. You need to add the rule for both ways.

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

Added rules are registered in the switch as flow entries.

ovs-ofctl -O OpenFlow13 dump-flows s1

Try to send a ping from h1 to h2. Since rules to allow communication are set, the ping will go through.

  • On host: h1:
# ping 10.0.0.2
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_req=1 ttl=64 time=0.419 ms
64 bytes from 10.0.0.2: icmp_req=2 ttl=64 time=0.047 ms
64 bytes from 10.0.0.2: icmp_req=3 ttl=64 time=0.060 ms
64 bytes from 10.0.0.2: icmp_req=4 ttl=64 time=0.033 ms
...

Packets from h1 to h2 other than ping are blocked by the firewall. For example, if you execute wget from h1 to h2, a log is output that packets were blocked.

  • On host: h1:
# wget http://10.0.0.2
--2013-12-16 15:00:38--  http://10.0.0.2/
Connecting to 10.0.0.2:80... ^C
  • On controller: c0 (root):
[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=4812,dst='10.0.0.2',flags=2,header_length=5,identification=5102,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=45753,dst_port=80,offset=10,option='\x02\x04\x05\xb4\x04\x02\x08\n\x00H:\x99\x00\x00\x00\x00\x01\x03\x03\t',seq=1021913463,src_port=42664,urgent=0,window_size=14600)
...

If you execute ping from h2 to h3, a log is output that packets were blocked by the firewall.

Adding a rule to allow UDP

curl -X POST -d '{"nw_src": "10.0.0.1/32", "nw_dst": "10.0.0.2/32", "nw_proto": "UDP"}' http://localhost:8080/firewall/rules/0000000000000001

curl -X POST -d '{"nw_src": "10.0.0.2/32", "nw_dst": "10.0.0.1/32", "nw_proto": "UDP"}' http://localhost:8080/firewall/rules/0000000000000001
  • Then in h1 run
iperf -s -u -i 1 

to start a udp server which sends packets with an interval of 1 second

  • Then in h2 run
iperf -c 10.0.0.1 -u -b 1m -n 1000 

which creates a udp client that connects to h1 at address 10.0.0.1, bandwidth = 1M, number of bytes to transport = 1000

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment