BSD DevCenter
oreilly.comSafari Books Online.Conferences.

advertisement


NAT with pf
Pages: 1, 2, 3, 4

Scrub Rules

Not all IP packets sent over the Internet are well-formed, which may cause problems to hosts or routers running IP stacks that cannot properly handle packet fragmentation and reassembly. Improperly formed packets may be sent by poorly written software running on some external or internal machines, or, quite frequently, by attackers trying to compromise your network.



You can scrub incoming or outgoing packets. There are two schools of thought. One claims that it is enough to scrub only the packets arriving at the external interface from the outside. The other claims that all packets that match in rules on all interfaces (packets sent from the outside and destined to the inside of your network, and packets sent from your network to outside hosts) ought to be scrubbed. While a paranoid mind gravitates toward the second solution, remember that every rule costs CPU cycles and memory. Also, there are times when scrubbing may interfere with network intrusion detection systems (NIDS) because packet normalization may not detect rogue traffic which would be detected if no scrubbing were done. Of course, it is possible to log such packets and set your NIDS to take appropriate action. As you can see, there is no one-size-fits-all solution.

#################################################################
# macro definitions

ext_if = "ne1"

#################################################################
# options: "set"

#################################################################
# scrub rules: "scrub"

# ex. 1: scrub all incoming packets on all interfaces
scrub in all

# ex. 2: scrub all incoming packets on the external interface 
scrub in on $ext_if all

The process of packet normalization with the scrub rules can be refined with these keywords:

  • fragment reassemble: reassemble fragmented packets. This is the default behavior. Fragments are held in memory until all fragments of the original packet have been collected. You can set a limit on the number of fragments with the set frags option.
  • fragment crop: do not reassemble fragmented packets, but pass them on. Track fragments, drop duplicate fragments, and crop overlaps.
  • fragment drop-ovl: similar to fragment crop, but drops all duplicate and overlapping fragments and their corresponding fragments.

Note that only the fragment reassemble modifier works when NAT rules are used at the same time. The fragment crop and fragment drop-ovl do not work with NAT in OpenBSD 3.2.

It is also possible to set some options:

  • no-df: clear the don't-fragment bit in the IP flags. This lets datagrams be fragmented by other routers.
  • min-ttl n: sets the minimum Time-To-Live for the matching packets to n hops. The longer the TTL, the longer the packet will circulate in the network. This modifier is only useful for finetuning tune your network's performance.
  • max-mss m: sets the Maximum Segment Size for a fragment to m bytes. Generally, the larger the MMS, the better the network performance. Again, you'll only need to worry about this option when there is a performance problem.

The above options are of interest to administrators of large networks. Their use and the way they affect performance of networks is best described in [Stevens 1994].

All scrub modifiers are listed at the end of the rule:

#################################################################
# macro definitions

ext_if = "ne1"
ext_ad = "any"
prv_ad = "f.f.f.f/24"

#################################################################
# options: "set"

#################################################################
# scrub rules: "scrub"

scrub in on $ext_if all no-df min-ttl 100 max-mss 1440 fragment reassemble
scrub in on $ext_if all no-df min-ttl 100 max-mss 1440 fragment crop 
scrub in on $ext_if from $ext_ad to $prv_ad no-df min-ttl 
   100 max-mss 1440 fragment drop-ovl 

Only IPv4 fragments can be processed in this way. IPv6 fragments are blocked.

For more information on packet normalization, read the pf.conf(5), RFC815 [Clark 1982], and this interesting paper [Handley and Paxson 2001].

NAT

Network address translation (NAT) is a technique for connecting hosts hidden behind firewalls to the Internet. It can be used to redirect traffic between external and internal hosts as a proxy. It's also often used to increase the number of hosts connected to the Internet.

In the early days of the Internet, every host (or, more precisely, every network interface connecting that host to other hosts on the Internet) needed a unique IP number. The dynamic expansion of the number of hosts connected to the Internet during the last decade made it obvious that the old pool of IP numbers will soon end. Of course, the best answer for that is IPv6, but before the world switches to it, NAT will see much use as a technique for better utilization of the existing pool of IPv4 numbers, as well as for some useful security setups.

Diagram.
Figure 1. A general outline of the network described in this article.

By definition, if a host has no public IP address assigned to it, it cannot be reached from the outside, even if you plug it into the connector that your Internet provider gave you, which is good from the point of view of security. It gets even better when you put a firewall between the internal network and the outside network, as shown in Figure 1 above. Then you can carefully log and screen all incoming and outgoing traffic to ensure maximum security. If you split your internal network into two or more segments, then your network becomes even more secure. However, since your internal networks use a private address space (read RFC1918 [Rekhter, Moskowitz, Karrenberg, de Groot, and Lear 1996]), they are unreachable from the outside and they cannot reach outside hosts. Such a setup is secure, but not very functional, which is why we need NAT.

Turning IP Routing On and Off

If you want to run NAT, you must enable IP routing before you load NAT rules. This is done with

$ sudo sysctl -w net.inet.ip.forwarding=1
net.inet.ip.forwarding: 0 -> 1

To turn IP routing off, use this command:

$ sudo sysctl -w net.inet.ip.forwarding=0 
net.inet.ip.forwarding: 1 -> 0

When you're unsure if IP routing is on or off, you can check it with

$ sudo sysctl net.inet.ip.forwarding      
net.inet.ip.forwarding = 0

To make changes permanent and always enable IP routing at system startup, edit /etc/sysctl.conf and change this line:

#net.inet.ip.forwarding=1   # 1=Permit forwarding (routing) of packets

to

net.inet.ip.forwarding=1     # 1=Permit forwarding (routing) of packets

Pages: 1, 2, 3, 4

Next Pagearrow





Sponsored by: