Switch to SpeakEasy.net DSL

The Modular Manual Browser

Home Page
Manual: (OSF1-V5.1-alpha)
Apropos / Subsearch:
optional field

IPF(5)								       IPF(5)

  ipf, ipf.conf, ipf6.conf - IP	packet filter rule syntax


  A rule file for ipf may have any name	or even	be stdin.  As ipfstat pro-
  duces	parsable rules as output when displaying 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 -


  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 ] [ tag ] [ "quick" ]	[ "on" interface-name [	dup ]
	     [ froute ]	[ replyto ] ] .
  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" [ return-icmp[return-code] | "return-rst" ]	.
  log	  = "log" [ "body" ] [ "first" ] [ "or-block" ]	[ "level" loglevel ] .
  tag	  = "tag" tagid	.
  skip	  = "skip" decnumber .
  auth	  = "auth" | "preauth" .
  call	  = "call" [ "now" ] function-name .
  dup	  = "dup-to" interface-name [ ":" ipaddr ] .
  froute  = "fastroute"	| "to" interface-name [	":" ipaddr ] .
  replyto = "reply-to" interface-name [	":" ipaddr ] .
  protocol = "tcp/udp" | "udp" | "tcp" | "icmp"	| decnumber .
  srcdst  = "all" | fromto .
  fromto  = "from" [ "!" ] object "to" [ "!" ] object .

  return-icmp =	"return-icmp" |	"return-icmp-as-dest" .
  return-code =	"(" icmp-code ")" .
  object  = addr [ port-comp | port-range ] .
  addr	  = "any" | nummask | host-name	[ "mask" ipaddr	| "mask" hexnumber ] .
  addr	  = "any" | "<thishost>" | 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 ]	.
  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"	optname	.
  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).


  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 rule determining
  the fate of the packet (but see the quick option, below).

  Filters are installed	by default at the end of the kernel'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(8) for more information.


  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

       indicates that the packet should	be flagged to be dropped. In response
       to blocking a packet, the filter	may be instructed to send a reply
       packet, either an ICMP packet (return-icmp), an ICMP packet masquerad-
       ing 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 optionally be speci-
       fied, 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 unreachable,	port unreachable or even
       administratively	prohibited. 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.

       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(8).

  call this action is used to invoke the named function	in the kernel, which
       must conform to a specific calling 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

  skip <&lt;n>&gt;
       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.

       tells the filter	that for packets of this class,	it should look in the
       pre-authenticated list for further 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 person.

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


  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).

  tag tagid
       indicates that, if this rule causes the packet to be logged or entered
       in the state table, the tagid will be logged as part of the log entry.
       This can	be used	to quickly match "similar" rules in scripts that post
       process the log files for e.g. generation of security reports or
       accounting purposes. The	tagid is a 32 bit unsigned integer.

       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 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 pro-
       cedure. 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 interfaces).  Filter rulesets
       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 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.

       causes the packet to be copied, and the duplicate packet	to be sent
       outbound	on the specified interface, optionally with the	destination
       IP address changed to that specified. This is useful for	off-host log-
       ging, 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


  The keywords described in this section are used to describe attributes of
  the packet to	be used	when determining 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.  Indi-
       vidual service levels or	combinations can be filtered upon.  The	value
       for the TOS mask	can either be represented as a hex number or a
       decimal integer value.

  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

       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 duplica-
       tion of otherwise-identical rules.

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

  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 confi-
  guration and library)	or of the dotted numeric form.	There is no special
  designation for networks but network names are recognised.  Note that	hav-
  ing 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
  (see below for mask syntax) and matches all IP addresses.  Only the pres-
  ence 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	consecutive 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 break-
  fast anymore).

  If a port match is included, for either or both of source and	destination,
  then it is only applied to TCP and UDP 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 informa-

  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	asso-
       ciated 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, individual options can be

       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.

       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 association	is as follows:

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

       The various flag	symbols	may be used in combination, so that "SA"
       would represent a SYN-ACK combination present in	a packet.  There is
       nothing preventing the specification of combinations, such as "SFR",
       that would not normally be generated by law-abiding TCP implementa-
       tions.  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".

       is only effective 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 recognised by this language, or the
       numbers with which they are associated can be used.  The	most impor-
       tant from a security point of view is the ICMP redirect.


  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:

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

       keeps information on fragmented packets,	to be applied to later frag-

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

  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 pro-
  cessing 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 <&lt;n>&gt;
       indicates that a	new group (number n) should be created.

  group	<&lt;n>&gt;
       indicates that the rule should be put in	group (number n) rather	than
       group 0.


  When a packet	is logged, with	either the log action or option, the headers
  of the packet	are written to the ipl packet logging pseudo-device. Immedi-
  ately	following the log keyword, the following qualifiers may	be used	(in

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

       If log is being used in conjunction with	a "keep" option, it is recom-
       mended that this	option is also applied so that only the	triggering
       packet is logged	and not	every packet which thereafter matches state

       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	<&lt;loglevel>&gt;
       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 format this log.


  The quick option is good for rules such as:

  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 process-
  ing 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 processing 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 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.


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