Comments ▾
Figures ▾
Tables ▾

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

3.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.

Figure 1 — The GL-iNet Admin Panel, the friendlier vendor UI that layers on top of LuCI and the UCI configuration system to drive the OpenWrt stack. Source: static.gl-inet.com.
Figure 1 — The GL-iNet Admin Panel, the friendlier vendor UI that layers on top of LuCI and the UCI configuration system to drive the OpenWrt stack. Source: static.gl-inet.com.

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.

3.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.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.3.1 What GL-iNet adds

Table 1 — 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.3.2 Differences from upstream OpenWrt

Table 2 — 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.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.

3.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.

3.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.

3.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.

3.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

3.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.

3.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

3.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.

3.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.

3.6 The OLED + LED + Mode Daemons

Three GL-iNet-specific userspace daemons handle the front-panel UX:

Table 3 — 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.

3.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)

3.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.

3.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.

3.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.

3.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.

3.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).

3.11 Footnotes & References

Comments (0)

  1. Loading…

Comments are held for moderation — nothing appears until approved.