Configuring a Simple Firewall
In this section, we start with a deny-all firewall for two cases: a simple network where no
servers are configured and the same network, but with some servers configured. In the
first case, we assume a simple network with two sides: inside on the 10.1.1.0/24 network
(eth1) and the Internet (eth0). Note that by “server,” we mean anything that needs a con-
nection made to it. This could, for example, mean a Linux system running an ssh daemon
or a Windows system running a web server.
Let’s start with the case where there are no servers to support.
First we need to make sure that the NAT module is loaded and that FTP support for
NAT is loaded. We do that with the modprobe commands:
[root@serverA ~]# modprobe iptable_nat
[root@serverA ~]# modprobe ip_nat_ftp
With the necessary modules loaded, we define the default policies for all the chains. For
the INPUT, FORWARD, and OUTPUT chains in the filter table, we set the destination to
be DROP, DROP, and ACCEPT, respectively. For the POSTROUTING and PRE ROUTING
chains, we set their default policies to ACCEPT. This is necessary for NAT to work.
[root@serverA ~]# iptables -P INPUT DROP
[root@serverA ~]# iptables -P FORWARD DROP
[root@serverA ~]# iptables -P OUTPUT ACCEPT
[root@serverA ~]# iptables -t nat -P POSTROUTING ACCEPT
[root@serverA ~]# iptables -t nat -P PREROUTING ACCEPT
With the default policies in place, we need to define the baseline firewall rule. What
we want to accomplish is simple: Let users on the inside network (eth1) make connec-
tions to the Internet, but don’t let the Internet make connections back. To accomplish this,
we define a new chain called “block” that we use for grouping our state-tracking rules
together. The first rule in that chain simply states that any packet that is part of an estab-
lished connection or that is related to an established connection is allowed through. The
second rule states that in order for a packet to create a new connection, it cannot origi-
nate from the eth0 (Internet-facing) interface. If a packet does not match against either of
these two rules, the final rule forces the packet to be dropped.
[root@serverA ~]# iptables -N block
[root@serverA ~]# iptables -A block -m state --state ESTABLISHED,RELATED -j ACCEPT
[root@serverA ~]# iptables -A block -m state --state NEW -i ! eth0 -j ACCEPT
[root@serverA ~]# iptables -A block -j DROP
With the blocking chain in place, we need to call on it from the INPUT and FORWARD
chains. We aren’t worried about the OUTPUT chain, since only packets originating from
the firewall itself come from there. The INPUT and FORWARD chains, on the other hand,
need to be checked. Recall that when doing NAT, the INPUT chain will not be hit, so we
need to have FORWARD do the check. If a packet is destined to the firewall itself, we
need the checks done from the INPUT chain.
[root@serverA ~]# iptables -A INPUT -j block
[root@serverA ~]# iptables -A FORWARD -j block
Finally, as the packet leaves the system, we perform the MASQUERADE function
from the POSTROUTING chain in the NAT table. All packets that leave from the eth0
interface go through this chain.
[root@serverA ~]# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
With all the packet checks and manipulation behind us, we enable IP forwarding (a
must for NAT to work) and SYN cookie protection, plus we enable the switch that keeps
the firewall from processing ICMP broadcast packets (Smurf attacks).
[root@serverA ~]# echo 1 > /proc/sys/net/ipv4/ip_forward
[root@serverA ~]# echo 1 > /proc/sys/net/ipv4/tcp_syncookies
[root@serverA ~]# echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
At this point, you have a working firewall for a simple environment. If you don’t run
any servers, you can save this configuration and consider yourself done. On the other
hand, let’s assume you have two applications that you want to make work through this
firewall: a Linux system on the inside network that you need ssh access to from remote
locations and a Windows system from which you want to run BitTorrent. Let’s start with
the ssh case first.
To make a port available through the firewall, we need to define a rule that says, “If
any packet on the eth0 (Internet-facing) interface is TCP and has a destination port of 22,
change its destination IP address to 172.16.1.3.” This is accomplished by using the DNAT
action on the PREROUTING chain, since we want to change the IP address of the packet
before any of the other chains see it.
The second problem we need to solve is how to insert a rule on the FORWARD
chain that allows any packet whose destination IP address is 172.16.1.3 and destination
port is 22 to be allowed. The key word is insert (-I). If we append the rule (-A) to the
FORWARD chain, the packet will instead be directed through the block chain, because
the rule “iptables -A FORWARD -j block” will apply first.
[root@serverA ~]# iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 22 -j DNAT\
--to-destination 172.16.1.3
[root@serverA ~]# iptables -I FORWARD -p tcp -d 172.16.1.3 --dport 22 -j ACCEPT
We can apply a similar idea to make BitTorrent work. Let’s assume that the Windows
machine that is going to use BitTorrent is 172.16.1.2. The BitTorrent protocol uses ports
6881–6889 for connections that come back to the client. Thus, we use a port range setting
in the iptables command.
[root@serverA ~]# iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 6881:6889 -j
DNAT --to-destination 172.16.1.2
[root@serverA ~]# iptables -I FORWARD -p tcp -d 172.16.1.2 --dport 6881:6889 -j
ACCEPT
Ta da! You now have a working firewall and support for an ssh server and a BitTorrent
user on the inside of your network.
Tuesday, September 15, 2009
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment