IPTABLES explained: Part 3 (Creating a complex IPTables script)
SCENARIO: A friend of mine had a problem, he has a home network similar to mine and a Wireless Access Point (AP) that he wanted to use since mobility is everything. We sat down and designed his network and then wrote an iptables script for his setup. What follows is a more or less picture so you get the idea what the system looked like:
Now, the explanation. The AP is WEP capable only and WEP is good but not good enough for us security people (or anyone else really), so we decided to go this route: the server will have 2 NICs, one hooked up to the normal network and one going to the AP. The network on the AP is completely open, there is no WEP on the AP. This allows any mobile client to connect and get an IP in the mobile network. On the server we installed and configured OpenVPN (took about 3.492 minutes to install :)) and made it listen to a non standard port on the wireless network interface. We created a 3rd network within OpenVPN and modified it to route. Routing! I hear you scream, yes that is 3!! IP networks to access one. But here is the reason: routing, meaning different networks, allow you to VERY easily modify your IPTables scripts and restrict access. We then copied the OpenVPN server config file and named it differently, changed the virtual IP range and what interface to listen on. After a service restart we had OpenVPN now listening on both NICs. It might look like overkill but any person to try and crack your WLAN and use your internet access will go away because they will not succeed. And if you now forward port 9000 on your router to the MAIN interface IP port 9000 you can have a VPN connection from anywhere in the world to your home , securely! (use a DYNDNS service if you have a dynamic IP)
Anyway, back to our scenario. The Server has IP forwarding enabled this is the reason why the wireless network interface needs to be locked down. Once you have decided your networks please make sure you add the appropriate routes to our main router so all machines can find each other.
The 3 networks we are using here are :
- 192.168.0.0/24 for our MAIN network on eth
- 192.168.1.0/24 for our WLAN on eth1
- 192.168.2.0/24 for our OpenVPN WLAN network on tun0
- 192.168.3.0/24 for our OpenVPN PUBLIC network on tun1
SCRIPT:Now that you have an idea of what we are trying to do, lets start writing the script that will do the following:
- block all access from the WLAN to the internal network except port 9000 TCP for OpenVPN and ssh
- allow all traffic from the MAIN network to the server
- allow traffic from ?anywhere? to the MAIN server interface port 9000 OpenVPN
- allow traffic from the OpenVPN network to the server and main network
- allow all localhost traffic
- use statefullness wherever possible
Looks difficult? Well it really isn’t. We start as usual with the beginning:
#!/bin/sh
IPT=”/sbin/iptables”
#GLOBAL VARIABLES
good=?192.168.0.0/24,192.168.2.0/24,192.168.3.0/24?
bad=?192.168.1.0/24?
any=?0.0.0.0/0?
#Flush old rules, delete the firewall chain if it exists
echo “-> FLUSHING ALL TABLES”
$IPT -F
$IPT -X
#CONSTRUCT THE DEFAULT POLICY - DROP EVERYTHING
echo “-> SETTING POLICIES”
$IPT -P INPUT DROP
$IPT -P OUTPUT DROP
$IPT -P FORWARD DROP$IPT -N local
$IPT -N state
$IPT -N lan
$IPT -N vpn
$IPT -N drop
#ENABLE IP_FORWARDING
echo “-> ENABLING IP FORWARDING”
echo 1 > /proc/sys/net/ipv4/ip_forward
…and most of these things you already know. The -N parts define the new chains we create already so we can add rules to them later on. As the script is a normal shell script we can add normal shell commands there as well as you see at the bottom to enable ip forwarding.
First we want to make the state traffic ready. This way when traffic comes in it wont have to traverse all rules until it hits the state chains if it is a statefull connection already.
#Check for statefullness
echo “-> CHECKING STATE TRAFFIC”
$IPT -A state -p tcp,udp -m state –state ESTABLISHED,RELATED -j ACCEPT
$IPT -A INPUT -p tcp,udp -j state
$IPT -A OUTPUT -p tcp,udp -j state
$IPT -A FORWARD -p tcp,udp -j state
Then, for our first real rule we start by adding the localhost traffic as allow and then pointing to the local tale from INPUT, and OUTPUT as FORWARD is not needed since we are not forwarding traffic through localhost.
No Tags#ACCEPT LOOPBACK
echo “-> ACCEPTING LOCALHOST TRAFFIC”
$IPT -A local -s 127.0.0.1/8 -d 127.0.0.1/8 -j ACCEPT
$IPT -A local -s 127.0.0.1/8 -d 0.0.0.0/0 -j ACCEPT
$IPT -A local -j drop
$IPT -A INPUT -s 127.0.0.1/32 -j local
$IPT -A OUTPUT -s 127.0.0.1/32 -j local
Popularity: 9% [?]
Pages: 1 2
Where *nix and security meet the general public


[…] IMPORTANT: This tutorial is oriented for Fedora, but shouldn’t be hard to adapt to Debian/Ubuntu. If someone knows the startup scripts well, mail me or please leave a comment with the changes needed. Ok, as we saw in the previous chapters of this tutorial series, iptables is an amazingly flexible and powerful tool. By now you should have a good grasp of what iptables can do. It is time to bring in the sidekick: Portsentry. Due to the fact that portsentry has no pre-built packages (to my knowledge) for any distributions, you will have to download it from here:[Sourceforge] ; and build it. The process is very easy BUT (yes there is always a but) it requires you to edit one file. More on that a bit down the road. First, what does Portsentry do? Well, you see Portsentry is a nifty little program that listens on your Linux (or any Unix, but for now Linux) box on a set of defined (by you) ports. That way, when someone port scans you to find open ports, say for example ssh or web or any other open port that they could attack, Portsentry will notice this and take an appropriate action (also defined by you!). […]
[…] IPTABLES explained: Part 3 (Creating a complex IPTables script) EMail this post to a friend […]
Hello again,
Just finished reading this part. I like your easy writing style, it definitely makes iptables much clearer.
Can you give me some more information about your friend’s openvpn and wireless setup? I’ve got a similar situation that i’d like to use this setup.
Thanks.
Dave.
hey dave, i sure can, you can mail me directly at flosse@2blocksaway.com cheers..