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).
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...
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
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:
Expanding The Root Filesystem to use the entire SD Card I tried it, it works.
Version 20231028