Open-source project
3899/SimAdmin avatar
3899/SimAdmin

SimAdmin: a web control panel for Debian cellular CPE devices

🎉 面向Debian蜂窝CPE、随身WiFi、软路由类设备的 SIM/eSIM、蜂窝网络、短信、DDNS和系统状态管理系统。

813 stars289 forksRustGPL-3.0

At a glance

What is it?
SimAdmin is a GPL-3.0 licensed Rust and React application that puts a browser interface on a cellular CPE, portable hotspot or software router, covering SIM and eSIM management, network registration, SMS, DDNS, notification rules, scheduled automation, backup and OTA updates. It suits operators of small cellular devices who need a UI instead of modem commands, and it is a poor fit if you need a general purpose router interface or a device you do not control.
Who is it for?
SimAdmin suits an operator of a cellular CPE or portable hotspot who wants a browser based management plane instead of a serial console, because it wraps the modem APIs the device already exposes and adds the parts operators actually need, which are SMS handling, dynamic DNS, notification rules, scheduled tasks and remote updates.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 9 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A control panel for a box whose only interface is a modem

SimAdmin is described as a SIM and eSIM management system for Debian based cellular CPE devices, portable WiFi hotspots and software router type devices, covering SIM and eSIM, cellular networking, SMS, DDNS and system status.

The audience is specific, and it is not people building routers in general. It is operators of small cellular devices, where the device is a Debian box with a modem in it and the management surface is otherwise a serial console and a set of AT commands. A USB dongle sold as a mobile hotspot, an industrial CPE, a Debian based travel router or hotspot with a modem attached: these are the machines this software assumes.

The stack is a Rust backend and a React frontend. The backend is Rust with Axum and zbus, and the frontend is React with Vite and Material UI. The pages cover a dashboard, SIM card management, cellular network, device network, SMS management, a notification centre, an automation centre and OTA updates, with screenshots of each in the README.

The dashboard is the useful place to start reading, because it shows what the application considers its core state: online status, carrier, signal, network latency, quick switches for data, roaming and airplane mode, system resources, temperature, traffic, and device information.

The project is licensed GPL-3.0, the package manifest declares GPL-3.0-or-later, the primary language is Rust, the last push to the repository was on 2026-10-14, and the recent releases are v1.2.4 on 2026-10-14, v1.2.3 on 2026-10-09 and v1.2.2 on 2026-10-02. The project homepage points at SimAdminHub, a separate repository for multi-device centralised management.

ModemManager over D-Bus, with three fallbacks behind it

The mechanism the backend uses to talk to the hardware is stated plainly: it manages the modem mainly through the ModemManager D-Bus interface, and in some scenarios uses mmcli, qmicli or a direct AT connection as a fallback.

That layering is the right design for this class of device, and the reason is that ModemManager is the only interface that behaves consistently across modem vendors. Different modems expose different AT command sets, different QMI variants and different quirks, and ModemManager exists to paper over that. Building on its D-Bus API means the application inherits that abstraction rather than re-implementing it.

The fallbacks exist because ModemManager is not always present or not always working. The capability list mentions that when ModemManager is lost, the system triggers mmcli --scan-modems, and after repeated failures restarts ModemManager. The install path also completes and starts ModemManager and NetworkManager, cleans up historic wwan unmanaged configurations, and retriggers udev modem candidate detection.

The direct AT path is the last resort, and it is the reason the disclaimer exists. Band locking, for example, depends on ModemManager exposing a supported bands list, and the README states that some interfaces are limited by hardware and by ModemManager capabilities. The project is explicit that the overall health check is organised around Linux cellular devices that support ModemManager, and that the features available depend on the modem firmware, the kernel and the ModemManager version, so the actual device is the specification.

For an ARMv7 target specifically, the project states that QMI is the verified modem path for the first candidate release, and that MBIM and SMS capabilities are not in scope for it.

One binary serves the SPA, and systemd keeps it running

The deployment shape is unusually simple for an application of this size, and it is a deliberate constraint of the target hardware.

The backend binary hosts the frontend single page application in the same process, the default install location is /opt/simadmin, and the service runs under systemd. There is no separate web server, no node runtime in production and no reverse proxy to configure.

That matters on the devices in question. A portable hotspot has a modest CPU and often a small amount of RAM, and every additional process is memory that is not available for the modem stack and the data path. Serving the SPA from the same binary removes an entire runtime from the device.

The installation and operations documentation lives in the docs directory. There is an install and deployment guide covering one-click device installation and uninstallation, the default background access address and the first administrator password setup, a changelog, an environment and system management document covering the target device hardware and dependency requirements, the default install path, the eSIM management mechanism, systemd service maintenance and data persistence, and a developer guide covering the project structure, frontend and backend development builds, OTA builds, ADB deployment debugging and the D-Bus interface.

The security model is also simple, and the README describes it in one line: single administrator password login, with first-time setup, session cookies, protected API interception, and local SSH recovery. There is a dedicated security configuration page covering administrator password change, password policy, login protection and session timeout.

That is a defensible design for a device with one operator, and it is also a design that does not scale to multiple people, which is presumably why a separate project, SimAdminHub, exists for centralised multi-device management.

Three static builds, and the ARMv7 gap

The release architecture is described in one sentence: static builds are provided for aarch64-unknown-linux-musl, armv7-unknown-linux-musleabihf and x86_64-unknown-linux-musl, and the installation script selects one based on the device architecture.

Static linking against musl is the right choice for this target, and the reason is the same as the single process design. A statically linked binary has no shared library dependencies to resolve on a device whose root filesystem may be a minimal BusyBox system, and it removes a class of installation failures on embedded hardware with unusual library versions.

The Cargo workspace reinforces that this is a multi-crate project rather than a single binary, with the backend as one member and a set of crates alongside it.

toml
[workspace]
members = [
  "backend",
  "crates/simadmin-agent",
  "crates/simadmin-auth",
  "crates/simadmin-device-core",
  "crates/simadmin-device-runtime",
  "crates/simadmin-notify",
  "crates/simadmin-protocol",
  "crates/simadmin-sms-core",
]

The split by concern is informative on its own. There is a crate for the agent, one for authentication, two for the device layer, one for notifications, one for the protocol and one for SMS, which is a fairly clean statement of what the system actually does.

The release profile is tuned for small binaries, with symbols stripped, optimisation level set to z, link time optimisation enabled, a single codegen unit, and panics set to abort so the binary does not carry unwinding tables.

The one gap to know about is eSIM on ARMv7. The README states that the ARMv7 MVP does not include lpac or eSIM, that the install script does not install or call lpac on that target, and that the frontend hides the working mode and eSIM management entries there. On aarch64 and x86_64 the installer prepares a private lpac with a QMI APDU backend and validates the qmi and curl driver capabilities, while the OTA packages themselves are not bound to a particular lpac architecture or version.

The automation centre is a scheduler with a small action set

The automation centre page manages automation tasks and lets you search, filter and clean up the task execution logs, and the backend description gives the scheduling model in detail.

The scheduling engine is dual track. It supports a fixed point schedule, which is a weekday plus a specific time such as 03:00 on Tuesdays, and an interval schedule, which is every N minutes, hours or days such as every 180 days. Tasks can run in parallel in the background.

The action set is small and deliberately operational. There is a baseband restart, a safe system reboot with a delay, and sending an SMS, where the SMS action supports a random delay, automatic generation of random characters to avoid interception, and automatic retry when sending fails.

The random character generation is a small detail that tells you something about the target environment. It exists because some networks and some gateways filter automated looking SMS, and a scheduled report that looks identical every time is easy to block. It is a pragmatic answer to a problem that only appears in production.

The result of each run is written to a local SQLite log table with keyword search, date filtering, and manual or automatic cleanup strategies, and the success or failure of a task is pushed in real time to a notification channel. So the automation centre is not a script runner with a web page, it is a scheduler with a feedback loop, and the notification centre is where that feedback lands.

Notification rules, backup with rollback, and OTA updates

Three subsystems are worth pulling out of the page list, because they are where an operator spends the most time.

The notification centre has separate pages for forwarding logs, forwarding rules, forwarding channels and a multi-channel test send, plus a device status rules page and a notification log. Underneath, the backend supports SMS sending, receive listening, SQLite persistence and multi-channel notification forwarding, and the native DDNS synchronisation supports Tencent Cloud DNSPod, Alibaba AliDNS and Cloudflare, with independent IPv4 and IPv6 configuration, IP retrieval from the API or from the network interface, and change and failure event notifications. The default is to take the IP from the interface, with a built-in multi-interface API fallback available.

Backup and restore covers ten categories of component, including system configuration, SMS and notifications, packaged for archiving with verified import, scheduled cleanup, automatic backup scheduling, and a pre-import snapshot that allows a one-click rollback. The separate library and snapshot page suggests that configuration versions are kept as first class objects rather than as flat files.

The OTA page handles uploading an OTA package, fetching a release online, verification, and then applying or cancelling the update, with the backend doing the binary and frontend resource replacement. This is the feature that closes the loop for a device you cannot physically reach, and it is also the one the disclaimer treats most carefully.

The watchdog is worth noting in the same breath. Every 15 seconds it checks the connection state, the number of iptables rules and modem availability, and the design decision embedded in the disclaimer is that when it detects host firewall rules it only writes diagnostic logs and does not clear the rules automatically.

Editorial conclusion

SimAdmin suits an operator of a cellular CPE or portable hotspot who wants a browser based management plane instead of a serial console, because it wraps the modem APIs the device already exposes and adds the parts operators actually need, which are SMS handling, dynamic DNS, notification rules, scheduled tasks and remote updates. It does not suit a general purpose router, and it does not suit a device where someone else controls the hardware, because the project manipulates registration, data sessions, APN and system services directly. Before you install it, read the disclaimer section in the README, confirm your modem is managed by ModemManager and that your firmware exposes the capabilities you need, since the project states plainly that available features differ by modem firmware, kernel and ModemManager version, and note that the ARMv7 build is an MVP without lpac or eSIM support.

Frequently asked questions

What is SimAdmin?

It is a SIM and eSIM management system for Debian based cellular CPE devices, portable WiFi hotspots and software routers, covering cellular networking, SMS, DDNS and system status. The project is a Rust backend with Axum and zbus paired with a React, Vite and Material UI frontend.

How does SimAdmin talk to the modem?

The backend manages the modem mainly through the ModemManager D-Bus interface, falling back to mmcli, qmicli or a direct AT connection in some scenarios. When ModemManager is lost it triggers mmcli --scan-modems and restarts ModemManager after repeated failures.

How is SimAdmin installed and run on a device?

The backend binary serves the frontend single page application in the same process, installs by default to /opt/simadmin and runs under systemd. The documentation includes an install and deployment guide covering one-click installation and uninstallation, the default access address and the first administrator password setup.

Which architectures does SimAdmin support?

Static builds are provided for aarch64-unknown-linux-musl, armv7-unknown-linux-musleabihf and x86_64-unknown-linux-musl, and the installation script selects the one matching the device. The ARMv7 build is an MVP that does not include lpac or eSIM, and the frontend hides those entries on that target.

What does the SimAdmin automation centre support?

A dual track scheduler that runs tasks in parallel in the background, with either a fixed weekday and time schedule such as 03:00 on Tuesdays or an interval schedule such as every 180 days. The actions include restarting the baseband, a safe system reboot with a delay, and sending SMS with random delay, random character generation and automatic retry on failure.

Official sources

  1. 3899/SimAdmin on GitHub
  2. License: GPL-3.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/3899-simadmin.svg)](https://hysenlabs.com/projects/3899-simadmin)

Was this useful?