Use Android Phone as advance router using OpenWrt
Tags: openwrt, android, virtualmachine, networking
Published: 2024-07-13 10:40:32

# Introduction
This project began with the idea of running OpenWrt with a 5G modem in the most affordable way possible.

# Background
As a software engineer specializing in Platform Engineering, I sought an advanced router solution for home use. Previously I already had a intel NUC which I used to run OpenWRT router for home network.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7rnnp06rzvrtn6dfafwi.png)

# Power Consumption:
After observing a power consumption of approximately 14 watts during normal use, I decided to explore ARM alternatives.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y0yy4x6qh0q5n6vyp905.png)

# Research and Alternatives
I initially researched alternatives like the Raspberry Pi 4B and 5 models. I also considered using mobile operator internet, as I have a free 5G trial from my provider.

# Cost Considerations:
I found 5G modems for the Raspberry Pi to be too expensive, leading me to consider using android mobile to run OpenWrt.

# Project Steps
This led me to the idea of running OpenWrt on an Android phone to save the cost of a Raspberry Pi. Below are some options of running OpenWrt on Android

## 1. Directly run OpenWrt on Android
This is exceedingly difficult, as you need to rebuild openwrt for your phone and need to figure out all drivers and other things.
I have dropped this idea as need to spend lots of time figuring it out.

## 2. Running OpenWrt on Android OS as Docker container (or maybe lxc)

There are two main prerequisites:
1. A custom kernel build is required to enable features not available by default on Android. So, it is only possible for those phones which provide source code of their kernel or any third-party Android OS like lineageos if available for your phone. Detailed steps are already share by someone else in this post https://gist.github.com/FreddieOliveira/efe850df7ff3951cb62d74bd770dce27

2. Need to have root access, this is very easy if your already figure out above steps

For detailed instructions OpenWrt already maintained a guide given below.
Note: I tried the latest available version 23.05.3 is not working according to the given setup. Procd hangs with /sbin/init script, which can be due to multiple reasons, if someone interested can get into https://openwrt.org/docs/techref/init.detail.cc at step 2, it get hanged.

## 3. Running OpenWrt on Android OS in QEMU
  
### 3.1 QEMU with KVM

1. This process is currently complicated as KVM is not available on most phones. So, there are two options which I can get
Using official kvm which is only available for Google Pixel 6+ from android 13. So we don't know when it will be available for other
2. Build own android kernel with KVM support.
This is also prety much similar to Running OpenWrt on Android OS as Docker container, where need to build kernel with kvm module. I search the internet but didn't find single solution which works for large set of android models

### 3.2 QEMU without any hardware virtualization
Pre-requisite:
* Root phone
* termux installed

It is the easiest and most compatible way to run openwrt or any OS. The only problem is slow performance as compared to other solutions.
I will describe it in detail below how I tried it on Oneplus 9R Android Phone.

## 4. Running OpenWrt component directly in Android OS (in progress)
Initially I started to try to run using proot avaialble in termux but not able to run it. When I run /sbin/init it gets hanged, after looking to code looks like it hanged at Step 2 of https://openwrt.org/docs/techref/init.detail.cc as procd want to acquire pid 1 which is not possible (still my guess needs to look to code of it). 

## 5. Running OpenWrt in Limbo EMU (in progress)
Running OpenWrt on Limbo EMU is faster in performance as compared to qemu in termux. I already tried Limbo x86 with OpenWrt x86 which is running smoothly with greater performance, but I am not able to use bridge and tap networking.
My android phone is root but Limbo EMU is not able to get root access for tap and bridging. If someone can get it working, please let me know, I am also curious.

# QEMU without any hardware virtualization
In this we will explain the process of running OpenWrt on android phone. I have tested the solution on OnePlus 9R (android 13) which is rooted, but we generally using general android adb command/features which are available in all phones, please let me know if you have any problems/questions.

## 1. Pre-requisite:
   1.1 Rooted phone (su access)
   1.2 termux installed
   1.3 a system with adb connectivity with phone for shell access
## 2. Selection of networks
### 2.1. Internet Source (WAN)
We need to find the source of WAN which will be used to get the internet. It can be your mobile operator network or can also be WIFI or can also be from ethernet connected to your android Phone. 
Phone just need to connect to internet via any means, it will automatically be used by OpenWrt, no extra configuration needed.

### 2.2. Internet sharing (LAN)
This is the network which others used to connect to your Phone. We can use android existing personal hotspot also for this.
To achieve this open Android hotspot setting in Android and set all setting required. Enable hotspot and disable it (why disable? we will enable it using cli later)

#### 2.1.1. Now open termux
#### 2.1.2. Check it required setting for hotspot by `cat /data/vendor/wifi/hostapd/hostapd_wlan1.conf`
#### 2.1.3. Turn on hotspot by CLI command `Note: If OS get restart, please do again`

```
pkg install iw -y
unset LD_PRELOAD
# Created a virtual managed interface for hotspot
sudo iw phy phy0 interface add wlan1 type managed
# Run hotspot. Don't connect your phone now as they will not able to get IP and internet
sudo /vendor/bin/hw/hostapd -dd -g /data/vendor/wifi/hostapd/global -B /data/vendor/wifi/hostapd/hostapd_wlan1.conf
```
Note: Some android phones are capable of provide hotspot and connect to other wifi network simultaneously. In this example I am using 5 ghz (Wifi 6 mode) for hotspot (For LAN) and 2.4 ghz to connect internet (For WAN). So please use your setting according to network technology needed for LAN and WAN. 

### 2.3 Install Qemu 

#### 2.3.1 Use adb to access termux from adb (optional)
As operating termux from mobile is not friendly as compared to from big screen computer, so below are some steps to run termux from computer.

* Open termux app on android
* Run following command to install ssh server
```
pkg update
pkg install openssh -y
# Set password for ssh
passwd
# run ssh server in background
sshd
```
* Now connect from laptop after having adb connect (connect android phone from system and enable usb debugging)
```
# Forward android 
adb forward tcp:8022 tcp:8022
#ssh connect to android
ssh user@localhost -p 8022
```
Now you don't need to type commands in termux

#### 2.3.2 Install qemu and other required software/files
```
pkg install qemu-system-aarch64-headless qemu-utils wget curl tsu vim iw -y
mkdir openwrt
cd openwrt
# Download openwrt kernel
wget https://downloads.openwrt.org/releases/23.05.3/targets/armsr/armv8/openwrt-23.05.3-armsr-armv8-generic-kernel.bin -O openwrt-23-kernel
# Download openwrt root image
wget https://downloads.openwrt.org/releases/23.05.3/targets/armsr/armv8/openwrt-23.05.3-armsr-armv8-generic-squashfs-rootfs.img.gz -O openwrt-23-root.img.gz
gunzip -d openwrt-23-root.img.gz

# Convert and Resize root img
qemu-img convert -f raw -O qcow2 openwrt-23-root.img openwrt-23-root.qcow2
rm openwrt-23-root.img
qemu-img resize openwrt-23-root.qcow2 1G # replace 1G with your value
```

#### 2.3.3 Setup network bridge, so that OpenWrt access and manage personal android hotspot.
* Create a file `/data/data/com.termux/files/usr/etc/qemu/bridge.conf` with following entry

```
allow br0
```
* Create bridge network for sharing. `Note: If OS get restart, please do again`
```
sudo ip link add br0 type bridge
sudo ip link set dev wlan1 master br0
sudo ip link set dev br0 up
```

#### 2.3.4 Run Openwrt 
* Qemu Start 
```
sudo qemu-system-aarch64 -M virt -cpu cortex-a76 -accel tcg,thread=multi -m 256 -smp 4 -nographic -kernel openwrt-23-kernel -drive if=none,file=openwrt-23-root.qcow2,id=hd0 -device virtio-blk-device,drive=hd0 -append "root=/dev/vda" -device virtio-net,netdev=eth0,mac=92:e1:8f:69:43:b4 -netdev bridge,br=br0,id=eth0 -device virtio-net,netdev=eth1 -netdev user,id=eth1,net=192.0.2.0/24,dns=8.8.8.8
```

* Wait for system to boot (takes 2-5 min), when you see 8021q: adding VLAN 0 to HW filter on device eth1, then press enter
Check all networking is setup by ifconfig

```
ifconfig
br-lan    Link encap:Ethernet  HWaddr 92:E1:8F:69:43:B4
          inet addr:192.168.1.1  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fd52:7f52:bb2b::1/60 Scope:Global
          inet6 addr: fe80::90e1:8fff:fe69:43b4/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:4 errors:0 dropped:0 overruns:0 frame:0
          TX packets:32 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:240 (240.0 B)  TX bytes:4384 (4.2 KiB)

eth0      Link encap:Ethernet  HWaddr 92:E1:8F:69:43:B4
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:11 errors:0 dropped:0 overruns:0 frame:0
          TX packets:41 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:866 (866.0 B)  TX bytes:7056 (6.8 KiB)

eth1      Link encap:Ethernet  HWaddr 52:54:00:12:34:56
          inet addr:192.0.2.15  Bcast:192.0.2.255  Mask:255.255.255.0
          inet6 addr: fec0::5054:ff:fe12:3456/64 Scope:Site
          inet6 addr: fe80::5054:ff:fe12:3456/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:176 errors:0 dropped:0 overruns:0 frame:0
          TX packets:198 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:19852 (19.3 KiB)  TX bytes:17786 (17.3 KiB)

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:65536  Metric:1
          RX packets:212 errors:0 dropped:0 overruns:0 frame:0
          TX packets:212 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
```
* Configure dns forwarding 
```
uci add_list dhcp.@dnsmasq[0].server="8.8.8.8"
uci add_list dhcp.@dnsmasq[0].server="8.8.4.4"
uci commit dhcp
service dnsmasq restart
```

## Now that is all, please connect to Wifi personal hotspot, hopefully internet will be running. 

#### 2.3.5 Configure QEMU for internet speed test (optional)
```
opkg update
opkg install iperf3
iperf3 -s -f M
```

Now on your connected system run iperf3 for testing

```
iperf3 -f m -c 192.168.1.1 -n 10240M

# When screen off
[  5] 459.00-460.00 sec  15.0 MBytes   126 Mbits/sec    0   2.00 MBytes   57ms
[  5] 460.00-461.00 sec  15.3 MBytes   128 Mbits/sec    0   2.00 MBytes   68ms
[  5] 461.00-462.01 sec  14.4 MBytes   119 Mbits/sec    0   2.00 MBytes   64ms
[  5] 462.01-463.00 sec  15.3 MBytes   130 Mbits/sec    0   2.00 MBytes   59ms
[  5] 463.00-464.00 sec  14.3 MBytes   120 Mbits/sec    0   2.00 MBytes   60ms
[  5] 464.00-465.00 sec  15.6 MBytes   131 Mbits/sec    0   2.00 MBytes   53ms
[  5] 465.00-466.00 sec  15.0 MBytes   126 Mbits/sec    0   2.00 MBytes   54ms
[  5] 466.00-467.00 sec  15.0 MBytes   126 Mbits/sec    0   2.00 MBytes   57m

# when screen On
[  5]   3.00-4.00   sec  44.4 MBytes   372 Mbits/sec    0   2.00 MBytes   14ms
[  5]   4.00-5.00   sec  41.4 MBytes   348 Mbits/sec    0   2.00 MBytes   31ms
[  5]   5.00-6.00   sec  39.3 MBytes   329 Mbits/sec    0   2.00 MBytes   16ms
[  5]   6.00-7.00   sec  40.9 MBytes   343 Mbits/sec    0   2.00 MBytes   22ms
[  5]   7.00-8.00   sec  40.6 MBytes   340 Mbits/sec    0   2.00 MBytes   23ms
[  5]   8.00-9.00   sec  39.7 MBytes   333 Mbits/sec    0   2.00 MBytes   17ms
[  5]   9.00-10.00  sec  39.2 MBytes   329 Mbits/sec    0   2.00 MBytes   15ms
[  5]  10.00-11.00  sec  41.5 MBytes   348 Mbits/sec    0   2.00 MBytes   44ms
```

#### 2.3.6 Use USB connected to android in OpenWrt/Qemu

You can directly mount USB connected to android Phone in Qemu, just add following command according to your necessity in qemu 

* Get productid and vendor id from lsusb 
   If you don't get enough information from lsusb on android please search the product name in folder /sys/bus/usb/drivers/usb/*/ , in these folders you will find all required information which is generally shown in lsusb on linux. 
* Add extra argument in QEMU command as below to share get USB in QEMU 
   ```
   -usb -device qemu-xhci,id=xhci -device usb-host,vendorid=0x0bda,productid=0x8153,bus=xhci.0,id=dev01
   ```


FAQs:
* IP not getting when connect to Android Hotspot
   
    This generally happens when dhcp server of OpenWrt is not running. Please check 67/UDP port is listing or not. For more details please go to https://openwrt.org/docs/guide-user/base-system/dhcp





   #openwrt