BSD DevCenter
oreilly.comSafari Books Online.Conferences.

advertisement


Securing Small Networks With OpenBSD, Part 2
Pages: 1, 2

Yet another useful feature is variable substitution. It allows us to define variables and reuse them in different places in our ruleset. For example, we can store the name of the external interface (tun0), and the list of non–routable network addresses can be stored in the variables ExtIF and NoGoIPs. Use them as follows:



ExtIF="tun0"

NoGoIPs="{ 192.168.0.0/16, 172.16.0.0/12, 127.0.0.0/8, 10.0.0.0/8, 0.0.0.0/8, 169.254.0.0/16, 192.0.2.0/24, 204.152.64.0/23, 224.0.0.0/3 }"

# prevent spoofing non-routable addresses

block in quick on $ExtIF from $NoGoIPs to any

block out quick on $ExtIF from any to $NoGoIPs

The final ruleset that implements the security policy presented in the earlier article looks like this:

#################################################################

# define variables

ExtIF="tun0"

PrvIF="ne1"

DMZIF="ne2"

NoGoIPs="{ 192.168.0.0/16, 172.16.0.0/12, 127.0.0.0/8, 10.0.0.0/8, 0.0.0.0/8, 169.254.0.0/16, 192.0.2.0/24, 204.152.64.0/23, 224.0.0.0/3 }"

PrivateIPs="192.168.1.0/24"

DMZIPs="192.168.2.0/24"

#################################################################

# normalize packets

scrub in all

#################################################################

# stop all IPv6 traffic

block in quick inet6 all

block out quick inet6 all

#################################################################

# pass everything on loopback (lo0)

pass in quick on lo0 all

pass out quick on lo0 all

#################################################################

# Internet (tun0)

# prevent spoofing of non-routable addresses

block in quick on $ExtIF from $NoGoIPs to any

block out quick on $ExtIF from any to $NoGoIPs

# stop all incoming packets

block in on $ExtIF all

pass in on $ExtIF inet proto { tcp, udp } from any to 192.168.2.4/32 port smtp keep state

pass in on $ExtIF inet proto { tcp, udp } from any to 192.168.2.3/32 port www keep state

# block all outgoing packets

block out on $ExtIF all

# allow TCP IPv4 connections to the outside world, keep state

pass out on $ExtIF inet proto tcp all flags S/SA modulate state

pass out on $ExtIF inet proto { udp, icmp } all keep state

#################################################################

# private network (ne1)

# prevent spoofing of non-routable addresses

block in quick on $PrvIF from ! $PrivateIPs to any

block out quick on $PrvIF from any to ! $PrivateIPs

# stop all incoming and outgoing packets

block in on $PrvIF all

block out on $PrvIF all

# allow TCP IPv4 connections to the outside world, keep state

pass in on $PrvIF inet proto tcp from $PrivateIPs to any flags S/SA modulate state

pass in on $PrvIF inet proto { udp, icmp } from $PrivateIPs to any keep state

#################################################################

# DMZ network (ne2)

# prevent spoofing of non-routable addresses

block in quick on $DMZIF from ! $DMZIPs to any

block out quick on $DMZIF from any to ! $DMZIPs

# stop all incoming and outgoing packets

block in on $DMZIF all

block out on $DMZIF all

# allow TCP IPv4 connections to the outside world, keep state

pass in on $DMZIF inet proto tcp from $DMZIPs to any flags S/SA modulate state

pass in on $DMZIF inet proto { udp, icmp } from $DMZIPs to any keep state

block in on $DMZIF inet from $DMZIPs to $PrivateIPs

pass out on $DMZIF inet proto tcp from any to $DMZIPs flags S/SA modulate state

pass out on $DMZIF inet proto { udp, icmp } from any to $DMZIPs keep state

There are now only 27 rules, compared to 58 in the ipfilter ruleset presented in the previous article. That’s quite a savings, and it makes managing firewalls so much easier. Careful readers will notice the use of the inet keyword. It tells pf that a particular rule applies to IPv4 packets. To apply the rule to IPv6 packets, use the inet6 argument.

If you want to apply the above ruleset to your own network, simply modify the names of the interfaces and network addresses. If you are running the mail and WWW servers on the same machine, you can compress the rules:

pass in on $ExtIF inet proto { tcp, udp } from any to 192.168.2.4/32 port smtp keep state

pass in on $ExtIF inet proto { tcp, udp } from any to 192.168.2.3/32 port www keep state

into

pass in on $ExtIF inet proto { tcp, udp } from any to 192.168.2.4/32 port { smtp, www } keep state

But remember to replace 192.168.2.4/32 with the actual address of the server.

How do I translate ipfilter NAT rules into pf NAT rules?

Changes made to the NAT rules syntax are small; administrators switching from the NAT found in OpenBSD 2.8 and 2.9 should feel right at home. When translating the old rules, remember that the map keyword has been replaced with nat on followed by the name of the external interface. Also, the portmap keyword is gone. So, instead of the old

map tun0 192.168.1.0/24 -> x.x.x.x/32 portmap tcp/udp 10000:20000

map tun0 192.168.1.0/24 -> x.x.x.x/32

map tun0 192.168.2.0/24 -> x.x.x.x/32 portmap tcp/udp 20001:30000

map tun0 192.168.2.0/24 -> x.x.x.x/32

we can now use a simple set of rules. (Note that there is no /32 at the end of the external address.)

nat on tun0 from 192.168.1.0/24 to any -> x.x.x.x

nat on tun0 from 192.168.2.0/24 to any -> x.x.x.x

More radical changes have been made to the rdr rules to make their syntax resemble pf filtering rules. The old rdr rules

rdr tun0 x.x.x.x/32 port 80 -> 192.168.1.3 port 80 tcp

rdr tun0 x.x.x.x/32 port 80 -> 192.168.1.3 port 80 udp

become

rdr on tun0 proto tcp from any to x.x.x.x/32 port 80 -> 192.168.254.2 port 80

rdr on tun0 proto udp from any to x.x.x.x/32 port 80 -> 192.168.254.2 port 80

As you can see, the differences are only in the arrangement of keywords in the rules. The new NAT rules set is shown below.

#################################################################

# NAT

nat on tun0 from 192.168.255.0/24 to any -> x.x.x.x

nat on tun0 from 192.168.254.0/24 to any -> x.x.x.x

#################################################################

# Internet (tun0)

rdr on tun0 proto tcp from any to x.x.x.x/32 port 25 -> 192.168.2.4 port 25

rdr on tun0 proto udp from any to x.x.x.x/32 port 25 -> 192.168.2.4 port 25

rdr on tun0 proto tcp from any to x.x.x.x/32 port 80 -> 192.168.2.3 port 80

rdr on tun0 proto udp from any to x.x.x.x/32 port 80 -> 192.168.2.3 port 80

#################################################################

# private network (ne1)

rdr on ne1 proto tcp from 192.168.1.0/24 to x.x.x.x/32 port 25 -> 192.168.2.4 port 25

rdr on ne1 proto udp from 192.168.1.0/24 to x.x.x.x/32 port 25 -> 192.168.2.4 port 25

rdr on ne1 proto tcp from 192.168.1.0/24 to x.x.x.x/32 port 80 -> 192.168.2.3 port 80

rdr on ne1 proto udp from 192.168.1.0/24 to x.x.x.x/32 port 80 -> 192.168.2.3 port 80

#################################################################

# DMZ network (ne2)

rdr on ne2 proto tcp from 192.168.2.0/24 to x.x.x.x/32 port 25 -> 192.168.2.4 port 25

rdr on ne2 proto udp from 192.168.2.0/24 to x.x.x.x/32 port 25 -> 192.168.2.4 port 25

rdr on ne2 proto tcp from 192.168.2.0/24 to x.x.x.x/32 port 80 -> 192.168.2.3 port 80

rdr on ne2 proto udp from 192.168.2.0/24 to x.x.x.x/32 port 80 -> 192.168.2.3 port 80

If you want to use that ruleset on your own firewall, remember to replace the IP numbers with the actual IP addresses on your network. You can find out more about these, the pf, and the syntax of pf and NAT rules in these man pages: pf, pf.conf, and nat.conf.

OpenBSD 3.1 will bring an interesting enhancement to pf in the form of authpf, which provides a mechanism for enabling and disabling access by users in addition to IP number control. The future is bright.

Coda, or "Why did you write about OpenBSD 2.8 and not 3.0?"

That was the question I got asked most of the time. There were two reasons: the mechanics of the publishing industry and my conservative approach to new releases of software. Let me explain this in a little more detail.

First, a little information about the time it takes to publish something. It is very rare that something you write will be published the day you submit it. Once an author sends an article to an editor, he loses direct control over his work and has to wait for the editor to decide if, and when, the article is going to be published. That may happen on the same day, but it could just as well be a few weeks or months before the general public can see it, and the fact that you submit your piece to an online publisher does not matter that much.

To put things in perspective, I once had to wait fourteen months for a publisher to decide that she wanted to publish my article! Of course, that is on the extreme side of things and it did not take as long to publish Securing Small Networks with OpenBSD, but the article did have to wait for its turn. And it's not the editor's fault either, as there are many issues beyond his or her control. That's how the publishing world works, even if something you write is published online.

Second, when the article was accepted (not published, but put on a list of articles awaiting publication), OpenBSD 3.0 had been available for only a week or so. There was no time to test it, and I wanted to wait for things to settle after the switch from ipfilter to pf. (Theo's decision to switch had a lot to do with ipf licensing issues and politics, which you can find out more about at http://slashdot.org/search.pl?query=ipfilter.)

To make things a bit more complicated, Darren Reed, the author of ipf, published his own OpenBSD 3.0 fork that uses ipf instead of pf. You can find it on Darren's site. (Of course, all information from "Securing Small Networks with OpenBSD" still applies to that release.) But you should remember that this is Darren's own fork, and it's not supported by the main OpenBSD team.

Oh, the politics, licenses, and egos. . . .

Jacek Artymiak started his adventure with computers in 1986 with Sinclair ZX Spectrum. He's been using various commercial and Open Source Unix systems since 1991. Today, Jacek runs devGuide.net, writes and teaches about Open Source software and security, and tries to make things happen.


Return to the BSD DevCenter.






Sponsored by: