Firewall Access Policy Rulesets, Part 2

Want to support HowtoForge? Become a subscriber!
 
Submitted by vkfwb (Contact Author) (Forums) on Mon, 2009-08-24 15:28. :: Security

Firewall Access Policy Rulesets, Part 2

Author: vadim@fwbuilder.org
http://www.fwbuilder.org

This article continues the series of articles on Firewall Builder, a graphical firewall configuration and management tool that supports many Open Source firewall platforms as well as Cisco IOS access lists and Cisco ASA (PIX). Firewall Builder was introduced on this site earlier with articles Getting Started With Firewall Builder, Using Firewall Object In Firewall Builder. Firewall Access Policy Rulesets, Part 1.

This article demonstrates several examples of Access Policy rules and generated configurations for iptables, PF and Cisco PIX.

More information on Firewall Builder, pre-built binary packages and source code, documentation can be found on the project web site at http://www.fwbuilder.org/. Numerous examples of iptables, pf and other rules are available in Firewall Builder Users Guide. Follow Firewall Builder Project Blog for announcements and articles on all aspects of using Firewall Builder.

 

Firewall object used in examples

We start with the firewall object that looks like shown in the next screenshot. This firewall has three interfaces: eth0 (outside), eth1 (inside) and loopback. All addresses are assigned statically. Address of the inside interface "eth1" is 192.168.1.1/24, we also have network object with name "net-192.168.1.0" that defines internal network 192.168.1.0/24.

To illustrate generated configurations for platforms other than iptables/Linux in this article, I am using similarly configured firewall objects with different platform and host OS settings.

 

Permit internal LAN to connect to the Internet

In this example we create a rule to permit our internal LAN to connect to the Internet using any protocol. Network object "net-192.168.1.0" should be configured with the IP address and netmask corresponding to those used on the internal network behind the firewall. Since internal LAN in this example uses private address block, the rules described here are insufficient and should be accompanied with corresponding NAT (Network Address Translation) rules. We discuss NAT rules in the next article.

Here are the iptables commands generated for this example:

$IPTABLES -A INPUT   -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A OUTPUT  -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
# Rule 0 (global)
# 
$IPTABLES -A INPUT  -s 192.168.1.0/24   -m state --state NEW  -j ACCEPT 
$IPTABLES -A OUTPUT  -s 192.168.1.0/24   -m state --state NEW  -j ACCEPT 
$IPTABLES -A FORWARD  -s 192.168.1.0/24   -m state --state NEW  -j ACCEPT 
# 
# Rule 1 (global)
# 
$IPTABLES -N RULE_1
$IPTABLES -A OUTPUT  -j RULE_1 
$IPTABLES -A INPUT  -j RULE_1 
$IPTABLES -A FORWARD  -j RULE_1 
$IPTABLES -A RULE_1  -j LOG  --log-level info --log-prefix "RULE 1 -- DENY "
$IPTABLES -A RULE_1  -j DROP 

Rules that utilize module state and match states ESTABLISHED,RELATED permit reply packets, such as TCP ACKs, UDP reply packets and ICMP messages associated with known sessions. These rules are automatically added at the beginning of generated iptables script if the option "Accept ESTABLISHED and RELATED packets before the first rule" is turned on in the firewall object "Advanced" settings dialog. If you turn this option off, the rule will not be added automatically and you'll have to add it yourself. You can use Custom Service object ESTABLISHED you can find in the Standard objects library to do this.

The first rule was placed in all three chains: INPUT, OUTPUT and FORWARD because option "Assume firewall is part of any" was turned on in the "Advanced" settings dialog of this firewall object. This option directs policy compiler to assume that object "Any" matches firewall itself as well. In other words, using "Any" in Destination of the rule is equivalent to using a combination of any address and the firewall. To match packets headed for the firewall, the rule should be placed in the INPUT chain. Also, network object within address 192.168.1.0/24 matches one of the interfaces of the firewall that has address on this network. This means, this rule should also match packets sent by the firewall itself provided source address is that of the interface on the internal net. This requires iptables command in the OUTPUT chain. And finally, iptables command in the FORWARD chain matches packets sent by machines on the internal net.

Rule #1 catches all other packets going to, from and across the firewall and logs and drops them.

Let's see what gets generated for iptables if option "Assume firewall is part of any" is turned off:

$IPTABLES -A INPUT   -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A OUTPUT  -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
# Rule 0 (global)
# 
$IPTABLES -A FORWARD  -s 192.168.1.0/24   -m state --state NEW  -j ACCEPT 
# 
# Rule 1 (global)
# 
$IPTABLES -N RULE_1
$IPTABLES -A FORWARD  -j RULE_1 
$IPTABLES -A RULE_1  -j LOG  --log-level info --log-prefix "RULE 1 -- DENY "
$IPTABLES -A RULE_1  -j DROP 

Automatically added rules that match packets in states ESTABLISHED,RELATED are not affected by the "Assume firewall is part of any" option and always match in chains INPUT, OUTPUT and FORWARD.

Since the compiler does not assume firewall matches "any" anymore, the rule with "any" is destination yields iptables command only in the FORWARD chain. This applies both to the rule that permits outgoing connections from internal LAN and to the "Catch all" rule #1. The choice of the setting for this option is up to the policy designer. Some people find it more intuitive to leave it off and add rules to control access to and from the firewall explicitly. Note that default policy for all chains is set to DROP with the following commands at the very top of the generated iptables script:

$IPTABLES -P OUTPUT  DROP
$IPTABLES -P INPUT   DROP
$IPTABLES -P FORWARD DROP

This means that if you do not add rules to permit access to the firewall and turn option "Assume firewall is part of any" off, then all generated iptables rules will be in the FORWARD chain and all access to the firewall itself will be blocked by the default policy in the INPUT chain. On the other hand, if the option "Assume firewall is part of any" is on, then the rule permitting access from internal network to "any" gets side effect of permitting access to the firewall as well. It is up to you to decide whether this is a good or bad thing. You can always restrict access to the firewall and control it with a few rules somewhere close to the beginning of the policy regardless of the setting of this option.

Even if you choose to turn option "Assume firewall is part of any" off and do not add any rules to permit access to the firewall in your policy rule set, you can use another option in the firewall object "advanced" settings dialog for this. The option is called "Always permit ssh access to the firewall from management station" and allows you to enter single ip address or subnet and then automatically adds a rule to the generated script to permit ssh access to the firewall from this address. We demonstrate this feature in one of the following articles.

Examples below have been compiled with the option "Assume firewall is part of any" turned on.

Here is the PF configuration created for the same rules:

# Rule  0 (global)
# 
pass  quick inet  from 192.168.1.0/24  to any keep state 
# 
# Rule  1 (global)
# 
block  log  quick inet  from any  to any 

Firewall Builder always generates PF configuration using its "quick" clause to switch to the first-match mode. In this PF configuration example, the first rule permits packets with source address on the 192.168.1.0/24 network and stops processing. The second rule will only inspect packets not matched by the first rule.

Here is the fragment of the PIX config generated for the same combination of rules:

! Rule  0 (global)
! 
access-list inside_acl_in  remark 0 (global)
access-list inside_acl_in permit ip 192.168.1.0 255.255.255.0 any 
! 
! Rule  1 (global)
! 
access-list outside_acl_in  remark 1 (global)
access-list outside_acl_in deny   ip any any log 4 interval 300 
access-list dmz50_acl_in  remark 1 (global)
access-list dmz50_acl_in deny   ip any any log 4 interval 300 
access-list inside_acl_in  remark 1 (global)
access-list inside_acl_in deny   ip any any log 4 interval 300 

access-group dmz50_acl_in in interface dmz50
access-group inside_acl_in in interface inside
access-group outside_acl_in in interface outside

Since source address in the rule #0 is limited to the internal network, policy compiler was able to determine which interface the access list command should be associated with and added it only to the ACL "inside_acl_in".

The "access-group" commands are actually located at the very bottom of the generated script, after all other access-list commands. It is shown right next to the ACL rules here for presentation.

 

Letting certain protocols through, while blocking everything else

This is one of the simplest, most basic tasks you may want your firewall to do - block all the traffic while letting certain protocols through. Let's assume that we have a network consisting of just the firewall "firewall1" and a few hosts behind it. We want to let SMTP through to the mail server from the Internet, and block everything else. All we need to do is put the following rules in the Global Policy:

Rule #0 allows SMTP through to the server, while rule #1 blocks and logs everything else. It is worth mentioning that this policy also blocks all the access to firewall itself, including access to it from internal hosts.

We do not need any additional rules to take care of "reply" packets coming back from the server to clients because our underlying firewall software supports stateful inspection and "understands" that such packets should be let through.

Here is iptables script generated for these two simple rules:

$IPTABLES -A INPUT   -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A OUTPUT  -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
# Rule 0 (global)
# 
$IPTABLES -A OUTPUT -p tcp -m tcp  -d 192.168.1.100  \
    --dport 25  -m state --state NEW  -j ACCEPT 
$IPTABLES -A FORWARD -p tcp -m tcp  -d 192.168.1.100 \
    --dport 25  -m state --state NEW  -j ACCEPT 
# 
# Rule 1 (global)
# 
$IPTABLES -N RULE_1
$IPTABLES -A OUTPUT  -m state --state NEW  -j RULE_1 
$IPTABLES -A INPUT  -m state --state NEW  -j RULE_1 
$IPTABLES -A FORWARD  -m state --state NEW  -j RULE_1 
$IPTABLES -A RULE_1  -j LOG  --log-level info --log-prefix "RULE 1 -- DENY "
$IPTABLES -A RULE_1  -j DROP 

Generated iptables rules were placed in both OUTPUT and FORWARD chains because option "Assume firewall is part of any" was turned on in the "Advanced" settings dialog of this firewall object. In other words, using "Any" in Source of the rule was equivalent to using a combination of any address and the firewall. Resultant iptables commands should be placed in the OUTPUT chain to match packets generated by the firewall and FORWARD to match packets crossing the firewall. If you turn this option off, the program will only generate iptables rules in the FORWARD chain for this rule.

Here is the code generated for PF for the same rule:

# Rule  0 (global)
# 
pass  quick inet proto tcp  from any  to 192.168.1.100 port 25 keep state 
# 
# Rule  1 (global)
# 
block  log  quick inet  from any  to any 

In PF we do not have to worry about chains and there is no option "Assume firewall is part of any" because there is no difference.

Here is the code generated for PIX for the same rule:

! Rule  0 (global)
! 
access-list outside_acl_in  remark 0 (global)
access-list outside_acl_in permit tcp any host 192.168.1.100 eq 25 
access-list dmz50_acl_in  remark 0 (global)
access-list dmz50_acl_in permit tcp any host 192.168.1.100 eq 25 
access-list inside_acl_in  remark 0 (global)
access-list inside_acl_in permit tcp any host 192.168.1.100 eq 25 
! 
! Rule  1 (global)
! 
access-list outside_acl_in  remark 1 (global)
access-list outside_acl_in deny   ip any any log 0 interval 300 
access-list dmz50_acl_in  remark 1 (global)
access-list dmz50_acl_in deny   ip any any log 0 interval 300 
access-list inside_acl_in  remark 1 (global)
access-list inside_acl_in deny   ip any any log 0 interval 300 

In PIX, all access lists must be attached to interfaces of the firewall. Since the rule did not specify source address, the program has to generate access lists that would match any source, which means they should be attached to all interfaces of the firewall. Since my PIX test object has three interfaces: outside, inside and dmz, I ended up with ACL lines in three access lists, one for each interface.

 

Letting certain protocols through from specific source

In this example, we look at the rule that is similar to the previous one, but also matches source address. This rule permits access to the mail server inside from mail relay on DMZ and from no other source. Generated rules for iptables and pf are very similar, they just add source address matching. Generated rules for PIX are different because now the program can intelligently pick the right access list and avoid generating redundant rules.

Here is the code generated for iptables from this rule:

# Rule 0 (global)
# 
$IPTABLES -A FORWARD -p tcp -m tcp  -s 192.168.2.22   -d 192.168.1.100  \
    --dport 25  -m state --state NEW  -j ACCEPT 

Since source rule element was limited to the host on DMZ, generated iptables rule is placed only in the FORWARD chain and also matches the source using "-s" clause.

Let's look at the configuration generated for PIX from the same rule:

! Rule  0 (global)
! 
access-list dmz50_acl_in  remark 0 (global)
access-list dmz50_acl_in permit tcp host 192.168.2.22 host 192.168.1.100 eq 25 

access-group dmz50_acl_in in interface dmz50
access-group inside_acl_in in interface inside
access-group outside_acl_in in interface outside

the rule was placed only in the access list attached to the DMZ interface because packets with source address of the host on DMZ can only cross this interface of the firewall, assuming spoofed packets are blocked by special rule, which will discuss below.


Please do not use the comment function to ask for help! If you need help, please use our forum.
Comments will be published after administrator approval.