Reverse USB tethering on Linux

Hi, I have long been struggling with trying to make reverse USB tethering work, it. share the internet connection of my PC with my phone, where there is no Wifi available. In Fairphone this option is called “USB internet”, and for the heck of it, it just wouldn’t work. I am using Debian and Arch Linux on my PC and both come with NetworkManager which offers connection sharing via ethernet. On the pc side everything seemed fine, the network is up, IP forwarding and NAT are there, the DHCP server is waiting for requests. Still the phone just would not pick up an IP address.

However, when I finally had the brilliant idea of actually looking at the IP configuration of my phone, I found that in the “USB Internet” mode, the phone does not send out a DHCP request over the USB connection and instead simply used a fixed IP configuration, which seems to be specific to individual versions of windows. That’s kind of braindead, I feel, and even more so, since it is totally unconfigurable.

To make reverse USB tethering work in Linux I did the following:

adb shell
ip addr # (to find out which device is the usb connection, turns out it was rndis0)
ip addr add dev rndis0 # to match the subnet used by NetworkManager by default)
ip link set up dev rndis0
route del default # to kill the old default route which doesn’t work
ip route add default via dev rndis0

Of course, this change is not persistent, you have to repeat it each time you connect the phone (or write your little shellscript). It would be much better if android actually obtained the correct IP configuration via DHCP (and used the builtin fixed config only as a fallback).

BTW: A quicker way is to manually launch the dhcp client in adb shell:

dhcpcd rndis0


First, I don’t have a solution to your problem. But thank you very much for your post. I tried reverse tethering some while ago and didn’t manage to get it working. With your help I had more luck this time. For the benefit of others, I record my setup.

  • I connect my Fairphone with my Linux machine via usb and select the “USB-tethering” mode (not the “USB internet” mode as was suggested by @Johannes_Rohr).

  • On my Linux machine I issue the following commands as root

    sysctl -w net.ipv4.ip_forward=1

    ifconfig usb0 netmask

    iptables -t nat -F

    iptables -t nat -A POSTROUTING -j MASQUERADE

  • In the network manager I open the connection and in the tab “IPv4 Settings”, I choose “Shared to other computers”

  • On the Fairphone I launch the DHCP client (you can either use adb shell from your pc or the app Terminal Emulator to type on your phone)

    $ su

    dhcpcd rndis0

  • Then I’m able to use my PC’s internet connection on my Fairphone. :smile:

  • As a bonus, I wondered if it is possible to share this internet connection via a hotspot created on the Fairphone. Turns out it works. The required setup is similar to the one on the PC. First I enable WiFi-Hotspot in the settings.

  • On the Fairphone I then type the following commands

    echo 1 > /proc/sys/net/ipv4/ip_forward

    iptables -t nat -F

    iptables -t nat -A POSTROUTING -o rndis0 -j MASQUERADE

    iptables -P FORWARD ACCEPT

  • Now I can connect other devices with the mobile hotspot. :smile:


I have some problems with this:

  1. I do not seem to have a “USB internet” option on my Fairphone so I tried “USB debugging”.

  2. I do not have an rndis0 device on the phone. The command “ip addr #” gives the result:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ifb0: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 32
link/ether b2:ef:7d:3d:46:90 brd ff:ff:ff:ff:ff:ff
inet6 fe80::b0ef:7dff:fe3d:4690/64 scope link
valid_lft forever preferred_lft forever
3: ifb1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 32
link/ether aa:d1:d3:7b:77:fb brd ff:ff:ff:ff:ff:ff
inet6 fe80::a8d1:d3ff:fe7b:77fb/64 scope link
valid_lft forever preferred_lft forever
4: tunl0: mtu 1480 qdisc noop state DOWN
link/ipip brd
5: sit0: <NOARP,UP,LOWER_UP> mtu 1480 qdisc noqueue state UNKNOWN
link/sit brd
inet6 :: scope host
valid_lft forever preferred_lft forever
6: ip6tnl0: <NOARP,UP,LOWER_UP> mtu 1452 qdisc noqueue state UNKNOWN
link/tunnel6 :: brd ::
inet6 fe80::b0ef:7dff:fe3d:4690/64 scope link
valid_lft forever preferred_lft forever
7: ccmni0: <NOARP,UP,LOWER_UP> mtu 1410 qdisc pfifo_fast state UP qlen 1000
link/ether da:92:38:ae:8a:c1 brd ff:ff:ff:ff:ff:ff
inet scope global ccmni0
8: ccmni1: <NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 72:65:69:33:26:df brd ff:ff:ff:ff:ff:ff
9: ccmni2: mtu 1500 qdisc noop state DOWN qlen 1000
link/ether ee:81:b9:ae:1a:df brd ff:ff:ff:ff:ff:ff

None of these devices work instead of rndis0.