Building the Firewall Rules

The most important responsibility of the gateway is to firewall our three separate network segments. We will again use the Netfilter functionality that was introduced in Section 5.3.1. See that section for a basic introduction to the functioning of Netfilter.

The rc.firewall script for the gateway is significantly more complex that the one laid out for use on the clients. It has to protect not only the gateway itself, but also ensure separation between the networks while allowing vital services on the gateway to be accessed by local users. This script is also much more aggressive in preventing abusive behavior since it will be the frontline against often hazardous Internet traffic.

This script is quite long; we will examine it section by section. To build the completed script, concatenate each of the example sections that follow into /etc/init.d/rc.firewall.

First, we establish several variables that will be used throughout the rest of the script. By placing these values into variables, we can easily update the script if these values change in the future. Here we define the three network interfaces that will be used for the upstream, wired, and wireless connections, respectively. Change these to match the configuration of your machine.

#!/bin/sh
# rc.firewall for gateway

# --- SETUP ---

# Variables (for easier changes)
IPTABLES=/sbin/iptables

INT_GW="eth0"
INT_WIRED="eth1"
INT_WIRELESS="eth2"
INT_ALL="$INT_GW $INT_WIRED $INT_WIRELESS lo"

The IP_ variables hold the IP addresses or ranges that will be used in the firewall rules. IP_GW is the address of the upstream connection interface. If your ISP assigns addresses using DHCP instead of static IP addresses, use the commented-out example, which will extract the DHCP-assigned address from ifconfig. (Note the command is enclosed in backticks, not quotes.) IP_WIRED holds the address range for our internal wired network, and IP_WIRELESS holds the address range for the internal wireless network. IP_GW_WIRED and IP_GW_WIRELESS hold the respective IP addresses for the network interfaces on the gateway that are connected to those networks. Change these to match the configuration of your networks and your ISP’s network.

# For DHCP use: IP_GW=`/sbin/ifconfig $INT_GW | grep inet | cut -f2 -d: | cut -f1 -d `
IP_GW="192.0.2.230"
IP_WIRED="192.168.1.0/24"
IP_WIRELESS="192.168.0.0/24"
IP_GW_WIRED="192.168.1.1"
IP_GW_WIRELESS="192.168.0.1"xxxxxxx

The next section in the script sets a number of values in the /proc file system. These settings should help to reduce certain types of malicious behavior directed at the network and the gateway. The comments in this snippet of the script provide a brief description of what each setting does.

# /proc variables

# Ignore broadcast pings
echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
# Ignore bogus ICMP errors
echo "1" > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
# Limit the reply rate to pings
echo "100" > /proc/sys/net/ipv4/icmp_echoreply_rate
# Use TCP SYN cookies
echo "1" > /proc/sys/net/ipv4/tcp_syncookies

# Do the following for each interface being used
for INT in $INT_ALL; do
    # Disable acceptance of redirects
    echo "0" > /proc/sys/net/ipv4/conf/$INT/accept_redirects
    # Disable source routing
    echo "0" > /proc/sys/net/ipv4/conf/$INT/accept_source_route
    # Enable routing verification to prevent spoofing of invalid IPs
    echo "1" > /proc/sys/net/ipv4/conf/$INT/rp_filter
    # Disable bootp relaying
    echo "0" > /proc/sys/net/ipv4/conf/$INT/bootp_relay
done

At this point, calls to iptables begin to set up the firewall ruleset. First, all of the existing rules are flushed. Then a default policy is set up which will drop all traffic sent to the gateway and forward it to other networks. Traffic from the gateway will be allowed by default.

# --- BEGIN IPTABLES SETTINGS ---

# Flush all chains to get a clean start
$IPTABLES -F
$IPTABLES -X
$IPTABLES -t nat -F

# Set default policies
$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT ACCEPT
$IPTABLES -P FORWARD DROP

An exception is then made to allow the gateway to communicate unrestricted over the local loopback interface.

# Allow local loopback traffic
$IPTABLES -A INPUT -i lo -j ACCEPT
$IPTABLES -A OUTPUT -o lo -j ACCEPT

These two commands establish chains of rules called allowed_icmp, to_gateway, and forward_checks. These chains will be used to consolidate sets of rules that will be used in multiple places.

# Create chains for common series of rules
$IPTABLES -N allowed_icmp
$IPTABLES -N to_gateway
$IPTABLES -N forward_checks

The next large block of the script will establish the rules to filter traffic being forwarded between any of the three interfaces in the gateway. This traffic will have to pass the rules defined for the FORWARD chain.

# --- FORWARDING ---
$IPTABLES -A FORWARD -j forward_checks
# Drop everything else.  This includes traffic between wired and wireless networks!
$IPTABLES -A FORWARD -j LOG
$IPTABLES -A FORWARD -j DROP

We tell the actual FORWARD chain to use the forward_checks chain that follows. To finish the FORWORD rules off, we log and drop any packets that were not accepted by one of the preceding forwarding rules.

# Allow established connections to come from Internet to wired and wireless networks
$IPTABLES -A forward_checks -m state --state ESTABLISHED,RELATED -j ACCEPT

This rule uses the state tracking abilities of Netfilter to allow any packets that are part of an existing and already approved connection to be forwarded.

# Allow wired and wireless networks to establish new connections
#  Check for proper source addresses for each source interface
$IPTABLES -A forward_checks -m state --state NEW -s $IP_WIRED -i $INT_WIRED -o $INT_
GW -j ACCEPT
$IPTABLES -A forward_checks -m state --state NEW -s $IP_WIRELESS -i $INT_WIRELESS -o 
$INT_GW -j ACCEPT

Using the state tracking facilities again, these two rules allow new connections to be started. Note the rules use -s to check the source IP addresses, -i to check the source interface, and -o to check the destination interface. This will ensure that clients on the wired and wireless networks can only create connections if they are using an IP address in the proper range for that network. Because -o specifies $INT_GW in both rules, connections can only be created to destinations that will routed through the upstream interface. These two rules will not allow connections to be created that connect between the wired and wireless networks.

# Allow certain ICMP packets
$IPTABLES -A forward_checks -p icmp -j allowed_icmp

This rule uses the allowed_icmp chain to examine any ICMP packets that are being forwarded. The rules for this chain are defined later in the script.

# Reject ident requests
$IPTABLES -A forward_checks -p tcp --dport 113 -j REJECT

Some daemons, namely sendmail, will query ident on hosts that attempt to use their service. By rejecting these requests rather than dropping them silently, the daemons will not have to wait for the ident query to timeout. This speeds up connections to these daemons, such as sending mail.

Another set of rules has to be constructed to filter the traffic destined for the gateway itself. The INPUT chain holds the rules that filter this traffic.

# -- CONNECTIONS TO/FROM THE GATEWAY ---

# Examine traffic from all three interfaces to gateway using same chain of rules
$IPTABLES -A INPUT -d $IP_GW -j to_gateway
$IPTABLES -A INPUT -d $IP_WIRED -j to_gateway
$IPTABLES -A INPUT -d $IP_WIRELESS -j to_gateway
$IPTABLES -A INPUT -j LOG
$IPTABLES -A INPUT -j DROP

Since there are three interfaces on the gateway, and we want to apply similar rules to all three interfaces, traffic destined for the three interfaces is all sent to the to_gateway chain. Any other traffic that happens to somehow end up in the INPUT chain is logged and dropped.

The to_gateway chain will prevent improper connections to the gateway itself and open up access to the services that we want to provide from the gateway.

# Allow all established traffic
$IPTABLES -A to_gateway -i $INT_GW -d $IP_GW -m state --state ESTABLISHED,RELATED -j 
ACCEPT
$IPTABLES -A to_gateway -i $INT_WIRED -d $IP_GW_WIRED -m state --state 
ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A to_gateway -i $INT_WIRELESS -d $IP_GW_WIRELESS -m state --state 
ESTABLISHED,RELATED -j ACCEPT

These three rules accept traffic from established connections on the three interfaces. The checking of the input interface in the three rules is to ensure that clients can only communicate with the correct one of the gateway IPs for the segment of the network on which they are located.

# Allow ssh from anywhere to all the gateway IP addresses
$IPTABLES -A to_gateway -p tcp -i $INT_GW -d $IP_GW --dport 22 -j ACCEPT
$IPTABLES -A to_gateway -p tcp -i $INT_GW_WIRED -d $IP_GW_WIRED --dport 22 -j ACCEPT
$IPTABLES -A to_gateway -p tcp -i $INT_GW_WIRELESS -d $IP_GW_WIRELESS --dport 22 -j 
ACCEPT

To provide access to the SSH server on the gateway, we allow clients on any of the three interfaces to connect to port 22 on the proper gateway IP address.

# Allow DHCP connections from wired and wireless networks
$IPTABLES -A to_gateway -p udp -i $INT_WIRED --dport 68 -j ACCEPT
$IPTABLES -A to_gateway -p udp -i $INT_WIRELESS --dport 68 -j ACCEPT

DHCP connections are sent to port 68 of 255.255.255.255. Because of this, we don’t want to filter on the destination IP. They originate from 0.0.0.0, since the client doesn’t have an address yet so we don’t want to filter on the source address either. These two rules just check that the DHCP request came from either the wired or wireless network; we definitely don’t want to answer DHCP requests on the ISP’s network.

# Allow wired and wireless networks to connect to DNS
$IPTABLES -A to_gateway -p udp -i $INT_WIRED -s $IP_WIRED -d $IP_GW_WIRED --dport 53 
-j ACCEPT
$IPTABLES -A to_gateway -p udp -i $INT_WIRELESS -s $IP_WIRELESS -d $IP_GW_WIRELESS --
dport 53 -j ACCEPT

These rules are only necessary if you want to run a local DNS server. Our DNS server is only going to act as a cache for the local clients and will serve them on UDP port 53. It only needs to accept connections from the local networks, so we perform the standard checks for appropriate source interface, source IP address, and destination IP address.

# Filter inbound ICMP
$IPTABLES -A to_gateway -p icmp -j allowed_icmp

Just like the in the FORWARD chain, ICMP packets will be filtered using the allowed_icmp chain.

# Reject ident requests
$IPTABLES -A to_gateway -p tcp --dport 113 -j REJECT

Again, like the FORWARD chain, this will speed up sendmail connections.

# Drop everything else
$IPTABLES -A to_gateway -j LOG
$IPTABLES -A to_gateway -j DROP

Anything that hasn’t been accepted by the to_gateway rules should be logged and dropped.

# Let the gateway connect to anywhere
$IPTABLES -A OUTPUT -j ACCEPT

The OUTPUT chain will simply allow the gateway to connect to anything it wants. You can definitely make this more restrictive if you want to limit where the gateway can connect to.

# --- COMMON ICMP RULE CHAIN ---

# Allow certain ICMP messages
$IPTABLES -A allowed_icmp -p icmp --icmp-type pong -j ACCEPT
$IPTABLES -A allowed_icmp -p icmp --icmp-type source-quench -j ACCEPT
$IPTABLES -A allowed_icmp -p icmp --icmp-type time-exceeded -j ACCEPT
$IPTABLES -A allowed_icmp -p icmp --icmp-type destination-unreachable -j ACCEPT
$IPTABLES -A allowed_icmp -p icmp --icmp-type parameter-problem -j ACCEPT

This defines the rules for the allowed_icmp chain that is used by both FORWARD and INPUT. It allows management packets such as answers to pings, source quench, time exceeded, destination unreachable, and parameter problem messages. Blocking these particular ICMP messages can cause excessive waits for time outs on the clients when something goes wrong with a connection. Most of the other ICMP messages are unneeded normally; some, like redirects, can be downright dangerous.

# --- NAT ---

# Perform NAT masquerading for traffic bound to Internet
# For DHCP use: $IPTABLES -t nat -A POSTROUTING -o $INT_GW -j MASQUERADE
$IPTABLES -t nat -A POSTROUTING -o $INT_GW -j SNAT --to $IP_GW

This rule provides source network address translation for all traffic heading out of the gateway upstream interface. It uses a special chain called POSTROUTING that processes the packets after the FORWARD and OUTPUT chains. All the packets from the gateway and both internal networks will be mapped to the gateways external address before being sent. If the external address of the gateway is set by DHCP, you should use the alternate NAT rule in the comment instead. The MASQUERADE-style NAT handles changes in IP addresses more gracefully and resets its state tables to prevent the packet mangling that can occur if the address changes while connections are active.

# -- TURN ON FORWARDING ---

# Enable IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward

The script concludes with one last setting to a /proc file, which will enable the routing of IP packets between the interfaces in the gateway.

That’s it! Place the completed script in /etc/init.d/rc.firewall, mark it as executable using chmod, and call it from the rc.local file. It will then be called when the system starts up.

Tip

If you find after a while that all the spurious traffic with spoofed source IP addresses is filling up your logs, consider removing the log command from some of the rules in this ruleset.

There are several good references on building Netfilter rulesets at http://www.netfilter.org and http://www.linuxsecurity.com/resources/firewalls-1.html. There are also many people who have posted example firewall scripts on web sites for people to look at; search around and look at them for alternate ways to build your rulesets, and additional protections to set up.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.58.82.79