Building a Gateway/Firewall
Create a FreeBSD-based Network Gateway (FreeBSD 5.4)
Posted 19.06.2006 | Updated 31.05.2007 | Contributed by Andy Mallett




The plan is to create a Gateway box to join two (or more) networks. Firewalling will be left for another article.

The local area network would be an internal LAN connected to the inward facing network card, shown here as fxp0.

The external network could be an internet connection or a wireless connection joined to the outward facing network card, shown as rl0.

The identifiers which FreeBSD gives to these two network interfaces will vary according to make and model of ethernet card.

Likewise the IP Addressing scheme used on another network may differ from the one used here. You will need to modify these instructions accordingly..


Network Layout

1. Installation

Installation of the FreeBSD operating system can be performed in the usual way, with the exception of answering "Yes" to the question, "Do you wish this system to function as a network gateway?". If this is not done at install it doesn't matter as the relevant network gateway functionality can be added afterwards.

2. Network Settings

These are the Gateway-relevant settings in /etc/rc.conf..

gateway_enable="YES"
ipnat_enable="YES"

hostname="viktor.gothic.net"
ifconfig_fxp0="inet 192.168.0.13  netmask 255.255.255.0"
defaultrouter="192.168.0.101"
ifconfig_rl0="inet 10.147.86.63  netmask 255.0.0.0"
The first two lines should get added when the network gateway function was confirmed above. gateway_enable="YES" basically tells the system to route data beteen multiple network interfaces and ipnat_enable="YES" tells the system to use Network Address Translation (NAT) on all packets passing through.

To add gateway functionality to a previous installation of FreeBSD, add those first two lines to /etc/rc.conf.

The system should already have one working network interface. In the example above, the inward facing network adapter is represented by the line ifconfig_fxp0="inet 192.168.0.13, showing the internal network interface is fxp0 with an IP Address of 192.168.0.13.

The next line defaultrouter="192.168.0.101" indicates the IP Address of the default gateway for internet access. This may seem odd as this machine is functioning as a network gateway, but my own LAN has two gateways: one for the internet (192.168.0.101) and the other as the gateway for a wireless WAN. So my workstations look to 192.168.0.101 for internet access and 192.168.0.13 for WWAN access.

The default gateway line is not strictly necessary if the server itself is the only gateway, i.e. an internet gateway, as used in most cases.

Naturally your settings may be different from mine with regards to interface names and IP Address details. Modify these instructions with your own settings.

If you know the name which FreeBSD gives to the second network card, then add the final line so that the outside-facing network interface is configured correctly..

ifconfig_rl0="inet 10.147.86.63 netmask 255.0.0.0"

If you are not familiar with FreeBSD networking, use the sysinstall method instead..

sysinstall
configure
networking
interfaces
(spacebar to select | OK)

You're presented with the choices of interfaces at the top of the screen, both indicated in the example below..

Network Interfaces


Select one of the interfaces and proceed through the following configuration screen. Once both interfaces have been configured, save and exit from sysinstall.

Finally recheck by editing /etc/rc.conf which should now have the correct entries for both network interfaces. Reboot the system and check by pinging systems attached to both interfaces.

3. IPNAT Ruleset

Once the network part is set up, you should be able to ping both interfaces on the FreeBSD gateway from another system on either network. If this is possible then the gateway aspect of the system is working fine so far.

The NAT part won't work without a set of rules, as exist in the file /etc/ipnat.rules. These rules basically tell the gateway how to translate the IP Addresses of packets passing through the system. Only 1 (unhashed) line is required to get all data flowing from the inside interface to the outside world.

Using vi, create a new IPNAT translation ruleset, /etc/ipnat.rules and add the following lines to it. Again modify it to reflect your own settings..

vi  /etc/ipnat.rules
#--------------------------------------------------------------------
# Do 'normal' IP address translation. This line will take all packets
# going out on your external NIC (rl0) that have a source address coming
# from your internal network (192.168.1.0), and translate it to whatever
# IP address your external NIC happens to have at that time
#--------------------------------------------------------------------
map rl0 192.168.0.0/24 -> 0/32

#--------------------------------------------------------------------
# If you have a system on your internal network that needs to be
# 'reachable' by external systems on the internet, you'll need a rule
# similar to the one below. This one takes all inbound http traffic
# (TCP port 80) that hits the firewall's external interface (rl0) and
# redirects it to port 80 on the 192.168.1.50 system on the internal network.
# Simply uncomment the rule, change the IP address and port number so that
# it does what you need. Remember that you have to enable the corresponding
# inbound filter in your /etc/ipf.rules file, too.
#--------------------------------------------------------------------
# rdr rl0 0.0.0.0/0 port 80 -> 192.168.1.50 port 80 tcp

Here's the diagram again from the beginning of the article..

Network Layout

3.1 Letting it all out

As indicated in the explanation above it, the first unremarked line of ipnat.rules..

map rl0 192.168.0.0/24 -> 0/32

..is saying 'when all packets coming from within the internal LAN (192.168.0.x) reach the external interface rl0, perform Network Address Translation (NAT) on them and send them through.'

So, all traffic coming from the protected LAN gets its IP Address changed to the IP of the outward-facing NIC (rl0, 10.147.86.63) through the wonders of NAT.

3.2 Flushit!

After modifying the gateway ruleset, you must flush out the old rules and reload the new ones. Run the following command every time you modify something..

ipnat  -C  -f  /etc/ipnat.rules

3.3 Letting something in

As indicated in the explanation above it, the last (remarked) line of ipnat.rules..

rdr rl0 0.0.0.0/0 port 80 -> 192.168.1.50 port 80 tcp

..is saying, 'redirect anything coming in from the external interface (rl0) using port 80 (http), to the internal server 192.168.1.50 on port 80.' In other words let them see the web server inside the firewall. Not a good idea for security reasons (the web server should be in a DMZ, not the protected LAN), but technically possible.

So just for testing purposes I set up an FTP service (port 21) on my workstation inside the protected LAN and ran some test FTP requests from a laptop on the outsdie of the gateway/firewall. The rule looks like this..

rdr rl0 10.147.86.0/0 port 21 -> 192.168.0.1 port 21 tcp

In this example the external interface (rl0) has an IP Address of 10.147.86.63 and the internal FTP Server has an IP of 192.168.1. FTP of course, runs on port 21 by default.

Again remember to flushit after modifying the ruleset.

A final but important note on testing. For systems in the protected LAN to be able to ping or interact with systems on the outside of the gateway, their Default Gateway setting must be the IP Address of the gateway's inward facing network interface. In my example, they need a Default Gateway IP of 192.168.0.13.

This way a workstation with an IP of 192.168.0.20 can ping another system (outside the gateway) of say, 10.147.86.20.

So Far So Good..

If everything is working as per instructions, you have a fully-functional gateway for connecting two or more different networks. Note that there are no security settings configured at this stage. I would suggest getting the gateway functionality happening first before attempting to restrict throughput with firewall rules.

The subject of setting up the firewall side of things is a specialist topic in its own right and requires the application of some rules of logic to get it running properly, whilst maintaining good performance and speedy data throughput. Firewalling will be covered in a later article, but the reader is directed to firewall.htm as an excellent and thorough reference on the subject.

Tweaking ipnat.rules

Adding to or modifying the functioning of the gateway usually involves editing the /etc/ipnat.rules file, after which the old gateway rules must be flushed out and the new ones reloaded. I have written a script to take care of these two functions, all in one speedy command..

#!/bin/sh
#Andys IPNAT Script

#1.Modify the ruleset
vi  /etc/ipnat.rules

#2.Flush and reload the ruleset
ipnat -C -f /etc/ipnat.rules


That second line is important as the old rules must be flushed and the new rules inserted, after modification of the ruleset.

More, more, more..

Further configuration of ipnat.rules can be found under Gateway Rules, Customising. Watch out for updated rulesets..

Some ongoing attempts at firewalling can be found at Firewalling with IPF, but note this is a work-in-progress, so watch for updates. Check out the notes at firewall.htm to see the direction I am planning to head for..

References

http://www.enderunix.org/docs/en/freebsd61/06.08-NAT_Explanation.htm
http://www.schlacter.net/public/FreeBSD-STABLE_and_IPFILTER.html
http://www.mostgraveconcern.com/freebsd.
http://inc2.com/isba/080-compilation-installation.html
https://neon1.net/misc/firewall.html
http://www.obfuscation.org/ipf
http://www.instructables.com/id/EN69P8RZ28EP2871BW