14.2.8. Using Groups

Sometimes we need to define a lot of very similar rules for multiple hosts or networks. For example, there may be a need to permit the same service to 10 different hosts on the network, while still blocking it to all others. The simplest way to accomplish this is to add 10 rules with the same source and service fields and just different destinations. Another method is to add 10 objects to the Source or Destination rule element of the same rule. Either method can clutter the firewall policy and make it less readable. To avoid this, we can use groups. A group is just a container which includes references to multiple objects of the same or similar type. Firewall Builder supports groups of objects and groups of services. You can put "Address", "Host", "Network" and "Firewall" objects in an object group, but you cannot put service objects in such a group. Similarly, a service group can contain "IP Service", "TCP Service", "UDP Service" and "ICMP Service" objects, but cannot contain hosts or networks. Groups can contain other groups of the same type as well. Figure 14.17 represents an object group used in this example.

Groups make policy rules more readable, but object groups have the additional great advantage of being reusable. You can have many different rules using the same group object. If you ever need to add another host or address to the group, you only need to do it once and all rules will automatically pick the change after recompile.

Figure 14.17. Object Group Consisting of Three Host Objects

Object Group Consisting of Three Host Objects

To add objects to a group, simply drag them from the tree on the left into group view on the right, or use Copy/Paste functions available via menus.

Once an appropriate group has been created, it can be used for the policy and NAT rules just like any other object.

Figure 14.18. A Rule Using an Object Group.

A Rule Using an Object Group.

Here is the iptables commands generated for this example:

# Rule 0 (global)
# 
$IPTABLES -N Cid17843X27745.0
$IPTABLES -A INPUT -p tcp -m tcp  --dport 22 -m state --state NEW  -j Cid17843X27745.0 
$IPTABLES -A Cid17843X27745.0  -s 192.168.1.110   -j ACCEPT 
$IPTABLES -A Cid17843X27745.0  -s 192.168.1.111   -j ACCEPT 
$IPTABLES -A Cid17843X27745.0  -s 192.168.1.112   -j ACCEPT 
      

The generated iptables command is placed only in the INPUT chain because it controls access to the firewall and not to any addresses across it. The first iptables command matches chain, tcp port and state. If this rule does not match the packet, there is no need to waste CPU cycles checking source IP addresses. However, if the first rule matches, it passes control to the special user-defined chain "Cid17843X27745.0", which checks the source address of the packet. If the compiler were to generate an iptables script not using this temporary chain, it would end up comparing the TCP port and state three times, together with each possible source address. This can be rather wasteful if the rule is to match a lot of addresses. Separation of the matches using a temporary chain can improve performance a lot.

The compiler decides whether to use the temporary chain not because administrator used an object group in source in the original rule in the GUI, but because it determined that in the end it needs to compare source address of the packet against several addresses defined in the policy. If the group contained just one address, the generated iptables script would have consisted of just one iptables command without the temporary chain. If there was no group in "Source" of the rule but instead all these host objects were placed in "source" of the rule directly, the generated iptables script would look exactly like shown above, using a temporary chain for optimization.

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

table <tbl.r0.d> { 192.0.2.1 , 192.168.1.1 } 
table <tbl.r0.s> { 192.168.1.110 , 192.168.1.111 , 192.168.1.112 } 

# Rule  0 (global)
# 
pass  quick inet proto tcp  from <tbl.r0.s>  to <tbl.r0.d> port 22 keep state 
      

The policy compiler for PF extensively uses tables to produce compact code. PF tables are reused when needed.

Here is the configuration generated for PIX:

object-group network inside.id20599X27745.src.net.0
 network-object  host 192.168.1.110 
 network-object  host 192.168.1.111 
 network-object  host 192.168.1.112 
 exit

! Rule  0 (global)
! 
access-list inside_acl_in  remark 0 (global)
access-list inside_acl_in permit tcp object-group inside.id20599X27745.src.net.0
         host 192.0.2.1 eq 22 
access-list inside_acl_in permit tcp object-group inside.id20599X27745.src.net.0
         host 192.168.1.1 eq 22 
! 
      

As in the case of iptables, it is not that a group object was used in the original rule what triggered using object-group PIX clause. The compiler always checks the number of objects it needs to compare the packet against and uses object-groups statements to optimize generated code as appropriate.

 

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