Wednesday, April 8, 2015

Internet sharing for Intel Edison on Linux

Recently I got hold of an Intel Edison with accompanying Arduino Expansion Board. The awkward development setup process (which requires two separate USB cable connections to a host computer) didn't make for a stellar first impression, but the possibilities of a full x86-64 computer that fits in a matchbox are intriguing. Of course, the fact both Linux and ROS are more-or-less readily available for the platform made the whole proposition a lot more interesting.

After flashing Edison with ubilinux the first order of business was getting the thing connected to the Internet. Edison includes an on-board wi-fi card and can simulate an ethernet port through its USB connections to the host computer, but bureaucratic questions would make a direct connection to my lab's network difficult. So I set up my notebook (Edison's host computer) as a local gateway, enabling Internet sharing through the virtual usb0 interface.

The procedure documented below was developed on a Kubuntu 14.04 host and ubilinux Edison unit, but it should be adaptable to other Linux distributions. It is largely based on a previous post on wireless Internet sharing; in fact that may be a better option, if unlike me you have a wireless interface to spare.

First open a command prompt and start a root session with su, then follow the steps below:

Step 1: Install Dnsmasq

Dnsmasq is a tool for setting up small networks. Install it from the command line by typing:
apt-get install dnsmasq
As it is the dnsmasq service will be automatically started when the computer boots, but we need better control than that. So change the default settings to manual start:
update-rc.d -f dnsmasq remove

Step 2: Configuration Files

Create or update the following config file with the contents below:

/etc/dnsmasq.conf
# disables dnsmasq reading any other files like /etc/resolv.conf for nameservers
no-resolv
# Interface to bind to
interface=usb0
# Specify starting_range,end_range,lease_time
dhcp-range=usb0,192.168.100.100,192.168.100.199,12h
# dns addresses to send to the clients
server=8.8.8.8
server=8.8.4.4

Step 3: Interface Scripts

Add the scripts below to your system:

/usr/local/bin/usb0start.sh
#!/bin/sh

ETH=eth0
USB=usb0
IP=192.168.100.99
MASK=255.255.255.0

# Enable IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward

# Setup USB interface
ifconfig $USB up $IP netmask $MASK

# Start dnsmasq
/etc/init.d/dnsmasq start

# Enable NAT
iptables --flush
iptables --table nat --flush
iptables --delete-chain
iptables --table nat --delete-chain
iptables --table nat --append POSTROUTING --out-interface $ETH -j MASQUERADE
iptables --append FORWARD --in-interface $USB -j ACCEPT

/usr/local/bin/usb0stop.sh
#!/bin/bash

USB=usb0

# Stops DNS making service
/etc/init.d/dnsmasq stop

# Asked nice the first time...
killall dnsmasq

ifconfig $USB down
Make sure to create the scripts from the root account, so they'll have the right ownership. Also don't forget to give them running permission:
chmod +x /usr/local/bin/usb0start.sh
chmod +x /usr/local/bin/usb0stop.sh

Step 4: Edison Configuration

Connect Edison to the host computer and start a remote session. Change the following configuration file as below:

/etc/network/interfaces
# Disable auto connection, enable DHCP
iface usb0 inet dhcp
#auto usb0
#iface usb0 inet static
#    address 192.168.2.15
#    netmask 255.255.255.0

Usage

After performing the steps above, you should be able to start the local gateway by running the usb0start.sh script:
sudo /usr/local/bin/usb0start.sh

Then on the Edison environment, start the usb0 interface:
ifup usb0

After you're done with Edison, the gateway can be deactivated by running the usb0stop.sh script:
sudo /usr/local/bin/usb0stop.sh

Troubleshooting

If Edison cannot lease an IP from the host computer or see IP addresses beyond the gateway, you can enable logging on Dnsmasq by adding the following lines to the /etc/dnsmasq.conf file:
log-queries
log-dhcp

Then use tail -f /var/log/syslog to check for messages.

On Kubuntu the network manager tried to setup the usb0 interface using eth0's configuration every time it was turned on, messing the DHCP service. This was solved by explicitly binding the configuration to eth0 on the network manager's GUI.