%man; ]>
Dialup firewalling with FreeBSD Marc Silver
marcs@draenor.org
$Date: 2000-08-19 20:51:20 $ This article documents how to setup a firewall using a PPP dialup with FreeBSD and IPFW, and specifically with firewalling over a dialup with a dynamically assigned IP address. This document does not cover setting up your PPP connection in the first place.
Preface Dialup Firewalling with FreeBSD This document aims to cover the process that is required in order to setup firewalling with FreeBSD when are dynamically assigned an IP address by your ISP. While every effort has been made to make this document as informative and correct as possible, you are welcome to mail your comments/suggestions to the maintainer. Kernel Options The first thing you'll need to do is recompile your kernel in FreeBSD. If you need more information on how to recompile the kernel, then the best place to start is the kernel configuration section in the Handbook. You need to compile the following options into the kernel: options IPFIREWALL Enables the kernel's firewall code. options IPFIREWALL_VERBOSE Sends logged packets to the system logger. options IPFIREWALL_VERBOSE_LIMIT=100 Limits the number of times a matching entry is logged. This stops your log files filling up with lots of repetitive entries. 100 is a reasonable number to use, but you can adjust it based on your requirements. options IPDIVERT Enables divert sockets, which will be shown later. There are also some other OPTIONAL items that you can compile into the kernel for some added security. These are not required in order to get firewalling to work, but some more paranoid users may want to use them. options TCP_RESTRICT_RST This option blocks all TCP RST packets. This is best used for systems that might be exposed to SYN flooding (IRC Servers are a good example) or for those who do not want to be easily portscannable. options TCP_DROP_SYNFIN This option ignores TCP packets with SYN and FIN. This prevents tools such as nmap etc from identifying the TCP/IP stack of the machine, but breaks support for RFC1644 extensions. This is NOT recommended if the machine will be running web server. Don't reboot once you have recompiled the kernel. Hopefully, we will need to reboot just once in order to complete the installing of the firewall. Changing <filename>/etc/rc.conf</filename> to load the firewall We now need to make some changes to /etc/rc.conf in order to tell it about the firewall. Simply add the following lines: firewall_enable="YES" firewall_script="/etc/firewall/fwrules" natd_enable="YES" natd_interface="tun0" natd_flags="-dynamic" For more information on what the above do take a look at /etc/defaults/rc.conf and read &man.rc.conf.5; Disable PPP's network address translation You may already be using PPP's built in network address translation (NAT). If that is the case you will have to disable it, as these examples use &man.natd.8; to do the same. If you already have a block of entries to automatically start PPP it probably looks like this: ppp_enable="YES" ppp_mode="auto" ppp_nat="YES" ppp_profile="profile" If so, remove the ppp_nat="YES" line. You will also need to remove any nat enable yes or alias enable yes in /etc/ppp/ppp.conf. The ruleset for the firewall We're nearly done now. All that remains now is to define the firewall rules and then we can reboot and the firewall should be up and running. I realise that everyone will want something slightly different when it comes to their rulebase. What I've tried to do is write a rulebase that suits most dialup users. You can obviously modify it to your needs by simply using the following rules as the foundation for your own rulebase. First, let's start with the basics of closed firewalling. What you want to do is deny everything by default and then only open up for the things you really need. Rules should be in the order of allow first and then deny. The premis is that you add the rules for your allows, and then everything else is denied. :) Now, let's make the dir /etc/firewall. Change into the directory and edit the file fwrules as we specified in rc.conf. Please note that you can change this filename to be anything you wish. This guide just gives an example of a filename. Now, let's look at a sample firewall file, and we'll detail everything in it. # Firewall rules # Written by Marc Silver (marcs@draenor.org) # http://draenor.org/ipfw # Freely distributable # Define the firewall command (as in /etc/rc.firewall) for easy # reference. Helps to make it easier to read. fwcmd="/sbin/ipfw" # Force a flushing of the current rules before we reload. $fwcmd -f flush # Divert all packets through the tunnel interface. $fwcmd add divert natd all from any to any via tun0 # Allow all data from my network card and localhost. Make sure you # change your network card (mine was fxp0) before you reboot. :) $fwcmd add allow ip from any to any via lo0 $fwcmd add allow ip from any to any via fxp0 # Allow all connections that I initiate. $fwcmd add allow tcp from any to any out xmit tun0 setup # Once connections are made, allow them to stay open. $fwcmd add allow tcp from any to any via tun0 established # Everyone on the internet is allowed to connect to the following # services on the machine. This example shows that people may connect # to ssh and apache. $fwcmd add allow tcp from any to any 80 setup $fwcmd add allow tcp from any to any 22 setup # This sends a RESET to all ident packets. $fwcmd add reset log tcp from any to any 113 in recv tun0 # Allow outgoing DNS queries ONLY to the specified servers. $fwcmd add allow udp from any to x.x.x.x 53 out xmit tun0 # Allow them back in with the answers... :) $fwcmd add allow udp from x.x.x.x 53 to any in recv tun0 # Allow ICMP (for ping and traceroute to work). You may wish to # disallow this, but I feel it suits my needs to keep them in. $fwcmd add 65435 allow icmp from any to any # Deny all the rest. $fwcmd add 65435 deny log ip from any to any You now have a fully functional firewall that will allow on connections to ports 80 and 22 and will log any other connection attempts. Now, you should be able to safely reboot and your firewall should come up fine. If you find this incorrect in anyway or experience any problems, or have any suggestions to improve this page, please email me. Questions Why are you using natd and ipfw when you could be using the built in ppp-filters? I'll have to be honest and say there's no definitive reason why I use ipfw and natd instead of the built in ppp filters. From the discussions I've had with people the consensus seems to be that while ipfw is certainly more powerful and more configurable than the ppp filters, what it makes up for in functionality it loses in being easy to customise. One of the reasons I use it is because I prefer firewalling to be done at a kernel level rather than by a userland program. If I'm using private addresses internally, such as in the 192.168.0.0 range, Could I add a command like $fwcmd add deny all from any to 192.168.0.0:255.255.0.0 via tun0 to the firewall rules to prevent outside attempts to connect to internal machines? The simple answer is no. The reason for this is that natd is doing address translation for anything being diverted through the tun0 device. As far as it's concerned incoming packets will speak only to the dynamically assigned IP address and NOT to the internal network. Note though that you can add a rule like $fwcmd add deny all from 192.168.0.4:255.255.0.0 to any via tun0 which would limit a host on your internal network from going out via the firewall.