Soft router with Internet via USB tethering
Buy a mini PC
I use a Nano-ITX (12 × 12 cm) board.
Install Linux
Install Linux on the mini PC. I use Debian 11.
Connect mobile phone
Internet access of the mini PC is provided via a mobile phone's USB tethering.
Connect the mobile phone to the mini PC via a USB cable.
Select USB network sharing mode or something alike on the mobile phone.
Run:
ip addr
A network adapter named usb0 or something alike should appear.
Run:
dhclient -v usb0
The network adapter should get network settings set up via DHCP.
The DHCP service is provided by the mobile phone's virtual router.
Now that we have got Internet access on the mini PC, next we need configure the mini PC to become a soft router.
Bridge Ethernet ports
My mini PC has two Ethernet ports. Their network adapters are named enp3s0 and enp4s0, respectively. To work as a soft router, it is preferred to bridge the two network adapters as a single network adapter, so that devices connected to the two ports are within the same subnet.
Run:
cat <<'ZZZ' > /etc/network/interfaces
auto lo
iface lo inet loopback
iface enp3s0 inet manual
iface enp4s0 inet manual
auto br0
iface br0 inet static
bridge_ports enp3s0 enp3s4
address 10.0.0.254
netmask 255.255.255.0
iface usb0 inet manual
ZZZ
systemctl restart networking
# or
reboot
10.0.0.254
is the bridge adapter's IP address.
Make sure network adapter br0
is up:
ip addr
Enable OS routing
Run:
cp -av /etc/sysctl.conf /etc/sysctl.old.conf
cat <<'ZZZ' > /etc/sysctl.conf
net.ipv4.tcp_syncookies = 1
net.ipv4.ip_forward = 1
net.ipv4.conf.all.accept_redirects = 1
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.all.send_redirects = 1
net.ipv4.conf.all.accept_source_route = 1
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
ZZZ
sysctl -p
Set up iptables
Install iptables-persistent:
apt-get install -y iptables-persistent
Configure iptables:
cat <<'ZZZ' >> /etc/iptables/rules.v4
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A FORWARD -j ACCEPT
COMMIT
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:FORWARD - [0:0]
-A POSTROUTING -s 10.0.0.0/24 -o usb0 -m comment --comment "NAT for intranet" -j MASQUERADE
COMMIT
ZZZ
iptables-restore /etc/iptables/rules.v4
For the intranet's IP packets going out to Internet, postrouting masquerade, i.e. NAT, is required because their source IP address is intranet address, which is not routable on Internet during return trip.
Set up dnsmasq
Install dnsmasq:
apt -y install dnsmasq
Configure dnsmasq:
cat <<'ZZZ' > /etc/dnsmasq.conf
# Never forward plain names.
domain-needed
# Never forward addresses in the non-routed address spaces.
bogus-priv
# Query with each server strictly in the order in resolv.conf.
strict-order
# Add domain name automatically.
expand-hosts
# Is authoritative DHCP server.
dhcp-authoritative
# Interface.
interface=br0
# Local domain.
domain=home.local
# Dynamic IP assignment.
dhcp-range=10.0.0.240,10.0.0.249,255.255.255.0,1h
# Static IP assignment.
dhcp-host=00:00:00:00:00:01,host1,10.0.0.1,infinite
ZZZ
Start dnsmasq:
systemctl restart dnsmasq
Configure udev rule
One drawback of using a mobile phone as the Internet router is it may be plugged off often, when you need carry it to toilet for example. Having to re-run dhclient each time is inconvenient. What makes it even more inconvenient is that I've got a bunch of services that need be restarted each time the soft router's Internet resumes.
The udev event system comes to the rescue. We can run a script when the mobile phone's USB cable connects back. The key here is finding the right udev event.
List USB devices:
lsusb
Result:
...
Bus 001 Device 005: ID 22b8:2e24 Motorola PCS XT2175-2
...
The 001:005
is the "bus_num:device_num" that may vary with the USB port to
which the mobile phone is connected.
The 22b8:2e24
is the "vendor_id:product_id" that is a phone-specific fixed
value.
List the udev properties of the mobile phone:
udevadm info --query=property /dev/bus/usb/001/005
Result:
DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-2
DEVNAME=/dev/bus/usb/001/005
DEVTYPE=usb_device
DRIVER=usb
PRODUCT=22b8/2e24/504
TYPE=0/0/0
BUSNUM=001
DEVNUM=005
MAJOR=189
MINOR=4
SUBSYSTEM=usb
USEC_INITIALIZED=115177231
ID_VENDOR=motorola
ID_VENDOR_ENC=motorola
ID_VENDOR_ID=22b8
ID_MODEL=XT2175-2
ID_MODEL_ENC=XT2175-2
ID_MODEL_ID=2e24
ID_REVISION=0504
ID_SERIAL=motorola_XT2175-2_ZY22F62M75
ID_SERIAL_SHORT=ZY22F62M75
ID_BUS=usb
ID_USB_INTERFACES=:ef0401:0a0000:
ID_VENDOR_FROM_DATABASE=Motorola PCS
ID_PATH=pci-0000:00:14.0-usb-0:2
ID_PATH_TAG=pci-0000_00_14_0-usb-0_2
ID_FOR_SEAT=usb-pci-0000_00_14_0-usb-0_2
TAGS=:seat:
CURRENT_TAGS=:seat:
Create a udev rule:
cat <'ZZZ' > /etc/udev/rules.d/10-local.rules
ACTION=="bind", ATTR{manufacturer}=="motorola", ATTR{product}=="XT2175-2", ATTR{idProduct}=="2e24", ATTR{idVendor}=="22b8", RUN{program}+="/usr/bin/bash /opt/mobile_phone_on_connect_phase1.sh"
ZZZ
Create udev rule phase1 script:
cat <<'ZZZ' > /opt/mobile_phone_on_connect_phase1.sh
#!/usr/bin/env bash
echo /opt/mobile_phone_on_connect_phase2.sh | /usr/bin/at now
ZZZ
Create udev rule phase2 script:
cat <<'ZZZ' > /opt/mobile_phone_on_connect_phase2.sh
#!/usr/bin/env bash
/usr/bin/killall dhclient
/usr/bin/sleep 1
/usr/sbin/dhclient -v usb0 > /opt/dhclient.log 2>&1
/usr/bin/sleep 1
# Restart other services.
# ...
The reason to split into two udev rule scripts is that long running script, even if only 1 or 2 seconds, will get killed by the udev event system.
Now each time the mobile phone reconnects to the soft router, the soft router's Internet resumes automatically.
Comments: