OpenBSD firewall using pf

 
OpenBSD pf by Hoang Q. Tran

OpenBSD firewall using pf

by Hoang Q. Tran

It is really easy to configure an OpenBSD gateway for a private network. Here are the following steps:

Lock down the box

The first step to lock down the firewall box is to disable all unnecessary running services. Luckily, OpenBSD out of the box is really secure even with ident, comsat, daytime, time, rstatd and rusersd enabled in /etc/inetd.conf. Comment out mentioned services in /etc/inetd.conf and edit /etc/rc.conf and make sure portmap, sendmail and ntpd daemons are disabled as well. Don't disable inetd as you will need it later for ftp-proxy.
check_quotas=NO
ntpd=NO
sendmail_flags=NO
sshd is enabled out of the box. If you don't plan to use it, disable it with sshd_flags=NO

Once you disabled unnecessary services, go to unixcircle to remotely port scan your own box from the outside. Be careful when you do this behind a firewall box as the port scan script will scan the firewall instead. If you have another box, use nmap to scan the box from the inside.

Get the latest OpenBSD security patches and manually apply or download all the patches in one file or use AnonCVS to synchronize to stable release and build from source.

Make sure you check out the 3.2 stable branch with -rOPENBSD_3_2. Otherwise, you're checking out the ``current'' branch instead.

Finally, readup on SANS's The Twenty Most Critical Internet Security Vulnerabilities (Updated)

Install second Ethernet card in the OpenBSD box

Use any supported ethernet card for the second NIC in the OpenBSD machine. One card will be given a public IP address (assigned by your ISP or obtained dynamically, e.g., with DHCP) and the other will be given an IP address in a non-routable network. Your choices for private network addresses must come from one of these ranges (see RFC 1918):
10.0.0.1 - 10.255.255.254      netmask 255.0.0.0
172.16.0.1 - 172.31.255.254    netmask 255.240.0.0
192.168.0.1 - 192.168.255.254  netmask 255.255.0.0
Assume the first card is ``ep", create /etc/hostname.ep0 with the following x.x.x.x netmask x.x.x.x where x.x.x.x is what you choose above.
# First NIC - private
192.168.1.1 netmask 255.255.255.0 media 10baseT
And if you have a static IP address for the second NIC, you naturally need to have it configured as /etc/hostname.ep1 as well.
# Second NIC with public IP address
123.221.8.1 netmask 255.190.280.0 media 10baseT
Be sure to indicate a correct IP address and netmask for both interfaces. Once you have chosen a private network address range for your inside machines, stay with that same range.

Whatever address you choose for the first interface in the OpenBSD gateway becomes the default gateway IP address for all machines on the inside private network.

Customize the kernel

Compile the new kernel and remove any unwanted devices from the kernel.

Retrieve the kernel source and unpack it as:

# tar xzvf srcsys.tar.gz -C /usr
( kernel source unpacking output... )
...

Or use AnonCVS to get just the kernel source it:
# setenv CVSROOT anoncvs@anoncvs.ca.openbsd.org:/cvs
# cd /usr
# cvs -q get -rOPENBSD_3_2 -P src/sys
( checking out files output... )
...
# cd /sys/arch/i386/conf
I usually name the kernel to the machine hostname, but you can give it any name. Edit the kernel config file:

Remove any hardware related options that are not relevant to your machine. One way to find out what to keep is to consult the dmesg output and remove all the rest. For all available kernel options, refer to GENERIC in the same directory as your kernel file and /sys/conf/GENERIC or man options(4).

Save the kernel config file and then compile and install it:

# config firewall
# cd ../compile/firewall
# make depend; make
( kernel building output... )
...
# cp /bsd /bsd.old
# cp bsd /bsd
# reboot
This will retain the old kernel as /bsd.old just in case something has gone awry with the new one and the box doesn't boot. If that happens you can type 'bsd.old' at the boot: prompt to boot the old kernel.

Enable packet forwarding, dhcp, firewall and network address translation

To enable packet forwarding uncomment the following line in /etc/sysctl.conf and for extra protection, enable encryption on swap pages:
net.inet.ip.forwarding=1        # 1=Permit forwarding (routing) of packets
vm.swapencrypt.enable=1         # 1=Encrypt pages that go to swap
To enable high performance data transfers on hosts according to Enabling High Performance Data Transfers on Hosts, add the following to /etc/sysctl.conf:
# 1. Path MTU discovery: enabled by default
# 2. TCP Extension (RFC1323): enabled by default
# 3. Increase TCP Window size for increase in network performance
net.inet.tcp.recvspace=65535
net.inet.tcp.sendspace=65535
# 4. SACK (RFC2018): enabled by default

And if you receive your routable address assignment dynamically through DHCP:
# echo dhcp > /etc/hostname.ep1
The dhcp server will assign the IP, netmask and default gateway for interface ``ep1''. /etc/resolv.conf will be created with ``search'' and ``nameservers'' statements from the ISP.

Filter rule:

Starting with OpenBSD 3.2, filter and nat rules are combined into /etc/pf.conf. The order of /etc/pf.conf is really important and the format of /etc/pf.conf must follow this order:

1. Options
2. Scrub
3. NAT & RDR
4. Filter

If there are no filter rules, the default action is pass.

Network Address Translation rule:

For clients behind NAT to work, 1 NAT and 1 RDR rule is sufficient:

# NAT internal IP addresses of range 192.168.1.0/24 to external routable
# IP on ep1 interface
nat on ep1 from 192.168.1.0/24 to any -> ep1

# Translate outgoing ftp control connections to send them to localhost
# for proxying with ftp-proxy(8) running on port 8081
rdr on ep0 proto tcp from any to any port 21 -> 127.0.0.1 port 8081

ftp-proxy runs inside inetd, add the following line to /etc/inetd.conf in order for ftp clients behind NAT to work by going through ftp-proxy daemon:
127.0.0.1:8081  stream tcp nowait root /usr/libexec/ftp-proxy ftp-proxy
As a result, ftp port and port 8081 will be opened. ftp-proxy supports -w option which will use tcp_wrappers to control source ftp client as well as destination ftp server access control based on /etc/hosts.allow and /etc/hosts.deny. Assume source ftp client IP 192.168.1.2 doesn't have permission to use ftp, a similar log entry in /var/log/messages when attempted to reach ftp.netbsd.org
Sep 14 15:55:38 firewall ftp-proxy[20970]: tcpwrappers rejected: 192.168.1.2 -> ftp.netbsd.org

An example of a working /etc/pf.conf

Transparent proxy:

If there's a mail server as 192.168.1.2 and a DNS server as 192.168.1.3 inside the private network, use ``rdr'' to transparent proxying. Since NAT happens before ``rdr'', a ``pass in'' is required in /etc/pf.conf for the translated packets to flow into the mail server and DNS server.

/etc/pf.conf:

# Redirect incoming smtp traffic to mail server behind NAT
rdr on ep1 proto tcp from any to 157.161.48.183/32 port 25 -> 192.168.1.2 port 25

# Redirect incoming domain traffic to DNS server behind NAT
rdr on ep1 proto { tcp,udp } from any to 157.161.48.183/32 port 53 -> 192.168.1.3 port 53
Finally, enable pf in /etc/rc.conf:
pf=YES                   # Packet filter / NAT / logging using pflogd

Configure machines behind NAT

All the machines on the private network should be configured to use the address of the private interface of the OpenBSD box as the default gateway. To set the internal boxes to the default OpenBSD gateway on various operating systems with IP address: 192.168.1.1
AIX: edit /etc/rc.net and add /usr/sbin/route add 192.168.1.1 gateway >> $LOGFILE 2>&1

FreeBSD: edit /etc/rc.conf and add defaultrouter="192.168.1.1"
HP-UX: edit /etc/rc.config.d/netconf and add ROUTE_GATEWAY[0]="192.168.1.1"
Linux Redhat: edit /etc/sysconfig/network and add GATEWAY=192.168.1.1
NetBSD:  echo "192.168.1.1" > /etc/mygate
OpenBSD: echo "192.168.1.1" > /etc/mygate

Solaris: echo "192.168.1.1" > /etc/defaultrouter
Win2k: Start-Settings->Control Panel->Network and Dial-up Connections->Local Area Network->
       Properties->Internet Protocol (TCP/IP)->Default Gateway->192.168.1.1

If you don't want to reboot to pick up the IP address for the default gateway, use ``route'' to manually add the default route.

AIX: route add 0 192.168.1.1

HP-UX: route add 192.168.1.1

FreeBSD,NetBSD,OpenBSD,Solaris: route add default 192.168.1.1

Linux Redhat: route add default gw 192.168.1.1

Familiarize with pf

Once your firewall is online, you should start reading pf.conf(5), nat.conf(5), ftp-proxy(8), pfctl(8), pf(4) and The OpenBSD Packet Filter HOWTO. Also consult IPFILTER-HOWTO since both pf and IP Filter have 90% identical syntax. One noticable difference is OpenBSD pf doesn't support IP Filter ``keep frags'' syntax. The alternative is to use ``scrub'' statement.

Each time /etc/pf.conf or /etc/nat.conf are modified, you have to reload them using pfctl. Reloading these rules will flush all current active connections. Unlike IPFilter, pf needs to enable nat and pf rules manually.

Flush current nat rules & reload:

# /sbin/pfctl -F nat && /sbin/pfctl -N /etc/pf.conf
Flush current filter rules & reload:
# /sbin/pfctl -F rules && /sbin/pfctl -R /etc/pf.conf
Show filter information (statistics and counters):
# pfctl -s info
To display the current list of active MAP/Redirect filters and active sessions:
# /sbin/pfctl -s state
To find out the ``hit" statistic for each individual rule in /etc/pf.conf:
# /sbin/pfctl -s rules -v
Watch port scans going by on the screen:

/var/log/pflog is a binary file generated by pflogd so you can't just view it. Use tcpdump instead:

# tcpdump -i pflog0

Read the log for pf activities:

# tcpdump -n -e -ttt -r /var/log/pflog

Quality of Service (QoS)

Bandwidth limiting:

OpenBSD 3.2 has ALTQ integrated in the base system. The kernel generic kernel is also compiled with options ALTQ so you're ready to use. Otherwise, download the latest KAME snap kit which has ALTQ bundle from: http://www.kame.net/retrieve.html

Now, to configure a token bucket regulator (tbrconfig) for the interface ep1 to rate limit the pipe from 100Mbps to 10Mbps for outgoing connection:

# tbrconfig ep1 10M auto
ep1: tokenrate 10.00M(bps)  bucketsize 12.21K(bytes)
#
To remove the installed token bucket regulator on ep1:
# tbrconfig -d ep1
deleted token bucket regulator on ep1
#

Class-based queuing (CBQ):

From man options(4) description of CBQ:

CBQ achieves both partitioning and sharing of link bandwidth by hierarchically structured classes. Each class has its own queue and is assigned its share of bandwidth. A child class can borrow bandwidth from its parent class as long as excess bandwidth is available.

Here is an example of a working /etc/altq.conf. /etc/altq.conf is read by altqd so to enable it on startup, edit /etc/rc.conf and change altqd_flags=NO to altqd_flags="". Or just manually start altqd. altqd won't start if there are errors in /etc/altq.conf. Watch /var/log/messages for any information.

Here's the class hierarchy: cbq.txt

#
# ep1: Interface to a 10M link
#
#
interface ep1 bandwidth 10M cbq
class cbq ep1 root NULL pbandwidth 100
#
# meta classes
#
class cbq ep1 ctl_class root pbandwidth 4 control
class cbq ep1 def_class root borrow pbandwidth 95 default
#
# Allocate bandwidth for:
# firstclass: 70%
# businessclass: 15%
# generalclass: 5%
#
class cbq ep1 firstclass def_class borrow pbandwidth 70
class cbq ep1 businessclass def_class borrow pbandwidth 15
class cbq ep1 generalclass def_class borrow pbandwidth 5
#
# Allocate bandwidth for firstclass (tcp) data classes:
# tcp: 28%
# smtp: 10%
# http: 30%
# dns: 2%
#
class cbq ep1 tcp firstclass borrow pbandwidth 28 red
    filter ep1 tcp 0 0 0 0 6    # other tcp
class cbq ep1 smtp firstclass borrow pbandwidth 10 red
    filter ep1 smtp 0 0 0 25 6  # smtp
    filter ep1 smtp 0 25 0 0 6  # smtp
class cbq ep1 http firstclass borrow pbandwidth 30 red
    filter ep1 http 0 0 0 80 6  # http
    filter ep1 http 0 80 0 0 6  # http
class cbq ep1 dns firstclass borrow pbandwidth 2 red
    filter ep1 dns 0 0 0 53 6   # dns
    filter ep1 dns 0 53 0 0 6   # dns

#
# Allocate bandwidth for businessclass (udp) classes:
# udp: 10%
# dns: 5%
#
class cbq ep1 udp businessclass borrow pbandwidth 10 red
    filter ep1 udp 0 0 0 0 17   # udp
class cbq ep1 dns businessclass borrow pbandwidth 5 red
    filter ep1 dns 0 0 0 53 17  # dns
    filter ep1 dns 0 53 0 0 17  # dns
#
# Allocate bandwidth for generalclass (icmp) classe:
# icmp: 5%
#
class cbq ep1 icmp generalclass borrow pbandwidth 5 red
    filter ep1 icmp 0 0 0 0 1   # icmp
Now, run altqstat and monitor the bandwidth. You should see something similar here: cbq stat

Weighted Fair Queueing (WFQ):

To use weighted fair queueing, add the following to kernel file.

option          ALTQ_WFQ

By default, WFQ allocates 256 queues and packets are mapped into one of the queues by hashing the destination address. So, packets for the same host will be put in the same queue.

To enable WFQ on interface "ep0" and "ep1", add the following lines to your altq.conf(5) and start altqd.

interface ep0 bandwidth 10M wfq
interface ep1 bandwidth 10M wfq
The following command can be used to monitor the wfq statistics.
altqstat -i ep1
You should see something similar:
% altqstat
altqstat: wfq on interface ep1
wfq on ep1: 256 queues are used

[QID] WEIGHT QSIZE(KB) SENT(pkts)     (KB)       DROP(pkts)     (KB)     bps
[ 141]  100    0         14              1          0              0     0.09K
[ 103]  100    0          2              0          0              0     0.09K
[ 131]  100    0         11              1          0              0         0
[ 155]  100    0         10              0          0              0         0
[ 124]  100    0          9              0          0              0         0
[ 184]  100    0          5              0          0              0         0
[  12]  100    0          2              0          0              0         0
[   0]  100    0          0              0          0              0         0
[   1]  100    0          0              0          0              0         0
[   2]  100    0          0              0          0              0         0
First-In First-Out Queueing (FIFOQ):

To use first-in first-out queueing, add the following to kernel file.

option          ALTQ_FIFOQ
To enable FIFOQ on interface ep1, add the following line to your altq.conf(5) and start altqd.
interface ep1 bandwidth 10M fifoq
Run altqstat and you should see something similar:
% altqstat
altqstat: fifoq on interface ep1
 q_len:0 q_limit:50 period:2
 xmit:2 pkts (108 bytes) drop:0 pkts (0 bytes)
 throughput: 0.17Kbps
 q_len:0 q_limit:50 period:2
 xmit:2 pkts (108 bytes) drop:0 pkts (0 bytes)
 throughput: 0bps
...
Random Early Detection (RED):

Since RED is part of ALTQ, no kernel option is required.

To enable random early detection on interface ep1, add the following line to your altq.conf(5) and start altqd.

interface ep1 bandwidth 10M red

Run altqstat and you should see something similar:
% altqstat
altqstat: red on interface ep1
 weight:512 inv_pmax:10 qthresh:(5,15)
 q_len:0 (avg: 0.00), q_limit:60
 xmit:1 pkts, drop:0 pkts (forced: 0, early: 0)
 throughput: 0.09Kbps

 weight:512 inv_pmax:10 qthresh:(5,15)
 q_len:0 (avg: 0.00), q_limit:60
 xmit:1 pkts, drop:0 pkts (forced: 0, early: 0)
 throughput: 0bps
...
Diffserfv traffic conditioner (CDNR):

>From man options(4):

Traffic conditioners are components to meter, mark, or drop incoming packets according to some rules. As opposed to queueing disciplines, traffic conditioners handle incoming packets at an input interface.

To use conditioner to drop incoming packets from a particular IP address, add the following to kernel file.

option          ALTQ_CDNR
To enable conditioner on interface ep1, add the following line to your altq.conf(5) and start altqd.
#
interface ep1
#
# Drop all packets coming in from 255.255.255.255 (ficticious)
#
conditioner ep1 dropper <drop>
     filter ep1 dropper 0 0 255.255.255.255 0 0
Run altqstat to monitor the drop packets:
% altqstat
altqstat: cdnr on interface _fxp0
actions:
  pass:471 drop:3 mark:0 next:0 return:0 none:0

actions:
  pass:501 drop:3 mark:0 next:0 return:0 none:0
...

Priority Queueing (PRIQ):

>From man options(4):

PRIQ implements a simple priority-based queueing. A higher priority class is always served first.

High number has higher priority. Maximum value is 15 and minimum value is 0. Default is 0. A higher priority class is always served first in PRIQ. Priority must be unique for the interface.

To use priority queueing to prioritize based on type of packet, add the following to kernel file.

option          ALTQ_PRIQ
To enable priority queueing on interface ep1, add the following line to your altq.conf(5) and start altqd.
#
# Prioritize based on protocol:
#
# tcp: high priority
# udp:  medium priority
# icmp: low priority
# others: bottom priority
#
interface ep1 bandwidth 10M priq
#
class priq ep1 highest_class NULL priority 3
     filter ep1 highest_class 0 0 0 0 6
class priq ep1 medium_class NULL priority 2
     filter ep1 medium_class 0 0 0 0 17
class priq ep1 lowest_class NULL priority 1
     filter ep1 lowest_class 0 0 0 0 1
class priq ep1 bottom_class NULL priority 0 default

% altqstat
altqstat: priq on interface ep1

ep1:
[highest_class] handle:0xe09fd0c0 pri:3
  measured: 0.34Kbps qlen: 0 period:180
     packets:180 (25637 bytes) drops:0
[medium_class] handle:0xe09f1d40 pri:2
  measured: 0bps qlen: 0 period:25
     packets:25 (1997 bytes) drops:0
[lowest_class] handle:0xe09fdcc0 pri:1
  measured: 0bps qlen: 0 period:19
     packets:19 (1862 bytes) drops:0
[bottom_class] handle:0xe09a4680 pri:0
  measured: 0bps qlen: 0 period:0
     packets:0 (0 bytes) drops:0
...

References

Daniel Hartmeier the author of pf and his original page:
   http://www.benzedrine.cx/pf.html
The OpenBSD Packet Filter HOWTO
   http://www.inebriated.demon.nl/pf-howto/
IPFilter how-to:
   http://www.unixcircle.com/ipf/
Address Allocation for Private Internets:
   http://www.muine.org/rfc/rfc1918.txt
The IP Network Address Translator (NAT):
   http://www.muine.org/rfc/rfc1631.txt
Traditional IP Network Address Translator (Traditional NAT)
   http://www.muine.org/rfc/rfc3022.txt
ALTQ
   http://www.csl.sony.co.jp/~kjc/software.html#ALTQ
CBQ:
   http://www.aciri.org/floyd/cbq.html
HFSC:
   http://www-2.cs.cmu.edu/~hzhang/HFSC/main.html
RED:
   http://www.aciri.org/floyd/red.html
RIO:
   http://diffserv.lcs.mit.edu/Papers/exp-alloc-ddc-wf.pdf
BLUE:
   http://thefengs.com/wuchang/blue/
Diffserv:
   http://www.ietf.org/html.charters/diffserv-charter.html
The Twenty Most Critical Internet Security Vulnerabilities (Updated)
  http://www.sans.org/top20/


last update: Oct 20, 2003


copyright © 2000-2003 unixcircle
Contact webmaster@unixcircle.com
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值