Firewall by ZaharlimZakaria


									HowTo: Building a firewall with Freebsd and IPfilter
Written by Steve Lake
Posted on: 05.14.2008 at 12:02pm
Section: Tutorials

For anyone who's ever been on the internet, even for as little as five minutes, knows that you can't play in the great big
world wide web anymore without some kind of protection. Typically this comes in the form of either simple NAT based
protection, or something stronger such as a firewall. In this tutorial I will be walking you through the setting up Freebsd
for maximum security, and and then as a full fledged firewall. Since security is of the utmost importance, the machine
you choose to use as your firewall should be set aside strictly for this task and should not be used for anything else. I
say this because additional services on the machine may create a potential security risk you won't want to deal with.

For those wondering why I'm using Freebsd for this tutorial, it's because Freebsd is well suited to this kind of task, and
is also one of the few OS's I trust to do the job properly. There are a couple others out there you could use if you
wanted to, but for this tutorial we'll be focusing on Freebsd as the core of your new firewall. Now, let's get started
building ourselves a firewall. If you're not sure what a firewall is, I recommend reading our "Understanding Firewalls"
tutorial first before you begin.

Setting up the hardware

Since a firewall will be doing little more than filtering traffic, the size of your firewall will depend on a lot of things. For
a home user, a small, inconsequential machine should be more than enough to do the job. For larger companies moving
greater amounts of bandwidth, a larger machine may be more appropriate. So choose your hardware wisely. For
connections ranging from 256kbps upwards to 20mbps, I recommend something in either the mini-itx or nano-itx class.

A good site for lots of great information on mini-itx and nano-itx is Epia Center. They have a lot of excellent
information on nearly everything relating to mini-itx and nano-itx hardware. We can also provide you with some good
suggestions on what hardware to choose in our forums as well if you need more specific guidance.

Here's a couple of good examples of various system configurations you can use.

Via SP13000 mainboard (includes 1.3ghz processor, onboard video, onboard lan)
256mb PC2700 memory (recommended 512mb, or 1gb)
1 Cdrom (standard or slimline depending on the case you choose)
1 10/100 PCI network card
40gb HD (slimline or standard depending on case form factor)
1 Mini-itx case (must support 170mm by 170mm board)

Standard PC: (high capacity connections greater than 20mbps)
2ghz equivalent AMD or Intel processor
Appropriate board for your CPU.
1gb ram (2gb if the connection is quite active)
graphics card (GF2 equivalent or higher)
Two 10/100/1000 network cards
Standard PC case.
1 cdrom
120gb HD

If you're curious about my suggestions, in these examples I allow for far more ram than is typically needed for most
firewalls. The reason I did that was to give you a machine that could do its job and have room to breath performance
wise. In reality, you can run a firewall on as small as an 600mhz machine without issue. The only times it will lag is
when it has to process some especially difficult data, or there's an excessive number of connections. At times like that,
the above suggestions work out better. So depending on what kind of traffic you will be passing through the firewall,
you may tax your firewall to its limit, or leave it completely bored.

The other reason for suggesting these systems is A) to allow for some growth in usage and network size down the road,
and B) to give you some breathing room in your configuration so as not to impact internet performance. Now that we've
got the hardware all picked out and everything decided, let's move on to actually installing Freebsd.

Installing Freebsd

The first thing you'll need to do is get a copy of Freebsd 7.0, which is what we'll be using for this tutorial. To get your
copy, first go to the Freebsd mirrors list and find a location near you where you can get the cd's the fastest. There are
currently 3 cd's for Freebsd 7. We will only need the first one. The other two are just extras. Now download the iso
for the first cd, burn it to a cdrom using your prefered burning software, label the new disk, place it in the cdrom drive
of the machine that will become your firewall, and then restart it.

Once it fully boots and reaches the install screen, select "Standard Install" from the menu using the arrow keys and
then hit enter. In this window you will likely see a partition that already exists. Possibly several depending on what OS
was on there previously. Select each and delete them until all the partitions are gone. If this is a clean drive, then no
partition should exist and you can skip the previous step. Now select A to make one gigantic UFS partition. Hit Q to
quit. Now you'll be asked to choose a boot manager for the drive. Select standard and hit enter. Next you'll be put
into the disk label editor.

To create a partition, press C, backspace out all of the numbers in there, and then type in the size of the slice you
want. Example: 2048M or 2G (M for megabytes or G for Gigabytes. Both examples create a 2gb slice) Hit enter. Type
in the mount point. Something like "/tmp" or "/var" for example. Hit enter. Rinse and repeat until done. If you're
not sure how big to make each slice, here's a list of recommended slice sizes and the order in which you'll want to
create them. Note, these recommendations are based on a 40gb drive. For a larger or smaller drive, scale the
partitions accordingly.

/ - 512 megs (this is your root partition. Never make this smaller than 256mb)
Swap - 4gigs (this should always be equal to no less than twice the amount of ram you have)
/var - 4g
/tmp - 4g
/usr - Whatever remains (to select the remaining space, don't backspace out the numbers when creating this slice. Just
hit enter and then type /usr for the mount point.

If you finish and find that you've made a mistake, remove all the slices and start over. Once you've got the drive where
you want it, hit Q. In the next screen, select "Kern-Developer" and hit space. It will then ask you to install the freebsd
ports collection. Hit enter to say yes. It should take you back to the previous screen at this point. Scroll up, select
"exit" and hit space. In the next screen select "cd/dvd" and hit enter. If it asks you which drive to install from, select
the first one and hit enter. Now it will say that this is your last chance to abort. Hit enter to continue. It should take
about five minutes to install. After this it'll ask you a few more questions. I'll list them as bullet points (with the
question at the front and answer at the end) to speed this up as this part is pretty quick to get through.


  * Would you like to configure any Ethernet or SLIP/PPP network devices? - YES
  * (select your network device, usually the first item listed, and hit enter. You'll have two devices, so be sure you
know which is the first one listed, and which is the second. This wil be important later on.)
  * Do you want to try Ipv6 configuration of the interface? - NO
  * Do you want to try DHCP configuration of the interface? - No (We'll want a static IP. In the next screen, enter
your hostname and domain name. Probubly something like "" or whatever you want to name it. Now
tab down, enter the IP address you want to use for this machine, the subnet and your gateway. You'll need to know
these in advance, so have them handy. Typically, since this is a firewall, unless you have a routing modem, you'll want
to assign the IP info given to you by your ISP. Once done, select OK and hit enter.)
    * Do you want this machine to function as a network gateway? - NO
    * Do you want to configure inetd and the network services that it provides? - NO (We won't be using this for
security reasons)
    * Would you like to enable SSH login - YES (we'll need this later for remote administration)
    * Do you want to have anonymous FTP access to this machine? - NO
    * Do you want to configure this machine as an NFS server? - NO
    * Do you want to configure this machine as an NFS client? - NO
    * Would you like to customize your system console settings? - NO
    * Would you like to set this machine's time zone now? - YES
    * Is this machine's CMOS clock set to UTC? If it is set to local time, or you don't know, please choose NO here! -
NO (some machines do have UTC CMOS clocks, most don't. So unless you're 100% certain your CMOS clock supports
UTC, say NO here)
    * Select your time zone based on continent, country and state/province. (In some cases when you hit enter after
doing this, you'll get a question that asks if the time zone abbreviation looks right. If it does, hit enter, if not, click no
and you can change it.)
    * Would you like to enable Linux binary compatibility? - NO (Ironically enough, this is actually a security risk for a
firewall. Go figure.)
    * Does this system have a PS/2, serial, or bus mouse? - NO (it's going to be a headless server, so it won't be having
a mouse)

Now that we've completed these steps, there's just a few more questions to answer. While it may seem like you're
having to answer a lot of questions, they're nessisary to the proper security of your system. On other systems and
distros, the answers to these questions tend to be "assumed", which can open you up to a variety of security risks.
Hence why it's better to answer the questions now, rather than plug holes later. Next, setup will ask you if you want to
browse the freebsd ports collection. Tell it no, because we'll want to install everything from the latest ports for security
reasons. Since you don't get the latest ports with the default install, you'll need to update your ports tree first before
installing anything.

Next it will ask you if you want to add additional accounts. Tell it yes and hit enter. Since we'll be using this machine
as a firewall, and not a workstation, we'll only need one. Select "add new user to system" and hit enter. In the next
screen, enter the username, tab twice, enter 0 for group ID, tab, enter the password, then tab down and change the
name of the user. Tab down to Ok and hit enter. Next, set root's password. Write it down and don't forget either it,
or the user/pass for the regular user you added. Loose either and you'll have to recover them the hard way.

Lastly, it'll ask you if you want to visit the general configuration screen before continuing. Select yes. Now scroll down
the list until you find "Networking". Hit enter. In this list, find "Ntpdate" and hit enter. Select a server near you.
Scroll back up and select "Exit". Hit enter. Repeat for the next screen. Now it should bring you back to the original
installer screen you started with. Go to the bottom and select "Exit Install". It may prompt you for one last time about
whether you're sure if you want to do this. If it does, select yes. Now remove the disk and let it reboot.

Updating the System

Congradulations! You're now the proud owner of a freshly installed copy of Freebsd 7! The next thing we need to do is
to get the system completely updated. This will be important for later. To get started we'll first need to update our
source and ports trees. Since Freebsd keeps all kernel and core system source code on your machine, you will have to
update it before we can get started. Also, don't forget to update it before doing any updates in the future! To do this
you'll want to use a handy little program called "cvsup" that's included in the ports tree. This will be the one and only
time we ever use the pkg_add system, as we'll need it get cvsup to do our updates. So don't panic that you won't have
the latest copy of cvsup right away. We'll correct that later.

To get cvsup, type "pkg_add -r cvsup", and then hit enter. After a few moments it'll download and install cvsup for
you. Next, type "cp /usr/share/examples/cvsup/stable-supfile ." (yes, that's a space and a dot after the file path) and
hit enter. Finally, type "vi stable-supfile". In here you'll want to change a couple of things. If you're not familiar with
VI, use this guide, or any other guide you want that teaches you how to use VI. Now, on to the edits you need to

   * About halfway down, find the line that reads "*default host" and change the part that reads
"" to a cvsup server that is closest to you, or the least congested. A list of available servers
can be found here at the Freebsd mirrors list.
   * Now go further down the page and find the following line: "src-all". Below it, add this on a separate line: ports-all
tag=. (don't forget the period on the end or bad things will happen)

Now save the file and then type "cvsup stable-supfile" and hit enter to begin updating your source and ports trees. This
can take anywhere from 15 minutes to as much as an hour to complete depending on the speed of your internet
connection. In the future, unless you go a long time between updates, this update will typically only take you about 3-
15 minutes to complete. Since the first update is always the biggest, it's also the one that takes the longest.

Once that's done, you'll need to start upgrading and adding things. The first thing you need to do is install
"portupgrade" to update all of our already installed applications. This shouldn't be many things, as we've only added
cvsup, so the update will be quick. You'll in turn use this program in the future to update applications on your system
fairly effortlessly. I'll explain how to do that later. First, we need to get it installed. To do that, type "cd
/usr/ports/ports-mgmt/portupgrade && make install". This puts you in the source directory for portupgrade, and
starts the install. Give it about five or six minutes and it should be done.

And contrary to all the talk about the ease and simplicity of package installs over source, building and installing from
source (what we're doing right now with cvsup) is always best, because you are always ensured the latest, most secure
code, and thus your applications will tend to be more secure. Package updates tend to lag behind source updates by
days, weeks, or even months. Plus if you install from source, the code is built specifically for your machine, on your
machine, and can be performance and security tweaked if you so choose during the install process. So there's some
advantages to that as well.

Now, once that's done, you'll want to type "portupgrade -r -all". When it's finished, all of your currently installed
ports (such as cvsup) will be up to date. Just use this command again in the future the next time you update your
firewall. Next, we need to add a couple of important applications. The first is bash. Despite all the controversy over
which shell is better, bash has always been my favorite and I've found few situations where it doesn't do everything I've
needed, hence my recommendation of it. And it's also not a matter of which system shell is more secure, as they're all
about the same.

To install bash, type "cd /usr/ports/shells/bash && make install". This can take anywhere from five minutes, up to to
fifteen to install. Once that's done, type "bash" to make sure it's installed right. If it is, then you'll want to add that as
your perminent shell. To do that, type "su root" and hit enter. Now enter root's password. If you're uncomfortable
using root, be thankful. He who does not fear root will wish he did some day. ;) So it's ok. It keeps you on your toes
and makes sure you don't do something silly in there.

Now, type "vipw" and change the part that says "/bin/sh" to "/usr/local/bin/bash". Do this for both root and your
regular user. Now save and exit. At this point you can test to see if this worked by typing "su username" where
username is the username of the regular user you added. Here's an example of how that might look: "su eddie" If you
setup the regular user correctly, you should automatically become your regular user, but with a bash shell and a
different prompt this time. Now type "su root" and enter root's password. It should bring you back to root with your
newly installed bash shell happily ticking away.

If both are successful, type exit and hit enter, then repeat again to get out of this. Next, type "vi .bashrc" and hit
enter. You should find yourself using a blank file. Put this in there, save and then exit vi:

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:/usr/local/sbin:$HOME/bin; export PATH
umask 077
PS1="[\u@\h \W]\\$ "
alias ls='ls -alFG'

Now, copy this to .bash_profile in the local directory, and then make copies of both .bashrc and .bash_profile for your
regular user in their home directory. Make sure the permissions and ownership are correct first though before moving
on. Permissions should be set to 755 for both root and your user. Ownership should be set to your user in the user
directory. To change ownership, as root change directory into your regular user's directory, then do "chown username
.bash*" and hit enter. Replace "username" with the name of your regular user. If you want to test and see if did
everything right, do the same test as before when you were testing your changes to the password file via vipw. If all
goes well, you are now safe to move on to the next part. And that part, is updating the kernel and core system. Don't
panic as it's easier than it sounds.

To rebuild the kernel, I recommend using this tutorial I wrote on building a custom kernel in Freebsd. It will give you
everything you need to get your kernel and core applications updated. If you don't feel like tweaking the kernel
configuration file specifically to your hardware, which is completely fine security wise, once you reach the line that reads
"On line 25, change GENERIC to MY_GENERIC" you can pretty much ignore everything in that totorial down to the
point where it says "Now, to compile your kernel, you'll need to do the following things:" in the last third of the article.
Be sure to save your work and exit the editor before completing that next step.

Once you are done with that, you'll be ready to configure your system for use as a firewall.

Configuring the System

Ok, now is where the rubber meets the road and we get down to the final steps to build our firewall. While all of this
work may seem a bit tedious, it's important to help ensure that your system is as secure as it can be. Without these
little nitpicky steps, you could accidentally open yourself up to attack. So being slightly over zealous helps
sometimes. :)

Now on to the configurations. Since you've now rebooted with a completely fresh kernel and core apps, let's get on to
setting up the firewall. First, login as root.  (Later on you'll login as your regular user, then su to root, or use sudo
for whatever you need to do.)Â Next, type "vi /etc/aliases" and hit enter. Â Scroll down until you see this:

# root: me@my.domain

Remove the # sign and the space before the line. Next, change "me@my.domain" to your email address. Save the
file, then type "newaliases" to reload the file. Next, type "vi /etc/motd", clean out everything in the file so that it's
empty, then paste this inside.


Save and exit. Next, do "chmod 444 /etc/motd". This will keep the file from being randomly edited or updated by
anybody except root, including the system itself. After that, type "cp /etc/motd /etc/issue" and hit enter.  Do the
same chmod command to /etc/issue as well.Â

Next, we need to update the ssh configuration file. First, copy "/etc/ssh/sshd_config" to
"/etc/ssh/sshd_config.original" so that you have a backup copy for reference. Next, find the following lines in
sshd_config and update them as shown below. Pay careful attention to which lines have a # in front of them and which
don't. Make sure when you update the file, your lines look just like these here.  Author's notes are in parenthesis
and can be ignored. Just don't ignore the text outside the parenthesis on those lines. The lines to edit listed below
appear in sequential order in the file.

   * Port 22
   * Protocol 2
   * ListenAddressÂ Â (Put your internal interface's address here. This will be the address you plan to
assign to the 2nd network card)
   * #ListenAddress ::Â Â Â Â (Delete this line)
   * LogLevel VERBOSE (doesn't exist in file. Add below the line "#SyslogFacility AUTH")
   * PermitRootLogin no
   * StrictModes yes
   * RSAAuthentication yes
   * PubkeyAuthentication yes
   * AuthorizedKeysFile .ssh/authorized_keys
   * RhostsRSAAuthentication no
   * HostbasedAuthentication no
   * IgnoreUserKnownHosts yes
   * IgnoreRhosts yes
   * PasswordAuthentication no
   * PermitEmptyPasswords no
   * ChallengeResponseAuthentication no
   * UsePAM no
   * AllowTcpForwarding no
   * GatewayPorts no
   * X11Forwarding no
   * PrintMotd yes
   * PrintLastLog yes
   * Banner /etc/motd
   * AllowUsers newuser    (Substitute 'newuser' with the username of your regular user. Note: This line doesn't
appear in the file and will need to be added on the last line)

Now save and exit. The next thing you need to do is setup your ssh key since you've now told sshd that you want to
use a custom public/private keypair rather than the one it would provide on its own. To do that, type the following
three commands:

  * cd /home/username (where username is your regular user)
  * su - username (substitute "username" for the username of your regular user)
  * ssh-keygen -d (accept the default DSA key name and enter a passphrase both times it prompts you for it.)

Next, you'll need to install the new key on your regular user's account so you can ssh in. To do that, enter these two

   * cd .ssh
   * cat > authorized_keys

Now, for security reasons, you'll want to remove and save a copy of your keys somewhere other than this machine.Â
Since this used to be done with floppys in the old days, and floppys are pretty much dead, you'll have to use a pen
drive. To start, plug your pen drive in. You should see a message on your screen that looks something like this:

umass0: on uhub3
da0 at umass-sim0 bus 0 target 0 lun 0
da0: Removable Direct Access SCSI-0 device
da0: 40.000MB/s transfers
da0: 1920MB (3932160 512 byte sectors: 255H 63S/T 244C)

Since I'm using a Corsair Flash Voyager drive for this, that's what's listed above. Â To mount the pen drive, first do
"mkdir pendrive" in the root of your user folder. You can also type "mkdir /home/username/pendrive" where
"username" is of course the name of your regular user. Next, you need to mount the pendrive, as pendrives aren't
automatically mounted in the console for security reasons. To mount the drive, type "mount -t msdosfs /dev/da0s1
/home/username/pendrive" and hit enter.Â

In some cases the slice will be different than "da0s1" depending on a variety of circumstances. To see what your pen
drive should be mounted as, look at the message that comes up when it is inserted. Look at the first part of the
second through fifth lines. In my case the device was known to the system as "da0".  But "da0" is the device
itself. To access the actual partition, or "slice" as it's known in Freebsd, I need to add "s1" after it, to indicate "slice
#1". If you're unsure whether "s1" exists, you can do "ls /dev | grep da0" (where da0 is the device ID for your
pendrive) to see what devices and slices are there. In my case I would see two items.  "da0" and "da0s1". The
second one is the item I'd want.

Now, to backup the ssh key file, type "mv id_dsa* /home/username/pendrive" and hit enter. The operation should be
almost instantaneous. Now, unmount your pendrive by typing "umount /home/username/pendrive" and hit enter.Â
Now, keep close tabs on that pendrive and those keys. You'll need them for later.  Now, type "exit" to get back to

The next thing we need to do is configure the hosts.allow file. Open up /etc/hosts.allow and delete all the lines in
it. Then add the following:

ALL : localhost : allow
sshd : : allow
ALL : ALL : deny

Make sure that when you add it, you edit the "sshd" line and replace the part that reads ""
with your internal ip block and subnet. Due note that the 0 at the end of the IP indicates the block of IP's, not a
specific one. So if your internal IP address for this machine was, you'd put for the IP. If you're
unsure of what subnet you want to use, or even how subnetting works, I recommend you read this article on subnetting
and then use our two IP subnet cheat cheat sheets here and here.

Next we need to setup AIDE, or Advanced Intrusion Detection Environment). To do this, enter these two commands:

   * cd /usr/ports/security/aide
   * make install clean
Next, we need to initialize the database:

  *   cp /usr/local/etc/aide.conf.sample /var/db/aide/aide.conf
  *   cd /var/db/aide
  *   aide --init
  *   mv databases/ databases/aide.db

And lastly, we need to setup a cronjob task to check system integrity every day at 4am. Â This is important, because if
someone's broken into your firewall (heaven forbid!) then you need to know about it first thing in the morning so that
you can do something about it before anything sensitive is stolen, or worse. To do this, add this line to the crontab
configuration file which can be found at "/etc/crontab".

  * 0 4 * * * root /usr/local/bin/aide --check

Now look through the file and remove or comment out this line:

  * */5 * * * * root /usr/libexec/atrun

Save and exit. Next, type "chmod 600 /etc/crontab" so that only root can see what's in the file. Since this is a
firewall and not a workstation, only root needs to see that. Now, if you want to add an extra level of security, you can
copy the file aide.db off the firewall and not add the crontab entry to check it automatically. Instead, you would go in
once a week or so and manually copy the file back, check the system, then delete the file, while keeping an original copy
of it somewhere safe. The only downside to this is, it's easy to forget to do this after a while and your system may go
for some time without being checked.

Now it's time to do some playing in the rc.conf file. Be aware that if you break something in here, the system won't
boot and you'll have to do a manual recovery. Â It's not that hard, but it is a pain to do and best avoided if possible.Â
Now, here's the list of changes you'll need to make to your /etc/rc.conf file. Author's notes are in red text and

   * syslogd_flags="-ss"
   * sshd_flags="-4"
   * ipfilter_enable="YES"
   * ipmon_enable="YES"
   * ipmon_flags="-Dsvn"
   * ipnat_enable="YES"
   * ipfs_enable="YES"
   * network_interfaces="rl0 rl1 lo0" (replace with the names of your internal and external interfaces. In the example
here, those are rl0 and rl1)
   * ifconfig_rl1="inet netmask" (this is for your internal interface. The rl1 in the name
indicates the name the system gave your internal network card. Yours might be different, so be aware of that. Be
sure to replace the ip and subnet in this example with those you will be using on your internal network.)
   * ifconfig_lo0="inet"
   * ifconfig_rl0="DHCP" (same as note above)
   * icmp_drop_redirects="YES"
   * kern_securelevel_enable="YES"
   * kern_securelevel="2"

Once those are in, verify your entries to be sure you have all the proper quotes and everything in there, then save and
exit. Next, do the following two commands to setup the firewall logs.

  * touch /var/log/firewall_logs
  * chmod 600 /var/log/firewall_logs

Now edit "/etc/syslog.conf" and change the security line to read as follows:

  * security.* /var/log/firewall_logs

Now add "security.none" to the line for "/var/log/messages". Â Make sure you separate it from the other entries in
that line with a semicolon. Look at how the line is formatted for an example of this. Next, edit
"/etc/newsyslog.conf" and add "/var/log/firewall_logs 600 14 100 * J /var/run/" to the bottom of the file.Â
Now save and exit.Â

The next thing up is to create your ipfilter rules. Edit "/etc/ipf.rules" and remove everything. Add the following
lines to the file. Remember, on your machine, change all applicable IP's and interface ID's to match your hardware
and your network setup.

# Outside Interface

# Allow out all TCP, UDP, and ICMP traffic & keep state on it
# so that it's allowed back in.
# If you wanted to do egress's where you'd do it.
# You'd change the lines below so that rather than allowing out any
# arbitrary TCP connection, it would only allow out mail, pop3, and http
# connections (for example). So, the first line, below, would be
# replaced with:
# pass out quick on rl0 proto tcp from any to any port = 25 keep state
# pass out quick on rl0 proto tcp from any to any port = 110 keep state
# pass out quick on rl0 proto tcp from any to any port = 80 keep state
# ...and then do the same for the remaining lines so that you allow
# only specified protocols/ports 'out' of your network
pass out quick on rl0 proto tcp from any to any keep state
pass out quick on rl0 proto udp from any to any keep state
pass out quick on rl0 proto icmp from any to any keep state
block out quick on rl0 all

# Block all inbound traffic from non-routable or reserved address spaces
block in log quick on rl0 from to any #RFC 1918 private IP
block in log quick on rl0 from to any #RFC 1918 private IP
block in log quick on rl0 from to any #RFC 1918 private IP
block in log quick on rl0 from to any #loopback
block in log quick on rl0 from to any #loopback
block in log quick on rl0 from to any #DHCP auto-config
block in log quick on rl0 from to any #reserved for doc's
block in log quick on rl0 from to any #Sun cluster interconnect
block in quick on rl0 from to any #Class D & E multicast
# Allow bootp traffic in from your ISP's DHCP server only.
pass in quick on rl0 proto udp from X.X.X.X/32 to any port = 68 keep state

# If you wanted to set up a web server or mail server on your box
# (which is outside the scope of this howto), or allow another system
# on the Internet to externally SSH into your firewall, you'd want to
# uncomment the following lines and modify as appropriate. If you
# have other services running that you need to allow external access
# to, just add more lines using these as examples.
# If the services are on a box on your internal network (rather than
# the firewall itself), you'll have to add both the filter listed below,
# plus a redirect rule in your /etc/ipnat.rules file.
# pass in quick on rl0 proto tcp from any to any port = 80 flags S keep state keep frags
# pass in quick on rl0 proto tcp from any to any port = 25 flags S keep state keep frags
# pass in quick on rl0 proto tcp from X.X.X.X/32 to any port = 22 flags S keep state keep frags

# Block and log all remaining traffic coming into the firewall
# - Block TCP with a RST (to make it appear as if the service
# isn't listening)
# - Block UDP with an ICMP Port Unreachable (to make it appear
# as if the service isn't listening)
# - Block all remaining traffic the good 'ol fashioned way
block return-rst in log quick on rl0 proto tcp from any to any
block return-icmp-as-dest(port-unr) in log quick on rl0 proto udp from any to any
block in log quick on rl0 all

# Inside Interface

# Allow out all TCP, UDP, and ICMP traffic & keep state
pass out quick on rl1 proto tcp from any to any keep state
pass out quick on rl1 proto udp from any to any keep state
pass out quick on rl1 proto icmp from any to any keep state
block out quick on rl1 all

# Allow in all TCP, UDP, and ICMP traffic & keep state
pass in quick on rl1 proto tcp from any to any keep state
pass in quick on rl1 proto udp from any to any keep state
pass in quick on rl1 proto icmp from any to any keep state
block in quick on rl1 all
# Loopback Interface

# Allow everything to/from your loopback interface so you
# can ping yourself (e.g. ping localhost)
pass in quick on lo0 all
pass out quick on lo0 all

# eof

Next, edit "/etc/ipnat.rules" and remove everything inside if anything exists. Add the following lines in their place.

# nat routing rules
map rl0 -> 0/32

Save and exit. Next, edit "/etc/sysctl.conf" and add the following two lines at the bottom:


Create the file "/var/cron/allow" and add the following two lines to it. Â If the file already exists, just add these at the


Obviously replace "username" with the name of your regular user. Next, make two copies of "/etc/fstab" and name
one "fstab.restrictive" and "fstab.original". Edit "fstab.restrictive" and replace the contents with the following:

# Device Mountpoint FStype Options Dump Pass#
/dev/ad0s1a / ufs rw,nosuid 1 1
/dev/ad0s1b none swap sw 0 0
/dev/ad0s1d /tmp ufs rw,noexec,nosuid,nodev 2 2
/dev/ad0s1e /var ufs rw,noexec,nosuid 2 2
/dev/ad0s1f /usr ufs ro 2 2
/dev/acd0 /cdrom cd9660 ro,noauto 0 0

Be aware though that your device names may be different, so if you want to be sure that both match so that the system
will boot properly, insert these lines above the original data, compare notes to be sure that all your slices match their
proper mount points and device names, then remove the old entries and save the file. Another note, due to the
limitations of html, my example above doesn't properly show the tabbed separation of the entries. Look at the
example that will already be in the file for a guide on how to tab separate all the entires correctly. If you don't have
them tab separated properly, the system may get cranky.

Now, copy "fstab.restrictive" to "fstab" so that your changes are saved. If you goofed on something and the system
fails to boot next time around, just copy "fstab.original" over "fstab" and reboot. Once it's back up, make the
nessisary changes in "fstab.restrictive" and copy it over "fstab" again to commit the changes.
Now, you have just one more set of steps to go. I know this is a lot, but when you're done you will have a VERY,
VERY secure firewall. First, reboot the machine, then go in and rebuild your AIDE file. Since we did a lot of
changes since our last build, you'll want to do this. So login as root and do the following commands:

   * cd /var/db/aide
   * aide --init
   * mv databases/ databases/aide.db

Again, don't forget that you can always back this up somewhere off the machine for added security if you want. In
fact, even if you want to go with the automated checks and don't want to remove the database, always keep a current
copy of the database on another machine anyways. If a hacker somehow gets into the firewall and corrupts or deletes
that database, you'll want to have a spare copy to know what damage needs to be undone. It also doesn't hurt to
login and copy over the database periodically anyways to ensure it hasn't been overwritten before doing a manual check,
which doesn't hurt for you to do periodically either. And if you choose to backup the database off the firewall, you
can use a pendrive just like we did with the ssh keys.


Well, that's it. You're done! Congradulations are in order, as you're the proud owner of a brand new Freebsd 7 based
firewall! Don't forget to periodically update it too in order to keep current with security updates and patches.
Updating it about once every month, or every 3 months should be enough. In order to do this, you'll need to make a
few changes to permit the upgrades. It's pretty simple, so just follow these last couple of steps periodically when

   *   Copy /etc/fstab.original to /etc/fstab
   *   In rc.conf change the two in the line "kern_securelevel" line to a 1 and reboot.
   *   Update your source and ports tree with cvsup.
   *   Do your upgrades via portupgrade and, if nessisary, any kernel rebuilds that are required.
   *   Go back into rc.conf and set "kern_securelevel" back to 1.
   *   Copy /etc/fstab.restrictive to /etc/fstab
   *   Reboot

And there you have it. Now you should be able to connect your firewall to your network and surf in safety. The best
part about this is, even though it took a while to build it, the server can now be tucked into a corner and forgotten
about for quite a while as it should run just fine on its own. I hope this tutorial has been a help to you. If you have any
comments, concerns, ideas or corrections, please let us know in the forums. I'm pretty sure I've dotted every I and
crossed ever T, but hey, I'm only human and even *I* can miss something. ^_^

To top