Friday, July 24, 2015

USB Reverse Tethering with Android 5.1 (Root required)


I've used USB reverse tethering years ago with my HTC Desire HD in cases were I had a faster ethernet connection or bad wifi signals. Today I wanted to use the ethernet connection of my laptop because the wifi was to unstable to make some videos offline available for later use.

So I decided to reactivate the (now officially unavailable) reverse tether mechanism of my Nexus 4 (with CM12).

The first steps were more or less easy:

  1. Enable the usb tethering device on the android phone (after connecting via USB of course)
    adb> # setprop sys.usb.config rndis,adb
  2. Making a "share connection with others" profile in NetworkManager
  3. Setup nat on the host
    host> # sysctl -w net.ipv4.ip_forward=1
    host> # iptables -t nat -F
    host> # iptables -t nat -A POSTROUTING -j MASQUERADE
  4. Setup the ip addresses and routes on the phone
    adb> # ip addr add dev usb0
    adb> # ip link set usb0 up
    adb> # ip route add default via
Aaaaand.... didn't work -.-

As I read somewhere many of the android apps ask the android API for a existing internet connection, and will only get a positive answer if a wifi or data connection is enabled.
As a wifi network was available (but with no internet uplink) I decided to connect to it to fool the system...

Things got weired... an ip route show command revealed that I had setup the route correctly:
adb> # ip route show
default via dev usb0 dev usb0  proto kernel  scope link  src dev wlan0  proto kernel  scope link  src

... but all connections were routed over the wlan0 device:
adb> # tracepath
 1:                                       1.129ms pmtu 1500

After some fiddling I noticed that the ip route command can handle multiple routing tables and there were a wlan0 routing table:
adb> # ip route show table wlan0
default via dev wlan0 dev wlan0  proto kernel  scope link  src

Now I had only to fix this table and everthing gots working :-) :
adb> # ip route delete default table wlan0
adb> # ip route add default via table wlan0
adb> # ip route add dev usb0 table wlan0

You'll find a shellscript setting things up for you at github