.\" $OpenBSD: pf.conf.5,v 1.10 2001/07/31 09:02:18 wilfried Exp $ .\" .\" Copyright (c) 2001, Daniel Hartmeier .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" .\" - Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" - Redistributions in binary form must reproduce the above .\" copyright notice, this list of conditions and the following .\" disclaimer in the documentation and/or other materials provided .\" with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS .\" "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT .\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS .\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE .\" COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, .\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, .\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; .\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER .\" CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN .\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" .Dd July 8, 2001 .Dt PF.CONF 5 .Os .Sh NAME .Nm pf.conf .Nd filter rule configuration file for packet filtering .Sh DESCRIPTION The .Xr pf 4 packet filter drops, passes and modifies packets according to the rules defined in this file. For each packet inspected by the filter, the set of rules is evaluated from top to bottom, and the last matching rule decides what action is performed. .Sh GRAMMAR Syntax for filter rules in BNF: .Bd -literal rule = action ( "in" | "out" ) [ "log" | "log-all" ] [ "quick" ] [ "on" interface-name ] [ "proto" ( proto-name | proto-number ) ] hosts [ flags ] [ icmp-type ] [ "keep-state" ] [ "no-df" ] [ "min-ttl" number ]. action = "pass" | "block" [ return ] | "scrub" . return = "return-rst" | "return-icmp" [ "(" ( icmp-code-name | icmp-code-number ) ")" ] . hosts = "all" | "from" ( "any" | host ) [ port ] "to" ( "any" | host ) [ port ] . host = [ "!" ] address [ "/" mask-bits ] . port = "port" ( unary-op | binary-op ) . unary-op = ( "=" | "!=" | "<" | "<=" | ">" | ">=" ) ( port-name | port-number ) . binary-op = port-number ( "<>" | "><" ) port-number . flags = "flags" ( flag-set | flag-set "/" flag-set | "/" flag-set ) . flag-set = [ "F" ] [ "S" ] [ "R" ] [ "P" ] [ "A" ] [ "U" ] . icmp-type = "icmp-type" ( icmp-type-name | icmp-type-number ) [ "code" ( icmp-code-name | icmp-code-number ) ] . .Ed .Sh FILTER RULES Filter rules are typically manipulated using .Xr pfctl 8 . Filter rules are loaded from a text file into the kernel using .Pp .Cm # pfctl -R file .Pp which replaces the active rule set with the new one. The active rule set can be displayed using .Pp .Cm # pfctl -s r .Pp For each packet processed by the packet filter, the filter rules are evaluated in sequential order, from first to last. Each rule either matches the packet or doesn't. The last matching rule decides what action is taken. .Pp If no rule matches the packet, the default action is .Em pass . .Pp To block everything by default and only pass packets that match explicit rules, one uses .Bd -literal .Cm block in all .Cm block out all .Ed .Pp as the first two rules. .Sh ACTIONS .Bl -tag -width Fl .It Em pass The packet is passed. .It Em block The packet is blocked. Optionally, the filter can return a TCP RST or ICMP UNREACHABLE packet to the sender, where applicable. .It Em scrub The packet is run through normalization/defragmentation. Scrub rules are not considered last matching rules. .El .Sh LOGGING .Bl -tag -width Fl .It Em log In addition to the action specified, a log message is generated. .It Em log-all Used with .Sq keep state rules. Not only the packet that creates state is logged, but all packets of the connection. .El .Pp The log messages can be viewed with tcpdump: .Bd -literal .Cm # ifconfig pflog0 up .Cm # tcpdump -n -i pflog0 .Ed .Sh QUICK If a packet matches a rule which has the .Sq quick option set, this rule is considered the last matching rule, and evaluation of subsequent rules is skipped. .Sh PARAMETERS The rule parameters specify for what packets a rule applies. A packet always comes in on or goes out through one interface. Most parameters are optional. If a parameter is specified, the rule only applies to packets with matching attributes. .Ss in or out The rule applies to incoming or outgoing packets. Either .Em in or .Em out must be specified. To cover both directions, two rules are needed. .Ss on The rule applies only to packets coming in on or going out through this particular interface. .Ss proto The rule applies only to packets of this protocol. Common protocols used here are tcp, udp and icmp. .Ss from port to port The rule applies only to packets with the specified source and destination addresses/ports. Addresses can be specified in CIDR notation (matching netblocks) and ports can be specified using these operators .Bd -literal = (equal), != (unequal), < (lesser), <= (lesser or equal), > (greater), >= (greater or equal), >< (range) and <> (except range). .Ed .Pp >< and <> are binary operators (they take two arguments), and the range doesn't include the limits, for instance: .Bl -tag -width Fl .It Em port 2000 >< 2004 means .Sq all ports > 2000 and < 2004 , hence ports 2001, 2002 and 2003. .It Em port 2000 <> 2004 means .Sq all ports < 2000 or > 2004 , hence ports 1-1999 and 2005-65535. .El .Pp The host and port specifications are optional, as the following examples show: .Bd -literal pass in all pass in from any to any pass in proto tcp from any port <= 1024 to any pass in proto tcp from any to any port = 25 pass in proto tcp from 10.0.0.0/8 port > 1024 to ! 10.1.2.3 port != 22 .Ed .Ss flags | / | / The rule only applies to TCP packets that have the flags set out of set . Flags not specified in are ignored. .Bl -tag -width Fl .It Em flags S/S Flag SYN is set. The other flags are ignored. .It Em flags S/SA Of SYN and ACK, exactly SYN is set. SYN, SYN+PSH, SYN+RST match, but SYN+ACK, ACK and ACK+RST don't. This is more restrictive than the previous example. .It Em flags S If the second set is not specified, it defaults to FSRPAU. Hence, only packets with SYN set and all other flags unset match this rule. This is more restrictive than the previous example. .It Em flags /SFRA If the first set is not specified, it defaults to none. All of SYN, FIN, RST and ACK must be unset. .El .Ss icmp-type code The rule only applies to ICMP packets with the specified type and code. This parameter is only valid for rules that cover protocol icmp. .Sh STATEFUL INSPECTION .Em pf is a stateful packet filter, which means it can track the state of a connection. Instead of passing all traffic to port 25, for instance, one can pass only the initial packet and keep state. .Pp If a packet matches a pass ... keep-state rule, the filter creates a state for this connection and automatically lets pass all following packets of that connection. .Pp Before any rules are evaluated, the filter checks whether the packet matches any state. If it does, the packet is passed without evaluation of any rules. .Pp States are removed after the connection is closed or has timed out. .Pp This has several advantages. Comparing a packet to a state involves checking its sequence numbers. If the sequence numbers are outside the narrow windows of expected values, the packet is dropped. This prevents spoofing attacks, where the attacker sends packets with a fake source address/port but doesn't know the connection's sequence numbers. .Pp Also, looking up states is usually faster than evaluating rules. If one has 50 rules, all of them are evaluated sequentially in O(n). Even with 50'000 states, only 16 comparisons are needed to match a state, since states are stored in a binary search tree that allows searches in O(log2 n). .Pp For instance: .Bd -literal block out all block in all pass out proto tcp from any to any flags S/SA keep state pass in proto tcp from any to any port = 25 flags S/SA keep state .Ed .Pp This rule set blocks everything by default. Only outgoing connections and incoming connection to port 25 are allowed. The inital packet of each connection has the SYN flag set, will be passed and creates state. All further packets of these connections are passed if they match a state. .Pp Specifying flags S/SA restricts state creation to the initial SYN packet of the TCP handshake. One can also be less restrictive, and allow state creation from intermediate .Pq non-SYN packets. This will cause pf to synchronize to existing connections, for instance if one flushes the state table. .Pp For UDP, which is stateless by nature, keep state will create state as well. UDP packets are matched to states using only host addresses and ports. .Pp ICMP messages fall in two categories: ICMP error messages, which always refer to a TCP or UDP packet, are matched against the refered to connection. If one keeps state on a TCP connection, and an ICMP source quench message refering to this TCP connection arrives, it will be matched to the right state and get passed. .Pp For ICMP queries, keep state creates an ICMP state, and .Em pf knows how to match ICMP replies to states. For example .Bd -literal pass out proto icmp all icmp-type echoreq keep state .Ed .Pp lets echo requests .Pq pings out, creates state, and matches incoming echo replies correctly to states. .Pp Note: nat/rdr rules .Po see .Xr nat.conf 5 .Pc implicitely create state for connections. .Sh NORMALIZATION Packet normalization is envoked via the .Pa scrub directive. Normalization is used to sanitize packet content in such a way that there are no ambiguities in packet interpretation on the receiver side. .Pp The normalizer does full IP fragment reassembly to prevent attacks that confuse intrusion detection systems by sending overlapping IP fragments. .Ss no-df Clears the .Pa dont-fragment bit from a matching ip packet. .Ss min-ttl Enforces a minium ttl for matching ip packets. .Sh EXAMPLES .Bd -literal # My external interface is kue0 (157.161.48.183, my only routable address) # and the private network is 10.0.0.0/8, for which i'm doing NAT. # block and log everything by default block out log on kue0 all block in log on kue0 all block return-rst out log on kue0 proto tcp all block return-rst in log on kue0 proto tcp all block return-icmp out log on kue0 proto udp all block return-icmp in log on kue0 proto udp all # block and log outgoing packets that don't have my address as source, # they are either spoofed or something is misconfigured (NAT disabled, # for instance), we want to be nice and don't send out garbage. block out log quick on kue0 from ! 157.161.48.183 to any # silently drop broadcasts (cable modem noise) block in quick on kue0 from any to 255.255.255.255 # block and log incoming packets from reserved address space and invalid # addresses, they are either spoofed or misconfigured, we can't reply to # them anyway (hence, no return-rst). block in log quick on kue0 from 10.0.0.0/8 to any block in log quick on kue0 from 172.16.0.0/12 to any block in log quick on kue0 from 192.168.0.0/16 to any block in log quick on kue0 from 255.255.255.255/32 to any # ----------------------------------------------------------------------- # ICMP # ----------------------------------------------------------------------- # pass out/in certain ICMP queries and keep state (ping) # state matching is done on host addresses and ICMP id (not type/code), # so replies (like 0/0 for 8/0) will match queries # ICMP error messages (which always refer to a TCP/UDP packet) are # handled by the TCP/UDP states pass out on kue0 proto icmp all icmp-type 8 code 0 keep state pass in on kue0 proto icmp all icmp-type 8 code 0 keep state # ----------------------------------------------------------------------- # UDP # ----------------------------------------------------------------------- # pass out all UDP connections and keep state pass out on kue0 proto udp all keep state # pass in certain UDP connections and keep state (DNS) pass in on kue0 proto udp from any to any port = domain keep state # ----------------------------------------------------------------------- # TCP # ----------------------------------------------------------------------- # pass out all TCP connections and keep state pass out on kue0 proto tcp all keep state # pass in certain TCP connections and keep state (SSH, SMTP, DNS, IDENT) pass in on kue0 proto tcp from any to any port = ssh keep state pass in on kue0 proto tcp from any to any port = smtp keep state pass in on kue0 proto tcp from any to any port = domain keep state pass in on kue0 proto tcp from any to any port = auth keep state .Ed .Sh FILES .Bl -tag -width "/etc/pf.conf" -compact .It Pa /etc/pf.conf .It Pa /etc/services .El .Sh SEE ALSO .Xr pf 4 , .Xr nat.conf 5 , .Xr services 5 , .Xr pfctl 8 .Pp .Pa http://www.obfuscation.org/ipf/ has an extensive filter rule tutorial which for the most part applies to .Em pf as well. .Sh HISTORY The .Nm file format appeared in .Ox 3.0 .