IPNAT(5) File Formats and Configurations IPNAT(5)
NAME
ipnat, ipnat.conf - IP NAT file format
DESCRIPTION
The format for files accepted by ipnat is described by the following
grammar:
ipmap :: = mapblock | redir | map .
map ::= mapit ifname lhs "->" dstipmask [ mapicmp | mapport | mapproxy ]
mapoptions .
mapblock ::= "map-block" ifname lhs "->" ipmask [ ports ] mapoptions .
redir ::= "rdr" ifname rlhs "->" ip [ "," ip ] rdrport rdroptions .
lhs ::= ipmask | fromto .
rlhs ::= ipmask dport | fromto .
dport ::= "port" portnum [ "-" portnum ] .
ports ::= "ports" numports | "auto" .
rdrport ::= "port" portnum .
mapit ::= "map" | "bimap" .
fromto ::= "from" object "to" object .
ipmask ::= ip "/" bits | ip "/" mask | ip "netmask" mask .
dstipmask ::= ipmask | "range" ip "-" ip .
mapicmp ::= "icmpidmap" "icmp" number ":" number .
mapport ::= "portmap" tcpudp portspec .
mapoptions ::= [ tcpudp ] [ "frag" ] [ age ] [ clamp ] .
rdroptions ::= rdrproto [ rr ] [ "frag" ] [ age ] [ clamp ] [ rdrproxy ] .
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 .
rdrproto ::= tcpudp | protocol .
rr ::= "round-robin" .
age ::= "age" decnumber [ "/" decnumber ] .
clamp ::= "mssclamp" decnumber .
tcpudp ::= "tcp/udp" | protocol .
mapproxy ::= "proxy" "port" port proxy-name '/' protocol
rdrproxy ::= "proxy" proxy-name .
protocol ::= protocol-name | decnumber .
nummask ::= host-name [ "/" decnumber ] .
portspec ::= "auto" | portnumber ":" portnumber .
port ::= portnumber | port-name .
portnumber ::= number { numbers } .
ifname ::= 'A' - 'Z' { 'A' - 'Z' } numbers .
numbers ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' .
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.
Packets which will be rewritten can only be selected by matching the
original source address. A netmask must be specified with the IP
address.
The address selected for replacing the original is chosen from an
IP#/netmask pair. A netmask of all 1's indicating a hostname is
valid. A netmask of 31 1's (255.255.255.254) is considered invalid
as there is no space for allocating host IP#'s after consideration
for broadcast and network addresses.
When remapping TCP and UDP packets, it is also possible to change the
source port number. Either TCP or UDP or both can be selected by
each rule, with a range of port numbers to remap into given as
port- number:port-number.
COMMANDS
There are four commands recognised by IP Filter's NAT code:
map that is used for mapping one address or network to another in
an unregulated round robin fashion;
rdr that is used for redirecting packets to one IP address and
port pair to another;
bimap for setting up bidirectional NAT between an external IP
address and an internal IP address and
map-block which sets up static IP address based translation, based on a
algorithm to squeeze the addresses to be translated into the
destination range.
MATCHING
For basic NAT and redirection of packets, the address subject to
change is used along with its protocol to check if a packet should be
altered. The packet
matching part of the rule is to the left of the
"->" in each rule.
Matching of packets has now been extended to allow more complex
compares. In place of the address which is to be translated, an IP
address and port number comparison can be made using the same
expressions available with
ipf. A simple NAT rule could be written
as:
map de0 10.1.0.0/16 -> 201.2.3.4/32
or as
map de0 from 10.1.0.0/16 to any -> 201.2.3.4/32
Only IP address and port numbers can be compared against. This is
available with all NAT rules.
TRANSLATION
To the right of the "->" is the address and port specification which
will be written into the packet providing it has already successfully
matched the prior constraints. The case of redirections (
rdr) is the
simplest: the new destination address is that specified in the rule.
For
map rules, the destination address will be one for which the
tuple combining the new source and destination is known to be unique.
If the packet is either a TCP or UDP packet, the destination and
source ports come into the equation too. If the tuple already
exists, IP Filter will increment the port number first, within the
available range specified with
portmap and if there exists no unique
tuple, the source address will be incremented within the specified
netmask. If a unique tuple cannot be determined, then the packet
will not be translated. The
map-block is more limited in how it
searches for a new, free and unique tuple, in that it will used an
algorithm to determine what the new source address should be, along
with the range of available ports - the IP address is never changed
and nor does the port number ever exceed its allotted range.
ICMPIDMAP
ICMP messages can be divided into two groups: "errors" and "queries".
ICMP errors are generated as a response of another IP packet. IP
Filter will take care that ICMP errors that are the response of a
NAT-ed IP packet are handled properly.
For 4 types of ICMP queries (echo request, timestamp request,
information request and address mask request) IP Filter supports an
additional mapping called "ICMP id mapping". All these 4 types of
ICMP queries use a unique identifier called the ICMP id. This id is
set by the process sending the ICMP query and it is usually equal to
the process id. The receiver of the ICMP query will use the same id
in its response, thus enabling the sender to recognize that the
incoming ICMP reply is intended for him and is an answer to a query
that he made. The "ICMP id mapping" feature modifies these ICMP id in
a way identical to
portmap for TCP or UDP.
The reason that you might want this, is that using this feature you
don't need an IP address per host behind the NAT box, that wants to
do ICMP queries. The two numbers behind the
icmpidmap keyword are
the first and the last icmp id number that can be used. There is one
important caveat: if you map to an IP address that belongs to the NAT
box itself (notably if you have only a single public IP address),
then you must ensure that the NAT box does not use the
icmpidmap range that you specified in the
map rule.
KERNEL PROXIES
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
IRC - Experimental
rpcbind - Experimental
H.323 - Experimental
Real Audio (PNA) - Aging
IPsec - Developmental
netbios - Experimental
R-command - Mature
TRANSPARENT PROXIES
True transparent proxying should be performed using the redirect
(
rdr) rules directing ports to localhost (127.0.0.1) with the proxy
program doing a lookup through
/dev/ipnat to determine the real
source and address of the connection.
LOAD-BALANCING Two options for use with
rdr are available to support primitive,
round-robin based load balancing. The first option allows for a
rdr to specify a second destination, as follows:
rdr le0 203.1.2.3/32 port 80 -> 203.1.2.3,203.1.2.4 port 80 tcp
This would send alternate connections to either 203.1.2.3 or
203.1.2.4. In scenarios where the load is being spread amongst a
larger set of servers, you can use:
rdr le0 203.1.2.3/32 port 80 -> 203.1.2.3,203.1.2.4 port 80 tcp round-robin
rdr le0 203.1.2.3/32 port 80 -> 203.1.2.5 port 80 tcp round-robin
In this case, a connection will be redirected to 203.1.2.3, then
203.1.2.4 and then 203.1.2.5 before going back to 203.1.2.3. In
accomplishing this, the rule is removed from the top of the list and
added to the end, automatically, as required. This will not effect
the display of rules using "ipnat -l", only the internal application
order.
EXAMPLES
This section deals with the
map command and its variations.
To change IP#'s used internally from network 10 into an ISP provided
8 bit subnet at 209.1.2.0 through the ppp0 interface, the following
would be used:
map ppp0 10.0.0.0/8 -> 209.1.2.0/24
The obvious problem here is we're trying to squeeze over 16,000,000
IP addresses into a 254 address space. To increase the scope,
remapping for TCP and/or UDP, port remapping can be used;
map ppp0 10.0.0.0/8 -> 209.1.2.0/24 portmap tcp/udp 1025:65000
which falls only 527,566 `addresses' short of the space available in
network 10. If we were to combine these rules, they would need to be
specified as follows:
map ppp0 10.0.0.0/8 -> 209.1.2.0/24 portmap tcp/udp 1025:65000
map ppp0 10.0.0.0/8 -> 209.1.2.0/24
so that all TCP/UDP packets were port mapped and only other
protocols, such as ICMP, only have their IP# changed. In some
instances, it is more appropriate to use the keyword
auto in place of
an actual range of port numbers if you want to guarantee simultaneous
access to all within the given range. However, in the above case, it
would default to 1 port per IP address, since we need to squeeze 24
bits of address space into 8. A good example of how this is used
might be:
map ppp0 172.192.0.0/16 -> 209.1.2.0/24 portmap tcp/udp auto
which would result in each IP address being given a small range of
ports to use (252). In all cases, the new port number that is used
is deterministic. That is, port X will always map to port Y.
WARNING: It is not advisable to use the
auto feature if you are
map'ing to a /32 (i.e. 0/32) because the NAT code will try to map
multiple hosts to the same port number, outgoing and ultimately this
will only succeed for one of them. The problem here is that the
map directive tells the NAT code to use the next address/port pair
available for an outgoing connection, resulting in no easily
discernible relation between external addresses/ports and internal
ones. This is overcome by using
map-block as follows:
map-block ppp0 172.192.0.0/16 -> 209.1.2.0/24 ports auto
For example, this would result in 172.192.0.0/24 being mapped to
209.1.2.0/32 with each address, from 172.192.0.0 to 172.192.0.255
having 252 ports of its own. As opposed to the above use of
map, if
for some reason the user of (say) 172.192.0.2 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.
/dev/ipnat
/etc/services
/etc/hosts
SEE ALSO
hosts(5),
ipf(5),
services(5),
ipfilter(7),
ipf(8),
ipnat(8) March 18, 2015 IPNAT(5)