My Linksys WRT54G is on its last leg. I put DDWRT on it which was a fun project and opened up a lot of possibilities. But lately, it keeps going stupid and requires a cold reboot. On reboot it forgets the last changes. It wont hold many nat entries, the iptables isn’t as powerful, and well.. maybe I’ve out grown it! I think it just doesn’t have the physical power to do what I want it to do. Ebay has this deal on a Dell server. The hardware was perfect for a network router. And I was looking for a fun project. I’m interested in products like Deep9s, Untangle and Zentya that are considered Unified Threat Management systems. But I want something more flexible and something that I can be more in control of. And I’ll either need to demote my WRT54G to just an access point, or replace it completely. In that event I’d need something that can take a wireless card.
System Specs
My System is probably a bit over kill. What you’ll need is a system that meets ubuntu server’s specs. And if you are going to run squid with some of the advanced filtering techniques, you will probably want at least 2 Gigs of RAM. You’ll need at least 2 NICs, one can be a wifi, but to make this project the most fun you’ll want at least 2 eth and one wlan. You only need a 100Mb eth card for your uplink to your ISP, but I’d put a 1Gb eth on the internal network interface. My Dell 1750 Server came with 2 eth on board and 2 eth on a PCI and I had a wlan G card from a previous project. My overkill stats include a Xeon Core 2 3Ghz with 4Gigs of RAM and a RAID 1 SCSI with 4Gigs of RAM. I’m running 32bit Ubuntu so I’m only seeing 3.69 Gigs.
Warned
This project isn’t for the linux newb or the networking newb. There will be several assumptions made about the skill level of the practitioner of this project.
Install the OS
There are enough tutorials out there to install the OS. Google one up if you need to. We don’t need the GUI or X so just install ubuntu server. I used 10.4 because it is LTS. When done installing go ahead and update.
sudo apt-get update && sudo apt-get upgrade –y && sudo apt-get autoremove –y
Here are a few of the handy tools we are going to need.
sudo apt-get install –y netperf nmap ntop apt-show-versions
Interfaces
The first thing you need to do is set up your interfaces. Now I’ve got 4 eths and a wlan. You may not have as many eths so modify the following interfaces file as you need for your router. Remember, we are assuming eth0 is the interface connected to the internet or wild network. I connect eth0 to the ISP cable modem and therefore I need eth0 to be dhcp. You probably will too.
Also, I’m setting up each interface as its own subnet. This is a router, not a bridge. If you want all of your interfaces on the same subnet you will need to set up a bridge. And that is not covered in this tutorial.
Warning: Always, make a backup of the original file. If anywhere anytime I or anyone else suggests you edit a file that already exists quickly back it up.
sudo mv /etc/network/interfaces /etc/network/interfaces.original
then
sudo nano /etc/network/interfaces
and paste in the following.
auto lo
iface lo inet loopback
#External Interface
auto eth0
iface eth0 inet dhcp
auto eth1
iface eth1 inet static
address 10.1.1.1
netmask 255.255.255.0
network 10.1.1.0
auto eth2
iface eth2 inet static
address 10.2.1.1
netmask 255.255.255.0
network 10.2.1.0
auto eth3
iface eth3 inet static
address 10.3.1.1
netmask 255.255.255.0
network 10.3.1.0
auto wlan0
iface wlan0 inet static
address 10.4.1.1
netmask 255.255.255.0
network 10.4.1.0
Routing
To make this computer become a linux router it a route we need to edit a few files.
Argument: I suppose one could argue that this is not a true router but is instead a multi-interface gateway device. A true router could share a routing table. And this device does not. I suppose it could, but since I don’t want it to, it isn’t.
sudo cp /etc/sysctl.conf /etc/sysctl.conf.bak && sudo nano /etc/sysctl.conf
to enable router mode you must remove the # before the line
net.ipv4.ip_forward=1
echo 1 > /proc/sys/net/ipv4/ip_forward
cat /proc/sys/net/ipv4/ip_forward
and be sure it says 1 instead of 0. I’ve seen it not take for some reason. If not just nano it.
And then reboot
sudo shutdown now –r
When the system comes back up it will have the potential to route packets. It wont. Not until you configure the firewall via iptables. Particularly the masquerade section.
iptables Firewall
I determined that webmin firewall is easy to configure and gives a nice graphic representation of the firewall, but it wasn’t as flexible and quick as I wanted. I wanted to run a script and link other non firewall things to that script. As a result I trashed my webmin firewall and implamented this script. But, I saved my documentation and made it its own blog entry. If you want to use webmin and make a router firewall with it instead of using an iptables script you can check it out.
WARNING: there maybe some nasty word wrapping in this script due to this blog layout.
sudo nano /bin/iptables.sc
and paste in the following
#!/bin/bash
######################
#
# Settings up variables for the script
#
######################
#SETS SERVER IPS TO VARAIBLES AND DETERMINES DHCP GATEWAY
echo "setting up variables"
#_GATEWAY=$(nslookup nedimare.game-host.org | grep 97 | cut -d : -f 2 | sed -e 's/^[ \t]*//')
_GATEWAY=$(ifconfig eth0 | grep -v inet6 | grep inet | cut -d : -f 2 | sed 's/Bcast//')
echo "The gateway inteface IP is $_GATEWAY"
_FTP=10.1.1.5
_HTTP=10.1.1.6
_RUNUO=10.1.1.7
_CYGNENOS=10.1.1.3
_Win2k8Server=10.1.1.8
########################
#
# Flushing and setting defaults
# accepts for some
#
######################
echo “Flushing and setting defaults”
echo ” flush nat”
iptables -t nat -F
echo ” flush input”
iptables -F INPUT
echo ” flush nat prerouting”
iptables -t nat -F PREROUTING
echo ” flush nat postrouting”
iptables -t nat -F POSTROUTING
echo ” flush output”
iptables -F OUTPUT
iptables -P OUTPUT ACCEPT
echo ” flush forward”
iptables -F FORWARD
##########################
#
# ICMP
#
##########################
iptables -A OUTPUT -p icmp –icmp-type echo-request -j ACCEPT
iptables -A INPUT -p icmp –icmp-type echo-reply -j ACCEPT
iptables -A INPUT -p icmp –icmp-type echo-request -m limit –limit 1/s -i eth0 -j ACCEPT
# Work around for stupid websites blocking ICMP (just for normal surfing)
# iptables -t mangle -A FORWARD -p tcp –tcp-flags SYN,RST SYN -j TCPMSS –clamp-mss-to-pmtu
# Allow ICMP for frag notification
# –icmp-type 8 = ping
# iptables -t filter -A INPUT -p icmp -s 0/0 -d $ip_eth2 -m state –state NEW -j ACCEPT
################
#
# Masqurading
# allows routing to work
#
#################
echo “setting up masqurading”
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
################
#
# INPUT
# connections to this firewall/router
###############
echo “setting up INPUT”
iptables -I INPUT 1 -i lo -j ACCEPT
iptables -A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp –dport ssh -j ACCEPT
iptables -A INPUT -p tcp –dport 10000 -j ACCEPT
################
#
# OUTPUT
# connections from this firewall/router
################
echo “setting up OUTPUT”
iptables -A OUTPUT -j ACCEPT
###################
#
# FORWARD
# connections going through this firewall/router
##################
echo “setting up FORWARD”
iptables -A FORWARD -m state –state ESTABLISHED,RELATED -j ACCEPT
##################
#
# Webmin DNATs
# allow various servers to connect from the internet
##################
echo “setting up Webmin DNATs”
iptables -t nat -A PREROUTING -p tcp -i eth0 –dport 10001 -j DNAT –to 10.1.1.5:10000
iptables -t nat -A PREROUTING -p tcp -i eth0 –dport 10003 -j DNAT –to 10.1.1.3:10000
iptables -t nat -A PREROUTING -p tcp -i eth0 –dport 10006 -j DNAT –to 10.1.1.6:10000
iptables -t nat -A PREROUTING -p tcp -i eth0 –dport 10007 -j DNAT –to 10.1.1.7:10000
##################
#
# RUNUO DNAT
#
#################
echo “setting up RUNUO DNAT”
iptables -t nat -A PREROUTING -p tcp –dport 2593 -j DNAT –to $_RUNUO:2593
iptables -t nat -A POSTROUTING -s $_RUNUO -p tcp –sport 2593 -j SNAT –to-source $_GATEWAY
iptables -A INPUT -d $_RUNUO -p tcp –dport 2593 -j ACCEPT
iptables -A OUTPUT -s $_RUNUO -p tcp –dport 2593 -j ACCEPT
##########################
#
# RDP DNAT
# untested
#########################
echo “setting up RDP DNAT”
iptables -A FORWARD -p tcp –dport 3389 -m state –state NEW -j ACCEPT
iptables -t nat -A PREROUTING -p tcp –dport 3389 -j DNAT –to $_Win2k8Server:3389
iptables -A FORWARD -i eth0 -p tcp –destination $_Win2k8Server -m multiport –dports 3389 -j ACCEPT
####################
#
# FTP DNAT
#
####################
# THIS SECTION IS STILL NOT FUNCTIONING CORRECTLY
echo setting up FTP DNAT
modprobe ip_conntrack_ftp
modprobe ip_nat_ftp
PREROUTING -p tcp –dport 20 -j DNAT –to $_FTP:20
PREROUTING -p tcp –dport 21 -j DNAT –to $_FTP:21
iptables -t nat -A PREROUTING -p tcp -i eth0 –dport 21 -j DNAT –to $_FTP:21
iptables -t nat -A PREROUTING -p tcp -i eth0 –dport 20 -j DNAT –to $_FTP:20
iptables -A FORWARD -i eth0 -p tcp -d $_FTP -m multiport –dports 20,21 -j ACCEPT
iptables -t nat -A PREROUTING -p tcp –dport 20 -j DNAT –to $_FTP:20
iptables -t nat -A POSTROUTING -s $_FTP -p tcp –sport 20 -j SNAT –to-source $_GATEWAY
iptables -A INPUT -d $_FTP -p tcp –dport 20 -j ACCEPT
iptables -A OUTPUT -s $_FTP -p tcp –dport 20 -j ACCEPT
######################
#
# Webserver DNAT
#
#######################
iptables -t nat -A PREROUTING -p tcp -i eth0 –dport 80 -j DNAT –to $_HTTP:80
iptables -t nat -A PREROUTING -p tcp -i eth0 –dport 443 -j DNAT –to $_HTTP:443
iptables -t nat -A PREROUTING -p tcp -i eth0 –dport 10022 -j DNAT –to $_HTTP:22
#####################
#
# OpenDNS DNAT OUTGOING
#
####################
# note 10.1.1.3 is the IP of my internal DNS server
echo “setting up OpenDNS prerouting (the trap)”
iptables -t nat -A PREROUTING ! -s 10.1.1.3 -p udp –dport 53 -j DNAT –to 208.67.222.222:53
iptables -t nat -A PREROUTING ! -s 10.1.1.3 -p tcp –dport 53 -j DNAT –to 208.67.222.222:53
###################
#
# Default settings end of chain and rejects
#
## tighten this up later.
echo “default rejects, end of chains”
iptables -P INPUT REJECT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD REJECT
Note: this is still a work in progress and may need tightening a bit more
Now that we have this script we can add modules like the ftp modules that load on execution, call this script from other scripts like the malware script below, call it from cron, and we can put a link into the /etc/network/if-pre-up.d and if-up.d folders so when the interfaces comes up the iptables gets reloaded.
sudo ln -s /bin/iptables.sc ./if-pre-up.d/iptables.sc
sudo ln -s /bin/iptables.sc ./if-up.d/iptables.sc
Wireless Access Point – Can you host?
Get the tools
sudo apt-get install -y wpasupplicant wireless-tools iw
Step 1 test your card:
Be sure your wireless device is up and functional. One test is to do a iwlist scanning wlan0 and verify that you can see other wireless networks. Setting up a WAP with a wifi card or other device that may or may not function could be a waste of time.
Step 2 Verify that your card supports being an access point
First try
and verify that AP is somewhere in the Supported Interface modes. If so, then just jump down to the section Wireless Access Point – hostapd, below. If not then you can try
sudo iw
sudo iwconfig mode master
If you got no errors in “mode master” then you need to do something like…
sudo nano /etc/network/interfaces
Find the wireless interface (often wlan0) and add these lines
wireless-mode master
wireless-essid YOURESSIDNAME
But I don’t have that type of card, so I can’t help with that, You can still try the next section about hostapd. It may still work. Otherwise, you are going to have to get another card, or research the wireless-mode master method.
Wireless Access Point – hostapd (basic unsecured setup
There is no webmin module for hostapd. Maybe someone should write one. That would be cool. For now, to the command line.
sudo apt-get install hostapd
cd /etc/hostapd
sudo mv hostapd.conf hostapd.conf.original
We are going to set up an unsecure wireless network and then lock it down. It is hard to troubleshoot security and connectivity. Lets first verify that we can connect. Then we will work on security.
sudo nano hostapd.conf
Paste in the following. Remember to change wlan0 to your wireless device that is displayed in an ifconfig. Also, the driver= section may not be the same as mine you may need to do some googling with “hostapd driver {your wifi card type}” and see what driver is suggest you use. I tried nl80211 on the first try and got lucky. Actually, my understanding is that nl80211 is the most common driver, so give it a try too.
interface=wlan0
driver=nl80211
ssid=test
channel=1
Exit saving and then
sudo hostapd ./hostapd.conf &
If there are no errors. Then we are golden. Go to another device and scan for a the network and see if you can see it.
Init.d fail: I noticed that starting this program as service by doing a “sudo /etc/init.d/hostapd restart” failed to load the correct conf file. Although the output was implying that the service started just fine. Using “sudo hostapd ./hostapd.conf &” brought up the service with the correct conf file. You know what that means? The init.d script borked. I have to edit the init.d script.
First backup the original
cd /etc/init.d
sudo mv hostapd hostapd.original
sudo chmod –x hostapd.original
Then
sudo nano hostapd
and paste in the following.
#!/bin/sh
### BEGIN INIT INFO
# Provides: hostapd
# Required-Start: $remote_fs
# Required-Stop: $remote_fs
# Should-Start: $network
# Should-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Advanced IEEE 802.11 management daemon
# Description: Userspace IEEE 802.11 AP and IEEE 802.1X/WPA/WPA2/EAP
# Authenticator
### END INIT INFO
PATH=/sbin:/bin:/usr/sbin:/usr/bin
case "$1" in
start)
echo "attempting to start hostapd using /etc/hostapd/hostapd.conf"
hostapd /etc/hostapd/hostapd.conf &
echo "done attempting. Did we fail? I can't tell because I'm a very simple script."
ps -A | grep hostapd
;;
stop)
echo "i'm going to attempt to kill hostpad using killall"
killall hostapd &
echo "done attempting. Did we fail? I can't tell because I'm a very simple script. If I did fail you can try again as there mayve multiple instances."
ps -A | grep hostapd
;;
reload)
echo "I'm too simple of a script to attampt a reload, do restart instead."
;;
restart|force-reload)
$0 stop
sleep 8
$0 start
;;
*)
N=/etc/init.d/$NAME
echo "Usage: $N {start|stop|restart|force-reload}" >&2
exit 1
;;
esac
exit 0
(this blog post screws up the tabbing format from the original. This looks sloppy, but works.)
sudo chmod +x hostapd
Now /etc/init.d/hostapd start | stop etc works and it loads up on reboot. I realize this is a hack. My init.d script skills aren't the best. If anyone has a better solution feel free to reply to this blog and I'll put it in here.
When hostapd is running, do an ifconfig. You should notice a new device named mon.wlan0. Got a client computer and scan for new networks. You should see, and be able to connect to it. If not, first suspect the driver= section.
Wireless Access Point – hostapd WPA2
Hint: Before continuing, connect to the WAP while unsecured to rule out security as a possible cause for failure to connect.
again do a
sudo mv /etc/hostapd/hostapd.conf /etc/hostapd/hostapd.conf_simple
sudo nano /etc/hostapd/hostapd.conf
and paste in the following.
interface=wlan0
driver=nl80211
ssid=rampart
hw_mode=g
channel=11
wpa=2
wpa_passphrase=yourpasswordinplaintext
wpa_key_mgmt=WPA-PSK
wpa_pairwise=CCMP
wpa_group_rekey=600
restart the service and try to connect. If you fail, but you succeeded when you had no security, then one of your devices may not support wpa2 (AP or wifi card) or the pairwise may need changing. You will need to research and attempt another security type.
DynDNS.com
If, like me, you plan to use DynDNS and OpenDNS, then you need an account at dnsomatic.com. This basically links your 2 services so you update your IP to dnsomatic and it updates the other 2. Yes, you must have 3 internet accounts to accomplish this. I used the same user name and the same secure password for each. But this password I use for these accounts only.
You must install ddclient and it will update dnsomatic. Most of the installation instructions can be located here
sudo apt-get install ddclient
The installer prompts you for the service info like user name and password and the hosts you want to update etc. It probably doesn't matter what you enter because we'll be editing the conf file on our own after it installs. The conf file is located at /etc/ddclient.conf
Below is a sample ddcient.conf file that I found here.
##
## DNS-O-Matic account-configuration
##
use=web, web=myip.dnsomatic.com
server=updates.dnsomatic.com
protocol=dyndns2
login=dnsomatic_username
password=dnsomatic_password
all.dnsomatic.com
Our iptables script above forces all outgoing dns queries to opendns. So now would be a good time to log into opendns and set up your filtering rules. Anyone who accesses the internet from inside your network will now be filtered to your opendns account. Even if they set their DNS settings to something else.
IP Tables and Malware
At first I was using swquid for filtering as described on the Webmin Firewall page. After I got it all to work I realized that I wanted to do something different. I descided to dump squid...
sudo apt-get remove squid3 -y
... and just use iptables to filter these malware sites, and allow opendns to filter the porn. Why? Well, for one it woudld be faster and use less resources. And, it sounded like a fun challenge. If you wanted to use dansguardian or squidguard or do some actual proxying then you may want to leave squid in place.
sudo nano /bin/malware.sc
and paste in the following
#!/bin/bash
cd /tmp
# Get the malware site list, exiting if it is not downloadable.
wget "http://malware.hiperlinks.com.br/cgi/submit?action=list_hosts_win_127001" -O malware.tmp || exit 0
# creating the scripts from the malware site list.
cat ./malware.tmp | sed '/^$/d' | sed '/#/d' > malware2.tmp
echo "#!/bin/bash" > mal_INPUT.sc
echo "#!/bin/bash" > mal_OUTPUT.sc
cat malware2.tmp | sed 's/127.0.0.1/iptables -A INPUT -s/' | sed 's/$/ -j REJECT/' >> mal_INPUT.sc
cat malware2.tmp | sed 's/127.0.0.1/iptables -A OUTPUT -d/' | sed 's/$/ -j REJECT/' >> mal_OUTPUT.sc
cat malware2.tmp | sed 's/127.0.0.1/iptables -A FORWARD -d/' | sed 's/$/ -j REJECT/' >> mal_FORWARD.sc
rm *.tmp
chmod +x mal_INPUT.sc
chmod +x mal_OUTPUT.sc
echo "exit" >> mal_INPUT.sc
echo "exit" >> mal_OUTPUT.sc
# Excution of the scripts adding them to iptables
/bin/iptables.sc
/tmp/mal_INPUT.sc
/tmp/mal_OUTPUT.sc
/tmp/mal_FORWARD.sc
Now we need to set it up to run once a day.
sudo crontab -e
and paste in the following
1 4 * * * /bin/malware
This will update the malware list and resets the firewall every day at 4:01AM.
ntop - network usage monitor
ntop installed from repos just fine. But it wouldn't launch I had to create the ntop directory and adjust its permissions. These permissions could be tightened up a bit maybe. I wonder if anyone knows the proper permissions and ownership for this
sudo apt-get install ntop
sudo mkdir -p /var/lib/ntop
sudo chmod 755 -R /var/lib/ntop
sudo nano /var/lib/ntop/init.cfg
and then verify the interfaces. I had to add more interfaces inside the quotes and seperate each one with a comma. Like this.
INTERFACES="eth0,eth1,eth2,eth3,wlan0"
Once installed, you can direct your browser to
http://yourhosturlorIP:3000
and get some very interesting statistics throughput and network usage. This is a very robust monitoring utility. Click here to see some screenshots of ntop.
DHCPD and DNS
Many Walmart brand home router boxes have DHCP and DNS Masquerading features built in. If you are creating a device to replace such a box then you will need to set up these servers as well. There should be ample documentation on the internet for these proceedures. I use DNS and DHCP on a device inside of the network. It is much more secure to not have these servers forward facing. If you also have a seperate yet internal DNS and DHCP server set up this box won't route dhcp broadcasts from subnet to subnet. So if you, like me, have eth0 internet facing, eth1 and eth2 with internal hosts then those hosts connected to the eth that the DHCP server is not connected to will not get an IP address. You must install a dhcp relay.
sudo apt-get install -y dhcp3-relay
and configure it to point to your internal dhcp server. It is all pretty strait forward.
nmap - network scanner
This tool can scan your network and look for hosts inside of your firewall. You can use this output to look for rouge devices. nmap is such an indepth tool that it deserves its own blog post.
sudo nano /bin/nmap.sc
and paste in the following.
#!/bin/bash
nmap -sP 10.1.1.0/24 > /tmp/nmap.last
nmap -sP 10.2.1.0/24 >> /tmp/nmap.last
nmap -sP 10.3.1.0/24 >> /tmp/nmap.last
nmap -sP 10.4.1.0/24 >> /tmp/nmap.last
Note: You probably wont be using the same networks as I am. So scanning a network that doesn't exist is not necessary. Edit the script to suit your network.
sudo crontabe -e
paste in the following line.
1 * * * * * /bin/nmap.sc
This will scan the network on the first minute of every hour and put the results into /tmp/nmap.last.log We’ll add more fun later in which we can set more detailed scans on those clients as well as send alerts if something doesn’t belong. For now, you can look at that log by doing a
cat /tmp/nmap.last.log
netperf
This handy utility measures actual throughput. Having this running on your gateway/router allows you to check your speed on any segment, and even though the internet.
tshark
coming soon

If you found this information helpful and saved you time or energy how about you buy me a beer by clicking the donate button below!