BSD DevCenter
oreilly.comSafari Books Online.Conferences.

advertisement


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

Which protocol(s) will be filtered (proto)?

Another layer of filtering is filtering by protocol name or number. This is done with an addition of the proto keyword followed by the name(s) or number(s) of protocols that the packets are formed in accordance with. The list of protocols can be found in /etc/protocols.



For example, if you want to let in only TCP packets, use this rule:

pass in quick on $ext_if proto tcp

Tip: Almost all popular services use TCP. You should block UDP packets sent to servers that only use TCP, because such packets are almost never legitimate traffic. If you do not know which protocol is used by which services, check /etc/protocols. This file is current as of the time of release of the OpenBSD system you are using. The latest and the freshest listings are always in the IANA's online database.

What is the packet's source address (from, any, all)?

Source address filtering is typically used to stop two kinds of packets: those originating from hosts with legal IP addresses that we do not want to accept traffic from, and those that carry spoofed source addresses. In the first case, you will want to block packets from legal IP addresses if they're giving you so much trouble that you'd rather not accept traffic from them. In the second case, you ought to block packets with spoofed source addresses for your own safety as they will never be legitimate traffic. The following rule blocks packets with spoofed source addresses sent from external hosts and arriving on the firewall's external interface:

$blockIPs = {10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, \
	224.0.0.0/4, 240.0.0.0/5, 127.0.0.0/8, 0.0.0.0}

block in quick on $ext_if from $blockIPs

Conversely, we can specify addresses of hosts that we want to accept traffic from, as in:

block in quick on $ext_if from ! $allow_ad to any

Tip: Note the exclamation mark (!), which negates the value that follows it, so the rule above reads "block incoming packets (and don't match them against other filtering rules) arriving on the external interface send from all IP addresses except $allow_ad and destined for any host."

There are two shortcuts that you can use to specify wider ranges of IP addresses. One is the any keyword, which when placed after from or to, matches any source (from any) or target (to any) address:

block in quick on $log_if from any to $log_ad
block in quick on $ext_if from $blockIPs to any

The second shortcut is the all keyword which replaces from any to any. The following two rules are synonymous:

block in on $ext_if from any to any
block in on $ext_if all

Tip: from and to go together, and you cannot write a rule with just either of them.

Source address specification is a required part of any packet filtering rule, even if you use an all-encompassing any or all shortcuts.

What is the source port of the packet (port)?

For a finer degree of control, we can block or pass packets sent from a specific port on the interface from which the matching packets were sent. The port specification is listed after the source address specification and is marked with the port keyword, as in:

block in on $ext_if proto tcp from any port 80

The port 80 is equivalent to port = 80 Other possible operators are <, >, <=, >=, !=, <>, and ><. Their use is shown in the following rules:

# block packets destined for port 80
block in on $ext_if proto tcp from any to $dmz_www_ad port = 80

# block packets destined for all ports except port 80
block in on $ext_if proto tcp from any to $dmz_www_ad port != 80

# block packets destined for ports lower than port 80
block in on $ext_if proto tcp from any to $dmz_www_ad port < 80

# block packets destined for ports lower than and port 80
block in on $ext_if proto tcp from any to $dmz_www_ad port <= 80

# block packets destined for ports higher than and equal to port 80
block in on $ext_if proto tcp from any to $dmz_www_ad port > 80

# block packets destined for ports higher than and equal to port 80
block in on $ext_if proto tcp from any to $dmz_www_ad port >= 80

# block packets destined for ports higher than port 80 and lower than port 1024
block in on $ext_if proto tcp from any to $dmz_www_ad port 80 >< 1024

# block packets destined for ports lower than port 80 and higher than port 1024
block in on $ext_if proto tcp from any to $dmz_www_ad port 80 <> 1024

Specifying port numbers makes sense only for those protocols that carry source port information (like TCP or UDP). That is why you need to use the proto keyword when you use the port keyword. Otherwise, pfctl(8) will complain and refuse to load rules.

Destination IP address (to, any, all)

Destination address filtering is typically used to pass only those packets that are destined to addresses where there are servers listening for connections, for example:

pass in on $ext_if from any to $dmz_www_ad

All syntax rules for source addresses discussed earlier are applicable to destination addresses.

Source target address specification is a required part of any packet filtering rule, even if you use an all-encompassing any or all shortcuts.

Destination port (port)

The destination port specification follows the destination address specification. All rules that apply to source ports, apply to destination ports. Of course, both are independent. You will probably use destination ports more often than source ports, as such rules are usually used to only let those packets through that are destined to ports where appropriate servers are listening, for example:

pass in on $ext_if proto tcp from any to $ext_www_ad  port $ext_www_port
pass in on $ext_if proto tcp from any to $ext_smtp_ad port $ext_smtp_port
pass in on $ext_if proto tcp from any to $ext_ftp_ad  port $ext_ftp_port

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

Next Pagearrow





Sponsored by: