{"id":50513043,"url":"https://github.com/alphafox02/wardragon-console","last_synced_at":"2026-06-02T21:33:03.196Z","repository":{"id":360104572,"uuid":"1240601302","full_name":"alphafox02/wardragon-console","owner":"alphafox02","description":"Local web console for WarDragon drone detection kits — health dashboard, curated DragonSync config editor, USB-tether tablet access","archived":false,"fork":false,"pushed_at":"2026-05-25T01:48:37.000Z","size":61,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-25T03:24:56.116Z","etag":null,"topics":["counter-uas","dragonsync","drone-detection","remoteid","tak","wardragon"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alphafox02.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-16T10:33:57.000Z","updated_at":"2026-05-25T01:48:41.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/alphafox02/wardragon-console","commit_stats":null,"previous_names":["alphafox02/wardragon-console"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/alphafox02/wardragon-console","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alphafox02%2Fwardragon-console","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alphafox02%2Fwardragon-console/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alphafox02%2Fwardragon-console/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alphafox02%2Fwardragon-console/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alphafox02","download_url":"https://codeload.github.com/alphafox02/wardragon-console/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alphafox02%2Fwardragon-console/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33838216,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-02T02:00:07.132Z","response_time":109,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["counter-uas","dragonsync","drone-detection","remoteid","tak","wardragon"],"created_at":"2026-06-02T21:33:01.636Z","updated_at":"2026-06-02T21:33:03.190Z","avatar_url":"https://github.com/alphafox02.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# WarDragon Console\n\nA local web console for [WarDragon](https://github.com/alphafox02/WarDragon) drone detection kits. It is intended to run on the kit and answer: is this kit healthy, and what is it seeing right now?\n\n## Current Scope\n\n- Health dashboard from ZMQ snapshots:\n  - `4225` wardragon_monitor system/GPS/DragonSDR status\n  - `4227` droneid-go health\n  - `4228` DragonSig health\n- Drone and signal summaries from DragonSync HTTP:\n  - `GET /status`\n  - `GET /drones`\n  - `GET /signals`\n- Curated read/write view for the two allowlisted DragonSync config files:\n  - `/home/dragon/WarDragon/DragonSync/config.ini`\n  - `/home/dragon/WarDragon/DragonSync/gps.ini`\n\nThe console does not subscribe to high-rate drone/signal ZMQ ports and does not query systemd for service state.\n\n## Install on a kit\n\nIf you have not cloned it yet, drop the checkout next to DragonSync inside the WarDragon directory and run the installer:\n\n```bash\ncd ~/WarDragon\ngit clone https://github.com/alphafox02/wardragon-console.git WarDragon-Console\ncd WarDragon-Console\nsudo packaging/install.sh\n```\n\nThe installer is opinionated and built for the WarDragon kit layout. It is honest about that: it assumes a user named `dragon`, with DragonSync at `/home/dragon/WarDragon/DragonSync`. Override with `WARDRAGON_USER=\u003cname\u003e` and `WARDRAGON_DRAGONSYNC_DIR=/path` if you have a different layout — or just run the installer on a TTY and it will prompt for the user. Non-default values work but are best-effort: DragonSync itself was built around `dragon`, so a different user means you also took on the path mapping for DragonSync. The installer exits cleanly if the chosen user does not exist.\n\n`install.sh` is idempotent — re-run it any time you change packaging files or want to refresh the systemd unit.\n\nWhat it does:\n\n- apt-installs anything missing from `python3 python3-zmq rsync avahi-daemon avahi-utils python3-dbus python3-gi gir1.2-glib-2.0`. No pip and no virtualenv on the kit.\n- Copies source to `/opt/wardragon-console` and creates a `/usr/local/bin/wardragon-console` wrapper.\n- Installs `wardragon-console.service` (templated to the chosen user). Runs as that user, not root.\n- Installs `/etc/sudoers.d/wardragon-console` with a single narrow rule letting the service account run `systemctl restart dragonsync.service` and nothing else.\n- Publishes `wardragon.local` on the LAN via Avahi (`packaging/avahi/wardragon-console.service`) and a small CNAME publisher unit (`wardragon-avahi-alias.service`) that adds the alias over the Avahi D-Bus API — no `/etc/hostname` change.\n- Pins `wardragon.local` to `127.0.0.1` in `/etc/hosts` on the kit only, so the kit's own browser always reaches loopback. Remote clients ignore this and keep using mDNS.\n- Sets `deny-interfaces=` in `/etc/avahi/avahi-daemon.conf` to the kit's current docker bridges and veth pairs, so Avahi only announces on real network interfaces. If you create new docker networks later, re-run `install.sh`.\n- Creates `\u003cDragonSync\u003e/certs` (mode 0700, owned by the service user) for TAK certificate uploads.\n- Hardens the service unit (`ProtectSystem=strict`, `ProtectHome=read-only`, `PrivateTmp`, `RestrictAddressFamilies`, etc.). `NoNewPrivileges` is deliberately not set so the sudoers DragonSync restart still works.\n\n### Optional helper: GPS as backup time source\n\n`packaging/setup-time-sync.sh` is a separate, operator-run helper. It is **not** invoked by `install.sh` because it touches system-wide time configuration, and that is your call. Run it once per fresh kit image:\n\n```bash\nsudo packaging/setup-time-sync.sh\n```\n\nWhat it does (idempotent — safe to re-run):\n\n- apt-installs `chrony`, `gpsd`, `gpsd-clients` if missing.\n- Sets `START_DAEMON=\"true\"`, `USBAUTO=\"true\"`, `GPSD_OPTIONS=\"-n\"` in `/etc/default/gpsd`. Leaves `DEVICES=\"\"` so the gpsd udev rules auto-pick a plugged-in USB GPS.\n- Adds a managed `refclock SHM 0` block to `/etc/chrony/chrony.conf` so chrony reads gpsd's shared-memory time samples. Stratum 10 so internet NTP stays preferred when reachable, with offset/delay tuned for non-PPS serial GPS so chrony does not mark it as a falseticker.\n- Enables and (re)starts `chrony` and `gpsd.socket`.\n- Backs up the originals to `*.wardragon.bak` on first run.\n\nWhen internet NTP is reachable, chrony keeps using it. When the kit goes offline, chrony falls back to GPS so the system clock keeps tracking UTC instead of free-running.\n\n## Configuration model\n\nUseful environment overrides (set in `packaging/wardragon-console.service` for the packaged install):\n\n```bash\nWARDRAGON_DRAGONSYNC_DIR=/path/to/DragonSync\nWARDRAGON_DRAGONSYNC_URL=http://127.0.0.1:8088\nWARDRAGON_CONSOLE_HOST=127.0.0.1\nWARDRAGON_CONSOLE_PORT=4280\nWARDRAGON_CONSOLE_CONFIG_WRITE=1\nWARDRAGON_CONSOLE_TETHER_ENABLED=1\nWARDRAGON_CONSOLE_TETHER_CIDRS=192.168.42.0/24,192.168.43.0/24,172.20.10.0/28\nWARDRAGON_CONSOLE_REMOTE_CONFIG_WRITE=1\nWARDRAGON_CONSOLE_REMOTE_RESTART=0\nWARDRAGON_CONSOLE_UPDATE_CHECK=1\nWARDRAGON_CONSOLE_UPSTREAM_REPO=alphafox02/wardragon-console\nWARDRAGON_DRAGONSYNC_UPSTREAM_REPO=alphafox02/DragonSync\n```\n\nThe Version tab has a **Check for updates** button. It compares the local install to the configured upstream GitHub repos and tells you whether you are behind. It does not pull or apply anything — actually upgrading is still a manual `git pull \u0026\u0026 sudo packaging/install.sh`. Set `WARDRAGON_CONSOLE_UPDATE_CHECK=0` on air-gapped kits to disable the endpoint entirely.\n\nConfig writes are only allowed by default when the server is bound to loopback. If a future tether/tablet mode exposes the console on a non-loopback address, config writes stay disabled unless `WARDRAGON_CONSOLE_REMOTE_CONFIG_WRITE=1` is set.\n\nDragonSync restart is separate. Remote/tablet config editing does not imply remote restart; keep `WARDRAGON_CONSOLE_REMOTE_RESTART=0` if tablet users should save changes but not restart the service. The default packaged service allows tablet config writes but keeps tablet restart disabled.\n\nThe config UI is intentionally curated. It does not expose Kismet or ADS-B options yet. Saves are atomic and short-circuit when nothing actually changed; real changes create a single timestamped backup beside the edited file. DragonSync still needs a restart or reboot before most changes take effect.\n\nTAK certificate upload stores files under `\u003cDragonSync\u003e/certs/` and writes absolute paths into `config.ini`. Absolute paths are intentional even though DragonSync runs with `WorkingDirectory=\u003cDragonSync\u003e` — they survive future service changes and remove ambiguity.\n\n## Run for development\n\n```bash\npython3 -m venv .venv\n. .venv/bin/activate\npip install -e .\nwardragon-console\n```\n\nOpen `http://localhost:4280/`. No system install needed for iteration — everything reads from the working tree, and tests run with `PYTHONPATH=src python3 -m unittest discover -s tests`.\n\n## Tablet/Tether Access\n\nThe safe default is still `127.0.0.1:4280`. When `WARDRAGON_CONSOLE_TETHER_ENABLED=1`, the console watches for USB-tether-like network interfaces and starts a second HTTP listener only while one is present. This should be enabled by default on kit images so a headless operator does not need to turn on tablet mode from the UI.\n\nThe tether listener binds to the interface IP itself, not `0.0.0.0`. It only activates for known phone/tablet tether drivers/vendors **and** expected tether subnets. This avoids opening the console on the normal WarDragon USB Ethernet adapter, which is always present on many kits.\n\nDefault tether subnets:\n\n- Android USB tether: `192.168.42.0/24`\n- Android hotspot/tether variants: `192.168.43.0/24`\n- Apple personal hotspot: `172.20.10.0/28`\n\nOverride with `WARDRAGON_CONSOLE_TETHER_CIDRS` if a real device uses a different tether subnet.\n\nExamples:\n\n- Android USB tether usually appears as `rndis_host` / `cdc_ether` with an address like `192.168.42.x`.\n- iPhone/iPad USB tether usually appears as `ipheth` or Apple USB vendor `05ac` with an address like `172.20.10.x`.\n\nThe Overview and System tabs show the current tablet URL, for example `http://172.20.10.2:4280/`.\n\n### What `install.sh` sets up for discovery\n\n`install.sh` apt-installs `avahi-daemon`, `avahi-utils`, `python3-dbus`, `python3-gi`, and `gir1.2-glib-2.0` if missing, then makes four small changes so the kit is reachable as `wardragon.local`:\n\n- Installs [packaging/avahi/wardragon-console.service](packaging/avahi/wardragon-console.service) — advertises the HTTP service on port 4280 over mDNS.\n- Installs [packaging/wardragon-avahi-alias](packaging/wardragon-avahi-alias), run as `wardragon-avahi-alias.service`. It publishes a `wardragon.local` CNAME alongside the kit's own `\u003chostname\u003e.local` record via the Avahi D-Bus API. No `/etc/hostname` change.\n- Adds a small managed block to `/etc/hosts` pinning `wardragon.local` to `127.0.0.1` on the kit only. This makes the kit's *own* browser hit loopback instead of getting a docker-bridge or veth IP back from avahi. Remote clients ignore this entry.\n- Sets `deny-interfaces=` in `/etc/avahi/avahi-daemon.conf` to the kit's current docker bridges and veth pairs, so avahi only announces on real interfaces (eth/wifi/USB tether). Re-run `install.sh` if you create new docker networks later.\n\n### Discovering the kit from the tablet\n\nAfter plugging the tablet into the kit via USB and turning on USB tethering, the order to try:\n\n1. **iPhone/iPad:** Safari resolves `.local` natively. Open `http://wardragon.local:4280/`. Done.\n2. **Android Chrome:** Chrome does **not** resolve `.local` URLs by default. Either:\n   - Install a service-discovery app — *Service Browser* (Druk1, free) is the most common; *Discovery - DNS-SD Browser* and *Bonjour Browser* also work. Open it on the tether network, find *\"WarDragon Console on dragon\"*, tap to launch the URL in a browser.\n   - Or use **Firefox for Android**, which honors `.local` via the system NSD.\n3. **Either platform, mDNS fails (some tethers NAT or client-isolate):**\n   - Read the tether-side IP from the kit's display if HDMI is plugged in.\n   - Or read it from your phone's network settings — the kit will have an address in `192.168.42.x` (Android) or `172.20.10.x` (Apple), typically `.1` or `.2`. Try `http://\u003cthat-ip\u003e:4280/`.\n   - The Overview and System tabs show the current tablet URL once you do get in, so it's easy to bookmark for next time.\n\n### Trust model\n\nRemote config writes are enabled in the packaged service because physical tether/local access is the intended configuration path. Remote restart remains disabled unless `WARDRAGON_CONSOLE_REMOTE_RESTART=1`. Password/token fields are masked on non-loopback tablet listeners. Saving the masked placeholder preserves the existing secret; typing a new value replaces it, and clearing the field clears it.\n\n## Headless Access Strategy\n\nFor a no-screen kit the answer in priority order is:\n\n1. USB tether listener is auto-enabled on trusted tether interfaces (default in the packaged unit).\n2. `wardragon.local` is advertised via Avahi on every real interface (not docker/veth/bridge).\n3. If the tablet can't resolve `.local` — install a discovery app per the section above.\n4. If discovery also fails (rare; some carriers or USB-tether stacks block multicast), plug in HDMI/keyboard once and either bookmark the URL or set a static tether subnet override via `WARDRAGON_CONSOLE_TETHER_CIDRS`.\n\nThe kit cannot fully guarantee IP discovery on every tablet without a screen, a managed Wi-Fi AP, or a companion scanner. The combination above covers the common phones.\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falphafox02%2Fwardragon-console","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falphafox02%2Fwardragon-console","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falphafox02%2Fwardragon-console/lists"}