GL-iNet GL-BE3600 · Volume 3
GL-iNet GL-BE3600 Volume 3 — Firmware Architecture: GL-iNet OpenWrt, Admin Panel, LuCI, UCI
Layered firmware stack from kernel to UI; the GL-iNet build vs upstream OpenWrt; package management and persistent state
Contents
1. About this Volume
This volume answers what’s running on the box, where it lives on disk, and what each layer is responsible for. From the kernel up: kernel + drivers, OpenWrt userspace, UCI configuration, LuCI (the OpenWrt UI), GL-iNet’s Admin Panel (the friendlier UI on top of LuCI), and the GL-iNet-specific daemons that handle modes / cloud / OLED.
Volumes that depend on this:
- Vol 4 boot/recovery — uses the partition layout and bootloader flow described here.
- Vol 5 networking — uses UCI config layout from §4.
- Vol 7 VPN workflows — sit in the Admin Panel layer (§5) but call into kernel WireGuard.
2. The Layered Stack
┌─────────────────────────────────────────────────────────────┐
│ Admin Panel (GL-iNet — vendor) │ http://192.168.8.1
│ Lua + Vue.js UI; calls UCI through ubus + JSON-RPC │
├─────────────────────────────────────────────────────────────┤
│ LuCI (upstream OpenWrt UI) │ http://192.168.8.1/cgi-bin/luci
│ Lua CGI; calls UCI directly │
├─────────────────────────────────────────────────────────────┤
│ UCI (Unified Configuration Interface) │ uci show / uci set
│ Reads /etc/config/*; writes through trigger scripts │
├─────────────────────────────────────────────────────────────┤
│ init.d services + procd │ /etc/init.d/* ; ubus
│ Service supervision; sock/event bus │
├─────────────────────────────────────────────────────────────┤
│ Kernel + drivers │ Linux 5.15.x (GL build)
│ mt7996 (Wi-Fi), mt753x (switch), kmod-usb-net-* (USB) │
├─────────────────────────────────────────────────────────────┤
│ U-Boot bootloader │ serial console / TFTP recovery
└─────────────────────────────────────────────────────────────┘
Each layer’s responsibilities are roughly:
- U-Boot: brings up DRAM, loads the kernel, sets up the watchdog. Recovery mode lives here (Vol 4 §3).
- Kernel: drivers (Wi-Fi, switch, USB), netfilter (firewall), routing table, SQM, eBPF JIT. Userspace doesn’t bypass the kernel for anything that matters.
- procd + init.d: OpenWrt’s service manager, replacing systemd. Lighter, scripts-based.
- UCI: configuration layer. Single source of truth for “what’s the LAN IP / SSID / firewall ruleset”. Stored as plain text under
/etc/config/. - LuCI: the upstream OpenWrt web UI. Maps UCI state to forms.
- Admin Panel: GL-iNet’s UI. Sits next to LuCI (not above), exposes the common 80% of operations as one-tap workflows. For anything not in the panel, drop to LuCI.
The two UIs read and write the same UCI config, so a change made in either propagates correctly. They occasionally race on simultaneous edits — don’t have both UIs up at once on the same setting.
3. The GL-iNet OpenWrt Build vs Upstream
GL-iNet ships a downstream fork of OpenWrt with their own version cadence (the “GL-iNet build” version — currently 4.x, semantically aligned roughly with OpenWrt 21.02 → 23.05 → 24.10 epochs). They take a stable upstream branch, layer their patches, build artifacts, and release.
3.1 What GL-iNet adds
| Add-on | Purpose |
|---|---|
gl-sdk4-* packages | Their downstream userspace: Admin Panel UI, mode daemons, OLED, cloud client |
gl-sdk-config-be3600 | Per-device hardware config (DTS overlays, RF cal, antenna matrix) |
gl-cloud-tunnel | Optional remote-management daemon — disable if not using cloud |
gl-mode | The mode-cycle state machine (Ethernet/Repeater/Tethering/Cellular) |
| Custom LuCI theme | Color/spacing tweaks, mostly cosmetic |
| Pre-installed VPN packages | WireGuard, OpenVPN, Tor — all compiled in by default |
mwan3 enabled by default | Multi-WAN stack — see Vol 5 §6 |
Most of these are user-friendly; some (gl-cloud-tunnel) you may want to disable on principle.
3.2 Differences from upstream OpenWrt
| Concern | GL-iNet build | Upstream OpenWrt |
|---|---|---|
| Default LAN subnet | 192.168.8.0/24 | 192.168.1.0/24 |
| Default management IP | 192.168.8.1 | 192.168.1.1 |
| Wi-Fi enabled OOB | Yes (printed SSID + key) | No (opt-in via LuCI/UCI) |
| Admin Panel | Installed | Not present |
| LuCI | Installed (at /cgi-bin/luci) | Installed (at /cgi-bin/luci) |
mwan3 | Installed + enabled | Not installed by default |
| Cloud daemon | Installed; toggleable | N/A |
| Kernel version | ~Linux 5.15 (varies by release) | Tracks upstream |
| Wi-Fi 7 driver | Vendor patches on top of mt7996 | mt7996 upstream (snapshot) |
| Update channel | GL-iNet’s signed releases | OpenWrt’s per-release ImageBuilder |
| Build reproducibility | Closed (signed binaries) | Open (rebuild from source) |
For travel use, the GL-iNet build wins on convenience. For long-term security + auditability, upstream OpenWrt wins. The escape path from one to the other is documented in Vol 4 §5.
3.3 Versioning convention
GL-iNet’s firmware versions look like 4.5.16-0809. The breakdown:
4— major release line (4.x is OpenWrt 22.03/23.05 era; 5.x is upstream 24.10)5— minor (kernel and toolchain refresh)16— patch (security fixes, package updates)0809— build date code (MMDD format)
Check current version: Admin Panel → System → Overview, or SSH cat /etc/openwrt_release.
4. UCI — The Configuration System
UCI (Unified Configuration Interface) is OpenWrt’s structured config layer. It’s the thing that makes OpenWrt declarative-config rather than the per-daemon-conf-file mess of a generic Linux box.
4.1 Files in /etc/config/
/etc/config/
├── dhcp ← DHCP server + DNS (dnsmasq config)
├── firewall ← Zones + rules (translated to nftables by fw4)
├── network ← Interfaces, routes, bridges, VLANs
├── system ← Hostname, timezone, NTP, log
├── wireless ← Wi-Fi radios + SSIDs
├── dropbear ← SSH server config
├── uhttpd ← The web server hosting LuCI/Admin Panel
├── wireguard ← WireGuard tunnels (when present)
├── openvpn ← OpenVPN clients/servers
├── mwan3 ← Multi-WAN policies
├── glconfig ← GL-iNet-specific: cloud, mode, LED, OLED policy
└── ... ← One file per service, more populated as packages add
Each file is ASCII and uci-format (a custom serializer). They look like:
config interface 'lan'
option device 'br-lan'
option proto 'static'
option ipaddr '192.168.8.1'
option netmask '255.255.255.0'
option ip6assign '60'
config interface 'wan'
option device 'eth1'
option proto 'dhcp'
Edit them with uci:
uci show network # everything
uci show network.lan # one section
uci set network.lan.ipaddr='192.168.10.1'
uci commit network # write to /etc/config/network
/etc/init.d/network restart # apply
Or directly (vi, nano), then uci commit + service restart.
4.2 Persistent vs volatile state
UCI lives in /etc/config/. On the BE3600, /etc/ is persistent — backed by a writeable overlay on top of the read-only rootfs. Specifically:
/ rootfs (read-only squashfs)
/overlay jffs2 overlay — the writeable layer
/etc, /var, /tmp tmpfs / overlay layered on top
Anything you write to /etc/ lands in the overlay and persists across reboots. Anything in /tmp/ or /var/run/ is volatile and disappears.
sysupgrade preserves /etc/config/ and /root/ by default. firstboot (factory reset) wipes the overlay — back to defaults from the squashfs.
4.3 The procd ubus interface
UCI changes don’t take effect until the relevant service notices. procd handles this through ubus triggers — when uci commit network runs, procd’s network init script picks up the change and restarts the right pieces.
For ad-hoc inspection:
ubus call network.interface.lan status # current LAN state
ubus call network reload # poke the network stack
ubus call session list # active LuCI sessions
5. Admin Panel (the GL-iNet UI)
Admin Panel is a Lua-backed web app served from uhttpd at http://192.168.8.1/. It’s distinct from LuCI (/cgi-bin/luci); both run side-by-side, both edit the same UCI config.
5.1 What it covers well
- VPN client setup (WireGuard, OpenVPN) — paste config, click Connect
- Mode switching (Router / Repeater / Access Point / Extender / Bridge)
- Captive-portal helper
- Cellular / tethering setup with one-tap detection
- Firmware upgrade UI (signed image upload + verify)
- LED + OLED behavior toggles
- Cloud-management opt-in/out
- DDNS
5.2 What it doesn’t cover
- Custom firewall rules beyond a small allow/deny preset list
- VLAN tagging on the switch (drop to LuCI)
- Per-interface mwan3 weights and policies (drop to LuCI)
- Custom DNS overrides (other than the DoH preset)
- IPv6 prefix delegation tuning
- Static routes other than the basic ones
- Anything requiring a UCI section the panel doesn’t model
For everything in the second list, LuCI is one click away at the same URL with /cgi-bin/luci appended. SSH is one ladder rung deeper. There’s nothing the Admin Panel locks you out of — it just doesn’t surface everything.
5.3 The cloud client
gl-cloud-tunnel is the daemon that, when enabled, opens a persistent connection to GL-iNet’s goodcloud.xyz infrastructure for remote management. By default on the BE3600 it ships disabled and opt-in. Verify:
/etc/init.d/gl_clouduser status
uci show glconfig.cloud_user
# both should show disabled / off
If you don’t want it ever: /etc/init.d/gl_clouduser disable and reboot. The Admin Panel’s cloud-management toggle is the friendly equivalent.
6. The OLED + LED + Mode Daemons
Three GL-iNet-specific userspace daemons handle the front-panel UX:
| Daemon | What it does |
|---|---|
gl-mode | Mode-cycle state machine: Ethernet / Repeater / Tethering / Cellular. Reads Mode-button events, drives mode transitions, updates the OLED. |
gl-oled (or similar) | Renders the icon row to the OLED via I²C. Polls mode state. |
gl-led | Front status-LED policy — boot, mode-transition, fault states. |
6.1 Files & init scripts
/etc/init.d/gl_mode ← procd init for the mode daemon
/etc/init.d/gl_health ← health monitor (LED green vs amber)
/sbin/gl-oled ← OLED renderer (binary)
/etc/config/glconfig ← UCI config consumed by these daemons
/etc/rc.button/ ← button-press handlers (Mode button → /etc/rc.button/wlan0)
6.2 Hacking the OLED
Two starting points:
- Custom OLED renderer: write a userspace program that grabs the I²C device the GL daemon owns (after stopping
gl-oled) and renders whatever you want. Suitable for a “VPN status / public IP / WAN throughput” dashboard. - Different mode set: edit
/etc/config/glconfigand/usr/sbin/gl-mode-handlerto add custom modes (e.g., “Tor”, “Bridge to Wireshark”, “Pentest mode”). Vol 10 §5 has a worked example.
Both require a backup before you start — see Vol 4 §6.
7. Customizing the Admin Panel
The Admin Panel UI lives under /usr/lib/lua/luci/ (LuCI extensions) and /www/ (static assets, Vue.js bundles for the GL panel).
The GL-iNet panel is closed-source in the binary distribution but the JS bundle is readable; you can reverse-engineer endpoints if needed. For most cases, just don’t bother — drop to LuCI or SSH. Editing the panel makes upgrades painful.
The two places customization makes sense:
- A separate small status page at a custom path (e.g.,
/statusshowing VPN/IP/throughput). Add auhttpdrule and a small Lua CGI. - A LuCI extension (a new tab under LuCI’s existing menu structure). LuCI is upstream and stable to extend.
8. Package Management — opkg
OpenWrt’s package manager. SSH in, then:
opkg update # refresh package indices
opkg list-installed | wc -l # see how many packages are present (~600+ on a stock GL-iNet build)
opkg list | grep wireguard # search the available packages
opkg install kismet-wrapper # install kismet (Vol 10 §3)
opkg remove gl-cloud-tunnel # remove a package (the cloud client, in this case)
Notes:
- Disk space is constrained — 256 MB NAND. Big packages (suricata-full, kismet with all UI components) eat 50+ MB. Watch
df -h. - opkg installs into the overlay (
/overlay), so a package install survives reboot but not factory reset. - GL-iNet’s package feeds add
gl-sdk4-*packages that aren’t in upstream OpenWrt. If you migrate to pure OpenWrt, you lose these.
9. uci-defaults — First-Boot Configuration
/etc/uci-defaults/ holds shell scripts that run once on first boot of a sysupgrade or firstboot. They’re how the device sets its factory defaults.
ls /etc/uci-defaults/
# 01-network 02-wifi 10-glconfig 99-migration
Useful pattern: drop a custom 99-my-defaults script in there before flashing, and the next boot applies your customizations automatically. Anything from a fresh-flash config recipe lives here.
After execution, the script is moved to /etc/uci-defaults-bak/ (or deleted, depending on the OpenWrt version). It does not re-run on subsequent boots.
10. Cheatsheet Updates
Inputs to Vol 12 from this volume:
- The two UI URLs:
http://192.168.8.1/(Admin Panel),http://192.168.8.1/cgi-bin/luci(LuCI). - SSH defaults:
ssh root@192.168.8.1, password from first-boot wizard. - UCI cheats:
uci show <file>,uci set <file>.<section>.<option>='value',uci commit <file>,/etc/init.d/<service> restart. - Persistent vs volatile:
/etc/config/persists;/tmp/doesn’t. - Cloud disable:
/etc/init.d/gl_clouduser disable. - Disk space watch:
df -h /overlay(NAND is small).