14.2.22. Branching rules

Many firewall platforms support mechanisms by which control can be passed from one group of rules to another, much like in programming languages control can be passed to a subroutine. The rule set that gets control in such operation can then make final decision about the packet and accept or deny it, or it can return control back to the rule set that was running before. Firewall Builder provides the same mechanism using a branching action that is called "Chain" for iptables firewalls and "Anchor" for PF firewalls to reuse the familiar names from iptables and pf, respectively.

Note

Platform-specific action names "Chain" and "Anchor" will disappear in Firewall Builder v4.0. The name of the action that creates a branch in the rule set processing sequence will be just "Branch" regardless of the chosen target firewall platform.

Branching rules can be used to create optimized rule sets or to improve readability or both. Consider the example shown in the following screenshot:

Figure 14.67. A Firewall Object with Two Policy Rule Sets

A Firewall Object with Two Policy Rule Sets

Firewall fw2 has two rule sets: "Policy" and "rate_limit". I am going to demonstrate how the second rule set can be used to rate limit packets that match different rules in the main rule set "Policy".

Note

Figure 14.52 demonstrated how to add policy rule set object to the firewall.

Let's create a rule to match ssh sessions to the firewall and instead of accepting or dropping them right away, pass control to the rule set "rate_limit" that will accept them only if they are not opened too fast. First, create this rule and choose action "Chain", then double-click the action and drag rule set object "rate_limit" into the well in the action dialog as shown in the screenshot:

Figure 14.68. A Rule with Action "Chain"

A Rule with Action "Chain"

Now we can configure rate limiting rule in the "rate_limit" rule set. I am going to use the iptables module "hashlimit" to configure rather sophisticated rate-limiting. When I recreate the same example for PF below, the options will look different.

Figure 14.69. Rate limiting rule

Rate limiting rule

Here is the iptables script generated by the program for these rules:

# Rule 0 (global)
# 
$IPTABLES -N rate_limit
$IPTABLES -A INPUT -p tcp -m tcp  --dport 22  -j rate_limit 

# ================ Table 'filter', rule set rate_limit
# 
# Rule rate_limit 0 (global)
# 
$IPTABLES -A rate_limit  -m state --state NEW  \
    -m hashlimit --hashlimit 5/minute --hashlimit-mode srcip \
    --hashlimit-name htable_rule_0 -j ACCEPT 
        

Those familiar with iptables will notice that Firewall Builder created user-defined chain with the name of the second rule set ("rate_limit") and used "-j" option to pass control to it from the top-level rule.

Branching from a single rule is not very interesting. I could just use the same options with the rule #0 in the top level Policy rule set and get the same result, except instead of the user defined chain "rate_limit" this all would have been done in the same iptables command. However branching to a dedicated rule set becomes more useful if I want to use the same rate limiting to control access to several servers behind the firewall on entirely different protocols. Here is new example:

Figure 14.70. Several rules branching to the same rule set "rate_limit"

Several rules branching to the same rule set "rate_limit"

Here is how generated iptables script looks like:

# ================ Table 'filter', rule set Policy
# 
# Rule 0 (global)
# 
$IPTABLES -N rate_limit
$IPTABLES -A INPUT -p tcp -m tcp --dport 22 -j rate_limit 
# 
# Rule 1 (global)
# 
$IPTABLES -A FORWARD -p tcp -m tcp -d 192.168.1.100 --dport 25 -j rate_limit 
# 
# Rule 2 (global)
# 
$IPTABLES -A FORWARD -p tcp -m tcp -d 192.168.1.200 --dport 80 -j rate_limit 

# ================ Table 'filter', rule set rate_limit
# 
# Rule rate_limit 0 (global)
# 
$IPTABLES -A rate_limit  -m state --state NEW  \
    -m hashlimit --hashlimit 5/minute --hashlimit-mode srcip \
    --hashlimit-name htable_rule_0 -j ACCEPT 
        

Here are three iptables rules that match different addresses and services but pass control to the same chain "rate_limit". Now if I need to tune my rate-limiting parameters for all destinations, I can do it in one place instead of three.

The rule #0 in the "rate_limit" rule set matches packets only if they come at the rate no more than five per minute per source IP address. Packets that match these criteria will be accepted, but those that don't will not match the rule. Since this rule is the last in the branch rule set, control will return to the top level and firewall will continue examining the packet with rules below the one that passed control to "rate_limit" rule set. Eventually it may hit the "catch all" rule and get dropped, but more complex policies may do something else with these packets such as try different rate-limiting criteria or mark them for traffic shaping.

An action that creates a branch is available in Firewall Builder only if the target firewall platform provides some kind of mechanism to support it. In iptables it is user-defined chains, in PF it is anchors. Unfortunately, branching can not be implemented in Cisco IOS access lists and PIX. Let's try to recompile the same rules for PF. First, we'll need to change rate limiting parameters because its implementation in PF is different from that in iptables.

Figure 14.71. Rate-Limiting Rule for PF

Rate-Limiting Rule for PF

I am using the same three rules in the main policy to rate-limit connections to the firewall itself and two servers behind it. The generated PF config is split so that main policy rules are in the file "fw2-pf.conf" and rules for the rule set "rate_limit" are in the file "fw2-pf-rate_limit.conf". When configuration with multiple rule sets is compiled for PF, each new branch rule set has its own separate file with the name composed from the name of the firewall object and the name of the rule set object.

File fw2-pf.conf:

# Tables: (1)
table <tbl.r9999.d> { 192.0.2.1 , 192.168.1.1 } 

# Policy compiler errors and warnings:
# 
# Rule  0 (global)
# 
anchor rate_limit in  inet proto tcp  from any  to <tbl.r9999.d> port 22 
# 
# Rule  1 (global)
# 
anchor rate_limit inet proto tcp  from any  to 192.168.1.100 port 25 
# 
# Rule  2 (global)
# 
anchor rate_limit inet proto tcp  from any  to 192.168.1.200 port 80 
        

File fw2-pf-rate_limit.conf:

# Tables: (0)

# Policy compiler errors and warnings:
# 
# Rule  rate_limit 0 (global)
# 
pass  quick inet  from any  to any keep state  (  max-src-conn 10, max-src-conn-rate 5/60 ) 
        

Firewall Builder also generates a shell script to load these rules. The script is in the file with the name the same as the name of the firewall, with extension ".fw":

Here is the code that loads rules in the file fw2-pf.fw:


$PFCTL -f ${FWDIR}/fw2-pf.conf || exit 1
$PFCTL -a rate_limit -f ${FWDIR}/fw2-pf-rate_limit.conf || exit 1
        

Rules from the file "fw2-pf-rate_limit.conf" are loaded into anchor "rate_limit".

 

Copyright © 2000-2012 NetCitadel, Inc. All rights reserved.
 Using free CSS Templates.