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="" INT_WIRED="
eth0
" INT_WIRELESS="
eth1
" INT_ALL="$INT_GW $INT_WIRED $INT_WIRELESS lo"
eth2
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="" IP_WIRED="
192.0.2.230
" IP_WIRELESS="
192.168.1.0/24
" IP_GW_WIRED="
192.168.0.0/24
" IP_GW_WIRELESS="
192.168.1.1
"xxxxxxx
192.168.0.1
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.
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.
18.218.55.14