Low-Cost Invisible Firewall HowTo on OpenBSD
by psygnosis <norbert@feu-nrmf.ph>
Last updated May 09, 2003 (see the Changelog below)
This document discusses the steps in building a low-cost and stateful invisible firewall. This document assumes that you have at least a basic knowledge on
UNIX-like operating systems,
IPFilter or
pf,
text file editing,
ifconfig(8) tool (duh!),
and at least a basic knowledge on network cables and network interfaces.
Also take note that this document does not broadly explain what bridge or repeater is. If you want to learn more complex details about network bridges/repeaters. You may take a look at the man pages or any
documentation that is well-suited to that topic but i'll try to explain briefly what bridge is :-)
According to
bridge(4)
man page:
The bridge device creates a logical link between two or more Ethernet interfaces or encapsulation interfaces (see
gif(4)).
This link between the interfaces selectively forwards frames from each interface on the bridge to every other interface on the bridge.
It simply means that packets that reaches one interface of the bridge shall be sent to another interface of the bridge.
But the good thing is.. as the packet goes from one interface to another, OpenBSD's
pf(4) can give you the option what to do with the packet.
Introduction
Packet filtering type of firewalls are used to allow and deny traffics according to your rules. Unfortunately, common packet filtering firewalls often waste IP space and can be accessed
remotely. Their activities are very visible and obvious to the world. I think it's hard to tell what will going to happen next when somebody has managed to access your firewall remotely.
Thanks to some freely available operating systems like the BSDs and their filtering utilities. Now, you can setup your firewall that don't waste any IP space. It can't be compromised remotely either because of
it's IP-less nature, and it's cost-effective compared to other commercial solutions. It is just a simple, robust and low-cost firewall sitting on the corner of your network and is
"invisible" to the
world. This document will help you setup and feel the power and ease of transparent bridging and stateful filtering using
OpenBSD's pf.
Invisible firewalls has some security advantage over other kind of firewalls. It does not waste IP space, it can't be portscanned or tracerouted and it can't be accessed remotely.
To the attacker's outside, it seems that their packets has been sucked by a blackhole.
Requirements and Assumptions:
We need at least 100Mhz x86 compatible machine (with at least 64mb RAM). We also need two network adapters (be sure to have a reliable adapters,
some of them won't work reliably on bridges, one example is the
TI ThunderLAN chip),
and an estimated 1.2gb capacity hard disk for OpenBSD installation.
And now, Let's assume we have a cable or DSL internet access. The following diagram below will show how the bridge will be installed.
[ internet ]-----[ modem ]-----[ openbsd bridge ]-----[ hub ]-----[ servers ]
If you don't have any hub to spare (and you're only using one server), you can make a cross-cable connection between the bridge and the server. It will look like the following illustration below.
[ internet ]-----[ modem ]-----[ openbsd bridge ]---cross cable---[ server ]
Setting up the bridge
The first step is to install the two (2) NICs on the PC slots (obviously you'll skip these step if the two NICs are already installed)
Attach the cable on the first NIC to the cable modem, then attach the second NIC to the hub (see the sample diagram below).
[ cable modem ]-----[ nic 1 of the bridge ]
[ nic 2 of the bridge ]-----[ hub ]-----[servers]
Optionally if you don't have any hub to spare, and you're only using one server, you may attach a cross-cable from the second NIC of the
bridge to the NIC of the server that is used to access the internet (see the sample diagram below).
[ cable modem ]-----[ nic 1 of the bridge ]
[ nic 2 of the bridge ]---cross cable---[server]
Install OpenBSD 3.3 or higher and remove any IP address information and configuration during install. You may refer to
OpenBSD Installation Guide for details. You may also want
to
recompile your kernel to
remove or add some
options(4).
Enable IP forwarding (using the command,
sysctl -w net.inet.ipforwarding=1)
and make sure that IP forwarding will be enabled during reboots by uncommenting the line
net.inet.ip.forwarding=1
in
/etc/sysctl.conf).
Setting up the interfaces
Setup the network interfaces to be enabled during reboots (assuming we'll use
ne2
and
xl0),
by putting the word '
up' in
/etc/hostname.ne2 and
/etc/hostname.xl0
(see
/etc/hostname.if(5)).
You can manually set up the interfaces now via
ifconfig(8) utility (e.g.
ifconfig ne2 up).
Setup the bridge to be enabled during reboots, you can put the line '
add ne2 add xl0 up' to
/etc/bridgename.bridge0 or if you
wish to block non-IP traffics by default you should put '
add ne2 add xl0 blocknonip ne2 blocknonip xl0 up' instead. You can also manually enable the bridge now via the
brconfig(8) tool (e.g.
brconfig bridge0 add ne2 add xl0 up or to block non-IP, you can use
brconfig bridge0 add ne2 add xl0 blocknonip ne2 blocknonip xl0 up).
You may verify if the
bridge(4) interface is already up by issuing the command:
# ifconfig -a | grep bridge0
You may then see the following output:
bridge0: flags=41 <UP,RUNNING> mtu 1500
If the bridge fail to run, Refer to the
brconfig(8)
and
bridgename.if(5)
man pages.
OpenBSD's pf configuration
pf(4)
is disabled by default. You must setup pf to automatically start during boot by editing
/etc/rc.conf and replacing the line
pf=NO
with
pf=YES. However you can manually enable pf anytime using the
pfctl(8)
utility. To enable pf, issue the command '
pfctl -e'.
Building the firewall ruleset
For more information on OpenBSD's pf syntax, you may refer to the
pf.conf(5)
man page.
Now, for the ruleset... Let's give a very simple example. Assuming we have an external IP of
1.2.3.4 on our webserver and
5.6.7.8 on our mailserver and DNS and we want the following
ruleset in our firewall.
- Expire stale connections quickly
- Deny RFC1918 networks
- Allow ICMP ping
- Allow only UDP queries to our DNS server
- Allow HTTP and HTTPS connections to our webserver from the outside
- Allow SMTP connections on our mailserver
- Allow only webserver and smtp/dns outgoing packets
- And block the rest of the incoming packets from the internet.
Then, /etc/pf.conf may look like as follows:
#### begin of packet filter rules ####
# initialize some macro variables
ext_if="ne2" # this is the one that is connected to the cable modem
int_if="xl0" # obviously, the one connected to the hub/server =)
webserver="1.2.3.4/32"
mailserver="5.6.7.8/32" # also the DNS server
# set table
table <rfc1918> const { 10/8, 172.16/12, 192.168/16 127/8 }
# expire stale connection quickly
set optimization aggressive
# set timeout for keeping tcp connections
set timeout { tcp.established 86400, tcp.closing 6, \
tcp.opening 6,tcp.closed 10 }
# let's add some sanity
scrub in on $ext_if all
# block all
block all
# we'll filter only one interface
pass in quick on $int_if all
pass out quick on $int_if all
# log blocked packets
block in log on $ext_if all
# deny rfc1918 packets
block in quick on $ext_if all from <rfc1918> to any
# allow icmp ping and keep state them
pass in quick on $ext_if inet proto icmp all icmp-type echoreq code 0 \
keep state
pass out quick on $ext_if inet proto icmp all icmp-type echoreq code 0 \
keep state
# allow udp traffic on our dns server
pass in quick on $ext_if proto udp from any to $mailserver \
port = domain keep state
# allow http and https connections on our webserver
pass in quick on $ext_if proto tcp from any to $webserver \
port { www, https ) flags S/SA modulate state
# allow smtp connection on out mailserver and log them
pass in quick on $ext_if proto tcp from any to $mailserver \
port = smtp flags S/SA modulate state
# pass outgoing smtp and www/smtp traffic
pass out quick on $ext_if proto { tcp, udp, icmp } from $mailserver to any keep state
pass out quick on $ext_if proto { tcp, udp, icmp } from $webserver to any keep state
##### end of packet filter rule #####
To enable the ruleset, we can issue the command
pfctl -f /etc/pf.conf,
(see
pf.conf(5)
for more information). For a broad scope on how to control the pf device, refer to the
pfctl(8) man page.
Reminders
Remember that this machine has NO IP address. It is unreachable from anywhere except on the console. This also means that you can't ping or ssh any other
machines from the bridge. Also don't bother to use the invisible firewall as a NAT router because it will not surely work.
I hope this document has been useful as a reference, and if you find any errors on this document, feel free to email me at
norbert@
feu-nrmf.ph. If you like to
help in improving this document. Feel free to do so :-)
Links and References
The OpenBSD Homepage
http://www.openbsd.org
OpenBSD pf Homepage
http://www.benzedrine.cx/pf.html
Credits and Greets
All credits goes to the OpenBSD team
Greetings to Jim, Keech, Sunyata, T2K, Sutil, Tanabe, z3r0kul, and the rest
Also a special greet to Ycel :)
Changelog:
Jun 03 2001 - covers OpenBSD 2.8 and
2.9
Nov 07 2002 - covers OpenBSD 3.0 and
3.1
Dec 22 2002 - covers OpenBSD 3.2
May 09 2003 - covers OpenBSD 3.3
License and Disclaimer
Copyright © 2001-2003 Norbert P. Copones <norbert@feu-nrmf.ph>
All rights reserved.
Permission to use, copy, modify, and distribute this document for any purpose is hereby granted. provided that
the above copyright notice and this permission notice appear in all copies.
THE DOCUMENT IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS DOCUMENT INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS DOCUMENT.