Saturday, October 14, 2023

Raspberry Pi Zero W OpenWrt Image With USB Ethernet Support

I made a secure and portable WiFi hotspot with a Raspberry Pi Zero W. Standard OpenWrt for the Pi didn't include necessary USB-to-Ethernet kernel modules, so I figured out the required packages and dependencies to add to the standard list. Then, I used this to generate a custom OpenWrt version. This allows you to use a USB-to-Ethernet adapter or connect the Pi Zero with USB OTG for WAN traffic.

The Pi Zero W mounted on USB-A Addon Board for power, or power and data (USB OTG).

Pi Zero WPi Zero W with USB Adapter Board


Note 1: YOU DO NOT NEED THIS ADDON BOARD. If all you want is a wired Ethernet port, get an adapter like the one you see below (and you'll need a power supply too,  of course).

Note 2: If you are using this addon board, I do not recommend plugging in the micro-USB hub shown below. (Things won't work right from what I can tell, and who knows it might even damage something? I don't intend on finding out myself).  The point of the add-on board is to enable you to plug it into a router or computer (with rNDIS enabled) so the Pi Zero can get power and (WAN) data from it.

The micro-USB hub I use...

USB OTG Adapter

Pi Zero W with USB-to-Ethernet adapter, micro-USB hub or as a USB OTG device, the OpenWrt firmware generated should work for all three of those options.

Building the OpenWrt Image

OpenWrt Firmware Builder



1. Navigate to the OpenWrt image for the Raspberry Pi Zero W image (22.03.5 at the time of this writing)


2. Click the Customize Installed packages and/or first boot script drop-down

3. Replace the list in the Installed Packages field with the following:

base-files bcm27xx-gpu-fw bcm27xx-userland brcmfmac-firmware-usb busybox ca-bundle cgi-io cypress-firmware-43430-sdio cypress-nvram-43430-sdio-rpi-zero-w dnsmasq dropbear e2fsprogs firewall4 fstools fwtool getrandom hostapd-common iw iwinfo jansson4 jshn jsonfilter kernel kmod-brcmfmac kmod-brcmutil kmod-cfg80211 kmod-crypto-crc32c kmod-crypto-hash kmod-crypto-sha256 kmod-fs-configfs kmod-fs-vfat kmod-hid kmod-hid-generic kmod-input-core kmod-input-evdev kmod-lib-crc-ccitt kmod-lib-crc32c kmod-libphy kmod-mii kmod-mmc kmod-nf-conntrack kmod-nf-conntrack6 kmod-nf-flow kmod-nf-log kmod-nf-log6 kmod-nf-nat kmod-nf-reject kmod-nf-reject6 kmod-nfnetlink kmod-nft-core kmod-nft-fib kmod-nft-nat kmod-nft-offload kmod-nls-base kmod-nls-cp437 kmod-nls-iso8859-1 kmod-nls-utf8 kmod-phy-ax88796b kmod-ppp kmod-pppoe kmod-pppox kmod-slhc kmod-sound-arm-bcm2835 kmod-sound-core kmod-usb-core kmod-usb-dwc2 kmod-usb-gadget kmod-usb-gadget-eth kmod-usb-hid kmod-usb-lib-composite kmod-usb-net kmod-usb-net-asix kmod-usb-net-asix-ax88179 kmod-usb-net-cdc-ether kmod-usb-net-cdc-ncm kmod-usb-net-rtl8152 kmod-usb-roles libblkid1 libblobmsg-json libc libcomerr0 libext2fs2 libf2fs6 libgcc1 libiwinfo-data libiwinfo-lua libiwinfo libjson-c5 libjson-script liblua5.1.5 liblucihttp-lua liblucihttp0 libmnl0 libnftnl11 libnl-tiny libpthread librt libsmartcols1 libss2 libubox libubus-lua libubus libuci libuclient libucode libustream-wolfssl libuuid libwolfssl logd lua luci luci-app-firewall luci-app-opkg luci-base luci-lib-base luci-lib-ip luci-lib-jsonc luci-lib-nixio luci-mod-admin-full luci-mod-network luci-mod-status luci-mod-system luci-proto-ipv6 luci-proto-ppp luci-ssl luci-theme-bootstrap mkf2fs mtd netifd nftables-json odhcp6c odhcpd-ipv6only openwrt-keyring opkg partx-utils ppp ppp-mod-pppoe procd procd-seccomp procd-ujail px5g-wolfssl r8152-firmware rpcd rpcd-mod-file rpcd-mod-iwinfo rpcd-mod-luci rpcd-mod-rrdns ubox ubus ubusd uci uclient-fetch ucode ucode-mod-fs ucode-mod-ubus ucode-mod-uci uhttpd uhttpd-mod-ubus urandom-seed usign wireless-regdb wpad-basic-wolfssl


4. Edit the wlan_name, wlan_password, root_password, etc. variables in the script below, and then add it in the Script to run on first boot (uci-defaults) field.


# Beware! This script will be in /rom/etc/uci-defaults/ as part of the image.
# Uncomment lines to apply:
#
wlan_name="YourWiFi"
wlan_password="YourSuperSecretWiFiPassword!"
#
root_password="YourSuperSecretPassword!"
lan_ip_address="192.168.1.1"
#
# pppoe_username=""
# pppoe_password=""

# log potential errors
exec >/tmp/setup.log 2>&1

echo g_ether > /etc/modules.d/56-g_ether
echo dtoverlay=dwc2 >> /boot/config.txt

if [ -n "$root_password" ]; then
  (echo "$root_password"; sleep 1; echo "$root_password") | passwd > /dev/null
fi

# Configure LAN
# More options: https://openwrt.org/docs/guide-user/base-system/basic-networking
if [ -n "$lan_ip_address" ]; then
  uci set network.lan.ipaddr="$lan_ip_address"
  uci commit network
fi

# Configure WLAN
# More options: https://openwrt.org/docs/guide-user/network/wifi/basic#wi-fi_interfaces
if [ -n "$wlan_name" -a -n "$wlan_password" -a ${#wlan_password} -ge 8 ]; then
  uci set wireless.@wifi-device[0].disabled='0'
  uci set wireless.@wifi-iface[0].encryption='psk2'
  uci set wireless.@wifi-iface[0].ssid="$wlan_name"
  uci set wireless.@wifi-iface[0].key="$wlan_password"
  uci commit wireless
fi

# Configure PPPoE
# More options: https://openwrt.org/docs/guide-user/network/wan/wan_interface_protocols#protocol_pppoe_ppp_over_ethernet
if [ -n "$pppoe_username" -a "$pppoe_password" ]; then
  uci set network.wan.proto=pppoe
  uci set network.wan.username="$pppoe_username"
  uci set network.wan.password="$pppoe_password"
  uci commit network
fi

echo "All done!"


5. Click Request Build

6. Download the resulting Factory (Ext4) image

7. Flash to you Pi's SD Card

8. Boot up the Pi Zero

9. Connect to the Pi Zero's WiFi, and open the web interface at https://192.168.1.1 with the root password you set above

10. Reboot the Pi Zero (so the g_ether module will load from now on)

11. Connect to the web interface again, and configure your OpernWrt router as desired

12. Bonus step: Delete the script in Step 4 from /rom/etc/uci-defaults/ because it is the right thing to do (security is important, right?)

I hope someone finds this useful.  It took me more time than I would've liked to figure it out and in getting it to work, so enjoy!

Resources:

micro-USB Hub:
OTG Cable to Ethernet Adapter for Alexa TV Cube, TV Stick Lite 2020, Show (2nd Gen), Micro USB HUB with Power 

Pi Zero W USB-A Addon Board:

A few helpful pages:



Version 20231028