Written by Steve Lake Posted on: 05.14.2008 at 01: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. Mini-ITX: Standard PC: (high capacity connections greater than 20mbps) 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) 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. --------------------------------------------------------
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 make..
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 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. * * * * * * * * * * * * W A R N I N G * * * * * * * * * * * * * 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.
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:
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 commands:
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: 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 root. 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 127.0.0.1 : allow Next we need to setup AIDE, or Advanced Intrusion Detection Environment). To do this, enter these two commands:
Next, we need to initialize the database:
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".
Now look through the file and remove or comment out this line:
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 parenthesis.
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.
Now edit "/etc/syslog.conf" and change the security line to read as follows:
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/ipmon.pid" 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. ################################################################# # eof Next, edit "/etc/ipnat.rules" and remove everything inside if anything exists. Add the following lines in their place. # nat routing rules Save and exit. Next, edit "/etc/sysctl.conf" and add the following two lines at the bottom: net.inet.tcp.blackhole=2 Create the file "/var/cron/allow" and add the following two lines to it. If the file already exists, just add these at the bottom. root 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# 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:
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. Conclusion 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 upgrading.
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. ^_^ |