Firewall Access Policy Rulesets, Part 2
Author: [email protected] 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
The first rule was placed in all three chains:
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
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
The
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
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:
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.