Firewall (Dev)
Author: Amer Tahir amertahir@gmail.com Edited by: KC Wang kc.wang@bigswitch.com Edited by: Ryan Izard ryan.izard@bigswitch.com
Introduction
The Firewall application has been implemented as a Floodlight Module that enforces ACL rules (Access Control List) on OpenFlow enabled switches in the network using flows and by monitoring packet-in behavior. ACL rules here are just sets of conditions that permit or allow or deny a traffic flow at its ingress switch.
Each packet-in triggered by the first packet(s) of a traffic flow is matched against the set of existing firewall rules. Firewall rules are sorted based on assigned priorities and are matched against the PacketIn's header fields as defined in OFMatch (as of OpenFlow Standard 1.0). The highest priority matching firewall rule determines the action (allow/deny) of the flow. Wildcards can be used as defined in OFMatch.Â
Firewall Strategy
The firewall operates in a reactive manner. Firewall rules are sorted by priority at the time they are created (via its REST API). Each incoming packet-in will be compared against the list from the highest priority until either a match is found or the list is exhausted. If a match is found, the rule's action (ALLOW or DENY) is stored in a IRoutingDecision object to be passed on to the rest of the packet-in processing pipeline. This decision eventually reaches Forwarding or any other chosen packet forwarding application (e.g., LearningSwitch). Forwarding pushes a regular forwarding flow entry if the decision is ALLOW, or a drop flow entry if the decision is DENY. In either case, the flow entry sent to the switch must exactly reflect the matching firewall rule's match attributes (including wildcards).
The firewall thus implemented allows rules to have partially overlapping flow space, arbitrated by their priority. Â In the simplified example below, all traffic to 192.168.1.0/24 subnet is denied except inbound HTTP (TCP port 80) traffic.
protocol | destination IP | destination port | action | priority* |
---|---|---|---|---|
TCP | 192.168.1.0/24 | 80 | ALLOW | 1 |
TCP | 192.168.1.0/24 | wildcard | DENY | 2 |
* lower number indicates higher priority
Special care is taken to handle the wildcard in this case. If a flow does not match the first (higher priority) flow but matches the second (lower priority) flow, the flow entry sent by Forwarding to the switch cannot and will not wildcard the destination port; instead, the specific port of that flow is specified in the flow entry, so that future packets of port 80 will not be dropped by the switch without sending a packet-in to the controller.
REST Interface
The Firewall Module exposes REST interface implemented as RestletRoutable using Rest API Service. Following is a list of REST methods exposed.
Test Methodology
Testing comprises of automated unit tests created using EasyMock. The "FirewallTest" class contains the test cases that can be executed using JUnit and Eclipse. In most of the test cases, packet-in event is simulated and the resulting firewall decision is verified based on the rules defined. Following is a list of the various test cases:Â
- testNoRules
- Description: without any rules, send a packet-in event. The firewall should DENY the traffic. This is a boundary case.
- testRuleInsertionIntoStorage
- Description: adds a rule into firewall and verifies it by checking storage. This is a normal positive test case.
- testRuleDeletion
- Description: deletes a rule from firewall and verifies it by checking storage. Again, this is a normal positive test case.
- testFirewallDisabled
- Description: with the firewall disabled and a rule inserted, send a packet-in event. The firewall should DENY the traffic. This is a negative test case.
- testSimpleAllowRule
- Description: Adds a simple rule to allow TCP traffic from one IP address to another and sends a packet-in event. After verifying the firewall's decision, it sends another packet that is supposed to be DROPPED, and then verifies the decision to be DROP. This test case covers normal rules (non-boundary case – i.e. no malformed packets or broadcasts)
- testOverlappingRules
- Description: Adds overlapping rules (deny all TCP traffic except destined for port 80). This test case covers complex cases of multiple rules (multiple allow-deny overlapping rules).
- testARP
- Description: tests a special scenario of ARP broadcast request packet and unicast ARP reply. There is no firewall rule allowing ARP reply, so only broadcast request packet should go through.
- testIPBroadcast
- Description: without any rules, send an IP broadcast (L3) packet-in event. The firewall should ALLOW the traffic. This is a positive test case that covers a special scenario of IP broadcasts (L3 + L2 broadcast).
- testMalformedIPBroadcast
- Description: without any rules, send a malformed IP broadcast packet-in event. The firewall should DENY the traffic, as the packet is L2 broadcast but L3 unicast. This is a boundary case.
- testLayer2Rule
- Description: with a rule to allow traffic from one specific MAC to another and another rule (lower priority) to deny all TCP traffic, a TCP packet-event is simulated. The firewall should ALLOW the traffic. This is a negative test case that covers a subset of scenarios where the rules cover only L2.
Issues and Limitations
- The firewall module's DELETE REST API call doesn't delete flow entries on the switch. The rule is only deleted from the controller storage while the flow entry on switch is expected to time out itself per standard timeout behavior. This means the effect of deleting a rule is effective after a certain time, and an existing flow can persist for as long as it has continuous traffic through the switches.
- In the initial proposal, TCP/UDP port ranges were proposed to be supported by the firewall rules. However, as OpenFlow flow matching mechanism doesn't allow specifying port ranges, this feature was not implemented.Â