Home Page
Linux Basics Debian Linux Installation Using Debian Packages Linux Modem Setup Setting Up A Network Setting Up DNS Servers Linux Internet Servers Linux LAN Servers Linux Database Server Linux Syslog Server Linux Fax Server Linux Web Cam Servers Linux Proxy/NAT Servers Linux Firewall Servers Linux Security Compiling Linux Programs Home Automation What Now?


How To Set Up A Debian Linux Firewall


The material on this page was prepared using Sarge or Etch
configured using our Installation and Packages pages.
If you did not use our pages to set up your system, what you
encounter on your system may be different than what is given here.


This page covers using IPCHAINS with the 2.2 Linux kernel.
For the page on using IPTABLES with the 2.4 Linux kernel click here.


A firewall is a system or router that sits between an external network (i.e. the Internet) and an internal network. This internal network can be a large LAN at a business or your networked home PCs. The firewall in it's simplest form is like a one-way street. It allows people on the internal network to access the external network (the Intenet), but it restricts traffic so that no one can use the external network to access the systems or files on the internal network.

If you connect to the Internet using a modem you typically don't have to be too concerned about firewalling your internal network. That's because each time you connect to the Internet you are assigned a different IP address by your ISP, and your dial-up sessions are limited in length. However, if you have a DSL line or a cable modem, you retain the same IP address for much longer periods of time, perhaps months, because you have an "always on" connection to the Internet. In this case a firewall is advisable.

A firewall has two network connections, one for the external network and one for the internal network. Traffic that is allowed to flow between the two networks is internally "bridged" between these two connections. Disallowed traffic is not. This decision-based bridging of traffic between two connections is called "routing" or "IP forwarding". What this means is that any firewall, by its very nature, is a router (but not all routers block traffic, so not all routers are firewalls).

You can buy "cable/DSL routers" (proxy-in-a-box) for under $100 which offer integrated firewalling functionality. However, the firewalling is typically limited in nature and may not be able to be upgraded as new threats are discovered.

So why use a Linux system as a firewall if these $100 boxes are available? One reason is flexibility. You could use your Linux firewall system to simultaneously act as a Web and/or e-mail server (more about this can be found on the Internet Servers page). Plus you can set up very fine controls about who can access what on the Internet. But the main reason for setting up a Linux firewall is because it will help you learn Linux.


The Firewall Script Top of page

If you haven't already done so, please read the Proxy/NAT page. Much of the information for proxy servers and firewalls is the same and we won't be repeating it here. As a matter of fact, if you created the proxy server on the previous page, all you have to do is add a few more IPCHAINS commands to enhance the firewalling functionality of the system.

All we're going to do is take the proxy server shell script from the Proxy/NAT page and add some more rules to it. Whereas the proxy script only had specific rules related to forwarding, the modified script will have all three types of rules (input, ouput, and forwarding).

Here's the proxy script. The things we will remove are in red.

#!/bin/sh

#  IPCHAINS  PROXY  script for the Linux 2.2 kernel.
#  This script is a derivitive of the script presented in
#  the IP Masquerade HOWTO page at:
#  www.tldp.org/HOWTO/IP-Masquerade-HOWTO/stronger-firewall-examples.html
#  It was simplified to coincide with the configuration of
#  the sample system presented in the Guides section of
#  www.aboutdebian.com
#
#    PLEASE SET THE USER VARIABLES
#    IN SECTIONS A AND B OR C

echo -e "\n\nSETTING UP IPCHAINS FIREWALL..."


# === SECTION A
# -----------   FOR EVERYONE 


# SET THE _NETWORK_ ADDRESS OF YOUR INTERNAL NETWORK
#   The default value below is for a 192.168.0.0 network.
#   Note that the "/24" is a network mask of 255.255.255.0
#   (meaning 24 bits - three octets - set to 1s).  Similarly,
#   a network mask of 255.255.0.0 would be "/16".
#       Note that this is a NETWORK address - not the
#       IP address of a specific device on the network.
#   Enter the internal network's (or subnet's) network
#   address for the INTLAN variable:

INTLAN="192.168.0.0/24"


# SET THE INTERFACE DESIGNATION FOR THE NIC CONNECTED TO YOUR INTERNAL NETWORK
#   The default value below is for "eth0".  This value 
#   could also be "eth1" if you have TWO NICs in your system.
#   You can use the ifconfig command to list the interfaces
#   on your system.  The internal interface will likely have
#   have an address that is in one of the private IP address
#   ranges.
#       Note that this is an interface DESIGNATION - not
#       the IP address of the interface.
#   Enter the internal interface's designation for the
#   INTIF variable:

INTIF="eth0"


# SET THE INTERFACE DESIGNATION FOR YOUR "EXTERNAL" (INTERNET) CONNECTION
#   The default value below is "ppp0" which is appropriate 
#   for a MODEM connection.
#   If you have two NICs in your system change this value
#   to "eth0" or "eth1" (whichever is opposite of the value
#   set for INTIF above).
#       Note that this is an interface DESIGNATION - not
#       the IP address of the interface.
#   Enter the external interface's designation for the
#   EXTIF variable:

EXTIF="ppp0"



# ! ! ! ! !  Use ONLY Section B  *OR*  Section C depending on
#  ! ! ! !   the type of Internet connection you have.



# === SECTION B
# -----------   FOR THOSE WITH STATIC PUBLIC IP ADDRESSES


   # SET YOUR EXTERNAL IP ADDRESS
   #   If you specified a NIC (i.e. "eth0" or "eth1" for
   #   the external interface (EXTIF) variable above,
   #   AND if that external NIC is configured with a
   #   static, public IP address (assigned by your ISP),
   #   UNCOMMENT the following EXTIP line and enter the
   #   IP address for the EXTIP variable:

# EXTIP="your.static.IP.address"



# === SECTION C
# ----------   DIAL-UP MODEM, AND RESIDENTIAL CABLE-MODEM/DSL (Dynamic IP) USERS


# SET YOUR EXTERNAL INTERFACE FOR DYNAMIC IP ADDRESSING
#   If you get your IP address dynamically from SLIP, PPP,
#   BOOTP, or DHCP, UNCOMMENT the FOUR commands below.
#   (No values have to be entered.)
#         Note that if you are uncommenting these lines then
#         the EXTIP line in Section B must be commented out.

# echo "    Enabling Dynamic IP Addressing..."
# echo "1" > /proc/sys/net/ipv4/ip_dynaddr
# /sbin/ipchains -A input -j ACCEPT -i $EXTIF -s 0/0 67 -d 0/0 68 -p udp
# EXTIP="`/sbin/ifconfig ppp0 | grep 'inet addr' | awk '{print $2}' | sed -e 's/.*://'`"


# --------  No more variable setting beyond this point  --------


echo "    Loading required IPMASQ kernel modules..."

/sbin/depmod -a
/sbin/modprobe ip_masq_ftp
/sbin/modprobe ip_masq_raudio

echo "    Enabling IP forwarding..."
echo "1" > /proc/sys/net/ipv4/ip_forward
echo "    Enabling IP Defragmentation..."
echo "1" > /proc/sys/net/ipv4/ip_always_defrag

# MASQ timeouts
#
#   2 hrs timeout for TCP session timeouts
#  10 sec timeout for traffic after the TCP/IP "FIN" packet is received
#  160 sec timeout for UDP traffic (Important for MASQ'ed ICQ users) 

echo "    Setting default timers..."
/sbin/ipchains -M -S 7200 10 160

echo "    Internal interface: $INTIF"
echo "       Internal network IP address is: $INTLAN"
echo "    External interface: $EXTIF"
echo "       External interface IP address is: $EXTIP"


echo "    Clearing any existing rules and setting default policy..."
/sbin/ipchains -P input ACCEPT
/sbin/ipchains -P output ACCEPT
/sbin/ipchains -P forward REJECT
/sbin/ipchains -F input
/sbin/ipchains -F output
/sbin/ipchains -F forward


echo "    Enabling IPMASQ functionality on $EXTIF..."
/sbin/ipchains -P forward DENY
/sbin/ipchains -A forward -i $EXTIF -s $INTLAN -j MASQ

echo -e "    Proxy server rule loading complete\n\n"
 


Now here's the firewall script. The things that were in red in the above script have been removed. The things we've added are in blue. As you can see, most of the script is the same.


#!/bin/sh

#  IPCHAINS  FIREWALL  script for the Linux 2.2 kernel.
#  This script is a derivitive of the script presented in
#  the IP Masquerade HOWTO page at:
#  www.tldp.org/HOWTO/IP-Masquerade-HOWTO/stronger-firewall-examples.html
#  It was simplified to coincide with the configuration of
#  the sample system presented in the Guides section of
#  www.aboutdebian.com
#
#    PLEASE SET THE USER VARIABLES
#    IN SECTIONS A AND B OR C

echo -e "\n\nSETTING UP IPCHAINS FIREWALL..."


# === SECTION A
# -----------   FOR EVERYONE 


# SET THE _NETWORK_ ADDRESS OF YOUR INTERNAL NETWORK
#   The default value below is for a 192.168.0.0 network.
#   Note that the "/24" is a network mask of 255.255.255.0
#   (meaning 24 bits - three octets - set to 1s).  Similarly,
#   a network mask of 255.255.0.0 would be "/16".
#       Note that this is a NETWORK address - not the
#       IP address of a specific device on the network.
#   Enter the internal network's (or subnet's) network
#   address for the INTLAN variable:

INTLAN="192.168.0.0/24"


# SET THE INTERFACE DESIGNATION FOR THE NIC CONNECTED TO YOUR INTERNAL NETWORK
#   The default value below is for "eth0".  This value 
#   could also be "eth1" if you have TWO NICs in your system.
#   You can use the ifconfig command to list the interfaces
#   on your system.  The internal interface will likely have
#   have an address that is in one of the private IP address
#   ranges.
#       Note that this is an interface DESIGNATION - not
#       the IP address of the interface.
#   Enter the internal interface's designation for the
#   INTIF variable:

INTIF="eth0"


# SET THE INTERFACE DESIGNATION FOR YOUR "EXTERNAL" (INTERNET) CONNECTION
#   The default value below is "ppp0" which is appropriate 
#   for a MODEM connection.
#   If you have two NICs in your system change this value
#   to "eth0" or "eth1" (whichever is opposite of the value
#   set for INTIF above).
#       Note that this is an interface DESIGNATION - not
#       the IP address of the interface.
#   Enter the external interface's designation for the
#   EXTIF variable:

EXTIF="ppp0"



# ! ! ! ! !  Use ONLY Section B  *OR*  Section C depending on
#  ! ! ! !   the type of Internet connection you have.



# === SECTION B
# -----------   FOR THOSE WITH STATIC PUBLIC IP ADDRESSES


   # SET YOUR EXTERNAL IP ADDRESS
   #   If you specified a NIC (i.e. "eth0" or "eth1" for
   #   the external interface (EXTIF) variable above,
   #   AND if that external NIC is configured with a
   #   static, public IP address (assigned by your ISP),
   #   UNCOMMENT the following EXTIP line and enter the
   #   IP address for the EXTIP variable:

# EXTIP="your.static.IP.address"



# === SECTION C
# ----------   DIAL-UP MODEM, AND RESIDENTIAL CABLE-MODEM/DSL (Dynamic IP) USERS


# SET YOUR EXTERNAL INTERFACE FOR DYNAMIC IP ADDRESSING
#   If you get your IP address dynamically from SLIP, PPP,
#   BOOTP, or DHCP, UNCOMMENT the FOUR commands below.
#   (No values have to be entered.)
#         Note that if you are uncommenting these lines then
#         the EXTIP line in Section B must be commented out.

# echo "    Enabling Dynamic IP Addressing..."
# echo "1" > /proc/sys/net/ipv4/ip_dynaddr
# /sbin/ipchains -A input -j ACCEPT -i $EXTIF -s 0/0 67 -d 0/0 68 -p udp
# EXTIP="`/sbin/ifconfig ppp0 | grep 'inet addr' | awk '{print $2}' | sed -e 's/.*://'`"



# --------  No more user variables beyond this point  ------------------



echo "    Loading required IPMASQ kernel modules..."

/sbin/depmod -a
/sbin/modprobe ip_masq_ftp
/sbin/modprobe ip_masq_raudio

echo "    Enabling IP forwarding..."
echo "1" > /proc/sys/net/ipv4/ip_forward
echo "    Enabling IP Defragmentation..."
echo "1" > /proc/sys/net/ipv4/ip_always_defrag

# MASQ timeouts
#
#   2 hrs timeout for TCP session timeouts
#  10 sec timeout for traffic after the TCP/IP "FIN" packet is received
#  160 sec timeout for UDP traffic (Important for MASQ'ed ICQ users) 

echo "    Setting default timers..."
/sbin/ipchains -M -S 7200 10 160

echo "    Internal interface: $INTIF"
echo "       Internal network IP address is: $INTLAN"
echo "    External interface: $EXTIF"
echo "       External interface IP address is: $EXTIP"


echo "    Setting up firewall rules..."

#   INPUT RULES
#############################################################################
# Incoming, flush and set default policy of reject.
#
ipchains -F input
ipchains -P input REJECT
ipchains -A input -i $INTIF -s $INTLAN -d 0.0.0.0/0 -j ACCEPT
ipchains -A input -i $EXTIF -s $INTLAN -d 0.0.0.0/0 -l -j REJECT
ipchains -A input -i $EXTIF -s 0.0.0.0/0 -d $EXTIP/32 -j ACCEPT
ipchains -A input -i lo -s 0.0.0.0/0 -d 0.0.0.0/0 -j ACCEPT


#   OUTPUT RULES
#############################################################################
# Outgoing, flush and set default policy of reject.
#
ipchains -F output
ipchains -P output REJECT
ipchains -A output -i $INTIF -s 0.0.0.0/0 -d $INTLAN -j ACCEPT
ipchains -A output -i $EXTIF -s 0.0.0.0/0 -d $INTLAN -l -j REJECT
ipchains -A output -i $EXTIF -s $INTLAN -d 0.0.0.0/0 -l -j REJECT
ipchains -A output -i $EXTIF -s $EXTIP/32 -d 0.0.0.0/0 -j ACCEPT
ipchains -A output -i lo -s 0.0.0.0/0 -d 0.0.0.0/0 -j ACCEPT


#   FORWARD RULES
#############################################################################
# Forwarding, flush and set default policy of deny.
#
ipchains -F forward
ipchains -P forward DENY
ipchains -A forward -i $EXTIF -s $INTLAN -d 0.0.0.0/0 -j MASQ


echo "    Firewall rule loading complete\n\n"


As with the proxy script, you can simply copy/paste the above script into a text editor and make the necessary changes for your system, network, and type of external connection Then save it using the file name firewall.txt and anonymous FTP it to your Debian system.

Note that, also like the proxy script, you cannot set this script to run at boot up if you are using a dynamic IP-based modem connection for the external interface unless you add the commands to call the pon script.
Once the file is transferred, use the following commands to copy/rename it to the appropriate scripts directory and to make it executable for root:

cp /home/ftp/pub/incoming/firewall.txt /etc/init.d/firewall.sh
chmod 755 /etc/init.d/firewall.sh
Now all you have to do is connect to your ISP and enter the following command to run the script:

/etc/init.d/firewall.sh

Using IPCHAINS sets up a "packet filtering firewall". It inspects packets for source or destination addresses, protocol (tcp, udp, or icmp), and port numbers (which indicate the type of Internet application being used such as 80 for http (Web browsing), 21 for ftp, 23 for telnet, etc.). There are other, more sophisticated types of firewalls. Those that examine the actual data in the packets to see if what's being transferred back and forth is a logical exchange of information are called "stateful" firewalls.

If you created a symbolic link on the Proxy/NAT page so the proxy script would run at bootup, you may want to delete it and recreate one for this script. The following two commands will take care of that:

rm /etc/rc2.d/S95proxy
ln -s /etc/init.d/firewall.sh /etc/rc2.d/S95firewall
If you added the commands to the proxy script to call the pon dialer you may want to add them to the firewall script also.



Where to learn more - The best of our bookshelves:

Linux Firewalls
More info...
    Linux Firewalls is extensive in its coverage of, not only firewalls, but other aspects of security as well. The book is crammed with examples of IPCHAINS chains for different firewall types and security scenarios including DMZs. The book starts out with a good explanation of the basics of TCP/IP, packets, and firewalls in general. As a result, when you do get into the later chapters you'll not only find out how to do things, but you'll know why you're doing them as well. The book focuses on setting up Linux-system type firewalls which is appreciated. Those that cover firewalls in general tend to blur the lines between commercial products and their non-commercial counterparts. However, within this focus the book runs wide as well as deep. I doubt there's anything you'd need to know about firewall-based security that's not in this book. The book also covers IPTABLES so it provides a good opportunity to compare the syntaxes of the IPCHAINS and IPTABLES commands.



There's an additional IPCHAINS input rule that will make the fiewall even tighter. You'll only want to use this rule if you don't want to remotely access any machines behind the firewall and you don't want your firewall system to act as any kind of (Web, FTP, telnet, etc) server. We modify the above INPUT rules by adding in this additional rule in the position indicated:

#   INPUT RULES
#############################################################################
# Incoming, flush and set default policy of reject.
#
ipchains -F input
ipchains -P input REJECT
ipchains -A input -i $INTIF -s $INTLAN -d 0.0.0.0/0 -j ACCEPT
ipchains -A input -i $EXTIF -s $INTLAN -d 0.0.0.0/0 -l -j REJECT
ipchains -A input -i $EXTIF -s 0.0.0.0/0 -d $EXTIP/32 -p tcp ! -y -j ACCEPT
ipchains -A input -i $EXTIF -s 0.0.0.0/0 -d $EXTIP/32 -j ACCEPT
ipchains -A input -i lo -s 0.0.0.0/0 -d 0.0.0.0/0 -j ACCEPT


The ! -y restricts incoming (from the outside) traffic to "established" traffic. Established traffic is that which is a response or reply to a connection which was initiated from a system on the internal network. (Cisco routers use the established keyword in Access Control List commands to specify such traffic.) As a result, no outside system is allowed to set up a TCP connection with a system behind the firewall.

The -p tcp specifies the TCP protocol which is required with -y because UDP and ICMP are "connectionless" protocols.

If you don't want a firewall system doing anything but firewalling any open ports represent a potential hole in your firewall. You can check to see if any ports are actively listening for traffic using the command:

netstat -an | more

If you see any entries with the word LISTEN next to them you've got open ports. Typically you'll see them listed with an address like:

0.0.0.0:80

which would indicate that the server is listening on port 80 (HTTP for a Web server). There are a lot of Web pages out there that list what port numbers are used by which services. You'll want to shut down any services that have ports open on a firewall system. You'll likely have to do this by renaming some of the links (so they don't run) in whichever /etc/rcX.d directory matches your default runlevel and then rebooting.

Debian also has an option that helps prevent spoofing. Check your /etc/network/options file to make sure it has the line:

spoofprotect=yes

If it doesn't, edit the file to add it in. Removing any unnecessary applications (packages) is also a good idea. We get into this more on the Securing Servers page.

If you just want to keep punks off your home or SOHO network a single firewall system is fine. If you want to protect Internet servers you'll want to use a couple IPCHAINS firewall systems to set up a DMZ (covered below). However, if your critical intellectual-property or sensitive data is stored on servers on your internal network you'd better look for something more secure. You can do packet filtering with a Cisco router, yet companies will spend tens of thousands of dollars on a Cisco PIX firewall product because it offers greater protection. For Linux systems, you may want to check out the NetMax Firewall Suite or VPN Suite (www.netmax.com). Their products include the Linux software so it's not an application you would install on a Debian system. With NetMax, you remove all existing partitions to create a "bare" hard-drive and pop in the CD to install everything.


Your Own Rules Top of page

Don't get the impression that packet filters aren't useful. As a matter of fact, you can do some neat things with them. You can accept or deny traffic based on the IP address of the target servers (like streaming audio sites) or the workstations making the request, on the type of application by using port numbers, or a combination of the two (i.e. only allow this or that workstation to ftp files from one certain site).

Learning IPCHAINS is a good investment because the commands are very similar to IPTABLES. IPTABLES is the equivalent of IPCHAINS in the Linux 2.4.x kernel. Note that you can compile the 2.4.x kernel to support IPCHAINS but it won't be able simultaneously support IPTABLES also. Compiling a 2.4.x kernel to support IPCHAINS instead of IPTABLES is only recommended if you have a large collection of IPCHAINS shell scripts that you don't want to have to convert to IPTABLES. However, because of the similarity in command syntax between IPCHAINS and IPTABLES, converting an IPCHAINS script to IPTABLES wouldn't take long and would be worth your time because IPTABLES offers additional features such as stateful packet inspection.
The above IPCHAINS commands may look cryptic, but they're really not all that bad once you get the hang of them.



It's important to remember that the order of the rules within each type (incoming, outgoing, or forwarding) are important. That's because once a packet is found to match a rule, no other rules are checked. If a packet doesn't match any rules, the default policy is applied to it. This orderly sequence of rules is the "chain", which is where the IPCHAINS name comes from.

The following guidelines are useful for any firewall:


Now that you're an IPCHAINS expert, lets add a rule to the above script. Remember that we want to use an input rule whenever possible so that's the group we'll work with. Lets say we want to block all access to www.napster.com so employees don't eat up the network's bandwidth with MP3 downloads. If we ping www.napster.com we see the IP address is 64.124.41.39.

We want to use an input rule so think about this for a minute. We could use a rule for the external interface that blocks traffic from 64.124.41.39 (the source address). But why even let the request go out to www.napster.com in the first place? It would be better to set up an input rule on the internal interface that would block traffic going to 64.124.41.29 (the destination address). So our new rule would look like this:

#   INPUT RULES
#############################################################################
# Incoming, flush and set default policy of reject.
#
ipchains -F input
ipchains -P input REJECT
ipchains -A input -i $INTIF -s $INTLAN -d 64.124.41.39 -j REJECT
ipchains -A input -i $INTIF -s $INTLAN -d 0.0.0.0/0 -j ACCEPT
ipchains -A input -i $EXTIF -s $INTLAN -d 0.0.0.0/0 -l -j REJECT
ipchains -A input -i $EXTIF -s 0.0.0.0/0 -d $EXTIP/32 -j ACCEPT
ipchains -A input -i lo -s 0.0.0.0/0 -d 0.0.0.0/0 -j ACCEPT

Easy! This rule basically says "reject any packets coming into the internal NIC from the internal network with a destination address of 64.124.41.39".

We placed the command where we did because it only applies to one specific destination. Granted this is a simple example, but it gives you a basic understanding of how the IPCHAINS command works. The IPCHAINS command has a lot more switches and options if you want to investigate it further. And if your network is growing to the point where you may need to use routers in the future, becoming knowledgable in the use of IPCHAINS commands could save you a lot of money. We'll see how you can use IPCHAINS to set up a Linux system to act as a router in a bit.

Lets look at an example of a single-protocol rule. If we wanted to allow those on the internal network to only surf the Web (no ftp, telnet, etc.) we wouldn't necessarily have to add a new rule. We could just modify one of the rules in the input group:

#   INPUT RULES
#############################################################################
# Incoming, flush and set default policy of reject.
#
ipchains -F input
ipchains -P input REJECT
ipchains -A input -i $INTIF -s $INTLAN -d 0.0.0.0/0 -p tcp --destination-port 80 -j ACCEPT
ipchains -A input -i $EXTIF -s $INTLAN -d 0.0.0.0/0 -l -j REJECT
ipchains -A input -i $EXTIF -s 0.0.0.0/0 -d $EXTIP/32 -j ACCEPT
ipchains -A input -i lo -s 0.0.0.0/0 -d 0.0.0.0/0 -j ACCEPT

This rules says "accept only those packets coming into the internal NIC from the internal LAN that are going to a Web site" (TCP protocol port 80 is the http protocol). Even though it only applies to a single protocol note that it has an accept action. Only accepting one protocol for the entire internal network makes it a very restrictive rule. If we had other input rules for the internal interface (which we don't) we'd have to not how restrictive this rule is and position it accordingly.

If you want to set up a firewalling proxy server that can also serve up Web pages you just add a similar line to the above to let port 80 traffic into the external interface:

#   INPUT RULES
#############################################################################
# Incoming, flush and set default policy of reject.
#
ipchains -F input
ipchains -P input REJECT
ipchains -A input -i $INTIF -s $INTLAN -d 0.0.0.0/0 -p tcp --destination-port 80 -j ACCEPT
ipchains -A input -i $EXTIF -s 0.0.0.0/0 -d $EXTIP/32 -p tcp --destination-port 80 -j ACCEPT
ipchains -A input -i $EXTIF -s $INTLAN -d 0.0.0.0/0 -l -j REJECT
ipchains -A input -i $EXTIF -s 0.0.0.0/0 -d $EXTIP/32 -j ACCEPT
ipchains -A input -i lo -s 0.0.0.0/0 -d 0.0.0.0/0 -j ACCEPT

Note that it's not advisable to have a serious firewall system also serve up Web pages. Due to it's critical role in the security policy of an organization, a firewall should be one thing and one thing only, a firewall. This is less of an issue for most home networks since home systems typically aren't powered up 24/7 and the external IP address (assigned by your ISP) isn't static.

If you want to get an overall view of your firewall, once you run the firewall script, use the command:

ipchains -L

The L stands for List. It gives a comprehensive listing of your rules which is easier to understand than simply looking at the rules themselves.


Setting Up A DMZ Top of page

A DMZ allows you place systems that you want the public to access in an "isolation network" between two firewall systems or routers. Recall the DMZ diagram from the Networking page.

Use PAT on a Linux Firewall DMZ

The outside firewall is set up to do the proxy/NAT stuff for your internal network, but it also offers two more benefits:


This functionality is called PAT (Port Address Translation). It allows you to specify that any HTTP traffic (port 80) coming into the outside firewall from the Internet be directed to a specific system (Web server) in the DMZ. Any incoming SMTP traffic (port 25) can be directed to a different (mail server) system. The same for FTP (ports 20 and 21), etc.

Why not run all those services on just one box? Any number of reasons. Load balancing, better security (only one service needs to be configured per system), finer control over who accesses what from your internal LAN, or you may already have a mail server but you'd like to add other servers along with implementing a DMZ.

The Outside Firewall

Let's expand the DMZ diagram a bit and see how we would set up the addresses, etc. As you can see, the DMZ is simply set up as a small private network with two gateways.

Addressing in a DMZ

So how do you accomplish PAT using IPCHAINS? You have to use a slightly different command, the ipmasqadm command. In the above diagram, the following lines would be added to the end of the firewall.sh script on the outside firewall Linux system:

echo "       Enabling PAT translations..."
ipmasqadm autofw -A -r tcp 80 80 -h 192.168.1.6

The two '80's just indicate the port number for HTTP traffic (coming into the firewall from the outside and sent out of the firewall to the target system in the DMZ). In most normal circumstances these two port numbers will always be the same. The -h specifies the IP address of the DMZ system you want the traffic forwarded on to. So for the mail server it would be:

ipmasqadm autofw -A -r tcp 25 25 -h 192.168.1.8

You can use PAT in this manner if you also have Citrix or VPN boxes set up in your DMZ for remote access by employees. That way they can just point their remote client to your domain name (providing it resolves to the public IP address on the external interface of the outside firewall) and you can have the outside firewall forward the traffic onto the appropriate box based on the port number in the incoming packets.

QUIZ!  You'll also need to add a static route to your outside firewall. Looking at the above diagram can you think of what it would be needed for? And if you know, what would the correct route command be? When you think you've got the answers, drag your mouse over the blank area below to see if you're right:

You need a static route which points traffic destined for the "Internal Network" to the external interface of the inside firewall. For the above diagram it would be:
route add -net 172.16.0.0 netmask 255.255.0.0 gw 192.168.1.2
Note that if you have problems accessing an FTP server that you have set up in the DMZ, make sure your FTP client or browser is set to use PASSIVE FTP. In IE6 there's a "Use passive FTP" checkbox under Tools/Options/Advanced. With the WS_FTP client there's a checkbox under the Advanced tab of the "Session Properties" window.

The Inside Firewall

While the outside firewall is mainly for PAT and masquerading, the inside firewall is where you do most of your traffic restriction. You want to restrict outgoing traffic to only those services (port numbers) you want users on the internal network to have, i.e. Web (80), POP (110) to the mail server in the DMZ, FTP (20/21), etc.

Incoming traffic should be restricted to only "established" traffic using the:

ipchains -A input -i $EXTIF -s 0.0.0.0/0 -d $EXTIP/32 -p tcp ! -y -j ACCEPT

rule mentioned earlier. Remember that this is an INPUT rule for the external interface of the inside firewall system (the interface that connects to the DMZ). This is different than the INPUT rules for the internal interface (the interface that connects to the internal network) which you would use to restrict outgoing user traffic from the internal network (one rule for each allowed port):

ipchains -A input -i $INTIF -s $INTLAN -d 0.0.0.0/0 -p tcp --destination-port 80 -j ACCEPT

Also remember that there are no MASQ rules on this inside firewall system. All the NAT stuff is done on the outside firewall system.

Getting the right rules on the right boxes is a balancing act. It all depends how you want to filter things. You can put traffic restrictions on your outside firewall too (limiting incoming traffic to Web, mail, and FTP traffic for instance). However, you wouldn't want to put the above established-traffic rule on the external interface of your oustide firewall or no one (or no system) on the Internet could ever create a connection to your Web or mail or other DMZ-located systems.


Linux As A Router Top of page

Cisco's claim to fame is not that they have routers that will route TCP/IP. It's that they have routers that will simultaneously route TCP/IP, IPX/SPX (Novell), AppleTalk, and a few others. These are the protocols that computers use to transfer data between each other and these are the protocols that routers route. These are called routed protocols. Another big benefit of Cisco routers is that they will "talk" to one another using routing protocols. Routing protocols enable routers to update each others routing information so they can automatically adjust to changes in the network (when links go down for example). Using routing protocols to automatically adjust for network changes is known as "dynamic routing".

However, if your internal network isn't very complex and you're strictly using TCP/IP you don't need all the features that Cisco routers offer. You can set up a Linux system with two or three or even four network cards and set it up to be a router rather than spending $5,000 on a Cisco router. In cases where a network isn't complex, there's really no need to run any routing protocols. Any necessary changes made to the network's architecture are rare and can be compensated for by manually changing the routing information. When referring to Cisco routers, manually maintaining the routing information is done using "static routes".

Linux has a route command which lets you enter static routes also. However, no checking of the packets is done. Whatever comes in gets sent out. The benefit of using IPCHAINS commands on a per-interface basis to do your packet forwarding is that you can do rules-based routing.



Where to learn more - The best of our bookshelves:

Linux Routers
More info...
    The title of Linux Routers - A Primer for Network Administrators is misleading. It's way more than a "primer". It gives detailed listings of route and IPCHAINS commands for setting up LAN, Internet, extranet, and satellite office routers. While it doesn't focus on any one distrbution, luckily Debian is the author's distro of choice so the examples in the book are based on it. Not only does the book give details on setting up frame relay and ISDN routers, but the author gives vendor information on where to obtain frame relay and ISDN capable PCI and ISA cards. He also covers how to use LRP (the Linux Router Project software that allows you to fit everything on a floppy disk) and has a very detailed chapter on masquerading. (Note: you'll see IPFWADM mentioned throughout the book. This is simply the IPCHAINS of the 2.0 kernel.)



In the firewall script above notice that some of the IPCHAINS commands had a -i switch followed by an interface designation. The ability to apply rules to specific interfaces is the same thing that Cisco does with the IOS (Internetwork Operating System) software that runs on its routers. Packet filtering is a two step process with the Cisco IOS. You set up ACLs (Access Control Lists) and then apply them to the appropriate router interface(s).

If you set up a Linux box with three NICs their designations would be eth0, eth1, and eth2. Each interface (NIC) would be connected to a different subnet. You would then use IPCHAINS commands to allow forwarding or denying of traffic between the NICs (and their connected subnetworks). Yes, it would be quite a sophisticated script, but it would be easier to learn IPCHAINS and figure out what rules would be needed to accomplish your goals than it would be to learn the Cisco IOS. And once you did learn the Cisco IOS, and pay big bucks for a router, you'd still have to develop similarly-sophisticated ACLs.

For those that may be well-versed in routers, and would like to play around with Linux in a more complex routing environment, there is a server application known as gated that allows a Linux system to work with dynamic routing protocols like RIP and OSPF.


SECURITY WARNING

Do NOT plan to use the system you will create using these guide pages as a "production" (real) server. It will NOT be secure!

There are many steps involved in creating a secure Internet or LAN server. While we do refer to some things you can do to make your system more secure, there are many other measures related to system security that also need to be taken into consideration and they are not covered on these pages.

These guide pages are meant as a learning tool only. The knowledge gained on these pages will help you understand the material covered in security-related publications when you are ready to consider setting up a production server.




Did you find this page helpful ?
If so, please help keep this site operating
by using our DVD or book pages.



Site, content, documents, original images   Copyright © 2003-2016   Keith Parkansky   All rights reserved
Duplication of any portion of this site or the material contained herein without
the express written consent of Keith Parkansky, USA is strictly prohibited.

This site is in no way affiliated with the Debian Project, the debian.org Web site, or
Software In The Public Interest, Inc. No endorsement of this site by the Debian Project
or Software In the Public Interest is expressed or implied. Debian and the Debian logo
are registered trademarks of Software In The Public Interest, Inc. Linux is a registered
trademark of Linus Torvalds. The Tux penguin graphic is the creation of Larry Ewing.

LIABILITY

IN NO EVENT WILL KEITH PARKANSKY OR BLUEHOST INCORPORATED OR ANY OF ITS' SUBSIDIARIES BE LIABLE TO ANY PARTY (i) FOR ANY DIRECT, INDIRECT, SPECIAL, PUNITIVE OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF PROGRAMS OR INFORMATION, AND THE LIKE), OR ANY OTHER DAMAGES ARISING IN ANY WAY OUT OF THE AVAILABILITY, USE, RELIANCE ON, OR INABILITY TO USE THE INFORMATION, METHODS, HTML OR COMPUTER CODE, OR "KNOWLEDGE" PROVIDED ON OR THROUGH THIS WEBSITE, COMMONLY REFERRED TO AS THE "ABOUT DEBIAN" WEBSITE, OR ANY OF ITS' ASSOCIATED DOCUMENTS, DIAGRAMS, IMAGES, REPRODUCTIONS, COMPUTER EXECUTED CODE, OR ELECTRONICALLY STORED OR TRANSMITTED FILES OR GENERATED COMMUNICATIONS OR DATA EVEN IF KEITH PARKANSKY OR BLUEHOST INCORPORATED OR ANY OF ITS' SUBSIDIARIES SHALL HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, AND REGARDLESS OF THE FORM OF ACTION, WHETHER IN CONTRACT, TORT, OR OTHERWISE; OR (ii) FOR ANY CLAIM ATTRIBUTABLE TO ERRORS, OMISSIONS, OR OTHER INACCURACIES IN, OR DESTRUCTIVE PROPERTIES OF ANY INFORMATION, METHODS, HTML OR COMPUTER CODE, OR "KNOWLEDGE" PROVIDED ON OR THROUGH THIS WEBSITE, COMMONLY REFERRED TO AS THE "ABOUT DEBIAN" WEBSITE, OR ANY OF ITS' ASSOCIATED DOCUMENTS, DIAGRAMS, IMAGES, REPRODUCTIONS, COMPUTER EXECUTED CODE, OR ELECTRONICALLY STORED, TRANSMITTED, OR GENERATED FILES, COMMUNICATIONS, OR DATA. ALL INFORMATION, METHODS, HTML OR COMPUTER CODE IS PROVIDED STRICTLY "AS IS" WITH NO GUARANTY OF ACCURACY AND/OR COMPLETENESS. USE OF THIS SITE CONSTITUTES ACCEPTANCE OF ALL STATED TERMS AND CONDITIONS.