How To Set Up a FreeBSD Router – Step-by-Step Tutorial
This tutorial explains how to set up a FreeBSD system that will act as a network router that takes advantage of the ported version of OpenBSD's PF packet filter. A network router is a system that forwards packets from one interface to another.
1. FreeBSD Installation
Install FreeBSD by using this tutorial.
Now that you have FreeBSD installed, lets proceed with the next step.
2. FreeBSD Network Configuration
Open /etc/rc.conf in your favorite editor. You need to add a line for each network card present on the system, for example in our case we'll use two network cards:
### rc.conf
# WAN connection
ifconfig_xl0="inet 10.0.0.2 netmask 255.255.255.0"
# If you are using dhcp for WAN connection use ifconfig_xl0="dhcp"
# LAN connection
ifconfig_xl1="inet 192.168.0.1 netmask 255.255.255.0"
# Default gateway
defaultrouter="10.0.0.1" # Set the gateway
# Enable ip forward
gateway_enable="YES"
# Hostname
hostname="freebsd.my.domain"
### end rc.conf
You have to replace xl0, xl1 with the correct device for your cards, and the addresses with the proper ones.
defaultrouter is needed only if you are not using dhpc for WAN connection.
NOTE: If you configured the network during installation, some lines about the network cards may be already present. Double check /etc/rc.conf before adding any lines.
You will also have to edit /etc/hosts to add the names and the IP addresses of various machines of the LAN, if they are not already there.
127.0.0.1 localhost localhost.my.domain
192.168.0.1 freebsdrouter.my.domain freebsdrouter
Set the DNS in /etc/resolv.conf :
nameserver 10.0.0.1
NOTE: You need to manually set up the nameserver only if you are not using dhcp for WAN connection.
3. Set up DHCP Server
The Dynamic Host Configuration Protocol (DHCP) is a network protocol used by hosts (DHCP clients) to retrieve IP address assignments and other configuration information. Each computer connected to a network must have a unique IP, and without DHCP TCP/IP information must be assigned manually on each computer. DHCP Server (or DHCPd) is the server that provides the DHCP client the information it needed.
To install DHCP Server, execute the following commands:
# cd /usr/ports/net/isc-dhcp3-server
# make install clean
Next we will configure the DHCP service. 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. (local DNS server,lease time, the network gateway, and the available IP address range). Below is an example configuration.
### dhcpd.conf
# name server
option domain-name-servers 10.0.0.1;
# lease time
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.
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
log-facility local7;
# subnet declaration
subnet 192.168.0.0 netmask 255.255.255.0 {
range 192.168.0.100 192.168.0.200;
option routers 192.168.0.1;
option subnet-mask 255.255.255.0;
}
### end dhcpd.conf
Enable dhcp to start on boot by modifying /etc/rc.conf.
dhcpd_enable=YES
dhcpd_ifaces="xl1" # LAN card
4. Set up FreeBSD Firewall using OpenBSD's PF packet filter
A firewall (in this context) is a set of rules that allows or denies certain types of network packets from entering or leaving your FreeBSD router. This section deals with building a firewall.
We'll use one of the example PF configuration files as a basis for our configuration.
This sample file has everything we need for a basic FreeBSD 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 router. Below is the /usr/share/examples/pf/faq-example1 file with additional modifications.
### pf.conf
### macross
## internal and external interfaces
int_if = "xl1"
ext_if = "xl0"
# 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 = "{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }"
### options
set block-policy drop
set loginterface $ext_if
set skip on lo0
### Scrub
# From the PF user's guide (http://www.openbsd.org/faq/pf/index.html):
# "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.
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 -> 127.0.0.1 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
### end pf.conf
To test the rules from pf.conf without loading them into pf, type the following command:
# pfctl -n -f /etc/pf.conf
To activate PF, and have it start automatically on boot-up, edit your /etc/rc.conf and add the following lines:
### rc.conf
pf_enable="YES" # Enable PF (load module if required)
pf_rules="/etc/pf.conf" # rules definition file for pf
pf_flags="" # additional flags for pfctl startup
pflog_enable="YES" # start pflogd(8)
pflog_logfile="/var/log/pflog" # where pflogd should store the logfile
pflog_flags="" # additional flags for pflogd startup
pflogd_enable="YES"
pfsync_enable="YES"
### end rc.conf
5. Conclusion
This tutorial has just touched on the basics of using FreeBSD and OpenBSD's PF packet filter as a router. PF offers many advanced features such as traffic shaping and blocking hosts based on their OS. For more information see the PF handbook.
Now you have to reboot the system for the changes to take effect.
# shutdown -r now
When the system comes back up, the LAN clients should be able to access the Internet through this FreeBSD router.
Print This Post