Build a Home-Office Router Using FreeBSD and PF

General Information

This guide will outline the basic steps for building a home-office router for use with a cable modem or DSL line using FreeBSD and Packet Filter (PF). nike roshe run It will cover updating FreeBSD, building a new kernel, and installing and configuring a DHCP server and DNS server to support a small internal network.


  1. Standard installation of FreeBSD 5.3 or greater
  2. Two network cards
  3. A text editor

Before beginning, we need to decide which network adapter is going to be connected to the internal network and which one is going to be connected to the external network (cable modem or DSL line).

Run ‘ifconfig‘ from the command line to list the network adapters:

 $ ifconfig dc0: flags=108843 mtu 1500 inet6 fe80::20c:29ff:fefc:800c%lnc0 prefixlen 64 scopeid 0x1 inet netmask 0xffffff00 broadcast ether 00:0c:29:fc:80:0c xl0: flags=108802 mtu 1500 ether 00:0c:29:fc:80:16 lo0: flags=8049 mtu 16384 inet6 ::1 prefixlen 128 inet6 fe80::1%lo0 prefixlen 64 scopeid 0x4 inet netmask 0xff000000 

For this document I am going to use the following configuration:

dc0: external interface (IP address provided by ISP’s DHCP server)

xl0: internal interface (IP address is static,

Internal network:


Kernel source

First, we need to ensure that the kernel source is installed. We will need the kernel source to recompile the kernel to add PF support. adidas pas cher The kernel source can be installed using ‘sysinstall‘ utility.

From the sysinstall menu:

  1. Select “Configure”
  2. Select “Distributions”
  3. Select “src”
  4. Select “sys”

Update the system

Next we need to update the system (don’t compile a kernel yet) and the ports tree.

Install network services

Once the system has been updated, we can install a few necessary services on our system; a DHCP server to provide IP addresses to clients on the internal network, and a DNS server to forward DNS requests from the internal clients to our ISP’s DNS servers.

DHCP server:

 # cd /usr/ports/net/ics-dhcp3-server # make install clean (the default options are fine) 

DNS server:

 # cd /usr/ports/dns/bind9 # make install clean 

Compile a new kernel with PF support

The last part of the installation process requires compiling a new kernel with PF support.

We will use the GENERIC kernel configuration as the basis for our CUSTOM kernel:

 # cd /usr/src/sys/i386/conf # cp GENERIC CUSTOM 


Change the line:

 ident GENERIC 


 ident CUSTOM 

Optionally, comment out options INET6 to remove IPv6 support.

Add the following PF options to the end of the file. You may also want to add ALTQ support. bottes ugg ALTQ provides traffic shaping and Quality of Service functionality.

 # PF device pf device pflog device pfsync # ALTQ options ALTQ options ALTQ_CBQ options ALTQ_RED options ALTQ_RIO options ALTQ_HFSC options ALTQ_CDNR options ALTQ_PRIQ 

We are now ready to recompile the kernel.

Note: If you commented out IPv6 support (INET6) you need to add the following line to /etc/make.conf before compiling:

 cd /usr/src make buildkernel KERNCONF=CUSTOM make installkernel KERNCONF=CUSTOM 

It may take quite some time to build the kernel. nike air presto soldes Once the kernel is installed we need to reboot to activate the new kernel:

 # shutdown -r now 

Assuming the system reboots without incident, let’s login and verify the kernel.

 $ uname -a FreeBSD freebsd6.localdomain 6.0 FreeBSD 6.0 #0: Mon Mar 13 16:29:47 EST 2006 root@freebsd6.localdomain:/usr/obj/usr/src/sys/CUSTOM i386 

Good, looks like it worked. asics soldes We are now using our custom kernel: (…/usr/obj/usr/src/sys/CUSTOM)

Let’s make sure PF is working:

 $ pfctl -e pf enabled $ pfctl -d pf disabled 

Installation is now complete. new balance We can proceed to configuring PF and the network services.


DNS Server

We need to edit the BIND configuration file, /var/named/etc/namedb/named.conf. timberland homme Set the listen-on IP address to the internal IP address and the loopback address of the FreeBSD box. Also, configure BIND to only forward DNS requests, and specify the IP addresses of your ISP’s DNS servers. You can also remove all the zone statements other than the “.” zone. adidas pas cher Sample file follows:

 // named.conf // Refer to the named.conf(5) and named(8) man pages, and the documentation // in /usr/share/doc/bind9 for more details. timberland 6-inch premium // // If you are going to set up an authoritative server, make sure you // understand the hairy details of how DNS works. asics gel lyte 5 Even with // simple mistakes, you can break connectivity for affected parties, // or cause huge amounts of useless Internet traffic. options { directory "/etc/namedb"; pid-file "/var/run/named/pid"; dump-file "/var/dump/named_dump.db"; statistics-file "/var/stats/named.stats"; // If named is being used only as a local resolver, this is a safe default. ugg bailey bow // For named to be accessible to the network, comment this option, specify // the proper IP address, or delete this option. nike internationalist cheap bns gold listen-on {;; }; // In addition to the "forwarders" clause, you can force your name // server to never initiate queries of its own, but always ask its // forwarders only, by enabling the following line: // forward only; // If you've got a DNS server around at your upstream provider, enter // its IP address here, and enable the line below.  ugg pas cher new balance gris asics gel lyte 3 This will make you // benefit from its cache, thus reduce overall DNS traffic in the Internet. nike flyknit lunar // forwarders { x.x.x.x; y.y.y.y; }; forwarders { [IP address of ISP DNS server]; [IP address of ISP DNS server]; }; }; // If you enable a local name server, don't forget to enter // first in your /etc/resolv.conf so this server will be queried.  asics gel lyte ugg mini bailey button // Also, make sure to enable it in /etc/rc.conf. nike air huarache botte ugg pas cher zone "." { type hint; file "named.root"; }; // end named.conf 

DHCP Server

Next we will configure the DHCP service. nike dunk Start off by copying a sample configuration file to /usr/local/etc.

 # cp /usr/local/etc/dhcpd.conf.sample /usr/local/etc/dhcpd.conf 

Then edit /usr/local/etc/dhcpd.conf; we need to specify our local DNS server, the network gateway, and the available IP address range. ffxiv Items Below is an example configuration.

 ### dhcpd.conf # option definitions common to all supported networks... # name server is running on this host option domain-name-servers; default-lease-time 600; max-lease-time 7200; # If this DHCP server is the official DHCP server for the local # network, the authoritative directive should be uncommented.  bottes ugg pas cher authoritative; # ad-hoc DNS update scheme - set to "none" to disable dynamic DNS updates. ddns-update-style none; # Use this to send dhcp log messages to a different log file (you also # have to hack syslog.conf to complete the redirection). chaussures timberland pas cher log-facility local7; # for small internal network, 100 IPs subnet netmask { range; option routers; option subnet-mask; } ### end dhcpd.conf 

Packet Filter

We will use one of the example PF configuration files as a basis for our PF configuration. This sample file has everything we need for a basic router.

 # cp /usr/share/examples/pf/faq-example1 /etc/pf.conf 

You will need to edit /etc/pf.conf, specifying the internal and external interfaces, as well as what services you want to allow external clients to access on the FreeBSD box. Below is the /usr/share/examples/pf/faq-example1 file with additional comments.

 ### macros # internal and external interfaces (run 'ifconfig' to find interfaces) int_if = "xl0" ext_if = "dc0" # Ports we want to allow access to from the outside world on our local # system (ext_if) tcp_services = "{ 22, 80 }" # ping requests icmp_types = "echoreq" # Private networks, we are going to block incoming traffic from them priv_nets = "{,,, }" ### options set block-policy return set loginterface $ext_if set skip on lo0 ### Scrub # From the PF user's guide ( # "Scrubbing" is the normalization of packets so there are no ambiguities in # interpretation by the ultimate destination of the packet. The scrub directive # also reassembles fragmented packets, protecting some operating systems from # some forms of attack, and # drops TCP packets that have invalid flag # combinations. adidas nmd scrub in all ### nat/rdr # NAT traffic from internal network to external network through external # interface nat on $ext_if from $int_if:network to any -> ($ext_if) # redirect FTP traffic to FTP proxy on localhost:8021 # requires ftp-proxy to be enabled in /etc/inetd.conf rdr on $int_if proto tcp from any to any port 21 -> port 8021 ### filter rules block all # block incoming traffic from private networks on external interface block drop in quick on $ext_if from $priv_nets to any # block outgoing traffic to private networks on external interface block drop out quick on $ext_if from any to $priv_nets # allow access to tcp_services on external interface pass in on $ext_if inet proto tcp from any to ($ext_if) port $tcp_services flags S/SA keep state # allow in FTP control port pass in on $ext_if inet proto tcp from port 20 to ($ext_if) user proxy flags S/SA keep state # allow in ping replies pass in inet proto icmp all icmp-type $icmp_types keep state # allow all traffic from internal network to internal interface pass in on $int_if from $int_if:network to any keep state pass out on $int_if from any to $int_if:network keep state # allow all traffic out via external interface pass out on $ext_if proto tcp all modulate state flags S/SA pass out on $ext_if proto { udp, icmp } all keep state 


The last configuration step is to enable our network services and PF at system startup by modifying /etc/rc.conf. Below is a sample rc.conf file.

 ### Networking # NIC is configured by our ISP's DHCP server ifconfig_dc0="DHCP" # Internal NIC has a static IP ifconfig_xl0="inet netmask" hostname="myhostname" ### Gateway, so we can forward traffic between the int. new balance france nike cortez and ext. networks gateway_enable="yes" ### PF pf_enable="YES" pf_rules="/etc/pf.conf" # pf rules pf_flags="" # pfctl flags pflog_enable="YES" # start pflogd pflog_logfile="/var/log/pflog" # pf logfile pflog_flags="" # pflogd flags ### DHCP server dhcpd_enable="yes" dhcpd_ifaces="xl0" # enabled on int. Soldes Chaussures Adidas interface ### DNS server - BIND named_enable="YES" ### INETD - need to enable if we use the ftp-proxy inetd_enable="YES" 

After editing rc.conf, reboot the system for the changes to take effect.

 # shutdown -r now 

When the system comes back up, the internal clients should be able to access the Internet through it.


This guide has just touched on the basics of using FreeBSD and PF as a router. PF offers many advanced features such as blocking hosts based on their OS and traffic shaping. avis bottes ugg For more information see the PF handbook.

Also, please be aware of the security implications of running your own FreeBSD router. ugg homme Since the FreeBSD system will be directly connected to the public Internet, it is highly recommended that you take steps to secure the system.

Speak Your Mind