BSD DevCenter
oreilly.comSafari Books Online.Conferences.

advertisement


Securing Small Networks with OpenBSD Changes in pf: More on NAT

by Jacek Artymiak
05/08/2003

Welcome back!

In the previous installment of this series, we had a close look at macros, options, scrub rules, and NAT rules. Today we continue our adventures with NAT. We'll take on board a sample ruleset, discuss its implementation, and explore various ways of customizing it to your specific needs.

Like before, we'll be working with the DMZ design described in one of my earlier articles. Implemented in practice, a generic ruleset that follows that design could contain the following NAT entries:


#################################################################
# macro definitions
#################################################################
# ext_if -- external interface, connects the firewall to the
#           outside world
# prv_if -- private interface, connects to the private network 
#           segment to the firewall
# dmz_if -- DMZ interface, connects to the DMZ network segment 
#           to the firewall
#################################################################

ext_if = "ne1"
prv_if = "ne2"
dmz_if = "ne3"

#################################################################
# ext_ad -- the IPv4 address of the ext_if external interface
# prv_ad -- the range of IPv4 addresses on the private network
# dmz_ad -- the range of IPv4 addresses on the DMZ network 
#################################################################

ext_ad = "x.x.x.x/32"
prv_ad = "192.168.1.0/24"
dmz_ad = "192.168.2.0/24"

#################################################################
# dmz_domain_ad -- the internal IPv4 address of the externally 
#                  accessible DNS server residing in the DMZ
# dmz_www_ad    -- the internal IPv4 address of the externally
#                  accessible HTTP server residing in the DMZ
# dmz_smtp_ad   -- the internal IPv4 address of the externally
#                  accessible SMTP server residing in the DMZ
# dmz_ftp_ad    -- the internal IPv4 address of the externally
#                  accessible FTP server residing in the DMZ
# dmz_nntp_ad   -- the internal IPv4 address of the externally
#                  accessible NNTP server residing in the DMZ
#################################################################

dmz_domain_ad  = "192.168.2.2/32"
dmz_www_ad     = "192.168.2.3/32"
dmz_smtp_ad    = "192.168.2.4/32"
dmz_ftp_ad     = "192.168.2.5/32"
dmz_nntp_ad    = "192.168.2.6/32"

#################################################################
# dmz_domain_pr -- protocols used by the DMZ DNS server
# dmz_www_pr    -- protocols used by the DMZ HTTP server 
# dmz_smtp_pr   -- protocols used by the DMZ SMTP server 
# dmz_ftp_pr    -- protocols used by the DMZ FTP server 
# dmz_nntp_pr   -- protocols used by the DMZ NNTP server 
#################################################################

dmz_domain_pr = "{tcp, udp}"
dmz_www_pr    = "{tcp}"
dmz_smtp_pr   = "{tcp}"
dmz_ftp_pr    = "{tcp}"
dmz_nntp_pr   = "{tcp}"

#################################################################
# dmz_domain_pt -- the port that DMZ DNS server is listening on
# dmz_www_pt    -- the port that DMZ HTTP server is listening on 
# dmz_smtp_pt   -- the port that DMZ SMTP server is listening on 
# dmz_ftp_pt    -- the port that DMZ FTP server is listening on 
# dmz_nntp_pt   -- the port that DMZ NNTP server is listening on 
#################################################################

dmz_domain_pt = "2053"
dmz_www_pt    = "8080"
dmz_smtp_pt   = "2025"
dmz_ftp_pt    = "2020"
dmz_nntp_pt   = "2119"

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

set limit { frags 10000, states 10000 }
set loginterface $ext_if
set optimization default

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

scrub in  all fragment reassemble
scrub out all fragment reassemble

#################################################################
# NAT rules: "rdr", "nat", "binat"
#################################################################

nat on $ext_if from $prv_ad to any -> $ext_ad
nat on $ext_if from $dmz_ad to any -> $ext_ad

#################################################################
# establish redirection rules for the hosts on the external,
# private, and DMZ networks
#################################################################

rdr on $ext_if proto $dmz_domain_pr from any \
 to $ext_ad port domain -> $dmz_domain_ad port $dmz_domain_pt

rdr on {$ext_if, $prv_if} proto $dmz_www_pr from any \
 to $ext_ad port www    -> $dmz_www_ad port $dmz_www_pt

rdr on {$ext_if, $prv_if} proto $dmz_smtp_pr from any \
 to $ext_ad port smtp   -> $dmz_smtp_ad port $dmz_smtp_pt

rdr on {$ext_if, $prv_if} proto $dmz_ftp_pr from any \
 to $ext_ad port ftp    -> $dmz_ftp_ad port $dmz_ftp_pt

rdr on $prv_if proto $dmz_nntp_pr from any \
 to $ext_ad port nntp   -> $dmz_nntp_ad port $dmz_nntp_pt

These rules are for a network with two segments: one private network with hosts not accessible from the outside, and one DMZ network with hosts partially accessible from the outside world and from the private network.

Rolling Your Own NAT Rules

The DMZ network segment is only needed when you plan to make some services available to hosts outside of your network. You will have to adapt the rules shown earlier to your own network setup. The following guide should help you in that respect:

  • ext_if = "ne1": change this to the name of the interface that connects your firewall to the Internet. If you forgot the name of the interface, check the output of dmesg | less. If OpenBSD is not recognizing your network interface, read this article for kernel modification tips. Note that if you are using a device connected to the serial interface (like a modem), such a device may not be listed in dmesg output, but should still be recognized by the system. When you are not sure what name your network card falls under in OpenBSD, check the list displayed by apropos driver. Still no luck? Have a look at this list.

  • Related Reading

    Building Internet Firewalls
    By Elizabeth D. Zwicky, Simon Cooper, D. Brent Chapman

  • prv_if = "ne2": change to the name of the interface that connects the private network segment to the firewall. Also, see my notes above.

  • dmz_if = "ne3": change to the name of the interface connecting the DMZ network segment to the firewall. Also, see my notes above.

  • ext_ad = x.x.x.x/32: change x.x.x.x to the IPv4 address that identifies your firewall on the Internet. This is the static IP you received from your ISP. If you do not have a static IP address (most likely, if you are using ISDN, ADSL, an old-style modem to connect to the Internet), use $ext_if/32 in the nat and rdr rules listed below and delete this line from the ruleset.

  • prv_ad = 192.168.1.0/24: change 192.168.1.0/24 to the range of the private IP addresses used on your private network segment. You do not have to choose addresses from the 192.168.0.0/16 range (Class C). Instead, you can choose parts of 10.0.0.0/8 (Class A) or 172.16.0.0 (Class B) private address space.

  • dmz_ad = 192.168.2.0/24: change 192.168.2.0/24 to the range of IP addresses used on your DMZ network segment. If you are not going to have an externally accessible DMZ segment, remove this line from your ruleset, and remove all other lines that define rules for the DMZ network and hosts. Also, see my comments above about private address space. The addresses you use in the DMZ do not have to belong to the same class as those used in the private network segment.

  • dmz_domain_ad = "192.168.2.2/32": change 192.168.2.2 to the IP address of the DNS server that resides in your DMZ segment and answers queries from external hosts (as well as those that reside inside of the private network segment) about other servers running in the DMZ. Since this server will answer queries from external hosts and is a possible attack target, it should not store information about hosts in the private network segment. Because BIND can be hard to secure, you might consider outsourcing DNS, leaving the local caching DNS server in the private network segment. If you do that, remove this line from your ruleset.

  • dmz_www_ad = "192.168.2.3/32": change 192.168.2.3 to the IP address of the HTTP server residing in your DMZ segment. For security reasons, it is wise to use that server for public access material and services only, and set up another HTTP server in the private network segment for private documents and services. If you do not run an HTTP server in your DMZ segment, remove this line from your ruleset.

  • dmz_smtp_ad = "192.168.2.4/32": change 192.168.2.4 to the IP address of the SMTP server residing in your DMZ segment. If you do not run an SMTP server in your DMZ segment, remove this line from your ruleset.

  • dmz_ftp_ad = "192.168.2.5/32": change 192.168.2.5 to the IP address of the FTP server residing in your DMZ segment. If you do not run an FTP server in your DMZ segment, remove this line from your ruleset. Also, see my notes on dmz_www_ad.

  • dmz_nntp_ad = "192.168.2.6/32": change 192.168.2.6 to the IP address of the NNTP server residing in your DMZ segment. If you do not run an NNTP server in your DMZ segment, remove this line from your ruleset.

Pages: 1, 2

Next Pagearrow





Sponsored by: