Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
IPNAT(5)		      File Formats Manual		      IPNAT(5)

       ipnat, ipnat.conf - IPFilter NAT	file format

       The  ipnat.conf	file  is used to specify rules for the Network Address
       Translation (NAT) component of IPFilter.	 To load  rules	 specified  in
       the ipnat.conf file, the	ipnat(8) program is used.

       For  standard  NAT functionality, a rule	should start with map and then
       proceeds	to specify the interface for which outgoing packets will  have
       their source address rewritten.	Following this it is expected that the
       old source address, and optionally port number, will be specified.

       In general, all NAT rules conform to the	following  layout:  the	 first
       word  indicates	what  type of NAT rule is present, this	is followed by
       some stanzas to match a packet, followed	by a "->"  and	this  is  then
       followed	 by  several more stanzas describing the new data to be	put in
       the packet.

       In this text and	in others, use of the term "left hand side" (LHS) when
       talking	about  a  NAT rule refers to text that appears before the "->"
       and the "right hand side" (RHS) for text	that appears after it.	In es-
       sence, the LHS is the packet matching and the RHS is the	new data to be

       This configuration file,	like all others	used with  IPFilter,  supports
       the use of variable substitution	throughout the text.

       map $nif	0/0 -> 0/32

       would become

       map ppp0	0/0 -> 0/32

       Variables  can  be used recursively, such as 'foo="$bar baz";', so long
       as $bar exists when the parser reaches the assignment for foo.

       See ipnat(8) for	instructions on	how to define  variables  to  be  used
       from a shell environment.

       Changing	 the source address of a packet	is traditionally performed us-
       ing map rules.  Both the	source address and optionally port number  can
       be changed according to various controls.

       To start	out with, a common rule	used is	of the form:

       map le0 0/0 -> 0/32

       Here we're saying change	the source address of all packets going	out of
       le0 (the	address/mask pair of 0/0 matching all packets) to that of  the
       interface le0 (0/32 is a	synonym	for the	interface's own	address	at the
       current point in	time.)	If we wanted to	pass the packet	 through  with
       no change in address, we	would write it as:

       map le0 0/0 -> 0/0

       If  we  only  want to change a portion of our internal network and to a
       different address that is routed	back through this host,	we might do:

       map le0 ->

       In some instances, we may have an entire	subnet	to  map	 internal  ad-
       dresses out onto, in which case we can express the translation as this:

       map le0 ->

       IPFilter	  will	cycle  through	each  of  the  256  addresses  in  the address space to	ensure that they all get used.

       Of course this poses a problem for TCP and UDP, with  many  connections
       made,  each  with its own port number pair.  If we're unlucky, transla-
       tions can be dropped because the	new address/port pair mapping  already
       exists.	 To  mitigate this problem, we add in port translation or port

       map le0 -> portmap tcp/udp auto

       In this instance, the word "auto" tells IPFilter	to calculate a private
       range  of  port numbers for each	address	on the LHS to use without fear
       of them being trampled by others.  This can lead	to problems  if	 there
       are  connections	 being generated more quickly than IPFilter can	expire
       them.  In this instance,	and if we want to  get	away  from  a  private
       range of	port numbers, we can say:

       map le0 -> portmap tcp/udp 5000:65000

       And  now	each connection	through	le0 will add to	the enumeration	of the
       port number space 5000-65000 as	well  as  the  IP  address  subnet  of

       If the new addresses to be used are in a	consecutive range, rather than
       a complete subnet, we can express this as:

       map le0 -> range
			     portmap tcp/udp 5000:65000

       This tells IPFilter that	it has a range of 240 IP address to use,  from to,	inclusive.

       If  there were several ranges of	addresses for use, we can use each one
       in a round-robin	fashion	as followed:

       map le0 -> range
			     portmap tcp/udp 5000:65000	round-robin
       map le0 -> range
			     portmap tcp/udp 5000:65000	round-robin

       To specify translation rules that impact	a specific  IP	protocol,  the
       protocol	name or	number is appended to the rule like this:

       map le0 -> tcp/udp
       map le0 -> icmp
       map le0 -> gre

       For TCP connections exiting a connection	such as	PPPoE where the	MTU is
       slightly	smaller	than normal ethernet, it can be	useful to  reduce  the
       Maximum	Segment	 Size (MSS) offered by the internal machines to	match,
       reducing	the liklihood that the either end will attempt to send packets
       that  are  too big and result in	fragmentation.	This is	acheived using
       the mssclamp option with	TCP map	rules like this:

       map pppoe0 0/0 -> 0/32 mssclamp 1400 tcp

       For ICMP	packets, we can	map the	ICMP id	space in query packets:

       map le0 -> icmpidmap icmp 1000:20000

       If we wish to be	more specific about our	initial	matching  criteria  on
       the  LHS,  we  can  expand  to  using  a	syntax more similar to that in
       ipf.conf(5) :

       map le0 from to ->
       map le0 from port > 1024 to -> portmap 5000:9999 tcp/udp
       map le0 from ! to -> portmap 5000:9999 tcp/udp

       NOTE:  negation matching	with source addresses is NOT possible with map
	      /	map-block rules.

       The  NAT	 code  has builtin default timeouts for	TCP, UDP, ICMP and an-
       other for all other protocols.  In general, the timeout for an entry to
       be  deleted  shrinks once a reply packet	has been seen (excluding TCP.)
       If you wish to specify your own timeouts, this can be  achieved	either
       by setting one timeout for both directions:

       map le0 0/0 -> 0/32 gre age 30

       or setting a different timeout for the reply:

       map le0 from any	to any port = 53 -> 0/32 age 60/10 udp

       A  pressing  problem  that many people encounter	when using NAT is that
       the address protocol can	be embedded inside an application's communica-
       tion.   To address this problem,	IPFilter provides a number of built-in
       proxies for the more common trouble makers, such	as FTP.	 These proxies
       can be used as follows:

       map le0 0/0 -> 0/32 proxy port 21 ftp/tcp

       In this rule, the word "proxy" tells us that we want to connect up this
       translation with	an internal proxy.  The	"port 21" is an	extra restric-
       tion that requires the destination port number to be 21 if this rule is
       to be activated.	 The word "ftp"	is the proxy identifier	that the  ker-
       nel  will  try  and resolve internally, "tcp" the protocol that packets
       must match.

       See below for a list of proxies and their relative staus.

       To associate NAT	rules with filtering rules, it is possible to set  and
       match  tags  during  either inbound or outbound processing.  At present
       the tags	for forwarded packets are not preserved	by forwarding, so once
       the  packet  leaves  IPFilter, the tag is forgotten.  For map rules, we
       can match tags set by filter rules like this:

       map le0 0/0 -> 0/32 proxy portmap 5000:5999 tag lan1 tcp

       This would be used with "pass out" rules	that includes a	stanza such as
       "set-tag	(nat = lan1)".

       If  the	interface  in which packets are	received is different from the
       interface on which packets are sent  out,  then	the  translation  rule
       needs to	be written to take this	into account:

       map hme0,le0 0/0	-> 0/32

       Although	 this  might seem counterintuitive, the	interfaces when	listed
       in rules	for ipnat.conf are always in the inbound , outbound order.  In
       this case, hme0 would be	the return interface and le0 would be the out-
       going interface.	 If you	wish to	allow return packets on	any interface,
       the correct syntax to use would be:

       map *,le0 0/0 ->	0/32

       A  special variant of map rules exists, called map-block.  This command
       is intended for use when	there is a large network to be mapped  onto  a
       smaller	network, where the difference in netmasks is upto 14 bits dif-
       ference in size.	 This is achieved by dividing the  address  space  and
       port  space  up	to ensure that each source address has its own private
       range of	ports to use.  For example, this rule:

       map-block ppp0 -> ports auto

       would result in being mapped to  with  each
       address,	from to having 252 ports of its own.
       As opposed to the above use of map, if for  some	 reason	 the  user  of
       (say)  wanted 260 simultaneous connections going out, they
       would be	limited	to 252 with map-block but would	just move  on  to  the
       next IP address with the	map command.

   Extended matching
       If  it  is  desirable  to match on both the source and destination of a
       packet before applying an  address  translation	to  it,	 this  can  be
       achieved	 by  using  the	same from-to syntax as is used in ipf.conf(5).
       What follows applies equally to the map rules discussed above  and  rdr
       rules discussed below.  A simple	example	is as follows:

       map bge0	from to ->

       This  would  only  match	packets	that are coming	from hosts that	have a
       source  address	matching  and  a	destination   matching	 This  can  be	expanded  upon with ports for TCP like

       rdr bge0	from to any	port = 25 -> port 2501 tcp

       Where only TCP packets from to port 25 will	be  redirected
       to port 2501.

       As  with	 ipf.conf(5),  if we have a large set of networks or addresses
       that we would like to match up with then	we can define a	pool using ip-
       pool(8)	in  ippool.conf(5)  and	then refer to it in an ipnat rule like

       map bge0	from pool/100 to any port = 25 -> port 2501 tcp

       NOTE:  In this situation, the rule is considered	to have	a  netmask  of
	      "0"  and	thus  is looked	at last, after any rules with /16's or
	      /24's in them, even if the defined pool only has /24's or	/32's.
	      Pools  may  also	be  used  wherever  the	 from-to syntax	in ip-
	      nat.conf(5) is allowed.

       Redirection of packets is used to change	the destination	 fields	 in  a
       packet and is supported for packets that	are moving in on a network in-
       terface.	 While the same	general	syntax for  map	 rules	is  supported,
       there are differences and limitations.

       Firstly,	 by  default all redirection rules target a single IP address,
       not a network or	range of network addresses, so	a  rule	 written  like

       rdr le0 0/0 ->

       Will  not  spread  packets  across all 256 IP addresses in that class C
       network.	 If you	were to	try a rule like	this:

       rdr le0 0/0 ->

       then you	will receive a parsing error.

       The from-to source-destination matching used with map rules can be used
       with  rdr  rules,  along	with negation, however the restriction moves -
       only a source address match can be negated:

       rdr le0 from to any ->
       rdr le0 ! from to any	->

       If there	is a consective	set of addresses you wish to spread the	 pack-
       ets  over,  then	 this can be done in one of two	ways, the word "range"
       optional	to preserve:

       rdr le0 0/0 -> -
       rdr le0 0/0 -> range	-

       If there	are only two addresses to split	the packets across, the	recom-
       mended method is	to use a comma (",") like this:

       rdr le0 0/0 ->,

       If  there  is  a	large group of destination addresses that are somewhat
       disjoint	in nature, we can cycle	through	them using a round-robin tech-
       nique like this:

       rdr le0 0/0 ->, round-robin
       rdr le0 0/0 ->, round-robin
       rdr le0 0/0 -> round-robin

       If there	are a large number of redirect rules and hosts being targetted
       then it may be desirable	to have	all those from a single	source address
       be  targetted  at  the  same destination	address.  To achieve this, the
       word sticky is appended to the rule like	this:

       rdr le0 0/0 ->, sticky
       rdr le0 0/0 ->, round-robin sticky
       rdr le0 0/0 -> round-robin sticky

       The sticky feature can only be combined with round-robin	and the	use of

       For  TCP	 and  UDP  packets,  it	 is possible to	both match on the des-
       tiantion	port number and	to modify it.  For example, to change the des-
       tination	port from 80 to	3128, we would use a rule like this:

       rdr de0 0/0 port	80 ->	port 3128 tcp

       If  a  range of ports is	given on the LHS and a single port is given on
       the RHS,	the entire range of ports is moved.  For example,  if  we  had

       rdr le0 0/0 port	80-88 -> port	3128 tcp

       then  port 80 would become 3128,	port 81	would become 3129, etc.	 If we
       want to redirect	a number of different pots to just a single  port,  an
       equals  sign  ("=")  is	placed	before the port	number on the RHS like

       rdr le0 0/0 port	80-88 -> port	= 3128 tcp

       In this case, port 80 goes to 3128, port	81 to 3128, etc.

       As with map rules, it is	possible to manually set a timeout  using  the
       age option, like	this:

       rdr le0 0/0 port	53 ->	port 10053 udp age 5/5

       The  use	 of  proxies  is not restricted	to map rules and outbound ses-
       sions.  Proxies can also	be used	with redirect rules, although the syn-
       tax is slightly different:

       rdr ge0 0/0 port	21 ->	port 21	tcp proxy ftp

       For  rdr	 rules,	 the  interfaces supplied are in the same order	as map
       rules - input first, then output.  In situations	where the outgoing in-
       terface	is not certain,	it is also possible to use a wildcard ("*") to
       effect a	match on any interface.

       rdr le0,* 0/0 ->

       A single	rule, with as many options set as possible  would  look	 some-
       thing like this:

       rdr le0,ppp0 port 80 ->, port 80 tcp
	   round-robin frag age	40/40 sticky mssclamp 1000 tag tagged

       Whilst  the above two commands provide a	lot of flexibility in changing
       addressing fields in packets, often it can be of	benefit	 to  translate
       both  source  and  destination at the same time or to change the	source
       address on input	or the destination address on output.	Doing  all  of
       these things can	be accomplished	using rewrite NAT rules.

       A  rewrite  rule	 requires the same level of packet matching as before,
       protocol	and source/destination information but in addition allows  ei-
       ther in or out to be specified like this:

       rewrite in on ppp0 proto	tcp from any to	any port = 80 ->
	    src	0/0 dst,3128;
       rewrite out on ppp0 from	any to any ->
	    src	0/32 dst;

       On  the	RHS we can specify both	new source and destination information
       to place	into the packet	being sent out.	 As with other rules  used  in
       ipnat.conf,  there are shortcuts	syntaxes available to use the original
       address information (0/0) and the address associated with  the  network
       interface  (0/32.)   For	TCP and	UDP, both address and port information
       can be changed.	At present it is only possible	to  specify  either  a
       range of	port numbers to	be used	(X-Y) or a single port number (= X) as

       rewrite in on le0 proto tcp from	any to any port	= 80 ->
	    src	0/0,2000-20000 dst,port = 3128;

       There are four fields that are stepped through in enumerating the  num-
       ber space available for creating	a new destination:

       source address

       source port

       destination address

       destination port

       If  one of these	happens	to be a	static then it will be skipped and the
       next one	incremented.  As an example:

       rewrite out on le0 proto	tcp from any to	any port = 80 ->
	    src,5000-5999 dst,6000-6999;

       The translated packets would be:

       1st src=,5000 dst=,6000

       2nd src=,5000 dst=,6000

       3rd src=,5001 dst=,6000

       4th src=,5001 dst=,6000

       5th src=,5001 dst=,6001

       6th src=,5001 dst=,6001

       and so on.

       As with map rules, it is	possible to specify a range  of	 addresses  by
       including the word range	before the addresses:

       rewrite from any	to any port = 80 ->
	    src	- dst -;

       If  you'd like to send packets to a UDP socket rather than just another
       computer	to be decapsulated, this can be	achieved using a divert	rule.

       Divert rules can	be used	with both inbound and outbound packet matching
       however	the rule must specify host addresses for the outer packet, not
       ranges of addresses or netmasks,	just single  addresses.	  Additionally
       the  syntax  must  supply  required information for UDP.	 An example of
       what a divert rule looks	ike is as follows:

       divert in on le0	proto udp from any to any port = 53 ->
	    src,54 dst,5300;

       On the LHS is a normal set of matching capabilities but on the  RHS  it
       is  a  requirement to specify both the source and destination addresses
       and ports.

       As this feature is intended to be used with targetting packets at sock-
       ets  and	 not  IPFilter running on other	systems, there is no rule pro-
       vided to	undivert packets.

       NOTE:  Diverted packets may be fragmented if the	addition of the	encap-
	      sulating	IP  header plus	UDP header causes the packet to	exceed
	      the size allowed by the outbound network interface.  At  present
	      it is not	possible to cause Path MTU discovery to	happen as this
	      feature is intended to be	transparent to both  endpoints.	  Path
	      MTU  Discovery  If  Path MTU discovery is	being used and the "do
	      not fragment" flag is set	in packets to be encapsulated, an ICMP
	      error  message will be sent back to the sender if	the new	packet
	      would need to be fragmented.

       This section deals with options that are	available with all rules.

       purge  When the purge keyword is	added to the end of  a	NAT  rule,  it
	      will cause all of	the active NAT sessions	to be removed when the
	      rule is removed as an individual operation. If all  of  the  NAT
	      rules  are  flushed  out,	 it is expected	that the operator will
	      similarly	flush the NAT table and	thus NAT sessions are not  re-
	      moved when the NAT rules are flushed out.

       NOTE: Rules in ipnat.conf are read in sequentially as listed and	loaded
       into the	kernel in this fashion BUT packet matching is done on netmask,
       going  from  32	down to	0.  If a rule uses pool	or hash	to reference a
       set of addresses	or networks, the netmask value	for  these  fields  is
       considered to be	"0".  So if your ipnat.conf has	the following rules:

       rdr le0 port	80 ->	3132 tcp
       rdr le0 port 80 -> 3131 tcp
       rdr le0 from any	to pool/100 port 80 -> port 3130 tcp
       rdr le0 port 80 -> 3129 tcp
       rdr le0 port 80 -> 3128 tcp

       then  the  rule with will match first,	regardless of where it
       appears in the ordering of the above rules.   In	 fact,	the  order  in
       which they would	be used	to match a packet is:

       rdr le0 port 80 -> 3128 tcp
       rdr le0 port 80 -> 3129 tcp
       rdr le0 port 80 -> 3131 tcp
       rdr le0 port	80 ->	3132 tcp
       rdr le0 from any	to pool/100 port 80 -> port 3130 tcp

       where the first line is actually	a /32.

       If your ipnat.conf file has entries with	matching target	fields (source
       address for map rules and destination address for rdr rules), then  the
       ordering	in the ipnat.conf file does matter.  So	if you had the follow-

       rdr le0 from to port 80 -> 3129 tcp
       rdr le0 from to port 80 -> 3128 tcp

       Then no packets will match the 2nd rule,	they'll	all match the first.

       In all of the examples above, where an IPv4 address is present, an IPv6
       address can also	be used. All rules must	use either IPv4	addresses with
       both halves of the NAT rule or IPv6 addresses for both  halves.	Mixing
       IPv6 addresses with IPv4	addresses, in a	single rule, will result in an

       For shorthand notations such as "0/32",	the  equivalent	 for  IPv6  is
       "0/128".	IPFilter will treat any	netmask	greater	than 32	as an implicit
       direction that the address should be IPv6, not IPv4.  To	be unambiguous
       with 0/0, for IPv6 use ::0/0.

       IP Filter comes with a few, simple, proxies built into the code that is
       loaded into the kernel to allow secondary channels to be	opened without
       forcing	the  packets through a user program.  The current state	of the
       proxies is listed below,	as one of three	states:

       Aging - protocol	is roughly understood from the time at which the proxy
	      was written but it is not	well tested or maintained;

       Developmental  -	basic functionality exists, works most of the time but
	      may be problematic in extended real use;

       Experimental - rough support for	the protocol at	best, may or  may  not
	      work  as testing has been	at best	sporadic, possible large scale
	      changes to the code in order to properly support the protocol.

       Mature -	well tested, protocol is properly understood by	the proxy;

       The currently compiled in proxy list is as follows:

       FTP - Mature
	      (map ... proxy port ftp ftp/tcp)

       IRC - Experimental
	      (proxy port 6667 irc/tcp)

       rpcbind - Experimental

       PPTP - Experimental

       H.323 - Experimental
	      (map ... proxy port 1720 h323/tcp)

       Real Audio (PNA)	- Aging

       DNS - Developmental
	      (map ... proxy port 53 dns/udp { block; })

       IPsec - Developmental
	      (map ... proxy port 500 ipsec/tcp)

       netbios - Experimental

       R-command - Mature
	      (map ... proxy port shell	rcmd/tcp)


       ipnat(4), hosts(5), ipf(5), services(5),	ipf(8),	ipnat(8)



Want to link to this manual page? Use this URL:

home | help