ipf

, ipf.conf

- IP packet filter rule syntax

Description

The ipf or ipf.conf configuration files are associated with the Solaris IP
Filter feature. See ipfilter(5).

A rule file for ipf(1M) can have any name or can be
stdin. You can use ipfstat(1M) output as input to ipf(1M). ipfstat outputs
parseable rules, suitable for input to ipf, when displaying the internal kernel filter
lists. Thus, for example, to remove all filters on input packets, you
can enter:

# ipfstat -i | ipf -rf -

Grammar

The IP filter feature uses the grammar shown below to construct filtering
rules. The syntax is simplified for readability. Note that some combinations that
match this grammar are disallowed by the software because they do not
make sense (for example, tcp flags for non-TCP packets).

Filter Rules

Filter rules are checked in order, with the last matching rule determining
the treatment of the packet. An exception to this is the quick
option, which is discussed below.

By default, filters are installed at the end of the kernel's filter
lists. Prepending a rule with @<num> causes it to be inserted as
the <num>th entry in the current list. This is especially useful when
modifying and testing active filter rule sets. See ipf(1M) for more information.

The simplest valid rules are:

block in all
pass in all
log out all
count in all

These rules do not have an effect on filtering, but are listed
here to illustrate the grammar.

Actions

Each rule must have an action. The action indicates what to do
with the packet if it matches the filter rule. The IP filter
feature recognizes the following actions:

block

Indicates that a packet should be flagged to be dropped. In response to blocking a packet, the filter can be instructed to send a reply packet, either an ICMP packet (return-icmp), an ICMP packet that fakes being from the original packet's destination (return-icmp-as-dest), or a TCP reset (return-rst). An ICMP packet can be generated in response to any IP packet and its type can optionally be specified, but a TCP reset can only be used with a rule that is being applied to TCP packets. When using return-icmp or return-icmp-as-dest, it is possible to specify the actual unreachable type. That is, whether it is a network unreachable, port unreachable, or even administratively prohibited. You do this by enclosing the ICMP code associated with the action in parentheses directly following return-icmp or return-icmp-as-dest. For example:

block return-icmp(11) ...

The preceding entry causes a return of a Type-Of-Service (TOS) ICMP unreachable error.

pass

Flag the packet to be let through the filter without any action being taken.

log

Causes the packet to be logged (as described in the LOGGING section, below) and has no effect on whether the packet will be allowed through the filter.

count

Causes the packet to be included in the accounting statistics kept by the filter and has no effect on whether the packet will be allowed through the filter. These statistics are viewable with ipfstat(1M).

skip <num>

Causes the filter to skip over the next <num> filter rules. If a rule is inserted or deleted inside the region being skipped over, then the value of <num> is adjusted appropriately.

auth

Allows authentication to be performed by a user-space program running and waiting for packet information to validate. The packet is held for a period of time in an internal buffer while it waits for the program to return to the kernel the “real” flags for whether it should be allowed through. Such a program might look at the source address and request some sort of authentication from the user (such as a password) before allowing the packet through or telling the kernel to drop it if the packet is from an unrecognized source.

The word following the action keyword must be either in or out.
Each packet moving through the kernel is either inbound or outbound. “Inbound”
means that a packet has just been received on an interface and
is moving towards the kernel's protocol processing. “Outbound” means that a packet has
been transmitted or forwarded by the stack and is on its way
to an interface. There is a requirement that each filter rule explicitly
state on which side of the I/O it is to be used.

Options

The currently supported options are listed below. Where you use options, you
must use them in the order shown here.

log

If this is the last matching rule, the packet header is written to the ipl log, as described in the LOGGING section below.

quick

Allows short-cut rules to speed up the filter or override later rules. If a packet matches a filter rule that is marked as quick, this rule will be the last rule checked, allowing a “short-circuit” path to avoid processing later rules for this packet. The current status of the packet (after any effects of the current rule) determine whether it is passed or blocked.

If the quick option is missing, the rule is taken to be a “fall-through” rule, meaning that the result of the match (block or pass) is saved and that processing will continue to see if there are any more matches.

on

Allows an interface name to be incorporated into the matching procedure. Interface names are as displayed by netstati. If this option is used, the rule matches only if the packet is going through that interface in the specified direction (in or out). If this option is absent, the rule is applied to a packet regardless of the interface it is present on (that is, on all interfaces). Filter rule sets are common to all interfaces, rather than having a filter list for each interface.

This option is especially useful for simple IP-spoofing protection: packets should be allowed to pass inbound only on the interface from which the specified source address would be expected. Others can be logged, or logged and dropped.

dup-to

Causes the packet to be copied, with the duplicate packet sent outbound on a specified interface, optionally with the destination IP address changed to that specified. This is useful for off-host logging, using a network sniffer.

to

Causes the packet to be moved to the outbound queue on the specified interface. This can be used to circumvent kernel routing decisions, and, if applied to an inbound rule, even to bypass the rest of the kernel processing of the packet. It is thus possible to construct a firewall that behaves transparently, like a filtering hub or switch, rather than a router. The fastroute keyword is a synonym for this option.

Matching Parameters

The keywords described in this section are used to describe attributes of
the packet to be used when determining whether rules do or do
not match. The following general-purpose attributes are provided for matching and must
be used in the order shown below.

tos

Packets with different Type-Of-Service values can be filtered. Individual service levels or combinations can be filtered upon. The value for the TOS mask can be represented either as a hexadecimal or decimal integer.

ttl

Packets can also be selected by their Time-To-Live value. The value given in the filter rule must exactly match that in the packet for a match to occur. This value can be given only as a decimal integer.

proto

Allows a specific protocol to be matched against. All protocol names found in /etc/protocols are recognized and can be used. However, the protocol can also be given as a decimal number, allowing for rules to match your own protocols and for new protocols.

The special protocol keyword tcp/udp can be used to match either a TCP or a UDP packet and has been added as a convenience to save duplication of otherwise-identical rules.

IP addresses can be specified in one of two ways: as a
numerical address/mask, or as a hostname mask/netmask. The hostname can be either
of the dotted numeric form or a valid hostname, from the hosts
file or DNS (depending on your configuration and library). There is no special
designation for networks, but network names are recognized. Note that having your
filter rules depend on DNS results can introduce an avenue of attack
and is discouraged.

There is a special case for the hostname any, which is taken
to be 0.0.0.0/0 (mask syntax is discussed below) and matches all IP
addresses. Only the presence of any has an implied mask. In all
other situations, a hostname must be accompanied by a mask. It is possible
to give any a hostmask, but in the context of this language,
it would accomplish nothing.

The numerical format x/y indicates that a mask of y consecutive 1
bits set is generated, starting with the MSB, so that a y
value of 16 would result in 0xffff0000. The symbolic xmasky
indicates that the mask y is in dotted IP notation or a
hexadecimal number of the form 0x12345678. Note that all the bits of
the IP address indicated by the bitmask must match the address on
the packet exactly; there is currently not a way to invert the sense
of the match or to match ranges of IP addresses that do
not express themselves easily as bitmasks.

If a port match is included, for either or both of source
and destination, then it is only applied to TCP and UDP packets.
This is equivalent to proto tcp/udp. When composing port comparisons, either the service
name or an integer port number can be used. Port comparisons can be
done in a number of forms, with a number of comparison operators,
or you can specify port ranges. When the port appears as part
of the from object, it matches the source port number. When it
appears as part of the to object, it matches the destination port number.
See EXAMPLES.

The all keyword is essentially a synonym for “from any to any”
with no other match parameters.

Following the source and destination matching parameters, you can use the following
additional parameters:

with

Used to match irregular attributes that some packets might have associated with them. To match the presence of IP options in general, use with ipopts. To match packets that are too short to contain a complete header, use with short. To match fragmented packets, use with frag. For more specific filtering on IP options, you can list individual options.

Before any parameter used after the with keyword, you can insert the word not or no to cause the filter rule to match only if the option(s) is not present.

Multiple consecutive with clauses are allowed. Alternatively, you can use the keyword and in place of with. This alternative is provided to make the rules more readable (“with ... and ...”). When multiple clauses are listed, all clauses must match to cause a match of the rule.

flags

Effective only for TCP filtering. Each of the letters possible represents one of the possible flags that can be set in the TCP header. The association is as follows:

F - FIN

S - SYN

R - RST

P - PUSH

A - ACK

U - URG

The various flag symbols can be used in combination, so that SA matches a SYN-ACK combination in a packet. There is nothing preventing the specification of combinations, such as SFR, that would not normally be generated by fully conformant TCP implementations. However, to guard against unpredictable behavior, it is necessary to state which flags you are filtering against. To allow this, it is possible to set a mask indicating against which TCP flags you wish to compare (that is, those you deem significant). This is done by appending /<flags> to the set of TCP flags you wish to match against, for example:

... flags S

Becomes flags S/AUPRFS and matches packets with only the SYN flag set.

... flags SA

Becomes flags SA/AUPRFSC and matches any packet with only the SYN and ACK flags set.

... flags S/SA

Matches any packet with just the SYN flag set out of the SYN-ACK pair, which is the common establish keyword action. S/SA will not match a packet with both SYN and ACK set, but will match SFP.

icmp-type

Effective only when used with proto icmp and must not be used in conjunction with flags. There are a number of types, which can be referred to by an abbreviation recognized by this language or by the numbers with which they are associated. The most important type from a security point of view is the ICMP redirect.

Keep History

The penultimate parameter that can be set for a filter rule is
whether or not to record historical information for a packet, and what
sort to keep. The following information can be kept:

state

Keeps information about the flow of a communication session. State can be kept for TCP, UDP, and ICMP packets.

frags

Keeps information on fragmented packets, to be applied to later fragments.

Presence of these parameters allows matching packets to flow straight through, rather
than going through the access control list.

Groups

The last pair of parameters control filter rule grouping. By default, all
filter rules are placed in group 0 if no other group is
specified. To add a rule to a non-default group, the group must
first be started by creating a group head. If a packet matches
a rule which is the head of a group, the filter processing then
switches to the group, using that rule as the default for the
group. If quick is used with a head rule, rule processing is
not stopped until it has returned from processing the group.

A rule can be both the head for a new group and
a member of a non-default group (head and group can be used
together in a rule).

head <n>

Indicates that a new group (number <n>) should be created.

group <n>

Indicates that the rule should be put in group (number <n>) rather than group 0.

Logging

When a packet is logged, by means of either the log action
or log option, the headers of the packet are written to the
ipl packet logging pseudo-device. Immediately following the log keyword, you can use
the following qualifiers in the order listed below:

body

Indicates that the first 128 bytes of the packet contents will be logged after the headers.

first

If log is being used in conjunction with a keep option, it is recommended that you also apply this option so that only the triggering packet is logged and not every packet which thereafter matches state information.

or-block

Indicates that, if for some reason, the filter is unable to log the packet (such as the log reader being too slow), then the rule should be interpreted as if the action was block for this packet.

levelloglevel

Indicates what logging facility and priority (or, if the default facility is used, priority only) will be used to log information about this packet using ipmon's -s option.

Loopback Filtering (Inter-Zone)

By default, the IP Filter feature will not filter or intercept any
packets that are local to the machine. This includes traffic to or
from the loopback addresses (127.0.0.1, and so forth), traffic between sockets that
are on the same host (for example, from eri0 to eri1), and
traffic between zones.

To enable loopback or zone filtering, you must add the following line
to ipf.conf file:

set intercept_loopback true;

This line must be placed before any block or pass rules in
this file or, put another way, it must be the first non-comment
line in ipf.conf.

When you enable filtering of packets in any one of the scenarios
described above, you enabling filtering for all them. That is, when you
enable the IP Filter feature to intercept packets between zones, you also
cause it to receive packets that are involved in loopback traffic.

Examples

Example 1 Using the quick Option

The quick option works well for rules such as:

block in quick from any to any with ipopts

This rule matches any packet with a non-standard header length (IP options
present) and aborts further processing of later rules, recording a match and
also indicating that the packet should be blocked.

Example 2 Using the Fall-through Nature of Rule Parsing

The “fall-through” rule parsing allows for effects such as the following:

block in from any to any port < 6000
pass in from any to any port >= 6000
block in from any to any port > 6003

These rules set up the range 6000-6003 as being permitted and all
others being denied. Note that the effect of the first rule is
overridden by subsequent rules. Another (easier) way to do the same is:

block in from any to any port 6000 <> 6003
pass in from any to any port 5999 >< 6004

Note that both the block and pass are needed here to effect
a result, because a failed match on the block action does not
imply a pass. It implies only that the rule has not taken
effect. To then allow ports lower than 1024, a rule such as:

pass in quick from any to any port < 1024

...would be needed before the first block. To create a new group
for processing all inbound packets on le0/le1/lo0, with the default being to
block all inbound packets, you would use a rule such as:

block in all
block in quick on le0 all head 100
block in quick on le1 all head 200
block in quick on lo0 all head 300

and to then allow ICMP packets in on le0 only, you would
use:

pass in proto icmp all group 100

Note that because only inbound packets on le0 are processed by group
100, there is no need to respecify the interface name. Likewise, you
could further breakup processing of TCP as follows:

block in proto tcp all head 110 group 100
pass in from any to any port = 23 group 110

...and so on. The last line, if written without the groups, would
be:

pass in on le0 proto tcp from any to any port = telnet

Note, that if you wanted to specify port = telnet, you would need to
specify proto tcp, because the parser interprets each rule on its own and
qualifies all service and port names with the protocol specified.

Files

/etc/ipf/ipf.conf

Location of rules file that is read upon startup of IP Filter feature.