PiTether: Mobile phone to ethernet bridge


If you saw me at DefCon this year, you probably saw me using my HP Jornada. There was also a pretty good chance that you saw me getting it online in strange ways...
HACK THE PLANET! (Or just dial up a BBS...)
Since there aren't payphones everywhere, though, I built something interesting back in May, preparing for DefCon. It's a very simple Raspberry Pi ethernet bridge. I did this mostly to avoid using the open WiFi at DefCon, understanding that 3G/4G shenanigans are happening, but with a higher barrier to entry than the 802.11a/b/g/n/ac mess.

Yes, that's a Raspberry Pi Model B inside a case made of LEGO bricks.

Setting up Arch Linux

Being no stranger to building embedded systems, I decided to go with a bare-bones Arch Linux ARM install on a 2GB SD card. You could likely run with an even smaller card if you wanted to. The installation instructions are pretty straight-forward if you're familiar with the command line.

Once you have Arch Linux up and running on the Pi, I recommend changing the default passwords (alarm/alarm, root/root) and then doing a system update to get the latest packages from base. Simply connect the Pi to the Internet through its ethernet port, then run "pacman -Syyu" as root.

Configuring the network

The 3 interfaces we worry about are eth0, usb0 and br0. The first two basically work right out of the box:

/etc/systemd/network/eth0.network exists from the default installation, so the ethernet port is already set up for us.

When you activate USB Tethering from Android while plugged in to most modern Linux distros, it shows up as a network device (in this case, usb0) without any extra configuration.

br0 (the bridge interface) needs to be configured. First, we establish a netctl profile for it. Put the following text into a file called /etc/netctl/br0

Description="PiTether USB/Ethernet connection"
BindsToInterfaces=(eth0 usb0)

Next, create a service file for systemd that calls netctl for the br0 interface. Put these contents in /etc/systemd/system/netctl@br0.service
.include /usr/lib/systemd/system/netctl@.service

Description=PiTether USB/Ethernet connection
Run the following command as root to enable the interface during start-up:

netctl enable br0

Reboot the Pi to make sure everything works as planned. To test:

  1. Plug in your phone and activate USB Tethering.
  2. Plug a device into the ethernet port of the Raspberry Pi
  3. Request a DHCP Lease (happens automatically on most devices)
  4. Try to browse the web or connect to something over the Internet (ping, ssh, etc)
As a finishing touch, I decided to make the entire filesystem read-only. This makes it so that the device can be safely powered off by simply unplugging it without any risk of corrupting the filesystem. I did this so that I never needed to SSH to it or hook up a console to safely shut it down. Since this is really a single-use project, this works pretty well. For more elaborate embedded-system work, I usually opt for a RAM disk configuration, but that's not needed here.

You can probably do this by sliding the write-protect tab on the SD card (for Pi A and B only) however, I opted to mark both filesystems "ro" in /etc/fstab. Apparently, root (/) is optional in fstab, but I added it by copying the /boot line and slightly altering the device and mountpoint fields. My /etc/fstab looks like this:
# /etc/fstab: static file system information
# file system   dir     type    options         dump    pass
/dev/mmcblk0p0  /       ext4    defaults,ro     0       0
/dev/mmcblk0p1  /boot   vfat    defaults,ro     0       0
You can give it one more reboot and test after that if you want. If you ever want to change anything in the filesystem, you can temporarily remount it read-write again by using the command "mount -o remount,rw /" while logged in as root. You can use that to remove ",ro" from the fstab options or to occasionally update packages.

blog comments powered by Disqus