Setting up Linux to be a (Masquerading) Firewall

PLEASE UNDERSTAND WHAT YOU ARE DOING BEFORE YOU START THIS. SAVE YOUR EXISTING CONFIGURATION FILES BEFORE CHANGING THEM. Please read my disclaimer about such things.

In the event that I've incorrectly stated something here, please let me know. My E-mail address is below.

These documents assume (sic) that you know what's going on with networks and Linux. Additional documentation can be found in the Linux Kernel Source tree in the Documentation/Configure.help file.

There are a few caveats to go into first.

If you don't need a "real" firewall, try this document.


Let's start from the beginning...

The first thing you need to do is identify a system you can run as a firewall. This generally means a system that can have a fresh installation of Linux loaded onto it.

The Linux installation should have the minimum number of packages installed, beyond the base OS installation. Specifically:

If you have an assigned IP address from you ISP, you will specify that address for the IP address during installation. This will configure eth0 for the outside network (the Internet). If, however, you have a dynamic IP address, select the BOOTP/DHCP when asked. This will configure eth0 properly for use with your ISP.

ALL updates for EVERY package used on the system should be installed, and kept up-to-date at all times. This is very important!

I also recommend running a terrific package from Psionic, Inc. called PortSentry. Look here for RPMs and retrieve version 1.0 or later. Read the manual for configuration options and a general idea of what it can do for you. I suggest the Advanced Stealth mode for TCP and UDP, it works very well for me.

Also, if you have some time and inclination to play, the Trex or OpenSource Firewall looks like a very good package. I'm working on making it into an RPM but the build procedure needs work before it'll be happy.

If you have only one IP address assigned to you or are already using private IP addresses, such as 10.x.x.x or 172.16.x.x or 192.168.x.x, configure eth1 as the gateway address for that network. Since there is no real standard as to what that should be, it can be anything you like. I use x.x.x.1 to make things easy. Red Hat uses x.x.x.254. It really doesn't matter.

NOTE for those you who have publicly assigned IP addresses for the machines behind the firewall: I don't have any experience with configuring firewalls for this purpose. Please send me feedback on what works and what doesn't and I'll incorporate the changes here.

Once you have the machine built and configured with the software you want on it, it's time to configure the firewall portion.

Edit /etc/inetd.conf or /etc/xinetd.conf and disable every service you don't need, either publicly or privately. When you have finished editing the file, restart For those left enabled, figure out which ones you want available publicly and note the service names. For each service, look up the port numbers of that service in /etc/services

If you have ipchains and an init script in /etc/rc.d/init.d called ipchains configuring the firewall is easy. As a start, copy this file to /etc/sysconfig/ipchains. Be sure to edit the last line:


(Nearly) Line by line description of the ipchains file:
:input ACCEPT  <-\
:forward DENY  <-|-- Define default rules for each chain.
:output ACCEPT <-/

Reject the loopback address for each "real" interface.
-A input -s 127.0.0.0/255.0.0.0 -d 0.0.0.0/0.0.0.0 -i eth1 -j REJECT
-A input -s 0.0.0.0/0.0.0.0 -d 127.0.0.0/255.0.0.0 -i eth1 -j REJECT
-A input -s 127.0.0.0/255.0.0.0 -d 0.0.0.0/0.0.0.0 -i eth0 -j REJECT
-A input -s 0.0.0.0/0.0.0.0 -d 127.0.0.0/255.0.0.0 -i eth0 -j REJECT

Reject private network addresses from the Internet interface.
-A input -s 192.168.0.0/255.255.0.0 -d 0.0.0.0/0.0.0.0 -i eth0 -j REJECT
-A input -s 0.0.0.0/0.0.0.0 -d 192.168.0.0/255.255.0.0 -i eth0 -j REJECT
-A input -s 172.16.0.0/255.255.0.0 -d 0.0.0.0/0.0.0.0 -i eth0 -j REJECT
-A input -s 0.0.0.0/0.0.0.0 -d 172.16.0.0/255.255.0.0 -i eth0 -j REJECT
-A input -s 10.0.0.0/255.0.0.0 -d 0.0.0.0/0.0.0.0 -i eth0 -j REJECT
-A input -s 0.0.0.0/0.0.0.0 -d 10.0.0.0/255.0.0.0 -i eth0 -j REJECT

Deny access from the Internet to internal-only services, such as SNMP
-A input -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 161:161 -i eth0 -p 17 -j DENY
-A input -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 162:162 -i eth0 -p 17 -j DENY

Accept access from the Internet to services meant for external use.
-A input -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 22:22 -i eth0 -p 6 -j ACCEPT
-A input -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 80:80 -i eth0 -p 6 -j ACCEPT
-A input -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 443:443 -i eth0 -p 6 -j ACCEPT
-A input -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 500:500 -i eth0 -p 17 -j ACCEPT

Deny access from the Internet to privileged service ports not listed above.
-A input -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 0:1024 -i eth0 -p 6 -j DENY
-A input -s 0.0.0.0/0.0.0.0 -d 0.0.0.0/0.0.0.0 0:1024 -i eth0 -p 17 -j DENY

Masquerade any traffic from "inside" going to the Internet.
-A forward -s 192.168.0.0/255.255.255.0 -d 0.0.0.0/0.0.0.0 -j MASQ
Misc notes:
  1. The general format of the file:
    -A                    <- Append to chain
    input                 <- Chain to be affected
    -s 0.0.0.0/0.0.0.0    <- The source IP address and network mask
    -d 0.0.0.0/0.0.0.0    <- The destination IP address and network mask
    0:1024                <- The range of destination ports
    -i eth0               <- The ethernet interface to be affected
    -p 6                  <- The protocol (TCP in this case) for the filter
    -j ACCEPT             <- The action for the filter
    
  2. Source ports can also be specified after the source IP address option.
  3. Filtering by protocol is specified on most lines, it's the -p flag. Protocol 6 is TCP and 17 is UDP. They can also be specified by name such as TCP, UDP, ICMP, etc. They were converted by the ipchains-save script which generated this file.
  4. The ipchains man page has complete details on the options it will accept.

Reboot your system. Everything should work now.

Disclaimer

-Paul
kronenpj@netzero.net
Last modified: Sun Nov 4 8:41:06 EST 2000
Valid HTML 4.0!