Friday, July 24, 2015

USB Reverse Tethering with Android 5.1 (Root required)

Hi,

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 10.42.0.2/24 dev usb0
    adb> # ip link set usb0 up
    adb> # ip route add default via 10.42.0.1
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 10.42.0.1 dev usb0 
10.42.0.0/24 dev usb0  proto kernel  scope link  src 10.42.0.2 
192.168.178.0/24 dev wlan0  proto kernel  scope link  src 192.168.178.164

... but all connections were routed over the wlan0 device:
adb> # tracepath 8.8.8.8
 1:  192.168.178.164                                       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 192.168.178.1 dev wlan0
192.168.178.0/24 dev wlan0  proto kernel  scope link  src 192.168.178.164

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 10.42.0.1 table wlan0
adb> # ip route add 10.42.0.0/24 dev usb0 table wlan0

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