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

SectionTopic
1About this Volume
2The Layered Stack
3The GL-iNet OpenWrt Build vs Upstream
· 3.1What GL-iNet adds
· 3.2Differences from upstream OpenWrt
· 3.3Versioning convention
4UCI — The Configuration System
· 4.1Files in /etc/config/
· 4.2Persistent vs volatile state
· 4.3The procd ubus interface
5Admin Panel (the GL-iNet UI)
· 5.1What it covers well
· 5.2What it doesn’t cover
· 5.3The cloud client
6The OLED + LED + Mode Daemons
· 6.1Files & init scripts
· 6.2Hacking the OLED
7Customizing the Admin Panel
8Package Management — opkg
9uci-defaults — First-Boot Configuration
10Cheatsheet Updates
11Footnotes & References

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-onPurpose
gl-sdk4-* packagesTheir downstream userspace: Admin Panel UI, mode daemons, OLED, cloud client
gl-sdk-config-be3600Per-device hardware config (DTS overlays, RF cal, antenna matrix)
gl-cloud-tunnelOptional remote-management daemon — disable if not using cloud
gl-modeThe mode-cycle state machine (Ethernet/Repeater/Tethering/Cellular)
Custom LuCI themeColor/spacing tweaks, mostly cosmetic
Pre-installed VPN packagesWireGuard, OpenVPN, Tor — all compiled in by default
mwan3 enabled by defaultMulti-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

ConcernGL-iNet buildUpstream OpenWrt
Default LAN subnet192.168.8.0/24192.168.1.0/24
Default management IP192.168.8.1192.168.1.1
Wi-Fi enabled OOBYes (printed SSID + key)No (opt-in via LuCI/UCI)
Admin PanelInstalledNot present
LuCIInstalled (at /cgi-bin/luci)Installed (at /cgi-bin/luci)
mwan3Installed + enabledNot installed by default
Cloud daemonInstalled; toggleableN/A
Kernel version~Linux 5.15 (varies by release)Tracks upstream
Wi-Fi 7 driverVendor patches on top of mt7996mt7996 upstream (snapshot)
Update channelGL-iNet’s signed releasesOpenWrt’s per-release ImageBuilder
Build reproducibilityClosed (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:

DaemonWhat it does
gl-modeMode-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-ledFront 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/glconfig and /usr/sbin/gl-mode-handler to 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:

  1. A separate small status page at a custom path (e.g., /status showing VPN/IP/throughput). Add a uhttpd rule and a small Lua CGI.
  2. 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 [email protected], 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).

11. Footnotes & References