BSD DevCenter
oreilly.comSafari Books Online.Conferences.

advertisement


Changes in pf: Packet Filtering
Pages: 1, 2, 3, 4, 5, 6

Which interface (on), IP address (from, to), and port (port) combination should be used with NAT rules?



When you don't use NAT rules, it is fairly easy to decide which interface/IP address/port ought to be used for in a filtering rule. For example, if you want to limit access to port 80 on the external interface and only let TCP packets in, you'd use something like this:

pass in quick on $ext_if proto tcp from any to $ext_ad port 80

Things are different when you add NAT rules and additional subnets. Then a single block or pass rule might not be enough to properly structure the flow of traffic through the firewall. In such cases, always remember that packets redirected to another port/interface have to be filtered on the target port/interface. For example, the following rules redirect traffic from the external interface port 80 to a DMZ HTTP server port 8080:

ext_if         = "ne1"
ext_ad         = "x.x.x.x/32"
dmz_www_ad     = "192.168.2.3/32"
rdr_www_protos = "{tcp}"
rdr_www_port   = "8080"

rdr on $ext_if proto $rdr_www_protos from any \
	to $ext_ad port www -> $dmz_www_ad port $rdr_www_port

If you want to block all incoming connections except connections to port 80 on the external interface (which are redirected to port 8080 on the DMZ HTTP server), use:

block in on $ext_if all
pass  in on $ext_if inet proto tcp from any to $dmz_www_ad port 8080

The pass rule uses the DMZ HTTP host address for the destination IP address. The same goes for the destination port (8080 instead 80). If you used the IP address of the external interface and port 80, you'd never see any packets passed to the DMZ HTTP server. Similarly, if you wanted to block a redirected packet, you'd need to write a rule that matched the destination IP address/port after redirection.

After a packet is passed on the external interface, it may have to pass another test on the DMZ interface. This is optional, but it is prudent to filter traffic going in and out of the DMZ. For example, you might want to block all external traffic except HTTP going into the DMZ segment. This is accomplished with these rules:

block out on $dmz_if all
pass  out on $dmz_if inet proto tcp from any to $dmz_www_ad port 8080

Note that these rules are for packets leaving (out) the DMZ interface. Why is that? You need to remember that all rules are written relative to the firewall; a packet sent from the outside first matches in rules on the external interface, then it matches out rules on the DMZ interface, and then it reaches the HTTP server. A packet sent from the DMZ HTTP server to the outside matches in rules on the DMZ interface, out rules on the external interface, and then it reaches some external host.

The out rules shown earlier will also match packets sent from the private network segment. Such packets match in rules on the private interface and then the out rules on the DMZ interface.

Do you want to bypass the routing table or duplicate packets (fastroute, route-to, dup-to)?

Ordinarily, packets examined by pf(4) are routed according to the entries in the firewall's routing table, which should be enough in most cases. However, there might be times when you will want to bypass the routing table or to duplicate packets for intrusion detection or logging purposes. The following three keywords allow us to influence packet routing:

  • fastroute: use the routing table
  • route-to: bypass the routing table and route the packet through the interface whose name must be given after the route-to keyword. The name of the interface may be followed by the IP address of the host that should receive packets, when the IP address is used. The name and the address must be enclosed in parentheses, as in:
    pass in on $ext_if route-to ($log_if $log_ad) all
    pass in on $ext_if route-to $log_if all
  • dup-to: create a copy of the matching packet, bypass the routing table and route the copied packet through the interface whose name must be given after the dup-to keyword. The name of the interface may be followed by the IP address of the host that is supposed to receive the copies, when the IP address is used. The name and the address must be enclosed in parentheses. The original packet is routed using entries in the routing table.

The dup-to keyword is very useful for setting up a separate packet logging or intrusion detection system host. Simply add this rule to /etc/pf.conf on the firewall:

pass  in on $ext_if dup-to ($log_if $log_ad) all

Then run pf(4) on the logging host with a the following rule:

block in log on $ext_if all

If you want to tune logging parameters, read this and this.

Letting another host take care of logging or analysis of packets is a good thing, because it moves the additional load placed on the firewall's resources to another host. It makes logging setups like those described in one of my earlier articles unnecessary, while making the whole process of logging simpler and more stable. Of course, to create such setup you will need another machine and an additional network interface on the firewall (it's best to put the logging/analysis machine on a separate segment). In any case, if you plan to log traffic, read this, this, and this.

Unlike all other keywords that can be followed by some value, dup-to and route-to do not allow us to specify more than one interface or interface/address combination.

Which IP addressing family will be filtered (inet, inet6)?

pf(4) can filter packets with IPv4 (inet) and IPv6 (inet6) addresses. You select the addressing family with the inet (IPv4) or inet6 (IPv6) keywords. If you plan on dealing with IPv4 traffic only, add these rules for every interface on the firewall:

block in  quick inet6 all
block out quick inet6 all

Pages: 1, 2, 3, 4, 5, 6

Next Pagearrow





Sponsored by: