Tuesday, June 7, 2011

Setting up Dreamplug as a router with Shorewall firewall

 I recently got an Dreamplug from New IT and the first use for it I wanted to try out was to set it up as an router.


My setup of the Dreamplug will be using the following scenario:
  • eth1 is my external interface connected to the ISP  and gets its ip via DHCP.
  • eth0 internal interface wired
  • uap0 internal interface wireless
  • wireless-guru bridged interface (eth0 and uap0) ip: 192.168.5.1 subnet mask: 255.255.255.0


First boot
When booting the Dreamplug for the first time it will start in AP mode by default with an IPv4 address of 192.168.1.1 where the SSID will have the name  "Dreamplug-uAP-xxxx” where xxxx are last digits of the MAC address of uap0.

Log in on the Dreamplug by using SSH and use the default user name: root  and the password: nosoup4u


NOTE! When changing the network information an JTAG adapter are useful if anything goes wrong!


Setting up the network
First we need to clear out the default setup that the Dreamplug are supplied with:
in the file /etc/rc.local comment out the call to initSetup.sh

Now since we comment out the initSetup.sh from the rc.local file we need to add a new file and enable the wireless uap0. I created a new call in the /etc/rc.local to a file I called /root/initwifi.sh and inserted these lines in the file (note, if you already disabled the root user you need to use sudo -i to edit the files under /root/ folder):

#Init the AP point
uaputl sys_cfg_ssid "My wifi AP name" # WLAN Name
uaputl sys_cfg_protocol 32 # Modus WPA2
uaputl sys_cfg_wpa_passphrase "password to the wifi" # WLAN password
uaputl sys_cfg_cipher 8 8 # Set the Cipher
uaputl sys_cfg_channel 0 1 # automatic channel
uaputl bss_start

/etc/init.d/udhcpd start # start DHCP server

# Set leds
echo 1 > `eval ls /sys/class/leds/guruplug\:green\:wmode/brightness`
echo 0 > `eval ls /sys/class/leds/guruplug\:red\:wmode/brightness`



To change the WLAN encryption mode change the values above based on the values shown below:

Options: PROTOCOL:
1 - No RSN
2 - WEP Static
8 - WPA
32 - WPA2
40 - WPA2 Mixed
empty - Get current protocol
Options: PAIRWISE_CIPHER:  
0 - NONE
4 - TKIP
8 - AES CCMP
12 - AES CCMP + TKIP
GROUP_CIPHER :
0 - NONE 
4 - TKIP
8 - AES CCMP
empty - Get current cipher settings
When using the Dreamplug as an router the ifplugd daemon are not needed, this module will automatically configure the ethernet device when a cable is plugged in and automatically unconfigure it if the cable is pulled:
apt-get remove --purge ifplugd

For the server several modules can be blacklisted, all of these disables the Bluetooth module.
Add the following line to the file /etc/modprobe.d/blacklist:
btmrvl, btmrvl_sdio, bluetooth, libertas, libertas_sdio, ipv6

Before we can bridge the interfaces the package bridge-utils must be installed
apt-get install bridge-util

Next we need to set up the network interfaces, edit the file /etc/network/interfaces so it looks like this:
auto lo
iface lo inet loopback

auto uap0
iface uap0 inet static
address 0.0.0.0

auto eth0
iface eth0 inet static
address 0.0.0.0

auto wifi-dream #this is the name of the bridge
iface wifi-dream inet static #name of the bridge
        address 192.168.5.1
        netmask 255.255.255.0
        network 192.168.5.0
        broadcast 192.168.5.255
        gateway 192.168.5.1
        bridge_ports eth0 uap0
        post-up route del default dev $IFACE

auto eth1
iface eth1 inet dhcp


The Dreamplug for some reason added two default routes, to fix this I had to add the line "post-up route del default dev $IFACE", this deletes the faulty route after the Dreamplug boots.

Thanks for "Portablejim" that showed me why the Dreamplug added two routes. My new interfaces file now look like this:
Take a look at his config that shows an static IP on the WAN port at https://gist.github.com/1539240

auto lo
iface lo inet loopback

auto wifi-dream
iface wifi-dream inet static
    address 192.168.5.1
    netmask 255.255.255.0
    network 192.168.5.0
    broadcast 192.168.5.255
    bridge_ports eth0 uap0

auto eth1
iface eth1 inet dhcp


Now lets add our new IP range to the DHCP, edit the file /etc/udhcp.conf:
start    192.168.5.100
end      192.168.5.200
interface wifi-dream #must be the same name as the bridge above
opt      lease  86400
opt      router  192.168.5.1
opt      subnet  255.255.255.0
opt      dns     192.168.5.1
opt      domain     localdomain

 max_leases     101
 lease_file     /var/lib/udhcpd.leases
 auto_time       5


First time when I changed the IP from the default range 192.168.1.1/24 to 192.168.5.1/24 I saw the Dreamplug still handed out the old range to my machines. After some digging I figured out the udhcp used the values stored in the file /var/lib/udhcpd.leases to hand out the old IP addresses. To view all the mac addresses and IP's stored in this file use the command "dumpleases -f /var/lib/udhcpd.leases".

To make udhcp use the new IP range the old udhcp.leases must be removed:
#Stop the udchpd deamon
/etc/init.d/udhcpd stop

#Remove the old lease file:
rm  /var/lib/udhcpd.leases

#create a new empty lease file
touch  /var/lib/udhcpd.leases

#start the udchpd deamon
/etc/init.d/udhcpd start


eth0 and uap0 are now in the same network using the bridge wifi-dream. a DHCP server is listening to give the clients an ip.

Instead of using the dnsmasq I use the bind9 deamon. So lets remove the dnsmasq and install bind9
apt-get remove --purge dnsmasq
apt-get install bind9

For me that was enough because the bind server reads the nameservers IPs of my ISP from /etc/resolv.conf and forwards the requests.

Shorewall
Now we will install the Shorewall firewall. Note, if you have ipv6 enabled this means you need to set up two separate firewalls since ipv6 and ipv4 got their own iptables. If you don't need ipv6 just blacklist it as I did above.
apt-get install shorewall

To enable routing we need to edit the file /etc/shorewall/shorewall.conf and set  the following:
IP_FORWARDING=On

Create or edit the file /etc/shorewall/zones:
net    ipv4        # internet
loc    ipv4        # local
fw     firewall    # firewall


Create or edit the file /etc/shorewall/interfaces

loc    wifi-dream  192.168.5.255  routeback
net    eth1    detect  dhcp

Make shure you set an broadcast address in the same ip range here as in/etc/udhcp.conf and /etc/network/interfaces
The option dhcp means that the external interface gets the ip via dhcp.
Routeback option is VERY important, if you forget to put it here your hosts in your private LAN won't communicate with each other because the FW will block it.

Create or edit the file /etc/shorewall/policy
fw   all   ACCEPT
loc  all   ACCEPT
net  all   DROP     info
all  all   REJECT   info


The option info means, that every blocked traffic will be logged into /var/log/messages (very useful for debugging)
Every traffic will be blocked apart from source loc or fw to every location (all) or specified explicit in the rules see next step

Create or edit the file /etc/shorewall/rules
#COMMENT   123 = NTP, 25 = SMTP, XXXX = SSH, 80 HTTP, 21 = FTP
ACCEPT   all   all   udp   123  123
ACCEPT   all   all   tcp   80
ACCEPT   all   all   tcp   21
ACCEPT   all   all   tcp   22  #port number for your ssh server
ACCEPT   all   all   tcp   25


Create or edit the file /etc/shorewall/routestopped
#Bridged interfaces should be reachable when shorewall is stopped
wifi-dream #Name of the Bridge


Create or edit the file /etc/shorewall/masq
#Masquerading
eth1   wifi-dream   #external interface to internal interface



Alternative policy and rules files
If you for some reason want to block all traffic to the firewall, even from loc ->fw,  you need to use the following settings in the policy and rules file.

policy:
fw    loc   ACCEPT
fw    net   ACCEPT
loc   fw    DROP
loc   net   ACCEPT
net   all   DROP info
all   all   REJECT info

Here all traffic from the firewall are allowed. Traffic from loc->firewall are dropped, loc->net are allowed and net to all zones are blocked. Because of this the dns and dhcp wont work so we need to ad a rule to allow dns and dhcp to connect to the firewall zone
#Change the port numer to the ssh port for your server!
ACCEPT  net   fw   tcp 22
ACCEPT  loc   fw   tcp 22

#Allow dns requests loc -> fw
ACCEPT  loc   fw   udp 53
ACCEPT  loc   fw   tcp 53

#Allow dhcp requests loc -> fw
ACCEPT  loc   fw   udp 67,68

#Allow ping loc->fw
ACCEPT loc fw icmp echo-request 


Starting Shorewall
Check all the settings by running the following command:
shorewall check

If everything are ok on the check the firewall can be startet by
shorewall start

By default the shorewall wont start automatically, if you want to enable this edit the file
/etc/default/shorewall
#set the following varible to 1 in order to allow Shorewall to start
startup = 1


Sources:
GuruPlug as a Router and Shorewall Firewall
dumpleases - display leases granted by udhcp server
DreamPlug User Guide

5 comments:

  1. Great work! There are pieces about Dreamplug I've been looking for!

    I still have a problem with default configuration: after tuning eth0 in /etc/network/interfaces it works great with "ifup eth0"

    But after reload eth0 interfaces is not up properly. I say "not properly", because in fact it has very strange behaviour:
    I'm continiously sending ping to address eth0 is configured in while rebooting Dreamplug. And I see that at just a moment when device is absolutely booting it's unpingable, then it's pinged successfully, then, just before lights begin blinking (bluetooth and wifi) server became unpingable again. At the moment I fixed it with /etc/init.d/networking restart in init_setup.sh, but it's not a solution for straight guys =)

    ReplyDelete
  2. As to make clear: I didn't use settingups you described at this topic.

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. Thanks for the config. I used it to set-up bridging on my Dreamplug. (I already had a squid, dnsmasq and a firewall set up, so I did not use those bits)

    The additional default route is due to you setting a gateway. A gateway should only be set on interfaces connected to the Internet.

    You can put the two interfaces to be bridged as 'manual' so that they are not configured individually.

    My config is at https://gist.github.com/1539240 if you are interested

    ReplyDelete
  5. Thank you for the feedback. I see now why the dreamplug added the wrong default route.

    My ISP requres me to set dchp on the interface, if I where to set an static ip your configuration would be perfect. I might add a shutdown script as you have done

    ReplyDelete