Network Address Translation


Network Address Translation is like making soup out of a bone; it makes what you have go much further. If you only have a handful of IP addresses, or only one, you can use NAT to place a whole bunch of private IP addresses behind the public address and attach dozens, hundreds, or thousands of computers to the Internet with one "real" IP. NAT can cause problems — some VPN protocols do not work well with NAT, and it really confuses anyone who is trying to control machine access by IP address — but in general it solves more problems than it causes. If some of your machines cannot use NAT for whatever reason, you must give them real IP addresses (or possibly use binat, as discussed in "Bi-directional NAT").

All you need to know to configure NAT is the external interface, the addresses you want translated, and the address you want to translate them to.

 nat on external-interface from internal-network to any -> external-interface-or- real-IP-address 

For example, if your external interface is fxp0, your internal IP addresses are 192.168.1.0/24, and your real IP address 10.0.5.4, you would write:

 nat on fxp0 from 192.168.1.0/24 to any -> 10.0.5.4 

PF rewrites outbound packets to give them a source IP of 10.0.5.4 and keep a state table of outgoing connections. When packets return it uses port numbers, IP addresses, and ISNs to match the returning packets to the real machine, rewrites the packets to give them the proper destination address, and send them back to the client.

If you only have one IP address, and that address changes when you connect to the Internet, you may not want to hard-code the interface name in your rules. That's fine. Instead of using the IP address as the translation address, use the interface name. PF will learn the IP on that interface and use it.

 nat on fxp0 from 192.168.1.0/24 to any -> fxp0 

If you're using DHCP to get your IP address, the IP may change while the system is still connected to the Internet. Just as you can put the interface name in parentheses to have a filter rule reevaluated when the IP address changes, use parentheses for NAT as well.

 nat on fxp0 from 192.168.1.0/24 to any -> (fxp0) 

You can also specify that NAT will take place only from certain networks or to certain networks. This is useful if you have several internal networks and don't want to translate traffic between them.

As a NAT device many different devices sharing one IP address, and rewrites outbound and inbound connecting ports and IPs as necessary, it is nearly impossible to write packet-filtering rules that will properly redirect responses back to the correct client. As such, a NAT rule automatically implies stateful inspection to all connections made out through that rule. You do not need to specify "keep state" on rules going out through the NAT, as that is applied automatically by the NAT. If you want to modulate state, you must specify that. But standard stateful inspection is enforced by the NAT rule.

NAT Rule Order

Unlike packet-filtering rules, NAT rules are processed on a first-fit basis. In most cases, you only have one NAT rule. If you're using binat rules (see "Bi-directional NAT") or if you have some special circumstances that require multiple NAT rules, keep this in mind. Put binat rules and exclusions before your default rule.

Private NAT Addresses

In theory, you could use any addresses behind your NAT device. If you just grab some IPs and use them, you won't be able to reach whoever has those IP addresses out in the real world. It's highly advisable to use some of the IP addresses reserved for private use. Those IP addresses are:

  • 10.0.0.0/8, (10.0.0.0-10.255.255.255)

  • 172.16.0.0/12 (172.16.0.0-172.31.255.255)

  • 192.168.0.0/16 (192.168.0.0-192.168.255.255)

You can subnet and rearrange these IP addresses in any way you wish, so long as you don't try to route them on the public Internet.

Exclusions from NAT

You may have a block of IPs that you do not want to allow to NAT, or a particular server that you do not want to allow on the Internet, or a protocol that chokes on NAT (such as IPSec). You can specifically exclude addresses or protocols from undergoing NAT by using the "no" keyword before the rule. Remember, in NAT the first matching rule is applied immediately! In this example, we first exclude protocol 51 (the AH protocol used in IPSec) from the NAT, then NAT everything else:

 no nat on fxp0 proto 51 from 192.168.1.0/24 to any nat on fxp0 from 192.168.1.0/24 to any -> 204.92.77.100 

Bi-directional NAT

It's not uncommon to have several real IP addresses available, but need more than you have available. Many ISPs will happily issue a block of 8 or 16 IP addresses to a company, and expect them to use NAT for most of their hosts and use the remainder of the address for DMZ hosts, nameservers, and so on.

You may have some hosts behind a firewall with special address-translation needs. Perhaps you need to allow Microsoft RPC [1] through your firewall to a particular host or some other protocol that uses a wide range of almost-random port numbers. You want all of your protected hosts on the same network. Bi-directional NAT might solve your problem. Bi-directional NAT allows one system to monopolize a single real IP address in a one-to-one relationship. Incoming requests to that IP are always directed to the bi-directional NAT host, and outbound packets from that host are always translated to have the monopolized IP address.

For example, suppose your firewall has two IP addresses bound to it — 10.0.5.4 and 10.0.5.5 — and you are using 192.168.1.0/24 for your machines. All of your office client machines and most of your servers use NAT through 10.0.5.4, but you reserve 10.0.5.5 for one special-purpose host at 192.168.1.66. Packets sent to 10.0.5.5 are directed to this 192.168.1.66, and packets from 192.168.1.66 are translated to have a source IP of 10.0.5.5. This allows you to make broad, sweeping port redirections and other rules that simply are not possible under many-to-one NAT. This is done via a "binat" rule.

 binat on external-interface from private-ip to any -> real-ip 

To continue our earlier example, if the external interface is fxp0, your private IP 192.168.1.66, and your reserved public IP 10.0.5.5, your binat rule would look like this:

 binat on fxp0 from 192.168.1.66 to any -> 10.0.5.5 

Put binat rules before other NAT rules.

Using a binat rule is not necessary if you want to redirect particular connections to hosts within your NAT network; they're only helpful if you need broad swaths of ports open and you don't want to overlap other services provided by your main NAT IP. Use redirection to send the occasional port to servers inside your NAT.

Packet Filtering and NAT

You need a packet-filtering rule to allow traffic to a host behind the firewall. Use the actual, not translated, IP addresses for such rules. Here, we allow inbound connections to SSH to a server behind our NAT:

 pass in on fxp0 proto tcp from any to 192.168.1.200 port 22 

While this rule will allow the traffic, how will the firewall know to route new requests to this machine? That's where connection redirection comes in.

[1]Allowing RPC to a host is almost saying "Here I am, hackers, take me now!" Get rid of the RPC box, tunnel RPC over HTTPS, or get a new job. With that box on your network, you'll be looking for a job soon anyway.




Absolute Openbsd(c) Unix for the Practical Paranoid
Absolute OpenBSD: Unix for the Practical Paranoid
ISBN: 1886411999
EAN: 2147483647
Year: 2005
Pages: 298

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net