I recently ditched our Comcast Business internet connection for Verizon FIOS in search of a more reliable provider. For well over a year I had seen intermittent high levels of packet loss with Comcast. One modem/router later and several technicians checking from the pole to the building resulted in everything looking fine in terms of signal strength according to them, but getting them to investigate further down the line seemed impossible. So since my contract was almost up I decided to give FIOS a try. Back when I originally switched from Comcast residential to business I had begged and pleaded for them to just allow me to use my own modem with my existing setup of my CentOS 6 server acting as the network gateway instead of their equipment but that was apparently not possible. With FIOS, thats one added bonus I get back is the ability to just get an ethernet connection straight to the public. However, since I've now switched my internal infrastructure to FreeBSD it was time to learn how to configure it as my gateway system for the network. Turns out, it was much simpler than I remember CentOS being.
Since I had a week from order to install, I did some planning ahead of time to get everything in place. My existing setup was as follows:
Once FIOS is installed I will have a straight ethernet connection to the public internet. Sure I could have taken their modem. but why I have all I need and it will be much more reliable. Here's how I figure it should go down.
A day before the install, I will stage the new configuration on the server so that all I will need to do is a quick cable swap and reboot to make the changes active. Sure, I could have just restarted services as needed but it had been a while since my last reboot so I figured that would be easiest.
First, I will need to configure my public facing port on the server since it was not previously used. Since I did not get a static IP with my FIOS it needs to simply be DHCP. For clarity I provide the configuration for both interfaces even though igb0 doesn't change. The following are changes required in /etc/rc.conf:
# Public Interface configuration. ifconfig_em0="dhcp" # LAN interface configuration ifconfig_igb0="inet 192.168.x.x netmask 255.255.255.0"
Next, since I previously had a different router, that was set in my configuration. This system will now be the default gateway for the rest of the network but its default gateway needs to come from the FIOS DHCP. I simply comment it out.
# Default gateway. Not required for FIOS #defaultrouter="192.168.x.x"
Next, I need to tell the system to forward packets for the rest of the network (NAT).
# Enable ip forward gateway_enable="YES"
And finally, since I want to provide firewall services now also, I need to enable PF.
# Enable PF pf_enable="YES" pflog_enable="YES" pflog_logfile="/var/log/pflog" pflogd_enable="YES" pfsync_enable="YES"
PF is FreeBSD's equivalent to iptables, but completely different. I do a little reading and configure a very basic ruleset to lock things down until I can rework the configuration as needed once I'm up and running. By default this is configured in /etc/pf.conf but that file will not exist if you haven't already been running PF.
Note that I have commented the options in the file as needed but better explanations can be found in the awesome FreeBSD documentation.
# $FreeBSD: releng/10.1/share/examples/pf/faq-example1 237681 2012-06-28 03:30:17Z rpaulo $ # $OpenBSD: faq-example1,v 1.5 2006/10/07 04:48:01 mcbride Exp $ # # Firewall for Home or Small Office # http://www.openbsd.org/faq/pf/example1.html # ###################################### # macros ###################################### # Define the external/public interface ext_if="em0" # Define the internal LAN interface int_if="igb0" # Define a list of services to allow traffic for tcp_services="{ 80 }" # Define what types of ICMP to allow icmp_types="echoreq" ###################################### # options ###################################### set block-policy return set loginterface $ext_if set skip on lo scrub in ###################################### # nat/rdr ###################################### # Handle the NAT forwarding for the LAN nat on $ext_if inet from !($ext_if) -> ($ext_if:0) ###################################### # filter rules ###################################### # Block all incoming block in # Allow outgoing and keep state pass out keep state # The antispoof mechanism protects against activity from spoofed or forged IP addresses antispoof quick for { lo $int_if } # Allow requests for our ports/services defined in the $tcp_services macro above to the server pass in on $ext_if inet proto tcp from any to ($ext_if) port $tcp_services # Allow the defined ICMP types pass in inet proto icmp all icmp-type $icmp_types # Allow all internal traffic pass quick on $int_if no state
There are various options for providing DHCP services to your network. Dnsmasq is a very nice little utility that provides alot of nice features yet is very simple to configure just what you want to use. Since I was already using it for DNS services on my network (Comcast's DNS is horrible), its trivial for me to just tell it to provide DHCP services too. To start with, the main configuration in /usr/local/etc/dnsmasq.conf. In this case, all I had to add were the last three lines for DHCP.
# Never forward plain names (without a dot or domain part) domain-needed # Never forward addresses in the non-routed address spaces. bogus-priv # The path to the resolv.conf file for DNSMASQ. This should NOT be your default /etc/resolv.conf. resolv-file=/usr/local/etc/resolv.conf # Only handle requests that are local. You could also specify specific interfaces to listen on but # This essentially listens on all local ones. local-service # Set the DHCP domain domain=your.local.domain # Set the DHCP address range (start, end, lease time) dhcp-range=192.168.x.x,192.168.x.x,36h # Set the default router to hand out. This probably isn't required since DNSMASQ apparently will use # itself as defaults but I did it for clarity dhcp-option=option:router,192.168.x.x
Then, for your public DNS resolvers, add them to the file set for resolv-conf. For example in /usr/local/etc/resolv.conf I have the following:
nameserver 8.8.8.8 nameserver 4.2.2.1
One additional note on Dnsmasq. By default it reads /etc/hosts on startup and serves the entries out of there for the LAN. This can be a very helpful feature to provide local addresses for public facing services if desired.
Now all that was left was to get my connection. Once the tech activated it I plugged into my server port and rebooted. Once the system came back up I had my public IP on em0 as expected and could ping out. Next step was to release/renew my DHCP on my laptop and run the same ping test...SUCCESS! All told my entire LAN was reconnected in less than 5 minutes like nothing changed.
As always, please contact us with any questions or inquiries about this post.