EBC Exercise 02 Internet Connection via the Host

From eLinux.org
Jump to: navigation, search

One of the slickest features of the Bone is it's ability to access the Internet through the USB connection. On your Linux host computer run:

host$ ifconfig
eth0     Link encap:Ethernet  HWaddr 00:18:8b:72:b8:c2  
         inet addr:137.112.41.109  Bcast:137.112.41.255  Mask:255.255.255.0
         inet6 addr: fe80::218:8bff:fe72:b8c2/64 Scope:Link
         UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
         RX packets:8481193 errors:0 dropped:0 overruns:0 frame:0
         TX packets:1871287 errors:0 dropped:0 overruns:0 carrier:0
         collisions:0 txqueuelen:1000 
         RX bytes:3172154531 (3.1 GB)  TX bytes:203188180 (203.1 MB)
         Interrupt:19 

eth4     Link encap:Ethernet  HWaddr d4:94:a1:39:ff:ff  
         inet addr:192.168.7.1  Bcast:192.168.7.3  Mask:255.255.255.252
         inet6 addr: fe80::d694:a1ff:fe39:ffff/64 Scope:Link
         UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
         RX packets:8 errors:0 dropped:0 overruns:0 frame:0
         TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
         collisions:0 txqueuelen:1000 
         RX bytes:2775 (2.7 KB)  TX bytes:1234 (1.2 KB)

lo       Link encap:Local Loopback  
         inet addr:127.0.0.1  Mask:255.0.0.0
         inet6 addr: ::1/128 Scope:Host
         UP LOOPBACK RUNNING  MTU:16436  Metric:1
         RX packets:37315 errors:0 dropped:0 overruns:0 frame:0
         TX packets:37315 errors:0 dropped:0 overruns:0 carrier:0
         collisions:0 txqueuelen:0 
         RX bytes:3665320 (3.6 MB)  TX bytes:3665320 (3.6 MB)

You'll see a new network has appeared, eth4 in my case. The IP address is 192.168.7.1. There's a good chance the Bone is at 192.168.7.2. Try connecting to it.

host$ ssh -X root@192.168.7.2
beagle$ 

You are now logged into the Bone through the network. This is much faster than the serial port (.115M vs. 100M) and supports many interesting network things. The only problem is, the Beagle doesn't know how to access the Internet through the host. Get back to the host computer by entering RETURN ~ ^Z. That is, hit RETURN, then ~ (it's up there near the ESC key) and then Ctrl-Z. This gets you back to your host, but leaves the ssh connection running.

Copy the following lines into a file call host.ipForward.sh

#!/bin/bash
# These are the commands to run on the host to setup IP masquerading so the Beagle
#  can access the Internet through the USB connection.
# Inspired by http://thoughtshubham.blogspot.com/2010/03/internet-over-usb-otg-on-beagleboard.html

if [ $# -eq 0 ] ; then
echo "Usage: $0 interface (such as eth0 or wlan0)"
exit 1
fi

interface=$1
hostAddr=192.168.7.1
beagleAddr=192.168.7.2
ip_forward=/proc/sys/net/ipv4/ip_forward

if [ `cat $ip_forward` == 0 ]
  then
    echo "You need to set IP forwarding. Edit /etc/sysctl.conf using:"
    echo "$ sudo gedit /etc/sysctl.conf"
    echo "and uncomment the line   \"net.ipv4.ip_forward=1\""
    echo "to enable forwarding of packets. Then run the following:"
    echo "$ sudo sysctl -p"
    exit 1
  else
    echo "IP forwarding is set on host."
fi
# Setup  IP masquerading on the host
sudo iptables -t nat -A POSTROUTING -s 192.168.0.0/16 -o $interface -j MASQUERADE

# Check to see what nameservers the host is using and copy these to the same
#  file on the Beagle
# This makes it so you can connect to the Beagle without using your password.
ssh-copy-id root@$beagleAddr
# Save the /etc/resolv.conf on the Beagle in case we mess things up.
ssh root@$beagleAddr "mv -n /etc/resolv.conf /etc/resolv.conf.orig"
# Copy the resolv.conf file to the Beagle.  Now the Beagle will use the
# same name servers as the host.
cat /etc/resolv.conf - << EOF > /tmp/resolv.conf
nameserver 137.112.18.59
nameserver 137.112.5.28
nameserver 137.112.4.196
search rose-hulman.edu
nameserver 8.8.8.8
nameserver 8.8.4.4
EOF
scp /tmp/resolv.conf root@$beagleAddr:/etc
# Tell the beagle to use the host as the gateway.
ssh root@$beagleAddr "/sbin/route add default gw $hostAddr"

Now run:

host$ chmod +x host.ipForward.sh
host$ ./host.ipForward.sh eth0

This will give you instructions on how to set up your host and will remotely set up your Beagle. Note: If you are using a wireless connection you should use host$ ./host.ipForward.sh wlan0

Once ./host.ipForward.sh has been run you can:

host$ fg
ssh -X root@192.168.7.2
(Hit RETURN)
beagle$ ping google.com

You should see Google responding. Hit Ctrl-C to stop.

Note: If you are using Ubuntu 12.04 and having an problem connecting to the internet, you may need to add a line to the /etc/resolv.conf file on the Bone. If ping google.com returns an "unknown host" error, this means that the Bone cannot resolve the url google.com to an IP address. Users with an Ubuntu 12.04 host may see this issue because the resolv.conf that Ubuntu uses (and is copied to the Bone in the host.ipForward.sh script) is not compatible with the Bone. The solution is to run the host.ipForward script as normal, then add the line "nameserver 8.8.8.8" above the existing entry in /etc/resolv.conf (run "nano /etc/resolv.conf" on the Bone to edit the file). This configures the Bone to use Google's Public DNS Server.

Congratulations! Your Beagle is now on the network through your host computer.

From Tips and Tricks

Two options: One uses Ubuntu's GUI network connections manager, the other requires modifying things yourself.

Option 1 - Using Ubuntu Network Connections GUI

  1. In Ubuntu, go to System -> Preferences -> Network Connections
  2. On the 'Wired' tab, select 'Auto eth0' and click 'Edit' (Note: name may be other than 'eth0'. If nothing exists in this list, then make sure there is not an entry starting with 'auto eth0' in your /etc/network/interfaces file; such an entry prevents Network Manager from managing that interface.)
  3. Click the 'IPv4 Settings' tab and change 'Method' to 'Shared to other computers'
  4. Click apply
  5. Restart Ubuntu
  6. Connect the BeagleBoard to the laptop with the crossover Ethernet cable
  7. Boot the BeagleBoard - if Ubuntu was already running and the Ethernet cable was already plugged in, the BeagleBoard should automatically get assigned an IP address and you should be able to access the Internet on the BeagleBoard via the laptop's wireless connection

Option 2 - Modifying Things Yourself (DHCP Server)

This will setup a DHCP server on the host machine that will listen to the Ethernet port and assign an IP address to the BeagleBoard when it is connected with an Ethernet crossover cable. The host machine will then act as a router using NAT to send packets out the wifi interface.
A number of steps were taken from the Ubuntu Community Documentation.
Notes:

  • 'eth0' will refer to the internal interface (connected to the BeagleBoard) and 'wlan0' will refer to the external interface (connected to the Internet). Your interface names may differ.
  • A number of configuration files are changed. It's a good idea to save a backup copy of these before modifying them.

On the host machine, configure eth0 for a static IP:

host$ sudo ifconfig eth0 192.168.1.13

If you don't want to configure this after every boot, add an entry to /etc/network/interfaces with the following:

auto eth0
    address 192.168.1.13
    netmask 255.255.255.0
    network 192.168.1.0
    broadcast 192.168.1.255 

On the host machine, configure the IP tables to use NAT translation for routing packets:

host$ sudo iptables -A FORWARD -o wlan0 -i eth0 -s 192.168.1.0/24 -m conntrack --ctstate NEW -j ACCEPT
host$ sudo iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
host$ sudo iptables -A POSTROUTING -t nat -j MASQUERADE

To avoid having to setup the IP tables after every boot, save the IP tables

host$ sudo iptables-save | sudo tee /etc/iptables.sav

And add the following command to /etc/rc.local (or other appropriate file for your distribution) to be run at boot

iptables-restore < /etc/iptables.sav

IP forwarding needs to be enabled:

host$ sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"

To make sure this is set after rebooting, add these lines to /etc/sysctl.conf:

net.ipv4.conf.default.forwarding=1
net.ipv4.conf.all.forwarding=1

Install the DHCP server software

host$ sudo apt-get install dhcp3-server

And edit the configuration file /etc/dhcp3/dhcpd.conf (comment out any already existing lines other than "ddns-update-style none;")

#Added for DHCP with BeagleBoard
default-lease-time 600;
max-lease-time 7200;
option subnet-mask 255.255.255.0;
option broadcast-address 192.168.1.255;
option routers 192.168.1.13;     #<--This must match the IP address you statically set for eth0
option domain-name-servers 137.112.4.196,137.112.5.28,137.112.12.11;    #<--Rose-Hulman's DNS servers (according to my laptop, at least)
option domain-name "rose-hulman.edu";

subnet 192.168.1.0 netmask 255.255.255.0 {
range 192.168.1.14 192.168.1.14;  #<--You can specify a larger range; I used this to force my BeagleBoard to always have the same IP so I could add an entry for that IP in /etc/hosts
}

You may need to edit /etc/default/dhcp3-server to specify the interface for the DHCP server

INTERFACES="eth0"

Then restart the DHCP server service

host$ sudo service dhcp3-server restart

You may need to reboot your host machine, and it may be necessary to run the command above to restart the DHCP server every time you boot (I'm not sure if it starts appropriately at boot).

Now connect the BeagleBoard to the host machine with a crossover Ethernet cable and boot the Beagle. After booting, run 'ifconfig' to see if the Beagle was assigned an IP address. If it does not have an IP address, try running the command 'dhclient usb0'.

Once the Beagle does have an IP address, try

beagle$ ping -c 3 -W 10 www.google.com

to test if the setup is working correctly. If it complains about a bad name, the DNS servers are incorrect; try pinging a specific IP such as 8.8.8.8 to see if packets get through (though unless you want to rely on all IP addresses, you will need to get some DNS servers that work).

Option 3 - Manual Routing, Static Beagle IP

This will setup the routing on Ubuntu (sending all eth0 traffic out wlan0). It will then set a static IP address on the BeagleBoard (so you can stick an entry for your BeagleBoard in /etc/hosts for convenience). The key difference from Option 2 is that the DHCP server in that option supplied the BeagleBoard with DNS servers. In this option, we add a script that gives the BeagleBoard some static DNS server addresses every time it boots.

First, follow through the steps in Option 2 right up until it starts talking about installing the DHCP server. Instead of installing the DHCP server, do the following.

On your BeagleBoard, add the following entry to /etc/network/interfaces (comment out any pre-existing entries regarding 'usb0')

auto usb0
iface usb0 inet static
      address 192.168.1.14         # This is the static IP address of your choice
      netmask 255.255.255.0
      network 192.168.1.0
      gateway 192.168.1.13         # This must match the static IP address you assigned to eth0 on your host machine

After booting, the BeagleBoard is now configured with a static IP address and knows the gateway for all its traffic is the address of your host machine. The last thing to do is to make sure your BeagleBoard knows what DNS servers to use. This information is stored in the /etc/resolv.conf file. You could add it manually every time after boot, but we'll make a script to do it at boot instead.

On your BeagleBoard, navigate to the /etc/rc5.d/ directory. In this directory, create a file named S99<name> where <name> can be anything you prefer. My file was named S99SetRoseHulmanNameServers. Add the following inside that file:

#! /bin/sh
echo "nameserver 137.112.4.196" >> /etc/resolv.conf      # These three IP addresses are the Rose-Hulman DNS servers
echo "nameserver 137.112.5.28" >> /etc/resolv.conf       # Replace them with whatever DNS servers you are using
echo "nameserver 137.112.12.11" >> /etc/resolv.conf

That should be it. Assuming all cables are connected properly and you have a WiFi connection on the host machine, after booting the BeagleBoard should have a usable Internet connection.