Firewalls are essential for managing and protecting computer networks. They permit specifying which packets are allowed to enter a network, and also how these packets are modified by IP address translation and port redirection. Configuring a firewall is notoriously hard, and one of the reasons is that it requires using low level, hard to interpret, configuration languages. Equally difficult are policy maintenance and refactoring, as well as porting a configuration from one firewall system to another.
To address these issues we introduce a pipeline that assists system administrators in checking if: (i) the intended security policy is actually implemented by a configuration; (ii) two configurations are equivalent; (iii) updates have the desired effect on the firewall behavior; (iv) there are useless or redundant rules; additionally, an administrator can (v) transcompile a configuration into an equivalent one in a different language; and (vi) maintain a configuration using a generic, declarative language that can be compiled into different target languages.
The pipeline is based on IFCL, an intermediate firewall language equipped with a formal semantics, and it is implemented in an open source tool called FWS. In particular, the first stage decompiles real firewall configurations for iptables, ipfw, pf and (a subset of) Cisco IOS into IFCL. The second one transforms an IFCL configuration into a logical predicate and uses the Z3 solver to synthesize an abstract specification that succinctly represents the firewall behavior. System administrators can use FWS to analyze the firewall by posing SQL-like queries, and update the configuration to meet the desired security requirements. Finally, the last stage allows for maintaining a configuration by acting directly on its abstract specification and then compiling it to the chosen target language. Tests on real firewall configurations show that FWS can be fruitfully used in real-world scenarios.
Firewalls are standard mechanisms for protecting computer networks but, as any other security mechanism, they become useless when incorrectly configured. Configuring and maintaining them is very difficult also for expert system administrators, and improper management of firewalls may lead to great business risks in any organization or company. The main challenges that call for technical solutions and tools are managing changes and analyzing their impact, as well as maintaining clean configurations, see e.g., [17]. These are relevant issues because of lack of formal policies, and of well-documented procedures for carrying out and enforcing them. Also, firewall configurations typically consist of a large number of rules and it is often hard to figure out their overall behavior. Addressing these problems may help in adopting widely-accepted firewall best practices and analyzing the current environment to highlight possible weaknesses. A proper firewall management is crucial for keeping up with compliance regulations and for proving compliance status at any given time.
However, these problems are not easy to solve, also because firewall policy languages are varied and rather complex. They account for low-level system and network details, and support non trivial control flow constructs, such as jump and goto. Further difficulties for network administrators come from Network Address Translation (NAT), a pervasive component of IPv4 networking that operates while packets traverse the firewall. In IPv4, NAT is essential to perform port redirection and translate addresses, e.g., when a single public address is used for a whole private network.
In addition, configurations enforce policies in a way that typically depends on how packets are processed by the network stack of the operating system. Also, firewall rules interact with each other, e.g., some shadow others making them redundant or preventing them to be triggered. Often administrators resort to policy refactoring to solve these issues and to obtain minimal and clean configurations. When a network is protected by more than one firewall the situation complicates further, since the configurations of the various firewalls need to be kept coherent: enabling or disabling a connection typically requires modifying the configurations of all the firewalls that are potentially traversed by the considered connection.
Over the past few years, there has been a growing interest in high level languages for programming the network as a whole. The Software Defined Network (SDN) paradigm decouples network control and forwarding functions, by abstracting the underlying infrastructure from applications and network services [37]. A unified, high level paradigm to configure networks and firewalls is appealing and might, in principle, make firewall configuration simpler and less error-prone. However, SDN requires a suitable infrastructure and, even though it seems to be spreading fast, it will take time before “old” technology is dismissed in favor of it. In the years to come, we will deal with many different firewall configuration languages, including the ones running on a variety of legacy devices. More often than nowadays, network administrators will have to face the porting of legacy firewall configurations to fit this new paradigm.
In this work, we propose a transcompilation pipeline to assist network administrators in analyzing, refactoring, maintaining and porting firewall configurations, with particular focus on most popular languages of well-established systems. Our proposal is independent of the specific target firewall system, so administrators are not required to have a deep knowledge about the internals of the system and its language. They can thus concentrate on the policy to enforce. Our pipeline is composed of the following stages, implemented in our tool named FireWall Synthesizer (FWS):
decompiling the policy from the source language into an intermediate language;
extracting the meaning of the policy as a set of non overlapping declarative rules describing the accepted packets and their translations in logical terms. In this way, administrators can maintain their policies by acting directly on the declarative rules;
compiling the declarative rules into the target language.
The first stage relies on IFCL, a generic intermediate language that incorporates all the typical features of firewall languages such as NAT, tags, jumps, invocations to rulesets and stateful packet filtering. It has been designed to encode real firewall languages in a relatively easy manner. Interestingly, IFCL unveils the bipartite structure common to each real firewall language: the first component consists of the rulesets determining the destiny of packets, whereas the second one specifies the steps needed to handling packets and the order in which rulesets are applied. While the format of the rules and the actions are largely shared by the available configuration languages, besides minor syntactic differences, the second component summarizes the specific low-level behavior of a particular system, and thus it is peculiar to each operating system and firewall tool.
The second stage transforms a real firewall configuration encoded in IFCL into an abstract specification that represents the set of the allowed connections. This version abstracts from low-level details, e.g., the control flow and duplicated or shadowed rules. In this way the meaning of the configuration is made explicit and it is easier for system administrators to check whether the intended security policy is correctly implemented or not.
The third stage allows for maintaining a configuration by acting directly on its abstract specification. Maintaining a configuration in this form is conceptually simpler, as the abstract specification is in a declarative form and its interpretation does not depend on the way rules are processed or implemented. In fact, the declarative representation enables the user of FWS to easily analyze configurations and to detect possible inconsistencies, to compare policies, to trace which hosts and ports are affected during maintenance.
The last stage supports cross-platform re-compilation into different firewall systems, and implements configuration porting, policy refactoring and maintenance. More precisely, our tool first transforms back the abstract version into an IFCL configuration, and then it generates a target firewall configuration.
As a proof of concept, the prototypical tool FWS has been used to assess our pipeline on the most used firewall systems in Linux and Unix, namely iptables [34], ipfw [44] and pf [38], and on a subset of Cisco IOS [10]. The tool is available for download at [18]. Other firewall systems can be easily managed by the tool, by just providing a plug-in for the front-end to our intermediate language. Indeed, once a configuration has been translated into IFCL, its analysis and transcompilation can be performed independently of the initial firewall language and system.
Contributions
Our contributions can be summarized as follows.
We present FWS, a tool that translates real firewall configurations into abstract specifications. Differently from many available tools (cf. Section 8), our approach is independent of the specific target firewall system and language. The abstract specification can be seen as a table that declaratively represents the set of accepted packets with their possible translations. Roughly, each row corresponds to a configuration rule. However, the resulting table is more readable than the standard rulesets, because its rows are independent from each other, while in real firewall configurations the meaning of a rule depends on the others and on the firewall control flow (cf. Section 3.7). As a consequence, the table contains no anomalies, e.g., shadowing or redundancies.
Once a configuration has been translated into its abstract specification, administrators can inspect the resulting table through the SQL-like query language of FWS, and analyze its behavior. In particular, they can check reachability properties, e.g., which subnets, hosts and ports are reachable from other hosts and subnets, as well as policy equivalence, implication and difference. By comparing two abstract specifications an administrator can detect discrepancies between actual configurations, also when written in different languages. Furthermore, the FWS query language supports administrators in maintaining a configuration by observing the effects of adding, deleting or modifying some rules. In other words, administrators can compute the overall impact of a selected rule in terms of accepted or dropped packets (cf. Section 3).
FWS supports policy maintenance, refactoring and porting, because it compiles an abstract specification into a real firewall configuration (cf. Section 6). Policies can be directly maintained in their abstract, declarative form and then compiled into a target firewall language. Maintaining a policy in this ways is simple, as all low-level implementation details are omitted, and allows for compiling the same policy into different target languages. Decompilation and compilation can also be combined to achieve refactoring and porting: when the source and the target languages coincide, one refactors the configuration in hand; when instead they differ, the given configuration is ported to a different firewall system. For that, we provide the user with a graphical tool for sumbitting queries in the SQL-like language of FWS and for handling the policies directly in their abstract, declarative specification.
We introduce the new language IFCL whose configurations are composed by rulesets and a control diagram. The rules determine the destination of packets and they resemble those of most existing languages. The control diagram describes the flow of the packet through the network stack of the operating system. Our language is the crucial component that makes FWS language-independent, but it is also of independent interest as a generic firewall configuration language. A relevant aspect of IFCL is its formal semantics (cf. Section 4.2), while real languages hardly have one. Remarkably the decompilation of stage 1 also endows real languages with a formal semantics, inherited from that of IFCL. In this way the meaning of a policy is formally defined, so allowing the algorithmic manipulations of our tool. In addition, the formal semantics enables us to prove the correctness of our transcompiling pipeline, i.e., that all its transformations preserve the meaning of the original firewall policy (Theorems 2 and 4). However, since real languages rarely have a formal semantics the correctness of their decompilation into IFCL (stage 1) cannot be assessed, but only empirically validated (see Section 4.3).
We associate a configuration from the intermediate language with a logical characterization, in the form of a first order logic predicate. It determines which are the packets accepted and which dropped by the configuration in hand, with all the possible NAT translations. The model of this predicate is then used to build the table representing the abstract specification of the configuration. The logical characterization is, by itself, insightful and provides the query engine of FWS with a formal, algorithmic basis. It also signals the presence of ill-formed configurations that may both accept and drop the same packets (cf. Section 5.2).
We assess the effectiveness of FWS by performing experiments on real firewall configurations (cf. Section 7). We show that the tool analyzes small configurations in real-time, whereas complex and long ones terminate in a matter of minutes. Policy implication and equivalence are checked very efficiently. After the synthesis step, we used the tool to refactor and port some policies. Only few seconds are required to generate the target configuration from the abstract specification.
Preliminary portions of this paper appeared earlier in two conference papers [5,6]. The main new contributions are: the possibility of modifying the abstract specification and maintaining a policy in its declarative, generic form; a finer treatment of iptables, ipfw, pf and a new one for Cisco IOS; an extension of FWS to support also the level 2 of the network stack (see the example layer2.fws in the repository [18]); a new version of the synthesis algorithm that now works also with symbolic names for networks, interfaces, IP addresses and ports; the new algorithm also computes the sets of all dropped packets; a complete implementation of the last stage of our pipeline, which is assessed on real cases; a new friendly query language that allows expressing and checking new properties, including the detection of non-determinism inside a configuration; a new prompt-based and a new batch interface of the tool; a deep evaluation of FWS considering additional real configurations.
Structure of the paper
In Section 2, we briefly survey iptables, ipfw, pf and Cisco IOS. We describe the syntax of their configuration languages and how they process packets. Section 3 illustrates FWS at work on a small yet realistic scenario. We focus on how network administrators can exploit FWS and use its query language for maintaining various firewall configurations. In particular, we show how one can check host reachability, policy implication, equivalence, difference and non-deterministic behavior, and how one can update the graphical representation of policies. In Section 4 we present our intermediate language IFCL, its formal semantics and the encodings of iptables, ipfw, pf and Cisco IOS. Section 5 presents the logical characterization of all packets accepted and dropped by a firewall, with their possible translations. It also describes the internals of the tool FWS and the algorithm for synthesizing abstract specifications and for analyzing policies. Finally, it proves the correctness of the first two stages of our pipeline. Section 6 describes the last stage, in particular the compilation strategy for generating target configurations. It also proves the source and target configurations equivalent, so establishing the correctness of the whole pipeline. In Section 7, we apply our tool on various real firewall policies to assess its effectiveness, scalability and usability. Section 8 compares our pipeline with other proposal in the literature and Section 9 concludes. All the proofs of our main theorems are in Appendix A that also contains additional results. In Appendix B, there is a table with the main notations used in the paper. Finally, Appendix C describes the command line interface and the SQL-like query language of FWS.
Background
Usually, system administrators classify networks into security domains. Through firewalls they monitor the traffic and enforce a predetermined set of access control policies among the various hosts and subnetworks (packet filtering). System administrators can also use a firewall to connect a network with private IPs to other (public IP) networks or to the Internet and to perform connection redirections through Network Address Translation (NAT).
Firewalls are implemented either as proprietary, special devices, or as software tools running on general purpose operating systems. Independently of their actual implementations, they are usually characterized by a set of rules that determine which packets reach the different subnetworks and hosts, and how they are modified or translated.
Below, we briefly review four different firewall systems: iptables [34], ipfw [44] and pf [38] that are the most used in Linux and Unix, and the fragment of Cisco IOS [10] covering Access Control Lists and NAT. We refer the reader to the manuals of these systems for additional details.
iptables
It is one of the most used tools for packet filtering being the default in Linux. It operates on top of Netfilter, the packets processing framework implemented in the Linux kernel [41].
The basic notions of iptables are tables and chains. Intuitively, a table is a collection of ordered lists of policy rules called chains. The most commonly used tables are: filter for packet filtering; nat for network address translation; mangle for packet alteration. There are five built-in chains that are inspected at specific moments of the packet life cycle [45]: PreRouting, when the packet reaches the host; Forward, when the packet is routed through the host; PostRouting, when the packet is about to leave the host; Input, when the packet is routed to the host; Output, when the packet is generated by the host. Tables do not necessarily contain all the predefined chains and further user-defined chains can be present.
Chains are inspected top-down to find a rule applicable to the packet under elaboration. Each rule specifies a condition and a target: if the packet matches the condition then it is processed according to the specified target, which can be either a built-in target or a user-defined chain. The most commonly used targets are: ACCEPT, to accept the packet; DROP, to discard the packet; RETURN, to stop examining the current chain and resume the processing of a previous chain; DNAT, to perform destination NAT, i.e., a translation of the destination address; SNAT, to perform source NAT, i.e., a translation of the source address. When the target is a user-defined chain, two “jumping” modes are available: call and goto. The difference between the two arises when a RETURN is executed or the end of the chain is reached: the evaluation resumes from the rule following the last matched call (just as for standard call-return of procedures). Some extensions also allow marking packets with a tag and to verify the tag value. Built-in chains have a user-configurable default policy (ACCEPT or DROP) which determines the future of a packet when no rule applies.
ipfw
It is the standard firewall for FreeBSD [44]. A configuration consists of a single ruleset that is inspected twice, when the packet enters the firewall and before it exits. It is possible to specify whether a rule should be applied only in one of the two directions using the keywords in and out.
Similarly to iptables, rules are inspected sequentially until the first match occurs and the corresponding action is taken. The packet is dropped if there is no matching rule. The most common actions in ipfw are the following: allow and deny are used to accept and reject packets; nat applies destination NAT to incoming packets and source NAT to outgoing packets; check-state accepts packets that belong to established connections; skipto, call and return allow to alter the sequential order of inspection of the rules in the ruleset. Differently from iptables, the targets of skipto and call are rules instead of rulesets. A packet is dropped if there is no matching rule.
Packet marking is supported also by ipfw: if a rule containing the tag keyword is applied, the packet is marked with the specified identifier and then processed according to the rule action.
pf
This is the standard firewall of OpenBSD [38] and is included in macOS since version 10.7. Each rule consists of a predicate which is used to select packets and an action that specifies how to process the packets satisfying the predicate. The most frequently used actions are pass and block to accept and reject packets, rdr and nat to perform destination and source NAT. Packet marking works as in ipfw. Differently from the other firewalls, the action taken on a packet is determined by the last matched rule, unless otherwise specified by using the quick keyword. There is a single ruleset in pf that is inspected both when the packet enters and exits the firewall. As in ipfw, keywords in and out can be used to specify whether a rule should be applied only in one direction. When a packet enters the host, DNAT rules are examined first and filtering is performed after the address translation. Similarly when a packet leaves the host: first its source address is translated by the relevant SNAT rules, and then the resulting packet is possibly filtered. Packets belonging to established connections are accepted by default, thus bypassing the filters.
Cisco IOS
It is the network infrastructure software used by Cisco devices, and it is one of the most widespread professional firewall systems. We consider the fragment of Cisco IOS for filtering and NAT. Filtering is configured through Access Control Lists (ACLs), i.e., lists of rules that dictate if a packet is accepted or dropped. ACLs have a default DROP policy: packets that are not accepted by one of the ACL rules are rejected. It is possible to associate at most two ACLs to each firewall interface, one for incoming and one for outgoing packets. NAT is defined in terms of inside and outside IPs, belonging to internal or external networks. To this aim, Cisco IOS requires configuring explicitly the interfaces as NAT inside or NAT outside. Translations can be bidirectional, e.g., when mapping a single IP, or monodirectional, e.g., when the source addresses of a whole private network are translated into a single public IP. A NAT translation happens in between incoming and outcoming filtering and before/after routing depending if it is from outside to inside or vice versa [9].
The pipeline at work
This section introduces a small yet realistic scenario through which we exemplify how our tool FWS supports the three stages of our pipeline: (1) the decompilation of a firewall configuration into the intermediate language IFCL; (2) the synthesis of the declarative specification; and (3) the compilation in the target language. In addition, we illustrate how FWS supports system administrators in managing and reasoning on a firewall configuration, spotting and fixing mistakes. In particular, we check the following behavioral properties:
Reachability, i.e., whether or not a certain address is reachable from another one, possibly through NAT;
Policy implication and equivalence, i.e., if the packets accepted by one configuration are at least/exactly the same accepted by another configuration;
Policy difference, i.e., what packets are accepted by one configuration and denied by another. This feature is particularly useful when maintaining a policy to check how updates affect the firewall behavior, because one can see which packets are accepted and which filtered out when a specific rule is added;
Related rules, i.e., which rules affect the processing of the packets identified by a user-provided query;
Policy non-determinism, i.e., if there are packets non-deterministically accepted or dropped.
Finally, we show how a system administrator can use FWS to refactor and port a configuration. This compilation stage also reveals subtle differences among the firewall languages considered, the expressivity and flexibility of which turn out to be diverse.
In Section 3.1 we describe a typical network of a small company, and we state some requirements that specify the desired security policy. We then consider three firewall configurations in iptables (Section 3.2), ipfw (Section 3.3) and Cisco IOS (Section 3.4). Finally, we apply FWS to decompile the actual configurations in a tabular, human-readable format and check whether they meet the requirements. In Section 3.7 we show how FWS can help administrators in maintaining a firewall configuration. An example in pf is in [5], and more can be found online [18].
Query view of FWS.
An overview of FWS interface
FWS is equipped with a graphical interface through which administrators can analyze, maintain and port configurations. The user can switch between query and compiler view. On the one hand, the query view is used to analyze one or more firewall configurations, helping the administrator to check their compliance with security requirements. On the other hand, the compiler view is needed to translate a high level specification of the expected behavior into one of the supported languages.
As shown in Fig. 1, the query view is divided in two panels, the one on the left allows the administrator to encode a series of analyses to be performed on the loaded policies, while the results of those analyses are shown on the right. Firewall policies are loaded and associated to a name using the Load Policy button. Then, the analyses are encoded using the query language, and, finally, they are executed and the results are printed when the Run button is clicked. Analyses are exemplified in the following subsections and discussed in depth in Appendix C.
The compiler view consists of a panel with the tabular representation of the firewall behavior. The administrator can edit the table and compile it in the chosen firewall language. More details are discussed in Section 3.6.
Network structure and policy requirements
As running example, consider the network shown in Fig. 2. The internal network (10.0.0.0/16) consists of two subnetworks:
network lan0 (i.e. 10.0.1.0/24) contains servers and production machines, including a HTTPS server (web_server: 10.0.1.15) that runs the company website on port 443;
network lan1 (i.e. 10.0.2.0/24) contains the employees’s computers, including the system administrator’s (ssh_server: 10.0.2.15) where a SSH service is running on port 22.
The firewall has three network interfaces: eth0 connected to lan0 with IP lan0_ip (10.0.1.1); eth1 connected to lan1 with IP lan1_ip (10.0.2.1); and ext connected to the Internet with public IP ext_ip (23.1.8.15).
A case study of a firewall with three interfaces.
Requirements
We want to enforce the following requirements on the internal and external traffic:
internal networks can freely communicate;
connections to the public IP on ports 443 and 22 are translated (DNAT) to web_server and ssh_server, respectively. This condition permits external hosts to access the website by connecting to the public IP address ext_ip at port 443, that is redirected to the corresponding internal host; similarly for accessing the SSH server;
connections from the internal hosts to the Internet are allowed only towards HTTP and HTTPS web servers, i.e., with destination ports 80 and 443, respectively;
source addresses of packets from the internal hosts to the Internet are translated (SNAT) to the external IP address of the firewall. This allows hosts with private IPs to access the Internet;
the firewall can connect to any other host.
Below, we encode the requirements above as queries that are checked by FWS.
We provide a configuration in iptables for the example of Section 3.1. Then, we use FWS to decompile and analyze the configuration and check if it complies with the requirements 1–5 above.
Configuring the firewall with iptables
Figure 3 shows the policy for our example in the standard iptables-save format used to store iptables rules in a configuration file.
The first sequence of commands delimited by *nat and COMMIT keywords sets the default policies of all nat chains to ACCEPT, inserts into the nat PREROUTING chain the rules for redirecting the incoming connections to the internal servers (requirement 2) and adds to the nat POSTROUTING chain the rule for SNAT (requirement 4).
The second block from lines *filter to COMMIT specifies a default DROP policy for the INPUT and FORWARD chains and a default ACCEPT policy for the OUTPUT chain, letting the firewall communicate with any host (requirement 5). The first two filtering rules allow the packets belonging to connections flagged as established to go through and towards the firewall, i.e., whenever a new connection is allowed any further packet belonging to the same connection will also be allowed. This is not explicitly required by the policy but is necessary to ensure functionality of connection-oriented protocols. Then, we have ACCEPT rules corresponding to the requirements 1, 3 and 2, respectively. Notice that requirement 2 has also rules in the nat table above.
Decompiling and analyzing the configuration
Results of FWS when checking the iptables configuration of Fig. 3; * denotes any value, and * denotes any value except for those included in S
(a) Requirement 1
Source IP
Source Port
Destination IP
Destination Port
Protocol
State
lan0
*
lan1
*
*
NEW
lan1
*
lan0
*
*
NEW
(b) Requirement 2
Source IP
Source Port
Destination IP
Destination Port
DNAT IP
Protocol
State
*
*
ext_ip
22
ssh_server
tcp
NEW
*
*
ext_ip
443
web_server
tcp
NEW
(c) Requirements 3 and 4
Source IP
Source Port
SNAT IP
Destination IP
Destination Port
Protocol
State
internal
*
ext_ip
* \ {internal}
443, 80
tcp
NEW
(d) Requirement 5
Source IP
Source Port
Destination IP
Destination Port
Protocol
State
ext_ip
*
*
*
*
NEW
We now use FWS to check that the configuration of Fig. 3 meets the requirements 1–5. First, we load the policy p into FWS by specifying the iptables rules and a configuration file that encodes what is shown in Fig. 2. We then ask the tool if arbitrary traffic is allowed among internal networks, raising the query
where srcIp, dstIp represent the fields for source and destination address of the IP packet entering the firewall interfaces, and state tells if a connection is new or established. The query checks whether hosts with srcIp in lan0 can start new connections towards those with dstIp in lan1, or vice versa, as stated by requirement 1. The operator = constrains a variable to be equal to a value or inside a certain interval; the operators and and or stand for logical conjunction and disjunction.
The output we obtain from the tool is in Table 1a. The table contains all the allowed connections matching the query, confirming that requirement 1 is satisfied. Note that FWS supports the projection of the result to a subset of the available columns using the project directive. Hence, from now onwards the results will be projected to the minimum set of columns that represent the considered packets.
We now check that external hosts can access the web and the SSH servers only by connecting to the firewall IP address ext_ip at port 443 and 22 respectively (requirement 2). To do that, we ask which packets reach the web_server and ssh_server hosts:
The operator in constrains a variable to be equal or inside one of the intervals in the list, hence the notation is a syntactic sugar for dnatIp = web_server or dnatIp = ssh_server. The variable dnatIp represents the destination address of the packet after a DNAT translation. The result in Table 1b confirms that requirement 2 is satisfied: indeed, the servers are reachable from any host connecting to the firewall on ports 443 and 22, only.
The next query checks the requirements 3 and 4 together:
Intuitively, the query asks for the new connections that are allowed from an internal source to an external destination. The answer in Table 1c shows that both the requirements are met. Indeed, the notation * \ {internal} represents all destination addresses except those in the internal subnet. Finally, by checking requirement 5 with the query
we obtain the output of Table 1d showing that the firewall can reach any host.
We can thus conclude that the configuration in Fig. 3 is correct with respect to the requirements.
Noncompliant configuration in ipfw
Figure 4 implements the example policy in ipfw. On purpose, we introduce subtle but realistic differences with respect to that of iptables and we show how FWS spots them in a clear and concise way.
The first command declares NAT rules, named nat 1, that will be activated by the following rules. Note that the next commands have numbers (after the add keyword) that can be used for jumps, as we will see below. We refer to those numbers in the description. Command 0001 accepts all the packets that belong to already established connections (command check-state). As for iptables this is important to ensure functionality of connection-oriented protocols. Command 0010 enables traffic between internal networks (requirement 1). Command 0100 applies nat 1 to the packets received via the interface ext, implementing the DNAT of requirement 2. The actual connections to hosts 10.0.1.15 (web_server) and 10.0.2.15 (ssh_server), respectively on ports 443 and 22, are enabled by the next commands 0200, 0201, 0300 and 0301. Notice that packets coming from those hosts are handled by jumping (command skipto 1000) to the last but one line, which applies nat 1, translating source address to 23.1.8.15 (ext_ip) (SNAT). Then, packets are accepted by command 1001. Next line (command 0500) implements the requirements 3 and 4 similarly to previous rules, i.e., by jumping to 1000 which enforces the SNAT on outgoing connections. Command keep-state is the counter-part of check-state: the connection is saved in the firewall state so that packets belonging to the same connection will be allowed through the firewall by rule 0001. Rule 0501 allows the firewall host to communicate to any host. Finally, command 0999 rejects any packet that does not match any previous rule, implementing a default deny policy.
Results of FWS when checking the ipfw configuration of Fig. 4
(a) Requirement 1
Source IP
Source Port
Destination IP
Destination Port
Protocol
State
lan0
*
lan1
*
*
NEW
lan1
*
lan0
*
*
NEW
(b) Requirement 2
Source IP
Source Port
Destination IP
Destination Port
DNAT IP
Protocol
State
* \ { lan0, lan1, loopback }
*
ext_ip
22
ssh_server
tcp
NEW
* \ { lan0, lan1, loopback }
*
ext_ip
443
web_server
tcp
NEW
(c) Requirements 3 and 4
Source IP
Source Port
SNAT IP
Destination IP
Destination Port
Protocol
State
ssh_server
22
ext_ip
* \ {internal}
*
tcp
NEW
internal
*
ext_ip
* \ {internal}
443, 80
tcp
NEW
web_server
443
ext_ip
* \ {internal}
*
tcp
NEW
(a) Requirement 5
Source IP
Source Port
Destination IP
Destination Port
Protocol
State
ext_ip
*
*
*
*
NEW
Decompiling and analyzing the configuration
We now use FWS to check if the configuration of Fig. 4 meets the requirements 1–5 of Section 3.1. We pose exactly the same queries done for iptables in Section 3.2. In fact, one of the advantages of our approach is that the analysis is fully independent of the particular firewall system and of the language analyzed.
Queries for the requirements 1 and 5 give exactly the same results we got for iptables (cf. Tables 2a, 2d and 1a, 1d). Instead, we get an interesting difference while considering requirement 2. For the ipfw configuration we obtain that the web_server and ssh_server hosts cannot be reached by the internal network and by the firewall host via DNAT (cf. Table 2b). This is because in the ipfw configuration, rule 0100 is defined for interface ext, i.e., for packets received from the Internet. In fact, requirement 2 could be interpreted in this stricter way by a system administrator, as hosts web_server and ssh_server are anyway reachable from internal hosts even without DNAT. FWS spots this subtle difference in the two configurations. To make the ipfw configuration behave as the iptables one (for requirement 2), it is enough to remove recv ext from rule 0100.
In checking the requirements 3 and 4, FWS reports that the hosts web_server and ssh_server can start new connections from source ports 443 and 22, respectively, to any other host. This is due to rules 0201 and 0301 that enable the two hosts to answer connections done through the DNAT and provides an alternative way to make connection-oriented protocols work without exploiting the check-state command. In principle, this should be considered non-compliant with requirement 3 as new connections from 443 and 22 from the two hosts will access any port and not just 80 and 443, as requested. Again, FWS spots this difference in the policy. This error can be rectified by removing rules 0201 and 0301 and by adding the keep-state keyword to the rules 0200 and 0300.
Interestingly, FWS can compute the equivalence of configurations written for different firewall systems/languages. In this particular case, FWS outputs that the fixed ipfw configuration and the iptables one are equivalent, as far as the five requirements are in order.
Figure 5 implements the example policy in Cisco IOS. As done in Section 3.3, we show that naively porting the iptables introduces subtle differences that violate the requirements, spotted by FWS.
Configuring the firewall with Cisco IOS
The first part of the configuration defines the network interfaces. Address translation is defined in terms of inside and outside IPs, belonging to internal or external networks. In particular, ext (GigabitEthernet1) is declared as nat outside while lan0 (GigabitEthernet2) and lan1 (GigabitEthernet3) are defined as nat inside. In order to implement the firewall rules, we associate ACLs 120 and 130 respectively with outgoing (out) and incoming (in) packets of ext interface. The ACLs, defined at the bottom of the configuration, only accept outgoing packets to ports 80 and 443 (requirement 3) and incoming packets to ports 22 and 443 (requirement 2), plus established connections. Note that the IP used in the ACLs as source/destination is the external firewall IP 23.1.8.15, because of addresses translations. Destination NAT (requirement 2) is defined through two rules that map ports 22 and 443 to the two hosts 10.0.2.15 and 10.0.1.15, respectively. These rules are bidirectional and let replies from these hosts go through without the need of inspecting the connection state. Source NAT (requirement 4) is defined using the overload keyword that maps a whole subnetwork into a single source address. In this case, the translation uses the connection state to translate back to the correct IP. The source NAT is only applied to packets matching the rule in the ACL 10, i.e., packets originated by the subnet 10.0.0.0/16. Since we assign ACLs to no other interfaces, traffic through internal networks is accepted by default (requirement 1).
Decompiling and analyzing the configuration
Results of FWS when checking the Cisco IOS configuration of Fig. 5
(a) Requirement 1
Source IP
Source Port
Destination IP
Destination Port
Protocol
State
lan0
*
lan1
*
*
NEW
lan1
*
lan0
*
*
NEW
(b) Requirement 2
Source IP
Source Port
Destination IP
Destination Port
DNAT IP
Protocol
State
* \ { lan0, lan1, ext_ip }
*
ext_ip
22
ssh_server
tcp
NEW
* \ { lan0, lan1, ext_ip }
*
ext_ip
443
web_server
tcp
NEW
(c) Requirements 3 and 4
Source IP
Source Port
SNAT IP
Destination IP
Destination Port
Protocol
State
lan0, lan1
*
ext_ip
* \ {internal}
443, 80
tcp
NEW
(d) Requirement 5
Source IP
Source Port
Destination IP
Destination Port
Protocol
State
ext_ip
*
*
443, 80
tcp
NEW
ext_ip
*
lan0, lan1
*
*
NEW
(e) Requirement 5 for the fixed configuration
Source IP
Source Port
Destination IP
Destination Port
Protocol
State
ext_ip
*
*
*
*
NEW
As we did for ipfw, we use FWS to check if the configuration of Fig. 5 meets the requirements 1–5 of Section 3.1.
Queries for the requirements 1, 3 and 4 give exactly the same results obtained for iptables (cf. Tables 3a, 3c and 1a, 1c). Similarly to ipfw, for requirement 2, we get that web_server and ssh_server hosts cannot be reached by the internal network (and by the firewall) via DNAT (cf. Table 3b). This is consistent with the fact that DNAT only applies from outside to inside IPs. Access to local servers for Cisco IOS networks is usually achieved through a suitable DNS configuration, as often discussed in official support forums. The most important difference concerns requirement 5: since we are filtering on the ext interface we cannot distinguish packets coming from internal networks, going through the source NAT, from packets originated by the firewall. They both have the same source IP when they reach the ext out interface. As a consequence requirement 5 cannot be satisfied: the firewall will be subject to the same filters as the internal networks.
In order to fix this issue we reconfigure the firewall so as to place output filters in the internal interfaces. In particular we disable ACL 120 in ext out and enable the following ACL 140 in both lan0 in and lan1 in:
By ACL 140 we enforce the filters on destination ports 80 and 443 (requirement 3) and enable internal traffic (requirement 1), together with established connections. Running again FWS we get that requirement 5 is satisfied by the new configuration (cf. Table 3e).
Checking for non-determinism
Some languages permit writing rules that translate the addresses of a packet into values not uniquely specified. For example, the NAT rules in iptables can specify a range of addresses within which a specific one is taken at run time, and the manual does not precisely state which value is chosen. We empirically observed that round robin is commonly used to redirect connection requests to a pool of duplicated servers so implementing a rough load balancing mechanism.
Since the actions of the firewall depend on the field values of the packet, such unspecified choices may unpredictably influence the effect of the subsequent rules. It may even happen that a packet is accepted if one value in the permitted range is used in the translation, or dropped if another admissible value is used instead. In other words, given two completely identical connection requests, received while the system is in the same state, the firewall may misbehave, by refusing the first and accepting the second. Regardless of other legitimate usages, this kind of non-determinism is arguably a misbehaviour.
Now we show how FWS can detect non-determinism of policies. Suppose that the web_server host has a slow backend so we replicate it for ensuring an acceptable quality of service. The new servers are assigned IP addresses 10.0.1.16 and 10.0.1.17. In this scenario iptables can also be used for load balancing at the connection level, by specifying a range of IP addresses in the DNAT target:
This rule redirects new connections to a different server in the range following a round-robin discipline. The packets after the DNAT need to be explicitly accepted in the FORWARD chain:
Suppose now that the host 10.0.1.16 is isolated from the network for maintenance or to mitigate a breach. A naive solution is dropping every connection directed to the server:
However, this rule introduces non-determinism in the firewall behavior: a connection to ext_ip on port 443 is dropped if the DNAT target is 10.0.1.16, while it is accepted if another server is selected. Our tool identifies these situations and synthesizes the affected packets. The following query performs this check, and the output in Table 4 confirms that the examined configuration is non-deterministic:
A packet dropped by a non-deterministic configuration
Source IP
Source Port
Destination IP
Destination Port
DNAT IP
Protocol
State
* \ {internal}
*
ext_ip
443
10.0.1.16
tcp
NEW
Decompiling a configuration and compiling a declarative specification
FWS editing and compiling a table.
The synthesis procedure returns a table consisting of a complete declarative description of the behavior of the firewall. In this way, the administrator can inspect the semantics of the configuration in a visual readable way. In addition, FWS can compile this description into any of the supported languages, for porting (when source and target languages are different) or refactoring (when source and target languages coincide).
For example, for porting the iptables policy presented in Section 3.2 to ipfw, the administrator (1) selects the compiler view of FWS, (2) loads the iptables policy, (3) synthesizes its declarative specification, and, finally, (4) compiles the table to ipfw. As shown in Fig. 6, the compiler view is composed by a single panel that shows the semantics of the firewall, plus a recap of the aliases. Once one of the supported language is selected, the compile button generates a proper policy, complying with the expected semantics.
Before compiling, the administrator can act on the expected semantics by editing the declarative specification in the table obtained through decompilation. Every field of the rows is editable and new rows can be added in order to change the declarative semantics of the firewall. In this way, the configuration can be repaired or modified to comply with new specifications.
Maintaining firewall configurations
In this section, we show how FWS can be used to perform maintenance of the iptables policy presented in Section 3.2.
Suppose that the company has added a new machine to the lan0 subnet, which has been assigned the IP address 10.0.1.22. Differently from the other hosts of the network, we want to allow Internet access (with SNAT) to this machine only over HTTPS. The other requirements on the traffic should be preserved. We can proceed at two different levels: at the low level by editing the iptables policy in hand, or at the high level by operating directly on the table. Maintaining a firewall configuration by editing the table is easier, faster and safer. We recommend it rather than maintaining the source configuration by hand. Given the intricacy of traditional firewall configuration languages, they are viewed as machine code in the approach we advocate. Their management should be performed by administrators through dedicated tools. Only specialized technicians may be interested in interacting directly with the low level for performing specific tasks.
Maintaining by editing the configuration
To edit the iptables policy directly, we add the following rule to the FORWARD chain, which drops connections to port 80 from host 10.0.1.22:
However, we must be careful about the position where to place this rule in order to fulfill the desired requirement and avoid to unintentionally block legal traffic. We discuss below three cases and show how FWS helps in determining the correct position.
The first case is when we place the new rule at the end of the FORWARD chain, which has no effect: the policy equivalence analysis of FWS reports that the new policy is equivalent to the previous version. To understand the reason why, we use the related rules analysis to detect which rules are relevant for processing HTTP packets. The output of the tool only includes the following filtering rule from the FORWARD chain:
The above rule accepts all the HTTP traffic from the internal networks and is evaluated before the new DROP rule. Hence, our new rule should be placed before this one.
The second case is when we insert the new rule before those of the other requirements, e.g., after the rules that allow packets of incoming connections. Now, FWS reports that the policy is not equivalent to the previous one. We check the impact of our changes by running the policy difference analysis projected over the HTTP traffic:
The answer to the query is shown in Table 5a. The first column is + or - for lines that appear in the synthesis or disappear after the updates, respectively. We see that host 10.0.1.22 is now unable to connect to the Internet, as desired (second table of Table 5a). However, our update also prevents communications over HTTP with other machines on the internal networks, thus violating requirement 1 (first table of Table 5a).
Maintenance of the iptables configuration. The rules in lines with a + are added, while those with a − are removed
(a) Policy differences after the wrong update
+/-
Source IP
Source Port
Destination IP
Destination Port
Protocol
State
+
internal \ {10.0.1.22}
*
internal
80
tcp
NEW
-
internal
*
internal
80
tcp
NEW
+/-
Source IP
Source Port
SNAT IP
Destination IP
Destination Port
Protocol
State
+
internal \ {10.0.1.22}
*
ext_ip
* \ {internal}
80
tcp
NEW
-
internal
*
ext_ip
* \ {internal}
80
tcp
NEW
(b) Policy differences after the correct update
+/-
Source IP
Source Port
SNAT IP
Destination IP
Destination Port
Protocol
State
+
internal \ {10.0.1.22}
*
ext_ip
* \ {internal}
80
tcp
NEW
-
internal
*
ext_ip
* \ {internal}
80
tcp
NEW
The correct place where to add the new rule is between the rule for requirement 1 and those for requirement 3. In this way we only allow HTTP traffic from 10.0.1.22 to the internal networks. If we repeat the check for policy difference, we see that now the only difference is just in the HTTP traffic towards the Internet, as desired (cf. Table 5b).
Maintaining by editing the table
Tabular representation of the semantics of the iptables configuration, before and after editing
(a) Before editing
Source IP
Source Port
SNAT IP
Destination IP
Destination Port
Protocol
State
internal
*
ext_ip
* \ {internal}
443, 80
tcp
NEW
(b) After editing
Source IP
Source Port
SNAT IP
Destination IP
Destination Port
Protocol
State
internal \ {10.0.1.22}
*
ext_ip
* \ {internal}
80
tcp
NEW
internal
*
ext_ip
* \ {internal}
443
tcp
NEW
To edit the table, we just ask FWS to synthesize the policy, hence obtaining a tabular description of the behavior of the firewall (see Fig. 6). Then, we find the row responsible for managing the HTTP traffic from 10.0.1.22 (see Table 6a). Finally, we edit the table by splitting the row in two parts. One for the HTTPS traffic (destination port 443) which preserves all the other values, and one for the HTTP traffic (destination port 80) in which the value 10.0.1.22 is removed from the input IP addresses (see Table 6b).
After the editing, the declarative specification can be compiled back to iptables (or any of the other supported languages).
The intermediate firewall configuration language IFCL
Our intermediate firewall configuration language IFCL is parametric with respect to the notion of state and the steps performed to elaborate packets. For generality, we do not detail the format of network packets. In the following we only use and to denote the source and destination addresses of a given packet p; additionally, returns the tag m associated with p, assuming that the empty tag ∙ identifies untagged packets. An address a consists of an IP address and possibly a port . An address range n is a pair consisting of a set of IP addresses and a set of ports, denoted : . An address a is in the range n (written ) if and when is defined, e.g., for TCP and UDP packets.
To record the modifications on packets, we write to denote a packet identical to p except for the destination address which becomes equal to a. Similarly, denotes a packet p where the source address is a and denotes p with a modified tag m.
Here, we consider stateful firewalls that keep track of the state s of network connections and use this information to process a packet. An existing network connection is described by several protocol-specific properties, e.g., source and destination addresses or ports, and by the translations to apply. In this way, filtering and translation decisions are not only based on administrator-defined rules, but also on the information built by previous packets belonging to the same connection. We omit a precise definition of a state, but we assume that it tracks at least the source and destination ranges, NAT operations and whether a connection is established or not. When receiving a packet p one checks whether it matches the state s or not. We left unspecified the match between a packet and the state because it depends on the actual shape of the state. When the match succeeds, we write , where α describes the actions to be carried out on p; otherwise we write .
A firewall rule is made of two parts: a predicate ϕ expressing criteria over packets, and an action t, called target, defining the destiny of matching packets. Just as in real languages, predicates are formulas in a propositional logic that mainly express identity or inclusion between ranges of IP addresses or ports, as well as the protocol in usage and the current state of the firewall. Herafter, we shall write whenever the fields of the packet p satisfy the constraints expressed by the proposition ϕ. Here we only consider a core set of actions included in most of the real firewalls. These actions not only determine whether or not a packet passes across the firewall, but they also control the flow in which the rules are applied. They are:
The targets and implement a procedure-like behavior; is similar to unconditional jumps. We only have the action and not a REJECT, because for our analysis there is no need of keeping rejected and dropped packets apart. In the action and are address ranges used to translate the destination and source address of a packet, respectively; in the following we use the symbol ⋆ to denote an identity translation, e.g., means that the address is translated according to n, whereas the port is kept unchanged. The MARK action marks a packet with a tag m. The argument of the action denotes the fields of the packets that are rewritten according to the information from the state. More precisely, → rewrites the destination address, ← the source one and ↔ both.
(Firewall rule).
A firewall rule r is a pair where ϕ is a logical formula over a packet, and t is the target action of the rule.
A packet p matches a rule r with target t whenever ϕ holds.
(Rule match).
Given a rule we say that p matches r with target t, denoted , if and ony if . We write when p does not match r.
We now define how a packet is processed given a possibly empty list of rules (denoted with ϵ), called ruleset. Similarly to real implementations of firewalls, we inspect the rules in the list, one after the other, until we find a matching one, which establishes the target of the packet. For sanity, we assume that no GOTO(R) and CALL(R) occur in the ruleset R, so avoiding self-loops. We also assume that rulesets have a default target denoted by , which accepts or drops according to the system administrator’s decision.
(Ruleset match).
Given a ruleset , we say that p matches the i-th rule with target t, denoted , if and only if
We also write if p matches no rules in R, formally if .
In our model we do not explicitly specify the steps performed by the kernel of the operating system to process a single packet passing through the host. We represent this algorithm through a control diagram, i.e., a graph where nodes represent different processing steps and the arcs determine the sequence of steps. The arcs are labeled with a predicate describing the requirements a packet has to meet in order to pass to the next processing phase. Therefore, they are not finite state automata. Our control diagrams are deterministic, i.e., every pair of arcs leaving the same node has mutually exclusive predicates. For generality, we let these predicates abstract, since they depend on the specific firewall.
(Control diagram).
Let Ψ be a set of predicates over packets. A control diagram is a tuple , where
Q is the set of nodes;
is the set of arcs with no self-loops and such that whenever , and then ;
, are special nodes denoting the start and the end of elaboration.
The firewall filters and possibly translates a given packet by traversing a control diagram accordingly to the following transition function.
(Transition function).
Let be a control diagram and let p be a packet. The transition function is defined as
A firewall in IFCL is defined as follows.
(Firewall).
A firewall is a triple , where is a control diagram; ρ is a set of rulesets; and is the correspondence mapping from the nodes of to the actual rulesets.
Decompiling real languages into IFCL
Here we encode the firewalls system considered so far as triples of our framework (stage 1). Notably, the encoding provides a formal semantics for those systems defined in terms of IFCL (see Section 4.2).
Modelling iptables. Let be the set of local addresses of a host, i.e., those associated with its network interface; and let and be the predicates over packets defined as follows:
Figure 7a shows the control diagram of iptables, where unlabeled arcs carry the label “.” It also implicitly defines the transition function according to Definition 5. In iptables there are twelve built-in chains, each of which correspond to a single ruleset. So we define the set of primitive rulesets as the one made of , , , , , , , , , , and , where the superscript represents the chain name and the subscript the table name. Needless to say, the set contains the user-defined chains.
The mapping function is defined as follows:
where R is an empty ruleset with as default policy.
Finally, note that the action implements the built in target .
Modelling ipfw. The control diagram of ipfw, displayed in Fig. 7b, is simpler than the one of iptables. The node represents the procedure executed when an IP packet reaches the host from the net. Dually, is for when the packet leaves the host. The predicates , are defined as for iptables and check whether the packet has been generated by or is addressed to the host itself, respectively. The transition function δ easily follows from , according to Definition 5.
Control diagrams of the four firewall languages.
We present the construction of the rulesets associated with the node . Let be the unique ruleset of ipfw, where are numeric identifiers associated with the rules, and the last rule encodes the default policy set by the user. The idea is to generate k different rulesets , one for each rule in R. If the rule contains the keyword out, i.e., the rule is not considered when the packet enters the firewall, we let . Otherwise, we define , where the translation is defined by cases below:
The construction of the rulesets for the node is similar, but in this case the rules containing the keyword in are ignored. The mapping function c returns for , for , and empty ruleset with as default policy for and . These rulesets form the component .
Modelling pf. Also pf has a single ruleset and, differently from above, the rule applied to a packet is the last matching one, except in the case of the so-called quick rules: as soon as one of these matches the packet, its action is applied and the remaining part of the ruleset is skipped.
Figure 7c shows the control diagram for pf. The nodes and represent the procedure executed when an IP packet reaches the host from the net. Dually, and are for when the packet leaves the host. The predicates and are those defined for iptables. Given the pf ruleset we include the following rulesets in :
contains the rule as the first one, followed by all the rules rdr of ;
contains the rule as the first one, followed by all the rules nat of ;
contains the rule followed by all the quick filtering rules of without modifier out, and finally the rule ;
contains all the no quick filtering rules of without modifier out, in reverse order;
contains the rule followed by all the quick filtering rules of without modifier in, and as last rule;
includes all the no quick filtering rules of without modifier in in reverse order.
Given the empty ruleset R with ACCEPT as default policy, the mapping function is:
Modelling Cisco IOS. The control diagram of Cisco IOS is displayed in Fig. 7d. The predicate is as for iptables and checks whether the packet has been generated by the host. In this case, it only goes through the output filters. Each device interface I is associated with the two rulesets, or ACLs, and , applied to incoming and outgoing packets with DROP as default policy. If there is no ACL for direction d (in or out) we let be empty, with ACCEPT as default policy. Let be the firewall interfaces, with representing the interface corresponding to the default gateway. We let
where is the set of IP addresses of the interface I. Intuitively, / apply the ACL of the interface that corresponds to the packet source/destination IP address. We do not consider here the case of overlapping networks on different interfaces, meaning that are all disjoint sets. When no match is found the default gateway interface is chosen.
We let contain the rule as the first one, followed by all the NAT rules that translate outside addresses into inside ones. Dually, we let contain the rule as the first one, followed by all the NAT rules that translate inside addresses into outside ones. When NAT is bidirectional (as the DNAT in the example of Fig. 5) the corresponding CHECK-STATE is omitted, since a single NAT rule is modeled as two complementary (SNAT/DNAT) IFCL rules. The mapping function is defined as follows, where R is an empty ruleset with as default policy:
Semantics
Now, we formally define the semantics of IFCL through two transition systems operating in a master-slave fashion. The master has a labeled transition relation of the form . The intuition is that the state s of a firewall changes to when a new packet p reaches the host and becomes .
The configurations of the slave transition system are triples where:
is a control diagram node;
s is the state of the firewall;
p is the packet.
A transition describes how a firewall in a state s deals with a packet p and possibly transforms it in , according to the control diagram . Recall that the state records established connections and other kinds of information that are updated after the transition.
In the slave transition relation, we use the following predicate, which describes an algorithm that runs a ruleset R on a packet p in the state s
This predicate searches for a rule in R matching the packet p through . If it finds a match with target t, t is applied to p to obtain the packet resulting from possible transformations.
Recall that actions , and are similar to procedure calls, returns and jumps in imperative programming languages. To correctly deal with them, our predicate uses a stack S to implement a behavior similar to the one of procedure calls. We will denote with ϵ the empty stack and with · the concatenation of elements on the stack. This stack is also used to detect and prevent loops in ruleset invocation, as it is the case in real firewalls.
In the stack S we overline a ruleset R to indicate that it was pushed by a and it has to be skipped when returning. For that, we use the following function in the semantics of the :
If the top of S is overlined, behaves as a standard pop operation; otherwise it extracts the first non-overlined ruleset. When S is empty, we assume that returns ϵ to signal the error.
Furthermore, in the definition of the notation indicates the ruleset () resulting from dropping the first rules from the given ruleset .
The predicate
We also assume as given the function establ that, taken an action α from the state, a packet p and the fields to rewrite, returns a possibly changed packet , e.g., in case of an established connection. Also establ depends on the specific firewall we are modeling, and so it is left unspecified.
Finally, we assume as given a function that returns the packet p translated under the corresponding NAT operation in the state s. The argument is used to modify the destination range of p, i.e., destination NAT (DNAT), while is used to modify the source range, i.e., source NAT (DNAT). Recall that a range of the form is interpreted as the identity translation, whereas one of the form modifies only the address. Also this function is left abstract.
Table 7 shows the rules defining . The first inference rule deals with the case when the packet p matches a rule with target or ; in this case the ruleset execution stops returning the found action and leaving p unmodified. When a packet p matches a rule with action , we query the state s: if p belongs to an established connection, we return and , obtained rewriting p. Otherwise, p is matched against the remaining rules in the ruleset. When a packet matches a rule, we return and the packet resulting by the invocation of the function . There are two cases when a packet p matches a . If the ruleset is not already in the stack, we push the current ruleset R onto the stack overlined to record that this ruleset dictated a . Otherwise, is in the stack, we detect the loop and discard p. The case when a packet p matches a rule with action is similar, except that the ruleset pushed on the stack is not overlined. When p matches a rule with action , we pop the stack and match p against the top of the stack. Finally, when no rule matches, an implicit return occurs: we continue from the top of the stack, if non empty. The MARK rule simply changes the tag of the matching packet to the value m. If none of the above applies, we return the default action of the current ruleset.
We now define the slave transition relation as follows.
The rule describes how we process the packet p when the firewall is in state s and performs the step represented by the node q. We match p against the ruleset R associated with q and if p is accepted as , we continue considering the next step of the firewall execution represented by the node .
Finally, we define the master transition relation that transforms states and packets as follows (as usual, below stands for the transitive closure of →):
This rule says that when the firewall is in the state s and receives a packet p, it elaborates p starting from the initial node of its control diagram. If this elaboration succeeds, i.e., if the node is reached, p is accepted as , and we update the state s by storing information about p, its translation and the connection they belong to, by the function ⊎, left unspecified for the sake of generality.
Rulesets
Ruleset
Ruleset
Ruleset
(, DROP)
(, ACCEPT)
(, ACCEPT)
(, CALL())
(, CALL())
(, RETURN)
(, ACCEPT)
(, DROP)
(, DROP)
Suppose to have the rulesets, defined in Table 8 and that the condition holds for a packet p. Then, the semantic rules (a), (b) and (c) are applied in order:
Semantics validation
We empirically validated the semantics inherited from IFCL by the firewall systems we have considered in Section 4.1. The validation process is composed of three main phases.
We first inferred the expected behavior of the various processing steps of the real firewall system in hand from its documentation, and collected a set of configurations playing the role of test cases T. We then run in a simulated environment, built on some virtual machines. Also, we synthesize the abstract specification of through FWS. Furthermore, we generated synthetic network traffic to make sure that we cover all the test cases in T. Finally, we compare the logs of against the results obtained by FWS, so as to check the correspondence between the actual behavior of and the one dictated by the semantics it inherits from IFCL.
We focused on corner cases that are not clearly explained in the official documentation of , or not even taken into account. Feedback from system administrators has been particularly helpful in detecting these cases. Often the corner cases concern local packets, i.e., packets generated by the firewall and directed to a local address of the firewall itself, in combination with NAT rules.
As an example, consider iptables. A local packet first enters the Output chain, being generated by the host, and then the PostRouting chain. Instead of leaving the firewall, it enters the PreRouting and Input chains, being also a packet directed to a local address. In these two chains, the processing of this kind of packets differs from the one of a generic packet coming from outside . Indeed a local packet does not traverse the nat table in the PreRouting and Input chains, skipping the NAT processing. This behavior is correctly encoded in the control diagram of Fig. 7a. The validation phase sketched above helped us in discovering this subtle behavior, which was not considered in the preliminary version of the iptables control diagram [6].
Synthesizing configurations
We now extract the semantics of a firewall written in our intermediate language by transforming it in a declarative, logical form that preserves its behavior (stage 2). Of course this transformation is independent of the firewall language in hand, and consists of the following three steps:
generate an unfolded firewall with a single ruleset for each node of the control diagram;
transform the unfolded firewall in a pair of first-order formulas, one for the accepted and one for the dropped packets;
determine the models for the obtained formulas, using a SAT solver.
The correctness of stage 2 follows from Theorem 1, which guarantees that the unfolded firewall is semantically equivalent to the original one, and from Theorem 2, which ensures that the derived formula characterizes exactly the accepted/dropped packets and their translations.
Unfolding rulesets
Our intermediate language deals with involved control flows, by using the targets , and (see Example 1). The following unfolding operation rewrites a ruleset into an equivalent one with no such control flow rules.
Hereafter, let be a non empty ruleset consisting of a rule r followed by a possibly empty ruleset R; and let be the concatenation of and .
The unfolding of a ruleset R is defined as follows:
whereis ϕ with its sub-predicate on the current tag replaced by its evaluation on m.
The auxiliary procedure recursively inspects the ruleset R. The formula f accumulates conjuncts of the predicate ; the set I stores the rulesets traversed by the procedure and helps detecting loops; m records the tag associated with the packets that satisfy f. If a rule neither affects the control flow nor it is a , we just substitute the conjunction for ϕ, and continue to analyze the rest of the ruleset with the recursive call .
In the case of a return rule we generate no new rule, and we continue to recursively analyze the rest of the ruleset, by updating f with the negation of . For the rule we have two cases: if the callee ruleset is not in I, we replace the rule with the unfolding of with as predicate, and append to the traversed rulesets; if is already in I, i.e., we have a loop, we replace the rule with a , with as predicate; in both cases, we continue unfolding the rest of the ruleset. We deal with the rule as in the previous one, except that the rest of the ruleset has as predicate. Finally, the rule originates two lists. The first is for the packets satisfying and thus the rule becomes and its tag . The other list is for packets not satisfying , so never applies and the tag m is left unchanged.
Back to Example 1, unfolding the ruleset gives the following rules:
We just illustrate the first three steps:
Note that the packet p is accepted also by the unfolded firewall, provided that holds.
An unfolded firewall is obtained by repeatedly rewriting the rulesets associated with the nodes of its control diagram, using the procedure above. Formally:
(Unfolded firewall).
Given a firewall , its unfolded version is where and .
We now prove that a firewall and its unfolded version are semantically equivalent, i.e., they perform the same action over a given packet p in a state s, and reach the same state . Formally:
(Correctness of unfolding).
Letbe a firewall andits unfolding. Letbe a step of the master transition system performed by the firewall. Then
Logical characterization of firewalls
We construct two logical predicates that characterize the packets accepted and those dropped by an unfolded ruleset, together with the relevant translations.
To deal with NAT, we define an auxiliary function that computes the set of packets resulting from all possible translations of a given packet p. The parameter specifies if the translation applies to source, destination or both addresses, respectively, similarly to .
Furthermore, we model the default policy of a ruleset R with the predicate , true when the policy is , false otherwise.
Given an unfolded ruleset R, we build two predicates: that holds when the packet p is accepted as by R, and when p is instead dropped. Their definition in Table 9 induces on the rules in R. Recall that formulas ϕ also predicate on the firewall state, e.g., checking if the packet belongs to an established connection. As a sanity check, we assume that this is always the case when the target is . We briefly comment on the definition of . The empty ruleset applies the default policy and does not transform the packet, reflected by the constraint . The rule considers two cases: when holds and the packet is accepted as it is; when instead holds, p is accepted as only if the continuation R accepts it. The rule accepts p only if the continuation does and is false. The rule works similarly to the rule , expect that, when holds, and it gives by applying to p the NAT translations . Finally, works similarly to the rule NAT that applies all possible translations of kind X (written as ). Intuitively, we over-approximate the state by considering any possible translations, because we abstract away from the actual established connections. At run-time, only the connections corresponding to the actual state will be possible. The rule works similarly to the rule NAT, but when holds it requires that the continuation accepts p tagged by m as . Apart from being monadic, the definition of follows the same schema.
Translation of rulesets into the logical predicates for accepted and for dropped packets
if
if
if
if
if
if
if
if
if
if
The predicates and of the ruleset in Example 2 when is
Note that if holds then the formula trivially holds and therefore the formula accepts the packet as the semantics does.
Also, consider the case in which , , , , hold for a packet p, while all the other predicates do not. Then, p is accepted as it is: the rule is not evaluated since holds and the RETURN is performed (cf. Example 1). Indeed, the predicate evaluates to the following, where we abbreviate true with T and false with F:
Instead, if holds too, the packet is rejected as expected:
Let be the ruleset R, where maps to a set of IP addresses. Now, where is any, , and . Therefore, R accepts p as , but it drops itself, because it belongs to .
The predicate in Table 9 is semantically correct, because if a packet p is accepted by a ruleset R as , then holds, and vice versa. Formally:
Given a ruleset R we have that
; and
We eventually define the predicates associated with a whole firewall as follows.
Let be a firewall with control diagram . The predicates and associated with are defined as follows:
for all such that , and where and are the predicates constructed from the ruleset associated with the node q of the control diagram.
Intuitively, in the final node we accept p as it is, and of course we drop nothing. In all the other nodes, p is accepted as if and only if there is a path starting from p in the control diagram that obtains through intermediate transformations. More precisely, for accepting we look for an intermediate packet , provided that (i) p is accepted as by the ruleset of node q; (ii) satisfies one of the predicates ψ labeling the branches of the control diagram; and (iii) is accepted as in the reached node . Instead, a packet is dropped directly in the node q or in one of its successors, possibly because it has been translated to via NAT. Note that we ignore paths with loops, because firewalls have mechanisms to detect and discard a packet when its elaboration loops. To this aim, our predicate uses the set I for recording the nodes already traversed.
As discussed in Section 3.5, configurations can behave non-deterministically, because some rules may unpredictably translate a packet field into a set of possible values, e.g., when a NAT translates an address to a value within an interval. Such a non-deterministic choice may influence the next actions over the packet and also the path it follows in the control diagram. We already argued that this form of non-determinism may be useful as a rough mechanism of load balancing among copies of servers, when it is only limited to the field values. However, it may happen that the choice of one or another value leads the firewall to non-deterministically accept or drop a given packet. Using and , we can recognize such misbehaving configurations.
We have seen an example of a non-deterministic configuration in Section 3.5, and below we present it again in a simplified form.
Consider the packets p and and the ruleset R of Example 4; let consist of ; and assume that the firewall inspects R before . The ruleset R accepts p either as or as with . Consequently, we have that both and are true, since the first rule of accepts and its second one drops .
We conclude this section by establishing the correspondence between the logical formulation and the operational semantics of a firewall. Formally, accepts the packet p as if the predicate is satisfied, and vice versa:
(Correctness of the logical characterization).
Given a firewalland its corresponding predicate, for all packets p we have thatholds and
Recall that the logical characterization abstracts away the notion of state, and thus holds if and only if there exists a state s in which p is accepted as . In particular, if the predicate holds for a packet p that belongs to an established connection, p will be accepted only if the relevant state is reached at runtime. This is the usual interpretation of firewall rules for established connections.
Synthesis algorithm
Here, we present the module of FWS [18] that synthesizes the declarative specification of a firewall configuration written in IFCL. The core of this module takes as input the predicates and and computes all their models. To do that, we adopt the algorithm of [26], which is based on the Z3 solver [49], and therefore we inherit soundness and completeness. In particular, our tool uses their multi-cubes representation to succinctly enumerate all the packets accepted and dropped by the firewall. From these multi-cubes our tool builds a tabular representation of the firewall containing only ACCEPT and NAT rules, with no overlapping rows.
Encoding in Z3
We model packets as tuples of Z3 bit-vector variables of appropriate size (srcIP, srcPort, dstIP, dstPort, srcMac, dstMac, protocol, state)
that represent source and destination IPs and ports, source and destination MAC addresses, the protocol and the packet state. Firewall predicates are expressed as logical formulas on those packet variables. For example,
selects packets with destination 10.0.2.15 and port 22. We write as a shortcut for equating with the numerical representation of the IP address 10.0.2.15. Intervals are encoded with two ⩽ constraints.
In order to succinctly enumerate packets, a multi-cube maps each packet variable v to a union of disjoint intervals to which the value of v belongs. For instance, the solutions of the formula
are expressed by the following multi-cube:
For each formula over bit-vector variables, we compute the satisfying multi-cubes using Algorithm 1 of [26]. Intuitively, each iteration of the while loop selects an assignment of variables that is not covered by any of the existing multi-cubes. First the algorithm tries to extend the existing multi-cubes with the values in ; next, if the formula is still satisfiable, a new multi-cube is created.
During the extension/creation of multi-cubes, the algorithm performs an expansion step that extends as much as possible the intervals both downwards and upwards. This step uses a variant of the binary search algorithm to find the bounds of the maximal interval that satisfies the given formula.
The complexity of this step is linear in the size in bits of the variable under consideration. We refer the interested reader to [26] for additional details about the algorithm.
Dealing with NAT
Synthesis gets complicated with NAT, because it can introduce many variables in the formulas, representing intermediate address values for the packet during different processing phases. Some variables, however, are not touched by NAT and this needs to be represented in the predicates, as discussed in the following.
An intuitive solution is to impose equality constraints on variables that are not touched by NAT, but this approach may be inefficient. For instance, consider the formula : Algorithm 1 uses the SMT solver to find a solution, e.g., , and tries to expand the intervals associated to and , one after the other. However, increasing the interval of violates the equality constraint with . The results of the algorithm are thus 5 distinct multi-cubes, i.e., .
A careful treatment of equality introduces new variables only for the packet features that are modified by NAT rules and implicitly model equality constraints by sharing the same variable in the input and in the output packet. For instance, if a NAT rule modifies the destination address of the input packet p, the output packet is represented with the same variables of p with the exception of the destination address that uses a fresh variable. Since the introduction of these fresh variables is only required for the packets that are subject to NAT, we consider separate predicates covering the different cases: DNAT, SNAT and filtering. In DNAT and SNAT all variables will be the same except for the destination and source address, respectively. In filtering, all variables will coincide, as the input and the output packets are the same.
In principle, this separation could lead to an explosion of the number of predicates. However, when studying existing firewall systems, we found that the maximum number of packets to be considered is three: the input packet, the packet after applying destination NAT and the packet after applying source NAT. In fact, in real systems NAT is applied at most twice during packet processing. For this reason, the proposed approach works very well in practice.
For detecting non-determinism, it is convenient to keep track of the transformations applied to a dropped packet. For that, we extend the predicate to , where is the transformation of p actually dropped. The tool verifies as described above. If both conjuncts hold, the destiny of p is non-deterministic and we chose to only display in the results of the analysis.
Supported analyses
Besides synthesizing high-level specifications, the FWS tool can perform various interesting fully automated analyses, ranging from reachability analysis to verification of equivalence of policies. These analyses can be restricted to a subset of input/output packets satisfying a predicate ϕ constructed from the constraints provided to the tool. A list of analyses supported by FWS follows:
Reachability: is a certain address reachable or not from another one (possibly through NAT) according to the policy of the firewall ? Which IP addresses are reachable from machines hosted in a certain network subnet? To answer this type of questions, we ask the solver which are the pairs of input/output packets p, that satisfy the predicate . Since the analysis requires the synthesis of a subset of the firewall policy, the execution time depends both on the size of the policy and on the specified constraints on the packets. The time for getting an answer ranges from seconds (for specific constraints or policies of limited size) to a few minutes (for large policies and very loose constraints): we refer to Section 7 for an extensive analysis of the performance of FWS both when synthesizing an entire policy and when restricting the synthesis to subnetworks.
Implication: is the policy of the firewall implied by that of the firewall (for packets satisfying ϕ)? The answer is obtained by asking the solver whether there exists no pair of packets p, such that the predicate . This type of analysis is very efficient, as it only requires one invocation of the Z3 solver.
Equivalence: are the firewalls , equivalent (for packets satisfying ϕ)? To answer this question, it suffices checking whether implies and vice versa. This kind of analysis requires two invocations of Z3.
Differences: given two firewalls and , we can synthesize the corresponding predicates , and show the differences in the extracted multi-cubes. Similarly to the previous analyses, we can restrict our attention to a subset of input/output packets. This is the most time-consuming analysis, since it requires two distinct synthesis operations.
Related rules: here the goal is to identify which rules of a firewall affect the processing of the packets selected by ϕ. To do this, we remove the first rule from and check whether the obtained firewall is equivalent to using the previously described analysis: if this is the case, the rule is marked as unrelated and removed from , otherwise it is kept. We proceed analogously for all the rules of . The rules contained in at the end of this procedure are those that affect the processing of packets. The time complexity of the analysis is linear in the size of the policy.
Finding non-determinism: are there packets that may be either accepted or dropped, e.g., due to NAT on range of IP addresses? To answer this question we use Z3 to find packets p that can be either accepted as or dropped as , i.e., whether the predicate holds. The same considerations of the Reachability analysis apply when the execution time is of interest.
We conclude with an example on how to define the predicate ϕ from the constraints of a query, starting from the following query of Section 3.2 which performs a reachability analysis, where internal is an alias for an IP subnet.
The three constraints in the where clause select packets that are not part of an established connection (i.e., the state is NEW), come from the internal subnet and (possibly after destination NAT) the target IP address is not in the internal subnet. Additionally, the forward keyword restricts the analysis to packets that are neither generated nor directed to the firewall. Similarly to forward, the tool also supports the keywords input, output, loopback1
to conveniently select packets that are directed to, or produced by, or generated and processed internally by the firewall. These constraints are encoded in the predicate as follows:
The first three expressions simply correspond to the constraints specified in the where clause: in particular, notice that the constraint on the destination IP (possibly after some DNAT) is checked on the output packet , while the remaining two are checked against the input packet p. The last two expressions encode the constraints of the forward keyword (recall from Section 4.1 that is the set of IP addresses assigned to the various network interfaces of the firewall).
Generating target configurations
The last stage of our pipeline compiles the declarative specification extracted from a firewall policy in stage 2. We assume that the policy has been amended by the system administrator, if the analyses detected some unwanted behavior like non-determinism. We easily build the declarative firewall whose control diagram has a single node and a single ruleset containing the ACCEPT and NAT rules, each corresponding to a line of the declarative specification (recall that rows do not overlap, and thus they may appear in the ruleset in any order). Then, we compile into a firewall in the target language, and we prove the two equivalent. However, there are cases in which the compilation fails because the configuration is not expressible in the target system. Note that starting the generation from a declarative firewall makes the process easier because it has a single ruleset R with no duplicate and useless rules. Therefore, one just needs to split R over the nodes of the control diagram of the target language.
The resulting firewall automatically accepts all the packets that belong to established connections with the appropriate translations. This is not a limitation, since it is the default behavior of some real firewall systems (e.g., pf) and it is quite odd to drop packets, once the initial connection has been established. Moreover, this is consistent with the over-approximation on the firewall state done in Section 5.2.
Generation of the rulesets of the compiled firewall
Compiling a firewall specification
We first introduce an algorithm that computes the rulesets of the target firewall . Then, we associate these rulesets with the nodes of its control diagram.
Algorithm 2 inputs the ruleset derived from a synthesized specification and splits it in the basic rulesets , containing filtering, and , (with default policy) for DNAT and SNAT rules. This separation reflects what is done in all the real systems we have analyzed. Indeed, they can place NAT rules only in specific nodes of their control diagrams, e.g., in iptables, DNAT is allowed only in rulesets and , while SNAT only in and .
Algorithm 2 leaves the filtering rules unchanged (line 4). Also, it produces rules that assign different tags to packets that must be processed by different NAT rules (lines 6 and 7). Each NAT rule is split in a DNAT (line 8) and an SNAT (line 9), where the predicate ϕ becomes a check on the tag of the packet. Packets subject to NAT are accepted in while the others are dropped (line 10). We prepend to all rulesets making sure that packets are always marked, independently of which ruleset will be processed first (line 11). Recall that the empty tag ∙ identifies untagged packets.
Recall that the operator combines rulesets in sequence. Note that drops by default and shadows any ruleset appended to it. In practice, the only interesting rulesets are , , , , , where is the empty ruleset with default policy.
We now introduce the notion of compiled firewall.
(Compiled firewall).
Let be . A firewall with control diagram is a compiled firewall if
for all
every path π from to in the control diagram traverses a node such that
Intuitively, the above definition requires that only the rulesets in are associated with the nodes in the control diagram and that all paths pass at least one through a node with the filtering ruleset.
Now it is clear that policy porting occurs when the source and the target firewall systems differ and policy refactoring when they instead coincide.
Now we map the rulesets to the nodes of the control diagrams of the real systems presented in Section 4.1, except for Cisco IOS that is not yet supported.
For iptables we have:
while the remaining nodes get the empty ruleset .
For pf we have:
For ipfw we have:
Correctness of the compiled firewall
We start by showing that a compiled firewall accepts the same packets as the original abstract firewall , possibly with a different translation. The differences may show up because the source and the target firewall systems may impose different constraints on which kinds of packets can be translated, and when.
Letbe a compiled firewall ofand let p be a packet, then
It is convenient introducing a few auxiliary definitions. Let be the set of translations of a packet while it traverses a firewall. The first, , represents the identity, and are for DNAT and SNAT, while represents both. Also, let be the partial order such that , , and . Finally, given a packet p and a firewall , we assume to be the unique path in the control diagram of along which p is processed. This is the case when to multiple addresses is not allowed, which is the most common situation in practice. The following function computes the translation capability of a path π, i.e., which translations can be performed on packets processed along π.
(Translation capability).
Let be a path on the control diagram of a compiled firewall . The translation capability of π is
where is the least upper bound operator on and γ is defined as
Let hold if and only if for some tag m; given a packet p and its translation , let be defined as follows, where :
The following theorem describes the relationship between a compiled firewall and the firewall . Intuitively, if both and accept a packet p, then they may apply different sets of translations. However, applies to p all and only the translations applied by along the accepting path , which appear along its accepting path . In other words, the translations of are as close as possible to those of , and only differ because languages may have unequal expressive power [8].
Let p be a packet accepted by bothand; let; and letfor some. We have thatwithwhenor.
Intuitively, Theorems 3 and 4 jointly guarantee that (i) the compiled firewall drops all and only the packets that the source drops, and that (ii) all the packets accepted by the source firewall are accepted by the compiled one with a translation as close as possible to the original one.
Consider again Example 6. Any path π in iptables has , which implies , i.e., behaves exactly as . Interestingly, the paths and in pf have equal to and , respectively. In fact, pf cannot perform and on packets directed to and generated from the host, respectively. The same holds for ipfw.
From IFCL to the target language
We produce the target configuration by translating the IFCL firewall obtained by Algorithm 2 into the target language, the rules of which have no control flow instructions, use many tags and a restricted form of . Essentially, we “reverse” the encoding of Section 4.1 in two steps: first the rulesets are translated one by one, then they are put together respecting the definition of the control diagram. Both steps just require easy syntactic manipulations, but while the second is trivial, the first needs some attention.
The first reason is because the languages we considered cannot express arbitrary unions of ranges of addresses. The rules with such conditions are thus split into a sequence of rules expressing the same intervals, but using subnet notation — our implementation then reduces the size of the obtained configuration.
Also dealing with raises some difficulties, because of two reasons: (i) in some languages (like iptables) marking a packet also requires specifying at the same time a , an , or a ;2
This because mark instructions are often implemented as options on rules instead of actual targets on their own.
and (ii) some languages (like pf), do not allow you to check whether the packet has no tags (as in “” of Algorithm 2, line 7). These problems are solved by postprocessing the compiled firewall rulesets as follows. For (i), any rule r having condition is prefixed by a sequence of rules , one for each m generated by Algorithm 2, where is the continuation of the ruleset after rule r. In this way, the check whether the packet is untagged becomes redundant and is removed. Note that in all the rules containing are consecutive, and that the rules are pairwise mutually exclusive, since they come from a declarative firewall. Thus the sequence of rules is inserted just once, before the first occurrence of . (Note also that these instances of are trivially translated in the target language.) For addressing (ii), we first move the accepting rules (in ) or the translating rules (in and ) immediately after the corresponding tagging rule. Finally, the whole pair (tagging rule, accepting/translating rule) is translated into a single rule of the target language.
Translating the targets , , , and the used instance of is straightforward.
Experimental evaluation
We have used our tool on several policies to assess how our approach scales to real-world scenarios. We have performed our tests on a desktop PC (running Ubuntu 16.04.2) equipped with an Intel i7-3770 CPU and 16 GB of RAM.
Stanford University backbone network
It is a medium-sized network that contains 16 operational zone Cisco routers [43]. From the configuration files of these routers we have extracted 252 ACL policies containing 1916 filtering rules in total. Our tool separately synthesized all the policies in 2 minutes and 17.46 seconds; the largest ACL, made of 111 rules, has been analyzed in 16.36 seconds and the corresponding specification consists of 12 multi-cubes. The encoding of the ACL policies in our framework has required a simple, mechanized syntactic translation from the Cisco routers configuration syntax into the intermediate language.
A departmental policy
Tests performed on the policy of the Venice CS department; times expressed in m:s.cs
Analysis
Multi-cubes
Time
35
0:53.73
28
0:37.77
25
1:20.65
45
0:45.32
39
0:34.27
31
0:57.40
47
2:19.16
17
0:05.68
8
0:09.45
52
6:02.08
10
0:11.41
8
0:08.12
Complete policy
138
17:09.31
The network of the CS department of Ca’ Foscari is logically partitioned in the main network , the labs network and a mixed network . The firewall acts as a router between these networks and is connected to the Internet via other routers. The policy is written in iptables, consists of 530 rules (including both SNAT and DNAT) and contains 5 user-defined chains. In Table 10 we report the execution times and the sizes of the obtained specifications when running our tool on the policy projected on specific source and destination networks, as well as the time required to synthesize the entire firewall policy. The analysis on specific source and destination networks takes less that one minute most of the times and six minutes in the worst case.
Other real-world policies
The authors of [14] have collected a set of anonymized iptables configurations from several institutions and from the Internet. Table 11 reports the time needed to perform a complete synthesis for a selected subset of these policies, together with their size and the number of multi-cubes of the synthesized specification.
Tests performed on real-world policies; times expressed in m:s.ms
Description
Rules
Multi-cubes
Synthesis
Generation
Policy from Github
15
11
00:00.765
00:00.072
Ticket from OpenWRT
65
11
00:01.519
00:00.029
Kerberos server
8
14
00:01.635
00:00.111
Policy from a blog
28
25
00:02.572
00:02.092
Eduroam laptop
21
15
00:01.018
00:00.061
Memphis testbed
34
15
00:01.233
00:00.049
Kornwall
52
23
00:02.362
00:00.067
Shorewall
77
48
00:28.154
00:02.398
Home router
76
36
00:05.879
00:02.783
Medium-sized company
90
20
00:25.289
00:00.397
veroneau.net
263
7
05:55.690
00:01.696
Cisco support forum 1
16
9
00:00.722
00:00.042
The repository also contains the firewall configuration of the lab the authors of [14] are affiliated to. The firewall has 22 network interfaces and its policy consists of 4841 iptables rules. In Table 12 we provide a summary of the time required to produce a synthesis of the policy with no checks on MAC addresses for each possible pair of input/output interfaces and to communicate with the Internet. Most of the analyses terminate in less than 3 minutes and just a couple of cases involving particularly complex subnets take more than 10 minutes to be completed. In these particular cases, the time for the synthesis increases, because the policy contains thousands of rules mapping IP to MAC addresses. In fact, a typical use case is to check that these bindings are correctly enforced. This can be achieved through queries on singles IPs which complete in less than 2 minutes.
Tests performed on the Chair for Network Architectures and Services policy
Analysis
<1m
1–3m
3–5m
5–10m
10–20m
Subnet → Subnet
0
405
37
20
0
Subnet → Internet
14
5
1
1
0
Internet → Subnet
5
13
1
0
2
Queries
We have performed some tests to evaluate the expressiveness of the output produced by FWS. For instance, in the Home router example, we can check which hosts in the private LAN are reachable via the public IP address of the router by running the query
FWS succinctly reports that external hosts can access the internal server 192.168.1.130 on ports 22, 80, 443 and 1194 via DNAT. For hosts in the private LAN 192.168.1.0/24, both SNAT and DNAT are applied to connections towards the public IP address to avoid the problem of asymmetric routing (also known as NAT reflection). For lack of space, we do not discuss the remaining examples that are available online [18]. We limit ourselves to say that the complexity depends on the policy under analysis. The complexity also grows when packets are spread on many intervals of addresses and ports, causing the generation of many multi-cubes. We observed that this happens when the policy uses many DROP rules, increasing thus the number of invocations of the Z3 solver.
Transcompilation assessment
As expected by a compiled code, the configuration obtained by transcompilation may have a weaker structure than the configurations written by hand. Pragmatically, system administrators group the rules in the rulesets according to some usage criterion, also taking into account the features of the network, e.g., its topology, the services it hosts, etc. Yet, the administrators are required some efforts to maintain this structure, while at the moment our tool has no information for keeping such a structure. Furthermore, the compilation of a multi-cube may result in multiple rules, because most of the target languages cannot directly express conditions on sets of ranges of addresses. For this reason, the transcompiled configuration may be longer than the original one. However, FWS is intended to provide its users with means for understanding and checking a configuration in its synthesized version through the provided query language, rather than inspecting the target configuration as it is.
The last column of Table 11, shows the time required by stage 3, when transcompiling to iptables, which is the most expensive case. The time is comparable with that of stage 2 when the synthesis is cheap, otherwise it is negligible. In addition, note that increasing the size of the synthesized configuration does not significantly affect the time of transcompilation.
Related work
The literature has many proposals for simplifying and analyzing firewall configurations. Some are based on formal methods, others consist of ad hoc configuration and analysis tools (we only consider here the publicly available ones). Many works take a top-down approach, proposing ways to specify abstract filtering policies that can be possibly compiled into the actual firewall systems, e.g., [1–4,12,20,21]. There also exist several tools for facilitating firewall management and detecting misconfigurations, still following a top-down approach, such as [15,16,25,29,35,39,42,46,50].
In this paper we took a dual, bottom-up approach: we synthesize a specification from the actual firewall configuration. Below, we revise papers that take a bottom-up approach and adopt formal methods. To the best of our knowledge, ours is the only one providing at the same time: (i) a language for analyzing multiple firewall systems; (ii) an effective technique for synthesizing abstract policies; (iii) a support for NAT; (iv) a formal characterization of firewall behavior; (v) a transcompiler. Some researchers focused on analyzing iptables: Jeffrey et al. introduce in [27] a formal model of firewall policy, based on iptables, and investigate the properties of reachability and cyclicity of firewall policy configurations. The proposal by Diekmann et al. [13] has some similarities with ours. In particular, the authors provide a “cleaned” ruleset that an automatic tool can easily analyze, using a formal semantics of iptables mechanized in Isabelle/HOL [36]. Furthermore, they propose a semantics-preserving ruleset simplification (e.g., chain unfolding) with a treatment of unknown match conditions, due to a ternary logic. The subset of iptables they consider includes only filtering and access control flow actions, but not packet modification such as NAT. Differently from theirs, our approach supports NAT, packet tagging, is able to detect non-determinism in policies, and it is based on a generic language that can target languages different from iptables. The tool ITVal [30] parses iptables rules and supports SQL-like queries to discover host reachability. Differently from our FWS, ITVal is specific for iptables and aims at answering reachability queries, only. In particular, it neither synthesizes an abstract firewall specification nor ports configurations to different languages and it does not detect non-determinism.
Other proposals in the literature are more general and target, in principle, various firewall systems. Below, we discuss the main differences with respect to our work. A model-driven approach is proposed in [31] to derive network access-control policies from real firewall configuration. A proof of concept is given only for iptables. Moreover, compared to our proposal this paper does not address NAT. In [11] the authors propose an algorithmic solution to detect and correct specific anomalies on stateful firewalls. However, the proposed approach does not aim at synthesizing an abstract specification, as we do. The tool FIREMAN [48] detects inconsistencies and inefficiencies of firewall policies. It does not support NAT though. In [33] the Margrave policy analyzer is applied to the analysis of IOS firewalls. The approach is rather general and extensible to other languages, but the analysis focuses on finding specific problems in policies rather then synthesizing a high-level policy specification. A framework for the static analysis of networks is proposed in [28]. It provides sophisticated insights about network configurations but does not specifically analyze real firewall configurations and, as for the previous papers, there is no synthesis of high-level specifications. Fang [32] is another tool for querying real policies in order to discover anomalies. Its authors state that it synthesizes an abstract policy that resembles the one we propose here, but we have been unable to use the tool and the paper does not describe its internals, making any comparison with our approach impossible.
Jayaraman et al. [26] propose an approach for validating network connectivity policies, implemented by the tool SecGuru. They extract logical specifications from real Cisco IOS routers and solve them in Z3. In our paper we have extended their approach under two main aspects. First we have treated NAT, so dealing with transformations happening to packets while they are filtered. Secondly, we have performed our analysis on a generic language that can be used to represent various real configuration languages, by taking into account the platform-depended packet processing flow. As a consequence, we have provided a common logical characterization that fits any real languages modeled in our settings.
Ranathunga et al. [40] introduce an algebraic description of firewall configurations where rules are monoid-endomorphisms transforming sequences of packets. Rulesets are obtained by suitably combining these endomorphisms. The authors exploit this representation to define algorithms for policy checking, implication and differences, which are implemented in the Malachite tool. Differently from ours, their proposal does not seem to automatically generate the algebraic representation from real configurations. Furthermore, Malachite seems only to analyze the policy without generating back a clean configuration.
Hallahan et al. [22] propose Firemason, a tool that verifies a firewall configuration against a given specification, producing a counterexample if it does not. When this happens, Firemason can also synthesize a fix using behavioral examples provided by users that describe the correct behavior. Similar to our proposal, Firemason internally converts a configuration into a logical formula and uses Z3 to perform the verification step and to generate the fix for the configuration. Differently from FWS, Firemason can handle rate limit rules, but currently it supports only iptables, and therefore offers no features to automatically port configurations. Finally, it does not implement any analysis to spot possibly non-deterministic behavior.
Another approach to modeling and verifying firewall policies consists in using Binary Decision Diagrams to efficiently represent packet filters, as first proposed by Hazelhurst in [23,24]. These data structures concisely represent the boolean expressions that describe which packets must be accepted and which rejected. A tool is also provided that can analyze rule sets. Differently from ours, this approach mainly focusses on Cisco and does not address NAT issues.
Other papers study the definition of network configurations and in particular their verification. Note that this is a different issue than ours, which instead focusses on well-established systems and languages. Note also that these two approaches can be combined together.
Anderson et al. [3] introduced NetKAT, a language for programming a collection of network switches. It is equipped with a denotational semantics and an axiomatic one, both based on Kleene algebra with tests. Although the primitives provided by NetKAT are similar to those of IFCL, i.e., for filtering, modifying, and transmitting packets, its focus is different from ours.
Fogel et al. [19] proposed Batfish, a tool for statically analyzing network configurations. Batfish encodes a configuration and the relevant information of that network, e.g., the used protocols and the data plane, into Datalog. Network administrators can exploit the Datalog deduction machinery to check correctness properties expressed as a first-order-logic formula. If a violation occurs, Batfish produces a counterexample in the form of concrete offending packets.
Bringhenti et al. [7] introduced VEREFOO, a tool that given a set of security requirements and a graph describing the network services, computes two pieces of information. The first one describes where to deploy the security function nodes (i.e., nodes that implement security checks on the traffic flow) in the network to meet the desired security goals. The second output is the configuration that implements the policy for each security function.
Valenza et al. [47] proposed a language-independent approach for the verification and the detection of anomalies of forwarding polices in a SDN scenario. Their proposal can be used both in a top-down or in bottom-up manner. In the first case, network administrators define a policy abstractly and translate it into a configuration to be deployed on a target device. The idea is to use a logical formalism for modeling the behavior of the forwarding policies and the network in hand, and to use a SAT solver for carrying out analyses on this logical model. If no anomaly is found, the forwarding policies are translated into a real SDN language. In the bottom-up approach administrators verify whether a change in the configuration of a network node causes some anomalies, by checking the logical formulation.
We remark that the goal of the above appoaches is modeling an entire network leaving out the details of the single firewalls, expressed in the most used configuration languages, that instead is our target. We see no particular difficulties in applying our proposal to manage the firewalls associated with each node of a network, so integrating the two approaches.
Conclusions
We have presented FWS [18], a semantic-based tool that implements a three-stage transcompiling pipeline, which supports the decompilation, analysis, porting and refactoring of real firewall configurations. The peculiarity of our approach is to be independent of any specific firewall system. Independence is achieved by defining IFCL, an intermediate language for configuring firewalls.
Our language has a formal semantics and it supports the typical actions of real configuration languages, including NAT, packet tagging and MAC filtering. Remarkably, IFCL separates the specification of filtering/NAT rules from the platform-dependent processing of the packet, expressed in terms of a control diagram. By providing a specific control diagram, we have encoded real firewall systems in IFCL, namely iptables, ipfw, pf and Cisco IOS, thus indirectly endowing them with a formal semantics.
The stage 1 of the pipeline compiles a real configuration by translating the firewall rules into the intermediate language, enabling an algorithmic processing of configurations.
The stage 2 characterizes IFCL in terms of logical predicates on pairs of packets , which hold true whenever packet p is accepted by the firewall as , so accounting for NAT; actually, also the set of dropped packets is determined. We extract a succinct representation, namely multi-cubes [26], of all the accepted pairs using the Z3 solver. A variety of analyses can be done on succinct representations through a SQL-like query language. Among them, host reachability, policy equivalence and difference, and non-determinism of configurations, which is seldom addressed. The results on real cases show that the tool is effective and can typically answer to queries in just a few seconds. Complex queries on large configurations, however, can require minutes because of multiple invocations of the Z3 solver.
The declarative specification is the input of stage 3, which compiles it to one of the real target language considered. The time needed for generating the target configuration ranges from seconds to a few minutes. When the source and the target languages coincide, this stage mechanically implements policy refactoring. Since the declarative specification has no anomalies, e.g., rule overlapping or shadowing, a system administrator is also supported in policy maintenance and adherence to regulations. At the same time, the administrator can mechanically port policies from one firewall system to another, when their languages differ.
All the stages have been proved to preserve the semantics of the original policy, so guaranteeing that our transcompilation pipeline is correct.
We also tested the usability of FWS with the help of a couple of network administrators. We used their feedback to enrich the query language and to improve the presentation of the analysis results.
Future work
We plan to extend our work in several directions. First we will complete the compilation stage towards Cisco IOS, and we will encode more languages, e.g., from specialized firewall devices.
Also, we plan to enrich IFCL with features for network interfaces and routing. Tools exist that syntethize and distribute over the nodes of a network the specification of local policies starting from a global one, e.g., [7]. The local policies obtained by this tool are represented in a tabular form, similar to ours. It would be then easy to compile these local specification in a chosen firewall language. We will further extend our approach to the SDN paradigm. The major difficulty in this case arises because of the high dynamicity of SDNs, while our proposal focuses on legacy networks and devices that are essentially static. The usability of the tool would benefit from a graphical user interface, as well as from further experiments and more feedback from network administrators. Other relevant issues deal with logging, rate limiting, tarpitting, and load balancing. As far as logging is concerned, a promising line to follow is defining predicates similar to and .
We will explore new techniques to synthesize the abstract specification in order to improve the tool performance. In particular, we want to take into account the initial intervals in the configurations while computing the abstract specification. The adopted algorithm in Z3 forgets this information by encoding the initial intervals as constraints on address variables in the logical predicate but, in fact, the bounds of the computed multi-cubes directly depends on the bounds of the intervals specified in the firewall rules. A promising alternative could be considering an approach based on Header Space Analysis [28].
Finally, it would be very interesting to extend our approach to deal with dynamic firewalls and with networks with more than one firewall. The idea would be to incrementally compute the relevant predicates for the first extension in order to keep the tool effective, while the second one can be addressed by combining the synthesized specifications based on network topology and routing.
Footnotes
Acknowledgments
We warmly thank the anonymous referees for their insightful comments and suggestions.
We acknowledge partial support for Chiara Bodei, Pierpaolo Degano and Letterio Galletta from MIUR project PRIN 2017FTXR7S “Methods and Tools for Trustworthy Smart Systems”; for Riccardo Focardi and Flaminia Luccio from POR FESR project “Sistema domotico IoT integrato ad elevata sicurezza informatica per smart building”; and for Mauro Tempesta and Lorenzo Veronese from the European Research Council (ERC) under the European Union Horizon 2020 research (grant agreement 771527-BROWSEC).
Part of the work was carried out when Mauro Tempesta and Lorenzo Veronese where at DAIS, Università Ca’ Foscari of Venezia.
Pierpaolo Degano is currently at IMT School for Advanced Studies, Lucca.
Formal proofs
Notations and symbols
Notation
Description
denotes any value (except for those included in S)
p
packet
, ,
source (destination) address (tag) of p (with ∙ as empty tag)
address, consisting in and possibly
address range consisting of a set of IP addresses and a set of ports
if and when is defined
, ,
p where the source (destination) address (tag) becomes equal to a (m)
,
if the packet p matches (does not match) the actions α
firewall rule, with ϕ logical formula and t target action of the rule
if the fields of the packet p satisfy the constraints of the proposition ϕ
,
if p matches (does not match) r with target t
ruleset, with ϵ empty ruleset
,
if p matches (does not match) the i-th rule in a ruleset R with target t
actions, with ruleset R
address translation action, with address ranges and
mark action, with tag m
check state action, with state
for rewriting the destination (source, both) addresses
⋆
identity translation
the address is translated according to n, while the port is kept unchanged
default target in
Ψ
set of predicates on packets
control diagram, with Q set of nodes, set of arcs, ,
transition function
firewall, with control diagram, ρ set of rulesets; and
labeled transition relation of the master semantics, with s state, p packet
labeled transition relation of the slave semantics, with , s state, p packet
if , t is applied to p to obtain ; S is the stack handling control flow
given an action α packet p and X, it returns a possibly changed packet
it returns p translated under NAT operation in the state s, with addresses ,
unfolding of a ruleset R (firewall )
unfolding with formula f, set of rulesets I and tag m of packets satisfying f
it computes the set of packets resulting from all possible translations of p
,
predicates that hold when p is accepted (dropped) as by R
,
predicates associated with
packet as a tuple of Z3 bit-vector variables v
intervals of variables in a multi-cube
partial order on , the set of translations of a packet
unique path in the control diagram of along which p is processed
translation capability
hold iff for some tag m
Interacting with FWS
Here we present the command language of FWS. In particular, we describe its query language that can be used to perform the various analyses implemented by the tool.
References
1.
P.Adão, C.Bozzato, G.Dei Rossi, R.Focardi and F.L.Luccio, Mignis: A semantic based tool for firewall configuration, in: Proc. of the 27th IEEE CSF, 2014, pp. 351–365.
2.
P.Adão, R.Focardi, J.D.Guttman and F.L.Luccio, Localizing firewall security policies, in: Proc. of the 29th IEEE CSF, Lisbon, Portugal, June 27–July 1, 2016, pp. 194–209.
3.
C.J.Anderson, N.Foster, A.Guha, J.-B.Jeannin, D.Kozen, C.Schlesinger and D.Walker, NetKAT: Semantic foundations for networks, in: Proc. of the 41st ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages (POPL 2014), ACM, 2014.
4.
Y.Bartal, A.J.Mayer, K.Nissim and A.Wool, Firmato: A novel firewall management toolkit, ACM Transactions on Computer Systems22(4) (2004), 381–420. doi:10.1145/1035582.1035583.
5.
C.Bodei, P.Degano, R.Focardi, L.Galletta and M.Tempesta, Transcompiling firewalls, in: Proc. 7th International Conference on Principles of Security and Trust, L.Bauer and R.Küsters, eds, LNCS, Vol. 10804, 2018, pp. 303–324.
6.
C.Bodei, P.Degano, R.Focardi, L.Galletta, M.Tempesta and L.Veronese, Language-independent synthesis of firewall policies, in: Proc. 2018 IEEE European Symposium on Security and Privacy, F.Piessens and M.Smith, eds, 2018, pp. 92–106.
7.
D.Bringhenti, G.Marchetto, R.Sisto, F.Valenza and Towards a fully automated and optimized network security functions orchestration, in: 2019 4th International Conference on Computing, Communications and Security (ICCCS), Rome, Italy, October 10–12, 2019, 2019, pp. 1–7.
8.
L.Ceragioli, P.Degano and L.Galletta, Are all firewall systems equally powerful? in: Procs of ACM SIGSAC 14th Workshop on Programming Languages and Analysis for Security, 2019, pp. 1–17. doi:10.1145/3338504.3357340.
9.
Cisco: NAT order of operation, https://www.cisco.com/c/en/us/support/docs/ip/network-address-translation-nat/6209-5.html/.
F.Cuppens, N.Cuppens-Boulahia, J.García-Alfaro, T.Moataz and X.Rimasson, Handling stateful firewall anomalies, in: SEC, IFIP Advances in Information and Communication Technology, Vol. 376, Springer, 2012, pp. 174–186.
12.
F.Cuppens, N.Cuppens-Boulahia, T.Sans and A.Miège, A formal approach to specify and deploy a network security policy, in: Formal Aspects in Security and Trust (FAST’04), 2004, pp. 203–218.
13.
C.Diekmann, L.Hupel, J.Michaelis, M.P.L.Haslbeck and G.Carle, Verified iptables firewall analysis and verification, J. Autom. Reasoning61(1–4) (2018), 191–242. doi:10.1007/s10817-017-9445-1.
14.
C.Diekmann, J.Michaelis, M.P.L.Haslbeck and G.Carle, Verified iptables firewall analysis, in: The 15th IFIP Networking Conference, Vienna, Austria, May 17–19, 2016, 2016, pp. 252–260.
Firewall management: 5 challenges every company must address, https://www.algosec.com/wp-content/uploads/2016/03/Firewall-Management-5-Challenges-Every-Company-Must-Address-WEB.pdf.
18.
FireWall Synthesizer (FWS): Tool and examples, https://github.com/secgroup/fws.
19.
A.Fogel, S.Fung, L.Pedrosa, M.Walraed-Sullivan, R.Govindan, R.Mahajan and T.D.Millstein, A general approach to network configuration analysis, in: 12th USENIX Symposium on Networked Systems Design and Implementation, NSDI 15, 2015, pp. 469–483.
20.
S.N.Foley and U.Neville, A firewall algebra for OpenStack, in: Proceedings of the 3rd IEEE Conference on Communications and Network Security, CNS 2015, 2015, pp. 541–549. doi:10.1109/CNS.2015.7346867.
W.T.Hallahan, E.Zhai and R.Piskac, Automated repair by example for firewalls, in: 2017 Formal Methods in Computer Aided Design (FMCAD), 2017, pp. 220–229. doi:10.23919/FMCAD.2017.8102263.
23.
S.Hazelhurst, Algorithms for analysing firewall and router access lists, CoRR cs.NI/0008006 (2000), https://arxiv.org/abs/cs/0008006.
24.
S.Hazelhurst, A.Attar and R.Sinnappan, Algorithms for improving the dependability of firewall and filter rule lists, in: 2000 International Conference on Dependable Systems and Networks (DSN 2000), IEEE Computer Society, 2000, pp. 576–585. doi:10.1109/ICDSN.2000.857593.
25.
High level firewall language, 2003, http://www.hlfl.org.
26.
K.Jayaraman, N.Bjørner, G.Outhred and C.Kaufman, Automated analysis and debugging of network connectivity policies, Technical Report, Microsoft, 2014.
27.
A.Jeffrey and T.Samak, Model checking firewall policy configurations, in: Proceedings of the 10th IEEE International Symposium on Policies for Distributed Systems and Networks, POLICY 2009, 2009, pp. 60–67.
28.
P.Kazemian, G.Varghese and N.McKeown, Header space analysis: Static checking for networks, in: Proceedings of the 9th USENIX Symposium on Networked Systems Design and Implementation, NSDI 2012, 2012, pp. 113–126.
R.M.Marmorstein, Formal analysis of firewall policies, PhD thesis, College of William and Mary, 2008.
31.
S.Martínez, J.Cabot, J.Garcia-Alfaro, F.Cuppens and N.Cuppens-Boulahia, A model-driven approach for the extraction of network access-control policies, in: Proc. MDSec’12, ACM, 2012, pp. 5:1–5:6.
32.
A.J.Mayer, A.Wool and E.Ziskind, Fang: A firewall analysis engine, in: Proc. of the 21st IEEE S&P 2000, 2000, pp. 177–187.
33.
T.Nelson, C.Barratt, D.J.Dougherty, K.Fisler and S.Krishnamurthi, The Margrave tool for firewall analysis, in: Proceedings of the 24th Large Installation System Administration Conference, LISA 2010, 2010.
34.
Netfilter, https://www.netfilter.org/.
35.
NeTSPoC: A network security policy compiler, 2011, http://netspoc.berlios.de.
36.
T.Nipkow, L.C.Paulson and M.Wenzel, Isabelle/HOL – a Proof Assistant for Higher-Order Logic, Lecture Notes in Computer Science, Vol. 2283, Springer, 2002. doi:10.1007/3-540-45949-9.
37.
Open Networking Foundation, Software-defined networking (SDN) definition, https://www.opennetworking.org/sdn-resources/sdn-definition.
D.Ranathunga, M.Roughan, P.Kernick and N.Falkner, Malachite: Firewall policy comparison, in: 2016 IEEE Symposium on Computers and Communication (ISCC), 2016, pp. 310–317. doi:10.1109/ISCC.2016.7543759.
41.
R.Russell, Linux 2.4 packet filtering HOWTO, http://www.netfilter.org/documentation/HOWTO/packet-filtering-HOWTO.html.
42.
Shorewall, IPtables made easy, Shorewall, 2014, http://www.shorewall.net/.
43.
Stanford University backbone network configuration ruleset, https://bitbucket.org/peymank/hassel-public/.
44.
The IPFW Firewall, https://www.freebsd.org/doc/handbook/firewalls-ipfw.html.
45.
The Netfilter Project, Traversing of tables and chains, http://www.iptables.info/en/structure-of-iptables.html.
F.Valenza, S.Spinoso and R.Sisto, Formally specifying and checking policies and anomalies in service function chaining, J. Network and Computer Applications146 (2019). doi:10.1016/j.jnca.2019.102419.
48.
L.Yuan, J.Mai, Z.Su, H.Chen, C.Chuah and P.Mohapatra, FIREMAN: A toolkit for FIREwall modeling and ANalysis, in: 27th IEEE S&P, 2006, pp. 199–213.
B.Zhang, E.Al-Shaer, R.Jagadeesan, J.Riely and C.Pitcher, Specifications of a high-level conflict-free firewall policy language for multi-domain networks, in: Proc. of ACM Symposium on Access Control Models and Technologies (SACMAT 2007), ACM, 2007.