Building the drone secure WAP VPN hub of activity

You’ve probably noticed me mentioning a TP-link powerline wireless access point (WAP) in my outdoor testing. It was the easiest way for me to get a decent WiFi signal outside the house.  But it does require a direct connection to the house ring-main to forward the IP traffic to the broadband router.  Good enough for testing, but useless for non-constrained live flying.  I knew at some point I needed the drone to be a Wireless Access Point in it’s own right, but I’ve been dodging the bullet for a while for a couple of reasons.  Here’s

  1. The drone is a headless model A so there’s no ethernet link to connect to the drone once it’s a WAP – that means I need to get everything I need installed before I turn on the WAP
  2. The WAP will not have bridging to the my broadband network; the drone will be using static IP addresses in its WLAN / VPN and will be secured; so again, another reason to get it right first time if at all possible
  3. My drone WiFi dongle uses the RealTek RTL8088 chipset which requires a modified host access point daemon (hostapd) and it’s only recently I’ve found a set of clear, concise, complete instructions how to set this up.

My aim here is to make the drone an isolated WAP (no access to the internet) which accepts secure client connections.  The clients need to be assigned IP addresses in the drone private nextwork, the the drone will run DHCP; the drone IP address will be static.  Since internet access is not required, no bridging, NAT or DNS services will be provided by the drone.

The information below is based on this link and this link, but is customized to give exactly what the drone needs: a secure WLAN / VPN with no internet access using a statically configured (constant) IP address.

The starting point is a Raspberry Pi, model A, newly flashed with the latest (Jun ’13) wheezy image; WiFi is working as a client to the main WiFi broadband hub and has internet access.

  • login (pi, raspberry), and start up LXDE (startx)
  • open an LXTerminal window
  • type “ping www.google.com” just to be certain of your internet access
  • open Midori browser and head here as a useful reference when making the changes below
  • type “sudo apt-get install hostapd udhcpd” to install the WAP and DHCP daemons
  • type the following to replace the standard WAP daemon with the Realtek version:
    wget http://www.daveconroy.com/wp3/wp-content/uploads/2013/07/hostapd.zip
    unzip hostapd.zip 
    sudo mv /usr/sbin/hostapd /usr/sbin/hostapd.bak
    sudo mv hostapd /usr/sbin/hostapd.edimax 
    sudo ln -sf /usr/sbin/hostapd.edimax /usr/sbin/hostapd 
    sudo chown root.root /usr/sbin/hostapd 
    sudo chmod 755 /usr/sbin/hostapd
  • Configure the revised hostapd by creating /etc/hostapd/hostapd.conf “sudo vi /etc/hostapd/hostapd.conf” and add the following:
    interface=wlan0
    driver=rtl871xdrv
    ssid=MyWAPSSID
    channel=1
    wmm_enabled=0
    wpa=1
    wpa_passphrase=MyWAPPassphrase
    wpa_key_mgmt=WPA-PSK
    wpa_pairwise=TKIP
    rsn_pairwise=CCMP
    auth_algs=1
    macaddr_acl=0
  • Now to configure the WAP static IP address – “sudo vi /etc/network/interfaces”, replacing the existing entry for wlan0 with the following
    iface wlan0 inet static
    address 192.168.23.1
    netmask 255.255.255.0
  •  In the same file, comment out (# at the start of the line) the following if present
    #allow-hotplug wlan0
    #wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
    #iface default inet dhcp
  • We next need to configure dhcp for the clients accessing the network to  provide their IP addresses – edit /etc/udhcpd.conf adding:
    start 192.168.23.2 # This is the range of IPs that the hostspot will give to client devices.
    end 192.168.23.20
    interface wlan0 # The device uDHCP listens on.
    remaining yes
    opt domain local
    # opt dns 8.8.8.8 4.2.2.2 # The DNS servers client devices will use.
    opt subnet 255.255.255.0
    opt router 192.168.23.1 # The Pi's IP address on wlan0 which we have set up.
    opt lease 864000 # 10 day DHCP lease time in seconds

    Note the dhcp address range starts at 192.168.23.20 allowing some space for static addresses 1 – 19.

  • In the same file, delete or comment out “#” any other lines as these are just example settings.
  • Enable dhcp by editing /etc/default/udhcpd thus to comment out the line
    #DHCPD_ENABLED="no"
  • Add the dhcp leases file by typing
    sudo touch /var/lib/misc/udhcpd.leases
    sudo chmod 666 /var/lib/misc/udhcpd.leases
  • Enable hostapd by editing /etc/default/hostapd thus, adding
    DAEMON_CONF="/etc/hostapd/hostapd.conf"
  • Now at this point, you should be ready for a reboot, but when I did that, although other devices could see and connect to my WAP, dhcp was not assigning IP addresses and whatever I did failed – so I abandoned dhcp for the moment, and assigned static IP addresses for the various clients I was going to use to access the drone thus…
  • edit /etc/hostname to ensure the domain name is included – in my case, the domain is called local, and the hostname is wappi, so /etc/hosts reads
    wappi.local
  • Strike this – DHCP problem solved below: Next assign static IP address for the server in /etc/hosts
    192.168.23.1 wappi wappi.local
  • Turn off the ifplugd (pluggable interface daemon) for the WiFi dongle as it seems to cause conflict between hostapd and udhcpd – edit /etc/default/ifplugd
    # This file may be changed either manually or by running dpkg-reconfigure.
    #
    # N.B.: dpkg-reconfigure deletes everything from this file except for
    # the assignments to variables INTERFACES, HOTPLUG_INTERFACES, ARGS and
    # SUSPEND_ACTION.  When run it uses the current values of those variables
    # as their default values, thus preserving the administrator's changes.
    #
    # This file is sourced by both the init script /etc/init.d/ifplugd and
    # the udev script /lib/udev/ifplugd.agent to give default values.
    # The init script starts ifplugd for all interfaces listed in
    # INTERFACES, and the udev script starts ifplugd for all interfaces
    # listed in HOTPLUG_INTERFACES. The special value all starts one
    # ifplugd for all interfaces being present.
    INTERFACES=""
    HOTPLUG_INTERFACES=""
    ARGS="-q -f -u0 -d10 -w -I"
    SUSPEND_ACTION="stop"
  • Finally (and I don’t know if this was necessary), update /etc/resolv.config to local domain name resolution rather than relying on an external DNS
    domain local
    search local
    nameserver 192.168.1.254
  • Check, double check, and triple check that you’ve done all the above steps, and then finally
     sudo reboot

Because there’s no internet connection, there’s no DNS available, so the clients for the WAP need the WAP static IP address added to /etc/hosts:

192.168.23.1       wappi.local

Now that this works on my test WAP RPi, I still have a few steps remaining:

  • These instructions are for the Edimax Nano USB dongle -EW-7811Un (Realtek RTL8188CUS chipset) and that’s what I tested. But the drone uses a different RealTek device so I need to test that on wappi first Strike that: both the Edimax Nano dongle and the EDUP MS-15003 dongles work successfully as WAPs with the modified hostapd listed above.
  • Once that’s working, I need to follow my own instructions to get the WAP onto the drone itself. Strike that – all working as of this morning following my own blog details
  • And I’d better make sure the drone is set up as an FTP server / daemon as that’s the only way to transfer files to it once it’s a private WAP – I could use a USB stick, but since it’s a model A, that means unplugging the WiFi dongle.Strike that, I’ll use a USB drive or connect to a different network when I need updates. Strike 2 – I installed the FTP server so clients can FTP into the drone, as the clients also have internet access.

When later you wish to update the RPi software, you’ll need to add an ethernet interface.  First, get a USB to Ethernet dongle – I use one by Pluggable which worked out of the box.  Then you need to re-enable the interface pluggable daemon:

# This file may be changed either manually or by running dpkg-reconfigure.
#
# N.B.: dpkg-reconfigure deletes everything from this file except for
# the assignments to variables INTERFACES, HOTPLUG_INTERFACES, ARGS and
# SUSPEND_ACTION.  When run it uses the current values of those variables
# as their default values, thus preserving the administrator's changes.
#
# This file is sourced by both the init script /etc/init.d/ifplugd and
# the udev script /lib/udev/ifplugd.agent to give default values.
# The init script starts ifplugd for all interfaces listed in
# INTERFACES, and the udev script starts ifplugd for all interfaces
# listed in HOTPLUG_INTERFACES. The special value all starts one
# ifplugd for all interfaces being present.
INTERFACES="all"
HOTPLUG_INTERFACES="auto"
ARGS="-q -f -u0 -d10 -w -I"
SUSPEND_ACTION="stop"

You may also need to update /etc/hostname if there is a domain name specified like phoebe.local, rather than just the machine name.

You also probably will need to update /etc/hosts to remove the WAP host  phoebe.local

Connect an ethernet cable to your hub, and a reboot then should give you internet access – ping www.google.co.uk to check. From there you can do a “sudo apt-get update && sudo apt-get upgrade”. Then reboot, revert /etc/default/ifplugd to

# This file may be changed either manually or by running dpkg-reconfigure.
#
# N.B.: dpkg-reconfigure deletes everything from this file except for
# the assignments to variables INTERFACES, HOTPLUG_INTERFACES, ARGS and
# SUSPEND_ACTION.  When run it uses the current values of those variables
# as their default values, thus preserving the administrator's changes.
#
# This file is sourced by both the init script /etc/init.d/ifplugd and
# the udev script /lib/udev/ifplugd.agent to give default values.
# The init script starts ifplugd for all interfaces listed in
# INTERFACES, and the udev script starts ifplugd for all interfaces
# listed in HOTPLUG_INTERFACES. The special value all starts one
# ifplugd for all interfaces being present.
INTERFACES=""
HOTPLUG_INTERFACES=""
ARGS="-q -f -u0 -d10 -w -I"
SUSPEND_ACTION="stop"

Readd the WAP domain into /etc/hostname if you changed it previously.  Likewise add back into /etc/hosts the WAP local address (192.168.69.1  phoebe.local phoebe)

Unplug the ethernet dongle and reboot. All should be back to how it was before with just the WAP.

Talking to a headless Turtle

So how do you talk to a headless turtle?

That’s the problem I wanted to solve.  A “headless” RPi had no screen, keyboard or mouse, meaning the only way of talking to it is over the wireless network I have here (as do most people with an internet connection).  The way I want to ultimately achieve is to connect the Turtle to SupeRpi with a dedicated TCP connection using Python on the SupeRPi to take commands from its keyboard, and pass them to the Turtle for it to carry out.  By commands, I mean “forward 10”, “rotate clockwise 90”, or “reverse 20”.

TCP connections are set up between a unique pair of IP addresses.  Each network card has it’s own unique one.  In my RPis, each has only one for the wireless link – SupeRPi is 192.168.1.66, and the Turtle is 192.168.1.67.  These addresses aren’t (in my case, yet) configured on the RPi – the RPi learns them over the wireless network from the dhcp server.  This runs (d)ynamic (h)ost (c)onfiguration (p)rotocol which assigns IP addresses to each network device it hears from on the network.  It is possible to ensure the dhcp server assigns the same device each time it starts up, but in my case, that’s not necessary as mine tries to assign the same IP address to each network device across each time it reboots.

So how do you find out the IP address for your device?  I ran “ifconfig” which lists all network interfaces, and shows their IP addresses amongst other stuff).  Having found the 2 addresses, I check they can talk to each other by using “ping”.  Typing ping from the SupeRPi (192.168.1.66)  to Turtle (192.168.1.67) like this “ping 192.168.1.67” tries to find 192.168.1.67 every few seconds, printing the results on screen.

So now I have IP addresses, and proof they talk to each other, the next step is to be able to send Turtle commands from SupeRpi.  As I said previously, I am going to do this with more Python code, but first I remembered a quicker way: “rlogin”.

From SupeRPi, I can type “rlogin 192.168.1.67” and after typing the password for the Turtle, the screen actually acts as though it’s on the Turtle, so typing “sudo python turtle.py” from the SupeRPi rlogin screen sets the Turtle running (well crawling actually, but…).

So the next step has changed.  I need to guillotine the Turtle (no harm was made to any animals), and then I can get back to the electronics of powering the Turtle without the mains – well within the bounds of a Lithium Ion battery, but outside of this months pay-packet.  Lucky payday is imminent so I hope my next post will be less wordy, and more interesting.  Until then…