FreeBSD: How to set up PPPoE
Now that broadband is widely available, wouldn’t it be nice to have all your machines
at home connected to it. (Note: Some providers disallow LANs as part of their AUP). With
this article we’ll go thru the configuration required to configure up a PPPoE interface
in FreeBSD, enable Network Address Translation, and setup basic firewall rules to protect
The things we need are a FreeBSD Box, a broadband modem that terminates as
ethernet. One of the USB modems might be usable if FreeBSD sees them as a network interface.
I’ve only had experience with the alcatel adsl modems that terminate as ethernet. We will also
need a 2nd network interface to connect to our LAN. For this article fxp0 will be our
adsl modem interface, and fxp1 will be our LAN interface.
The only software we need to establish the PPPoE connection is the user
daemon thats included in the base install of FreeBSD. Here is a
sample entry that will be required in the /etc/ppp/ppp.conf:
1234567891011121314 default:adsl:set device PPPoE:fxp0set mode ddialset authname username@providerset authkey passwordset speed syncset mru 1492set mtu 1492set ifaddr 0.0.0.0/0 0.0.0.0/0 255.255.255.0 0.0.0.0add default HISADDRenable dnsnat enable yes
For more information on what these options do, see the entries in the manpage. The things
that will need to be changed in the sample above are set device PPPoE:fxp0, fxp0
should be changed to the network interface that your adsl modem is connected to.
set authname username@provider obviously needs to be changed to your username
and the name of your provider. set authkey password again obviously change
password to be the password of your account.
And thats how easy it is to configure PPPoE on FreeBSD. But we better test it before we get
too far ahead of ourselves. The quickest way of testing to make sure your PPPoE connection is
working is to do the following:
123456789 [root@router]:/etc/ppp# ppp -i adslWorking in interactive modeUsing interface: tun0<strong>ppp</strong> ON router><strong>Ppp</strong> ON router><strong>PPp</strong> ON router><strong>PPP</strong> ON router> quit
You will notice how the ppp changes in case one P at a time. This shows the progress of the
connection. If all of the P’s become uppercase, this means your PPPoE connection was successful
and you should have network. If you don’t see PPP then there was a problem with establishing
the connection and you should check in the syslog file for error messages.
Now we have a working network link. Wouldn’t it be nice if it came up automaticly and
ran as a non privledged user, when we rebooted our machine? Again another easy thing to
do, add these lines to a script (make sure it’s executable) called
123456789 #!/bin/shcase "$1" instart)su -m ppp -c 'exec ppp -unit0 -quiet -ddial adsl';;stop);;esac
The reason we use a script and not just put the relevent lines into the /etc/rc.conf
file is because we want to specifiy the -unit<X> which will tell ppp which tun interface
we want. Why is this important? Because in our ipfw rules later we will be specifying which rules
apply to which interface.
You will notice that we’ve told the startup script to run the ppp process as ppp. We
need to create this user as it’s not in the default system. If you aren’t sure how
to create users, read the manpage for pw or adduser but a quick hint is
pw user add ppp -u 500 -G network. The primary group for the user should be
network this will let the ppp user execute the /usr/sbin/ppp binary.
Next we need to bind an IP range to the 2nd network card fxp1. The IP ranges reserved for
private use are 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16. So pick a network range out of those
for your LAN, EG 192.168.1.0/24. If you already have a LAN setup using one of these IP ranges then
thats good. If not, you might want to set one up/change to use these IP’s. It makes it easier later
down the track when you realise that the reason you can’t get to the website you really want to
look at, is because you’re using the website’s IP for a local machine :). Anyway bind an IP address to
the fxp1 network card by adding a line to the /etc/rc.conf file. Once thats done we need to
do the hard bit. Setting up the firewall.
You need to know how to compile a kernel for this part. If you are unfamiliar
with compiling a FreeBSD kernel you need to read the section in
The FreeBSD Handbook
titled Configuring the FreeBSD Kernel (http://www.freebsd.org/handbook/kernelconfig.html)
We need to enable the ipfw (ip firewall) in the FreeBSD kernel. To do this we need to add the
following lines to your conf file in /sys/i386/conf:
1234 options IPFIREWALLoptions IPFIREWALL_VERBOSEoptions IPFIREWALL_VERBOSE_LIMIT=5000options IPFIREWALL_DEFAULT_TO_ACCEPT
Once we have added these lines to our kernel config and have recompiled and installed the new
kernel, we can start to configure the firewall. It should be noted that you shouldn’t reboot
your machine until after the firewall rules are defined.You’ll notice one of the things we
added to the kernel was an option to make the default rule in the firewall, allow all. This
can save us later in life when we are changing and reloading rules. Nothing worse than \
to your router box to update rules and realising you just blocked yourself from being able to
get to the box when you reload the rules and something is wrong. Also for this reason you
should check your rules to make sure they look the way you were intending and that there
wasn’t an error and half your rules didn’t load. You can do this with ipfw list.
The rules we will be adding to the firewall are very simple. Allow anything to leave our network that
originated from it. But deny anything that tries to get in that hasn’t been asked for. This also means
things like ICQ and the like won’t be able to make direct connection to your ICQ. This can be worked around
but it’s outside the scope of this article. Create a file called /etc/ipfw.rules
and put the following lines in it:
12345678910111213141516171819202122 # fxp1 - LAN Interface# tun0 - Internet IP traffic interface..# Always allow traffic from our LANadd allow ip from any to any in via fxp1add allow ip from any to any out via fxp1# Check the state table to see if the connection is in thereadd check-state# Add all outgoing connections to the state table as they are setupadd allow tcp from any to any out via tun0 keep-state setupadd allow udp from any to any out via tun0 keep-state# Allow icmp in/out without putting it in the state table.add allow icmp from any to any out via tun0add allow icmp from any to any in via tun0# Last line in ipfw.rules should deny all since we allow all# by default! We will also log the blocked packets to see whats# going on. They will appear in our syslog.add deny log ip from any to any
You can read more about these rules in the manpage for
Something else to note, when I say stateful firewall, it’s not stateful on the
application layer, that is, the firewall will not automatic allow a back channel
connection from the ftp server to your
machine, or a back channel connection to your SQL server if it’s normally required. The way the state works is that if a connection appears in the table, then return traffic
for those hosts/ports is allow back thru the firewall until the connection is closed, or in the case
of udp, a timeout has been reached.
Finally we want to make these rules load every time we reboot. We need to add some more lines to our
/etc/rc.conf file that look like this:
Something else to note. When you reboot, you may see some warnings with regards to tun0 not being
configured. Ignore those warnings, it’s just that ppp hasn’t started yet and hasn’t configured the
tun device. The rules will still load into the firewall table and become active when tun0 is configured.
Well that should be about it. With any luck you should now have a
FreeBSD box that does PPPoE, NAT, and has some protection from the
evilness that is the internet. If you are new to FreeBSD I highly
recommend you take some time to read some/all of the FreeBSD Handbook
It has lots of information on all sorts of configuration settings and tuning.