


IPF(5)                                                     IPF(5)


NAME
       ipf - IP packet filter rule syntax

DESCRIPTION
       A  rule  file  for ipf may have any name or even be stdin.
       As ipfstat produces parseable rules as  output  when  dis-
       playing  the  internal  kernel  filter  lists, it is quite
       plausible to use its output to feed back into ipf.   Thus,
       to  remove  all  filters  on  input packets, the following
       could be done:

       # ipfstat -i | ipf -rf -

GRAMMAR
       The format used by ipf for construction of filtering rules
       can be described using the following grammar in BNF:

       filter-rule = [ insert ] action in-out [ options ] [ tos ] [ ttl ]
                  [ proto ] [ ip ] [ group ].

       insert    = "@" decnumber .
       action    = block | "pass" | log | "count" | skip | auth | call .
       in-out    = "in" | "out" .
       options   = [ log ] [ "quick" ] [ "on" interface-name [ dup ] [ froute ] ] .
       tos  = "tos" decnumber | "tos" hexnumber .
       ttl  = "ttl" decnumber .
       proto     = "proto" protocol .
       ip   = srcdst [ flags ] [ with withopt ] [ icmp ] [ keep ] .
       group     = [ "head" decnumber ] [ "group" decnumber ] .

       block     = "block" [ icmp[return-code] | "return-rst" ] .
       auth    = "auth" | "preauth" .
       log  = "log" [ "body" ] [ "first" ] [ "or-block" ] [ "level" loglevel ] .
       call = "call" [ "now" ] function-name .
       skip = "skip" decnumber .
       dup  = "dup-to" interface-name[":"ipaddr] .
       froute    = "fastroute" | "to" interface-name .
       protocol = "tcp/udp" | "udp" | "tcp" | "icmp" | decnumber .
       srcdst    = "all" | fromto .
       fromto    = "from" [ "!" ] object "to" [ "!" ] object .

       icmp = "return-icmp" | "return-icmp-as-dest" .
       object    = addr [ port-comp | port-range ] .
       addr = "any" | nummask | host-name [ "mask" ipaddr | "mask" hexnumber ] .
       port-comp = "port" compare port-num .
       port-range = "port" port-num range port-num .
       flags     = "flags" flag { flag } [ "/" flag { flag } ] .
       with = "with" | "and" .
       icmp = "icmp-type" icmp-type [ "code" decnumber ] .
       return-code = "("icmp-code")" .
       keep = "keep" "state" | "keep" "frags" .
       loglevel = facility"."priority | priority .

       nummask   = host-name [ "/" decnumber ] .



                                                                1





IPF(5)                                                     IPF(5)


       host-name = ipaddr | hostname | "any" .
       ipaddr    = host-num "." host-num "." host-num "." host-num .
       host-num = digit [ digit [ digit ] ] .
       port-num = service-name | decnumber .

       withopt = [ "not" | "no" ] opttype [ withopt ] .
       opttype = "ipopts" | "short" | "frag" | "opt" ipopts  .
       optname   = ipopts [ "," optname ] .
       ipopts  = optlist | "sec-class" [ secname ] .
       secname   = seclvl [ "," secname ] .
       seclvl  = "unclass" | "confid" | "reserv-1" | "reserv-2" | "reserv-3" |
              "reserv-4" | "secret" | "topsecret" .
       icmp-type = "unreach" | "echo" | "echorep" | "squench" | "redir" |
                "timex" | "paramprob" | "timest" | "timestrep" | "inforeq" |
                "inforep" | "maskreq" | "maskrep"  | decnumber .
       icmp-code = decumber | "net-unr" | "host-unr" | "proto-unr" | "port-unr" |
                "needfrag" | "srcfail" | "net-unk" | "host-unk" | "isolate" |
                "net-prohib" | "host-prohib" | "net-tos" | "host-tos" |
                "filter-prohib" | "host-preced" | "cutoff-preced" .
       optlist   = "nop" | "rr" | "zsu" | "mtup" | "mtur" | "encode" | "ts" |
              "tr" | "sec" | "lsrr" | "e-sec" | "cipso" | "satid" | "ssrr" |
              "addext" | "visa" | "imitd" | "eip" | "finn" .
       facility = "kern" | "user" | "mail" | "daemon" | "auth" | "syslog" |
               "lpr" | "news" | "uucp" | "cron" | "ftp" | "authpriv" |
               "audit" | "logalert" | "local0" | "local1" | "local2" |
               "local3" | "local4" | "local5" | "local6" | "local7" .
       priority = "emerg" | "alert" | "crit" | "err" | "warn" | "notice" |
               "info" | "debug" .

       hexnumber = "0" "x" hexstring .
       hexstring = hexdigit [ hexstring ] .
       decnumber = digit [ decnumber ] .

       compare = "=" | "!=" | "<" | ">" | "<=" | ">=" | "eq" | "ne" | "lt" |
              "gt" | "le" | "ge" .
       range     = "<>" | "><" .
       hexdigit = digit | "a" | "b" | "c" | "d" | "e" | "f" .
       digit     = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" .
       flag = "F" | "S" | "R" | "P" | "A" | "U" .

       This  syntax  is somewhat simplified for readability, some
       combinations that match this grammar are disallowed by the
       software because they do not make sense (such as tcp flags
       for non-TCP packets).

FILTER RULES
       The "briefest" valid rules are (currently) no-ops and  are
       of the form:
              block in all
              pass in all
              log out all
              count in all

       Filter  rules are checked in order, with the last matching



                                                                2





IPF(5)                                                     IPF(5)


       rule determining the fate of the packet (but see the quick
       option, below).

       Filters  are  installed  by default at the end of the ker-
       nel's filter lists, prepending the rule with @n will cause
       it  to  be inserted as the n'th entry in the current list.
       This is  especially  useful  when  modifying  and  testing
       active filter rulesets. See ipf(1) for more information.

ACTIONS
       The  action  indicates  what  to  do with the packet if it
       matches the rest of the filter rule. Each rule  MUST  have
       an action. The following actions are recognised:

       block  indicates  that  the packet should be flagged to be
              dropped. In response to blocking a packet, the fil-
              ter  may  be  instructed  to  send  a reply packet,
              either an ICMP packet (return-icmp), an ICMP packet
              masquerading  as  being  from the original packet's
              destination (return-icmp-as-dest), or a TCP "reset"
              (return-rst).   An  ICMP packet may be generated in
              response to any IP packet, and its type may option-
              ally be specified, but a TCP reset may only be used
              with a rule which 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 unreach-
              able, port  unreachable  or  even  administratively
              prohibitied.  This  is  done  by enclosing the ICMP
              code associated with  it  in  parenthesis  directly
              following  return-icmp  or  return-icmp-as-dest  as
              follows:
                      block return-icmp(11) ...

       Would return  a  Type-Of-Service  (TOS)  ICMP  unreachable
       error.

       pass   will  flag the packet to be let through the filter.

       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 fil-
              ter. These statistics are viewable with ipfstat(8).

       call   this action is used to invoke the named function in
              the  kernel, which must conform to a specific call-
              ing interface. Customised actions and semantics can
              thus  be implemented to supplement those available.
              This feature is for use by  knowledgeable  hackers,
              and is not currently documented.



                                                                3





IPF(5)                                                     IPF(5)


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

       auth   this 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 whilst it
              waits for the program to return to the  kernel  the
              real flags for whether it should be allowed through
              or not.  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 from an unrecognised source.

       preauth
              tells the filter that for packets of this class, it
              should  look in the pre-authenticated list for fur-
              ther clarification.  If no further matching rule is
              found,  the  packet will be dropped (the FR_PREAUTH
              is not the same as FR_PASS).  If a further matching
              rule  is found, the result from that is used in its
              instead.  This might be used in a situation where a
              person  logs in to the firewall and it sets up some
              temporary rules defining the access for  that  per-
              son.

       The  next word must be either in or out.  Each packet mov-
       ing through  the  kernel  is  either  inbound  (just  been
       received  on an interface, and moving towards the kernel's
       protocol processing) or outbound (transmitted or forwarded
       by  the stack, and on its way to an interface). There is a
       requirement that each filter rule explicitly  state  which
       side of the I/O it is to be used on.

OPTIONS
       The list of options is brief, and all are indeed optional.
       Where options are used, they must be present in the  order
       shown here. These are the currently supported options:

       log    indicates  that,  should  this be the last matching
              rule, the packet header will be written to the  ipl
              log (as described in the LOGGING section below).

       quick  allows  "short-cut"  rules in order to speed up the
              filter  or  override  later  rules.   If  a  packet
              matches  a  filter  rule  which 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) will



                                                                4





IPF(5)                                                     IPF(5)


              determine whether it is passed or blocked.

              If this option is missing, the rule is taken to  be
              a  "fall-through"  rule, meaning that the result of
              the match (block/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
              printed by "netstat -i". If this  option  is  used,
              the  rule  will  only  match if the packet is going
              through that interface in the  specified  direction
              (in/out).  If  this  option  is absent, the rule is
              taken to be applied to a packet regardless  of  the
              interface  it  is  present  on  (i.e. on all inter-
              faces).  Filter rulesets are common to  all  inter-
              faces,  rather  than  having a filter list for each
              interface.

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

       dup-to causes the packet to be copied, and  the  duplicate
              packet  to be sent outbound on the specified inter-
              face, 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  even  to
              bypass  the  rest  of  the kernel processing of the
              packet (if applied to an inbound rule). 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 deter-
       mining whether rules match or don't match.  The  following
       general-purpose  attributes are provided for matching, and
       must be used in this order:

       tos    packets with different Type-Of-Service  values  can
              be filtered.  Individual service levels or combina-
              tions can be filtered upon.  The value for the  TOS
              mask can either be represented as a hex number or a
              decimal integer value.




                                                                5





IPF(5)                                                     IPF(5)


       ttl    packets may 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 only be given as a decimal
              integer value.

       proto  allows a specific protocol to be  matched  against.
              All  protocol  names  found  in  /etc/protocols are
              recognised and may be used.  However, the  protocol
              may also be given as a DECIMAL number, allowing for
              rules to match your  own  protocols,  or  new  ones
              which would out-date any attempted listing.

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

       The from and to keywords are  used  to  match  against  IP
       addresses  (and optionally port numbers). Rules must spec-
       ify BOTH source and destination parameters.

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

       There is a special case for  the  hostname  any  which  is
       taken  to  be  0.0.0.0/0  (see  below for mask syntax) 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 is non-
       sensical.

       The numerical format "x/y" indicates that a mask of y con-
       secutive  1  bits set is generated, starting with the MSB,
       so a y value of 16 would give 0xffff0000. The symbolic  "x
       mask y" 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  isn't
       currently  a  way  to invert the sense of the match, or to
       match ranges of IP addresses which do  not  express  them-
       selves  easily as bitmasks (anthropomorphization; it's not
       just for breakfast anymore).

       If a port match is included, for either or both of  source
       and  destination,  then  it is only applied to TCP and UDP



                                                                6





IPF(5)                                                     IPF(5)


       packets. If there is no  proto  match  parameter,  packets
       from  both  protocols  are compared. This is equivalent to
       "proto tcp/udp".  When composing port comparisons,  either
       the  service  name  or an integer port number may be used.
       Port comparisons may be done in a number of forms, with  a
       number  of  comparison  operators,  or  port ranges may be
       specified. 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 the examples for more information.

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

       Following the source and destination matching  parameters,
       the following additional parameters may be used:

       with   is  used  to  match  irregular attributes that some
              packets may have associated with  them.   To  match
              the  presence  of  IP  options in general, use with
              ipopts. To match packets that are too short to con-
              tain  a  complete  header, use with short. To match
              fragmented packets, use with frag.  For  more  spe-
              cific  filtering  on IP options, individual options
              can be listed.

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

              Multiple  consecutive  with  clauses  are  allowed.
              Alternatively, the keyword and may be used in place
              of  with, this is provided purely to make the rules
              more readable ("with ... and ...").  When  multiple
              clauses are listed, all those must match to cause a
              match of the rule.

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

               F - FIN
               S - SYN
               R - RST
               P - PUSH
               A - ACK
               U - URG

              The  various  flag  symbols may be used in combina-
              tion, so that "SA" would represent a SYN-ACK combi-
              nation  present in a packet.  There is nothing pre-
              venting the specification of combinations, such  as



                                                                7





IPF(5)                                                     IPF(5)


              "SFR", that would not normally be generated by law-
              abiding TCP  implementations.   However,  to  guard
              against weird aberrations, it is necessary to state
              which flags you are filtering  against.   To  allow
              this, it is possible to set a mask indicating which
              TCP flags you wish to compare (i.e., those you deem
              significant).  This is done by appending "/<flags>"
              to the set of TCP flags you wish to match  against,
              e.g.:

            ... flags S
                      # becomes "flags S/AUPRFS" and will match
                      # packets with ONLY the SYN flag set.

            ... flags SA
                      # becomes "flags SA/AUPRFS" and will match any
                      # packet with only the SYN and ACK flags set.

            ... flags S/SA
                      # will match any packet with just the SYN flag set
                      # out of the SYN-ACK pair; the common "establish"
                      # keyword action.  "S/SA" will NOT match a packet
                      # with BOTH SYN and ACK set, but WILL match "SFP".

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

KEEP HISTORY
       The  second  last  parameter which can be set for a filter
       rule is whether or not to  record  historical  information
       for  that  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.

       allowing  packets  which  match  these  to  flow  straight
       through, rather than  going  through  the  access  control
       list.

GROUPS
       The  last  pair  of parameters control filter rule "group-
       ing".  By default, all filter rules are placed in group  0
       if  no  other group is specified.  To add a rule to a non-



                                                                8





IPF(5)                                                     IPF(5)


       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  isn't
       stopped until it has returned from processing the group.

       A  rule  may be both the head for a new group and a member
       of a  non-default  group  (head  and  group  may  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, with either the log action or
       option, the headers of the packet are written to  the  ipl
       packet  logging  psuedo-device.  Immediately following the
       log keyword, the following  qualifiers  may  be  used  (in
       order):

       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 this option is also
              applied 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.

       level <loglevel>
              indicates  what  logging  facility and priority, or
              just priority with the default facility being used,
              will  be  used to log information about this packet
              using ipmon's -s option.

       See ipl(4) for the  format  of  records  written  to  this
       device.  The ipmon(8) program can be used to read and for-
       mat this log.

EXAMPLES
       The quick option is good for rules such as:




                                                                9





IPF(5)                                                     IPF(5)


       block in quick from any to any with ipopts

       which will match any packet  with  a  non-standard  header
       length  (IP  options present) and abort further processing
       of later rules, recording a match and also that the packet
       should be blocked.

       The "fall-through" rule parsing allows for effects such as
       this:

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

       which sets 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 as a failed match on  the  "block"  action
       does  not  imply  a  pass, only that the rule hasn't taken
       effect.  To then allow ports < 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,  we
       would do something like:

              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, we would
       do:

              pass in proto icmp all group 100

       Note that because only inbound packets  on  le0  are  used
       processed  by group 100, there is no need to respecify the
       interface name.  Likewise, we could further  breakup  pro-
       cessing of TCP, etc, 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



                                                               10





IPF(5)                                                     IPF(5)


       would be:

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

       Note, that if we wanted to say  "port  =  telnet",  "proto
       tcp"  would  need to be specified as the parser interprets
       each rule on its own and qualifies all service/port  names
       with the protocol specified.

FILES
       /dev/ipauth
       /dev/ipl
       /dev/ipstate
       /etc/hosts
       /etc/services

SEE ALSO
       ipftest(1),  iptest(1),  mkfilters(1),  ipf(4),  ipnat(5),
       ipf(8), ipfstat(8)






































                                                               11


