NavigationUser loginPost This Page toWho's onlineThere are currently 0 users and 1 guest online.
Who's new
Search |
OpenBSD PF - More About PFIntroductionThis presentation is a follow-up to dwc's PF introduction and is part 2 of the PF presentation series. We continue to explore the PF packet filter in its use as a firewall on its native platform, OpenBSD. This presentation covers a subset of the features presented in the PF FAQ and the pf.conf(5) manual page. Refer to these resources for more information. More about PFIn the introduction to PF, we were presented with some of the fundamental components of a PF firewall including basic and stateful packet filtering, NAT, port redirection, and AuthPF. This presentation covers some of these in more depth and introduces other features of PF. Order of evaluationAn important concept to understand with any firewall implementation is the order of evaluation, or in other words the order in which rules in the ruleset take effect. PF uses a last match wins paradigm, meaning that the last matching filter rule a packet hits takes precedence. Note that this detail can be changed for increased flexibility by using the quick keyword and various state tracking options. It also means that a default filter policy can be established by placing a default rule at the top of the ruleset; assuming none of the following rules in the ruleset specifically match packets as they traverse the firewall, the "catch-all" rule will match. Here is an example:
---snip---
block all
pass in on $ext_if inet proto tcp to $web_server port 80 \
flags S/SA keep state
pass out on $int_if inet proto tcp to $web_server port 80 \
flags S/SA keep state
---snip---
In this example, all traffic is blocked at the firewall, both inbound and outbound, unless it matches the HTTP traffic which should be allowed in to the web server. As mentioned, normal rule evaluation can be altered with the use of the quick keyword on a rule. A packet which matches a "quick" rule will not continue to be evaluated against the remaining rules in the ruleset; a match against a quick rule is immediately considered "last match". As an example:
---snip---
block all
pass in quick log on $ext_if inet proto tcp from 192.0.34.166 \
to $web_server port 80 flags S/SA keep state
pass in on $ext_if inet proto tcp to $web_server port 80 \
flags S/SA keep state
pass out on $int_if inet proto tcp to $web_server port 80 \
flags S/SA keep state
---snip---
The use of the quick keyword in the first pass rule above makes sure that traffic from 192.0.34.166 is logged; without the quick option, evaluation would continue and the packet would match the following rule which does not log the connection. It is also important to understand the order in which translation rules apply in the ruleset. In PF, translations occur before filtering. This is important to understand when building a ruleset that uses both filtering rules and NAT or RDR rules; since translation happens before filtering, filter rules will need to use the translated addresses and ports to match properly. Block policyFirewalls can block traffic in two main ways, and which one you use depends on your goals. The first and most common way is to have the firewall silently drop packets which are not allowed to pass through the packet filter. This has the effect of simply causing the traffic to be discarded and disappear into a black hole. When this occurs, delays in connection attempts result; for example, a client attempting to reach a web server behind a firewall which drops connection attempts will experience a delay of several seconds until which point the user is notified that the connection timed out. This block policy is generally considered "stealthy" and oftentimes hides the fact that a firewall even exists; most of the time, users just notice that their communication is blocked with no indication why. The alternative policy is to use one of the return options which causes the firewall to communicate back to the client when its connection attempts are blocked. While this will typically give away the presence of the firewall, it results in immediate notification that communication has been denied and eliminates timeouts. In certain cases this can be desired. One example of such a case is when a service uses the ident facility to attempt to find out information about a connecting client. Two services that can utilize ident are IRC and SMTP. As an example, when clients attempt to connect to some IRC servers, the connection cannot be completed until the IRC server completes an ident lookup against the client. If the incoming ident lookup is dropped silently, the connecting client will notice a significant delay in the connection until the lookup times out. If a return option is used, the inbound ident lookup can be sent a RST packet, immediately terminating the lookup and allowing the client to connect immediately. Example: ---snip--- block all block return in on $ext_if inet proto tcp to any port 113 pass out on $ext_if keep state pass in on $int_if keep state ---snip--- In the above example, incoming ident lookups match the second rule, which will return an immediate RST to the IRC server. LoggingThe ability for a packet filter to perform logging is important for two reasons. It gives the firewall administrator a way to debug the ruleset evaluation, and it can give audit trails information about policy violations for network traffic. PF supports logging, using an innovative method of integrating tcpdump(8) into the logging system. As well, PF internal operations are logged via the kernel and can be captured in syslog. To enable logging for a rule, you can simply enable the log keyword. Logging may be used on pass and block rules alike. In order for logging to be enabled, the pflog(4) interface must be active and to write logs out to disk, the pflogd(8) daemon must be running.
ext_if = sis0
bad_pub_ports = "{ ssh, telnet, exec, shell, www, https }"
block in log on $ext_if inet proto tcp from any to ($ext_if) \
port $bad_pub_ports
The above example enables logging for any protocols defined in $bad_pub_ports that are seen incomign on sis0. If any packets match this rule, a log message is sent to the pflog(4) subsystem for handling. Stateful optionsThe stateful filtering options in PF are among the most important that can be used. Stateful filtering refers to connection state, and relates to the ability of the packet filter to gain an understanding of traffic as part of related flows rather than individual packets on the wire. TCP is a stateful protocol by design and its connection-oriented design lends well to stateful filtering. Even for relatively "connectionless" protocols such as UDP and ICMP, PF is able to filter in such a way that takes advantage of implicit state-like aspects. The advantages of stateful filtering are twofold. First, evaluating connection flows based on a state table allows PF to acheive higher performance than it would evaluating each rule in the ruleset sequentially for a match. Prior to evaluating the rules in the ruleset, PF will consult its state table to find out if the packet is part of an already established connection or authorized flow. The structure of the state table allows very rapid searching. Also, analyzing packets based on state gives PF the ability to apply more intelligent decision making to its filtering policy, since it can take into consideration more specific details of the traffic flow such as sequence numbers and flags set as part of the connection. In relation to the state tracking options supported by PF, several keywords can be used on the filter rules that impact how PF impacts the state tracking engine.
Operating system fingerprintingA fairly unique feature of PF is to be able to filter packets based on the operating system of traffic matched by filter rules. It is given this ability by the clever use of the p0f passive fingerprinting utility, and is useful for driving OS-based filtering policies. Example: pass out proto tcp from any os OpenBSD keep state block out proto tcp from any os Windows block out from any os "unknown" Interface modifiersThere are a number of options that make writing portable rulesets easier in PF, such as macros and interface groups. Another useful feature is that of interface modifiers, which allow you to define interface-bound attributes for filter targets. For example, specifying the :0 modifier after an interface name specifies the primary IP address of the interface, disregarding any IP aliases that are tied to it. (The default is to apply the filter to all IP addresses on the interface, including aliases). Another option is the :network modifier, which consults the interface's IP settings and represents the locally connected subnet of that interface. In this way, if the network address range used on that interface's segment ever changes, any references to the subnet will be automatically reflected in those rules. Example:
pass in on $int_if inet proto icmp from $int_if:network to \
$int_if:0 icmp-type echoreq keep state
The above rule allows the subnet attached to $int_if to ping the inside interface of the firewall, but only the primary IP address of the interface (assuming there are also aliases configured). So if the IP address of $int_if is 10.0.1.1 and the subnet mask is 255.255.255.0, $int_if:network will really be 10.0.1.0/24. Symbolic protocol namesPF is capable of reading symbolic protocol names from the file /etc/services in order to determine the port number. This can make the ruleset more understandable in cases where unfamiliar protocols are used in the ruleset. For example:
pass in on $int_if inet proto udp from $monitor to $int_if \
port snmp keep state
The above rule uses the word snmp for the port, which is looked up to be port 161 in the services file. LoggingThe final item we cover in this presentation is how logging is handled on a PF firewall. We saw above how to enable logging for rules in the ruleset. Depending on the configuration you've enabled, logs can now be viewed in one of two locations.
The most useful aspect of using tcpdump to view the log files is the flexibility it provides in filtering the logs for particular attributes. Tcpdump on OpenBSD has been modified to allow you to use any of the BPF style filter options such as source and destination address and port number, protocol types, and several other attributes that are PF-specific, such as:
Using these filter options, flexible log analysis can occur. Here are some examples:
$ tcpdump -nettt -i pflog0
tcpdump: WARNING: pflog0: no IPv4 address assigned
tcpdump: listening on pflog0, link-type PFLOG
Sep 29 10:10:14.504313 rule 16/(match) block in on sis1: 10.0.1.4.33855 > 10.0.1.1.80:
[|tcp] (DF) [tos 0x10]
Above we attach tcpdump to the pflog0 device and see a blocked packet logged. The host 10.0.1.4 attempted to connect to 10.0.1.1 on port 80, and we see that the filter policy contains a block rule for this connection on line 16 of the ruleset. $ tcpdump -nettt -r /var/log/pflog action block and dst port 80 \ and dst host 10.0.1.1 tcpdump: WARNING: snaplen raised from 96 to 116 Sep 29 10:16:00.667286 rule 16/(match) block in on sis1: 10.0.1.4.33678 > 10.0.1.1.80: S 3907633761:3907633761(0) win 5840 The above example reads from the log file on disk instead of interactively from the pflog0 device. It also uses a specific filter statement to find any packets blocked going to port 80 on the host 10.0.1.1. This query returns two logged packets which match those parameters. |
Upcoming eventsEvents
OpenBSD ErrataOpenBSD Journal |
|||||||||||||||||||||||||||||||||||||||||||||||||
Recent comments
1 year 13 weeks ago
1 year 13 weeks ago
1 year 18 weeks ago
1 year 22 weeks ago
1 year 26 weeks ago
1 year 26 weeks ago
1 year 29 weeks ago
1 year 31 weeks ago
1 year 42 weeks ago
1 year 48 weeks ago