Repository navigation
Releases: SleeperXr/GravityLAN
Release list
GravityLAN 0.5.2
Fixed
- GravityUI: deleting a device works again. The confirmation opened behind the device editor (both sat on the same layer, and the confirmation was mounted earlier), so it could not be clicked. Confirmations now always open above dialogs and sheets.
- Network scan: devices whose name is only known through mDNS, NetBIOS or the system resolver (often TVs, phones and Macs) now get their hostname during the scan. Until now only names from reverse DNS were picked up and the rest stayed "Unknown" until an Info-Refresh by hand. A device on the dashboard without a hostname also takes over a name the scan finds; a name you gave it stays.
docker pull sleeperxr/gravitylan:0.5.2Also available as sleeperxr/gravitylan:latest. The agent stays at 0.3.9, so no agent update is needed. Full history: CHANGELOG.md
GravityLAN 0.5.1
Fixed
- Package updates for a non-root user who logs in with an SSH key or a saved connection: the update dialog (React and GravityUI) has an optional sudo password field, so updates no longer fail with "sudo: a password is required" when sudo asks for one. It is used for that request only, like the other credentials, and is ignored for a password login, which keeps its own login password for sudo.
- GravityUI no longer reports a client device in standby as disrupted. A device not watched 24/7 (a TV, PC or phone) that still answers on the network with every port closed is asleep: it gets no "services disrupted" notice, the line overview does not count it as disrupted and the orbit map does not mark it, as the health page already shows it as standby. A device watched 24/7 with every port closed now reads "no services reachable" instead of "4 services disrupted".
docker pull sleeperxr/gravitylan:0.5.1Also available as sleeperxr/gravitylan:latest. The agent stays at 0.3.9, so no agent update is needed. Full history: CHANGELOG.md
GravityLAN 0.5.0
GravityLAN 0.5.0: Now on Unraid, with the new GravityUI
🚀 Highlights
📦 GravityLAN is available on Unraid
- Community Applications template (
templates/gravitylan.xml): valid CA categories (Network:Other,Status:Stable), square store icon and the new GravityLAN logo. - Network guide in the template (English and German): which network type to choose (host, custom
br0with macvlan/ipvlan, one custom network per VLAN, why not bridge) and how scanning works (L2 Direct, L3 Routed, L2 Probe). - Image:
sleeperxr/gravitylan:0.5.0(alsolatest).
🪐 GravityUI (/frontend-vue/), the new optional interface
Runs next to the unchanged React UI and covers the same features: overview, device editor, IP overview, settings, health, agents, SSH terminal, logs, racks and the setup wizard. Light and dark theme, phone layout, German and English.
🌌 Orbit network map
- The router is the star, switches, APs and hosts are planets, devices are moons, connected by light beams. Roles are choosable, small devices can be dwarf planets.
- Interactions: click to focus (the rest dims), animated fly-to, focus card with quick actions, search with highlight, double click to open a device, pinch-to-zoom and two-finger pan on touch screens.
- Path tracing: pick two devices and see the shortest route over the beams, with numbered hops and link types. Interrupted links are flagged.
- Link type colours: a fixed colour per connection type (10GbE, 2.5GbE, 1GbE, WLAN, Fiber), set in Settings.
- The view no longer jumps after saving a dragged position; it fits once on the first load.
🛠 Fixes
- IP overview: tiles no longer print an icon name such as
serverinstead of the address number; the services list leads with the port number (22 SSH). - Unraid template: unknown Community Applications categories replaced.
🔒 Security
certifirequired at 2026.10.19 or newer; dev tools bumped (Vite 8.3.5, Vitest 4.1.12, not part of the image).
📝 Notes
- Full list of changes in CHANGELOG.md.
- Update on Unraid: pull
sleeperxr/gravitylan:latestand restart the container.
GravityLAN 0.4.1
GravityLAN 0.4.1: Router Subnet/VLAN Import & Telemetry Database Separation
🚀 Highlights
🌐 Router Subnet & VLAN Import (Settings → Scan subnets → Import from router)
- Automated Subnet Discovery: Imports network ranges, gateways, interface names and VLAN IDs directly from your router.
- SNMP Provider (v1/v2c/v3): Pure Python via
pysnmp7.1. Queries IP-MIB (ipAddrTable/ipAddressTable), IF-MIB (ifName/ifAlias), and Q-BRIDGE (dot1qVlanStaticName). Supports OPNsense, pfSense, OpenWrt, MikroTik, Sophos and enterprise gear. - UniFi Network API: Direct integration for UniFi Consoles (Cloud Gateway, UDM, UXG) with official API key authentication.
- TLS Fingerprint Pinning: Enforces SHA-256 peer certificate pinning on HTTPS requests before any credentials leave the server.
- Safe Merging: Never overwrites existing names or custom settings; only fills missing gateways or VLAN IDs on user confirmation.
📊 Telemetry Database Separation (telemetry.db)
- Isolated Storage: Moves high-frequency health probes, latency metrics, jitter, and agent telemetry out of
gravitylan.dbinto a dedicatedtelemetry.dbschema. - Rollups (Hourly & Daily): Automatically summarizes raw measurements after 48h into hourly rollups (30 days) and daily rollups (365 days).
- Measurement Data Management (
Settings → Measurement data): Live DB size monitoring, tier retention controls, and selective/complete data cleanup with disk vacuuming.
📦 Docker Image
docker pull sleeperxr/gravitylan:0.4.1
docker pull sleeperxr/gravitylan:latestGravityLAN 0.4.0
GravityLAN 0.4.0: Health & Availability Radar and Mobile Experience Rework
🚀 Highlights
🩺 Health & Availability Dashboard (/health)
-
Network Health Score (0-100): Real-time SLA radar combining ICMP ping latency, jitter, uptime percentage, flapping frequency, SSL certificate validity, and pending security updates into an overall Network Health Score (
$0-100$ ). -
24/7 Server vs. Client Classification: Devices can be marked as non-24/7 client systems (
alert_offline: false), preventing offline laptops or sleeping workstations from dragging down the homelab's overall score or triggering false outage alarms. - Interactive Telemetry Graphs: High-resolution latency & jitter sparklines with smooth SVG cubic bezier curves, cursor tracking, and precise point inspection tooltips.
- Incident & Stability Timeline: Real-time log tracking connection drops, flapping cycles, certificate warnings, and security advisory notices.
- Telemetry Drawer: Full slide-over drawer with hardware telemetry (CPU, RAM, Temp), port probes, and SLA statistics for any inspected device.
- Mobile Touch Cards: Optimized card layout replacing wide tables on mobile screens for comfortable single-thumb navigation.
📱 Mobile UX Rework Across All Submenus
- Bottom Navigation Bar: Full 6-tab mobile navigation bar with touch-friendly 60px height and safe-area insets.
- Submenus & Dialogs: Responsive single-column collapse on screens < 640px for Device Inspector, Agent Management, and Settings lists.
- Popovers as Modals: Notification Center and Gateway popovers adapt dynamically as centered dialog sheets on mobile screens (
position: fixed; inset-x: 12px; max-height: 70vh). - Save Bar: Refined sticky Save Bar alignment directly above the mobile bottom tab bar.
🛠️ CSS Architecture Hardening
- Universal resets encapsulated inside
@layer base, resolving specificity collisions with Tailwind v4 utilities. - Replaced brittle
space-y-*child margin hacks with native CSSgaplayouts across the application.
📦 Docker Image
docker pull sleeperxr/gravitylan:0.4.0
docker pull sleeperxr/gravitylan:latestGravityLAN 0.3.25
Security
- A copy of the database could log in as any agent: Since 0.3.20 agent tokens were stored as SHA-256 hashes, but without a marker. New tokens are 64 hex characters, the same shape as a hash, so the server also compared the stored value directly with the submitted token. Anyone holding the database file or a volume backup could send the stored hash as the token, was logged in as that agent and locked the real agent out. Stored tokens and pending tokens are now tagged
sha256:<hash>, and a stored hash is never accepted as a token. One helper checks the agent report, the agent WebSocket, adoption, deploy and config download. On startup the stored tokens are converted: untagged hashes of agents that have reported before are tagged, and plaintext tokens from older versions are hashed. Running agents stay logged in and keep theiragent.conf. Two consequences: the plaintext token only exists in the config download or deploy, so every new config download issues a new token and the previousagent.confstops working. And an agent that installed a downloaded config but has not reported since before 0.3.20 is no longer accepted with its old token; adopt its pending token in the dashboard or download its config again.
docker pull sleeperxr/gravitylan:0.3.25
(also :latest)
Full changelog: CHANGELOG.md
GravityLAN 0.3.24
Fixed
- Subnet Area Manager Auto-Save Spam: In the 'Manage Areas' (Bereiche verwalten) modal of the Subnet View, modifying area names, start/end IP bounds, or colors no longer triggers immediate backend API calls and toast notifications on every single keystroke. Changes are kept in local dialog state and persisted cleanly with a single toast upon clicking the new 'Speichern' (Save) button. An 'Abbrechen' (Cancel) button allows discarding in-progress edits.
GravityLAN v0.3.23
Highlights
- Group Renaming: Device groups (both custom and default) can now be renamed directly in Settings → Manage Groups via an inline edit button with keyboard support (Enter to save, Escape to cancel). Duplicate and empty group names are validated and rejected gracefully.
- Multi-VLAN Gateway Architecture & Interfaces: Routers acting as gateways for multiple subnets/VLANs are now tracked as a single multi-homed device using the new
device_interfacestable. IP hopping and duplicate devices across scans are eliminated.- Subnet configuration supports
gateway_ipandvlan_id(1–4094). - Interactive "Gateways" popover in the dashboard with keyboard navigation, status badges, and copy buttons.
- "Interfaces" tab in the device inspector with inline state per address and a smart duplicate merge assistant.
- Color-coded VLAN chips on multi-homed device cards and topology nodes.
- Subnet configuration supports
- Security Hardening:
- CSRF protection for
GET /api/webhooks/test(strictly enforces Bearer token authentication). - Agent bearer tokens stored as SHA-256 hashes with transparent on-the-fly migration.
- API token scopes enforced across WebSocket endpoints (
settings:read,scanner:read,agent:read). - SSH TOFU (Trust On First Use) host-key pinning for remote package patching.
- Shell escaping with
shlex.quotefor remote package management commands.
- CSRF protection for
- MAC Vendor Resolution & Caching:
- Serialized 1.2-second outbound request throttling to comply with API rate limits.
- Negative caching for unresolvable/404 OUIs to prevent repeated queries across scan cycles.
- Graceful handling and informative logging for host-mounted volume permissions (
chown -R 1000:1000 ./data).
- Terminal & UI Improvements:
- "Agent update" button in the SSH terminal is now always visible for linked devices (active when an update is available, showing current version otherwise).
Container Images
docker.io/sleeperxr/gravitylan:latestdocker.io/sleeperxr/gravitylan:0.3.23
GravityLAN v0.3.19
Changelog
All notable changes to this project will be documented in this file.
[Unreleased]
[0.3.19] - 2026-10-17
Changed
- One List of Scan Subnets (#18): The subnets of the network overview are now the only source of what gets scanned. Scheduled scans, quick checks, the ARP turbo filter and the dashboard scan cover every enabled subnet; only while none is configured do they fall back to the container's own interfaces. Before, the scanners read the separate "Subnets to scan" text field, so a subnet added in the overview (e.g. an IoT VLAN) was never scanned and a subnet entered in Settings got no tab.
- Scan Subnets in Settings: The comma-separated "Subnets to scan" field is replaced by a list of the same subnets the overview shows: add one with an optional name, pause or resume scanning, or remove it. Changes apply immediately. Networks detected on the host but not yet scanned (e.g. a VLAN interface added after setup) are offered with one click.
- Paused Subnets in the Network Overview: Every subnet keeps its tab; a paused one is greyed out and marked "Paused", and the subnet settings dialog has a "Scan" switch per subnet.
- Setup Wizard Registers Its Networks: The networks scanned during setup are saved as scan subnets even when no device was found, so each one gets a tab right away. The network step also takes additional subnets the container can't see directly, such as an IoT VLAN behind the router (macvlan setups).
- Dashboard Scan Picker: The "Select network" dialog lists the enabled scan subnets instead of only the container's interfaces.
Fixed
- Legacy Scan Subnet Setting Merged on Start-up: Entries of the old
scan_subnetssetting are added to the subnet list on the first start (re-enabled if they were paused), then the setting is removed. This now also works when the list already has entries, and it runs before the scan scheduler starts. Clients that still sendscan_subnetstoPOST /api/settingsadd the subnets to the list instead of storing a second copy. - Subnet Validation: Subnets created or changed through
/api/network/subnetsmust be IPv4 networks no larger than a /16; host bits are cleared (192.168.110.5/24becomes192.168.110.0/24), the name defaults toNetwork <cidr>, and a duplicate returns 409 instead of a server error. - English L2/L3 Subnet Badges: The Network Planner's subnet badges no longer show German text (
L2 Direkt,L3 Geroutet) in the English UI. Tabs, header, and the subnet settings dialog now use translated labels, and the settings dialog showsL2 Probe (<Device>)for subnets served by an agent probe instead of calling them routed without MAC discovery.
Security
- Agent ARP relay limited to the probe's own subnets: the server applied the ARP table of every agent report, from any agent, so one agent token could overwrite the MAC, vendor and online state of any device in the inventory. Neighbors are now only taken from devices with the Layer-2 probe (
enable_scanner_relay) switched on, and only for addresses inside a scan subnet that contains the probe's own IP; all other entries are ignored. If a probe no longer fills in MAC addresses, add the subnet it sits in to the scan subnets (Settings or network overview).
[0.3.18] - 2026-10-15
This release introduces remote Layer-2 subnet scanning via agent probes, allowing Linux hosts with the GravityLAN agent installed to act as remote network probes for routed VLANs.
Added
- Agent Layer-2 Scanner Probe (Relay): The GravityLAN agent (v0.3.8) can now be toggled as a remote L2 probe (
enable_scanner_relay) in the Device Editor. The agent probes broadcast neighbors and reads the kernel ARP table (/proc/net/arp), reporting neighbor MAC and IP pairs to GravityLAN. - Remote ARP Ingestion & Device MAC Resolution: The backend ingests remote ARP tables, updating devices and discovered hosts in routed subnets with their native MAC addresses and vendor OUIs.
- Network Planner Probe Indicators: Subnets serviced by an active remote agent probe display a dedicated
● L2 Probe (<Device>)badge in tabs and headers with full status tooltips.
Fixed
- Setup Wizard Sign-in Flow: Restored automatic session login upon completing the setup wizard so the initial post-setup device refresh executes with valid authentication credentials.
[0.3.17] - 2026-10-15
This release hardens the first-run Setup Wizard with atomic session cookie issuance and full multi-subnet adoption, resolves gateway and proxy-ARP MAC collisions across routed VLANs, adds live Layer-2 vs. Layer-3 reachability indicators to the Network Planner, and provides a multi-VLAN Docker Compose template.
Added
- Layer-2 Direct vs. Layer-3 Routed Subnet Badges: The Network Planner tabs, header, and settings dialog now dynamically detect whether a subnet is directly attached to a host interface (
L2 Direct) or routed through a firewall/gateway (L3 Routed). Clear tooltips explain why routed subnets cannot resolve MAC addresses via ARP broadcasts and recommend using the host agent or multi-VLAN Docker Compose. - Multi-VLAN Docker Compose Template & Guide: Added
docker-compose.multi-vlan.ymldemonstrating IEEE 802.1Q tagged macvlan interfaces (eth0.10,eth0.20, etc.) along with comprehensive documentation indocs/multi-vlan-setup.md.
Fixed
- Setup Wizard Session and Login Desynchronization:
/api/setup/completenow sets the authenticated admin session cookie atomically upon saving the password, eliminating the redundant follow-up login call that could strand users on the login screen. - Setup Host Adoption across Routed VLANs: The initial setup discovery now imports online hosts from all user-selected subnets, including routed VLANs, rather than restricting adoption to local physical subnets.
- Proxy-ARP and Gateway MAC Collisions: Remote routed IPs sharing the gateway's MAC address via proxy-ARP or router caches no longer overwrite host identities; shared gateway MACs are isolated to the local interface subnet.
- Subnet Cleanup Database Loop: Optimized invalid subnet cleanup on backend startup to batch-delete records instead of making individual delete queries in a loop.
- Local Log Files in the Docker Image:
.dockerignoreexcludes*.logfiles to keep local developer logs out of container images.
[0.3.16] - 2026-10-15
Agents can now be updated straight from the SSH terminal, and the agent install and the Agent Update Center can log in with saved SSH key connections instead of asking for a password every time. Install codes no longer end up in the server's request log.
Upgrade notes
- No agent update is needed for this release; the agent stays at 0.3.7.
- To install or update an agent with a saved connection, connect to the device once in the SSH terminal and confirm its host key; until then the saved connection is refused.
- API:
POST /api/agent/deploy/{id}and/api/agent/uninstall/{id}withoutssh_user(and withoutprofile_id) now answer HTTP 400 instead of 422.
Added
-
Agent update from the SSH terminal: when the device a terminal is connected to runs an older agent than the server ships, the terminal toolbar shows an "Agent update" button. It types the same one-line installer as the device's Agent tab into the input line, with a fresh one-time install code (valid for 30 minutes, usable once), but does not run it: review it and press Enter yourself, sudo may ask for a password. The command starts with a space, so shells that leave such lines out of their history (
HISTCONTROL=ignorespaceorignoreboth, as in the default user~/.bashrcon Debian and Ubuntu) do not keep it; where it is kept, the code stops working once the installer has used it, or after 30 minutes. Only sessions opened for a device or through a saved connection of a device get the button; a plain host address is never matched to a device. -
Agent install and update with saved SSH connections: the Agent tab of the device editor and the Agent Update Center can log in with a saved SSH connection (SSH → saved connections) instead of asking for a password every time. Only connections that log in with a stored key are offered, and only for their own device; the Update Center uses each device's connection and falls back to the user and password typed in for all others. The key is decrypted on the GravityLAN server only and never sent to the browser. For safety, the device's host key must already be confirmed in the SSH terminal: GravityLAN then only logs in to a server presenting exactly that key and refuses before logging in if it differs. Saved connections work from the logged-in web interface only, not with API tokens. A user other than root may need a sudo password, which can be entered for the run and is not stored. Package updates (patches) still ask for credentials.
Fixed
- Failed SSH logins were reported as an unreachable host: when the agent deploy or uninstall was refused because of a wrong password or key, the message said "SSH connection failed. Please check host availability and port." It now says that the authentication failed.
Security
- Install codes were written to the access log: the manual install and update command carries its one-time code in the URL (
…/install-sh/<id>?code=…), and the server's request log recorded it in plain text, also in the log viewer. The value ofcode=is now masked as[redacted]in logged request lines.
[0.3.15] - 2026-10-14
A security and reliability release. Input that ends up in shell commands, nmap or the agent installer is now checked strictly, a backup import can no longer replace credentials, logins are rate-limited, webhooks can no longer target the GravityLAN host or cloud metadata services, and SSH update c...
GravityLAN 0.3.16
Agents can now be updated straight from the SSH terminal, and the agent install and the Agent Update Center can log in with saved SSH key connections instead of asking for a password every time. Install codes no longer end up in the server's request log.
Upgrade notes
- No agent update is needed for this release; the agent stays at 0.3.7.
- To install or update an agent with a saved connection, connect to the device once in the SSH terminal and confirm its host key; until then the saved connection is refused.
- API:
POST /api/agent/deploy/{id}and/api/agent/uninstall/{id}withoutssh_user(and withoutprofile_id) now answer HTTP 400 instead of 422.
Added
-
Agent update from the SSH terminal: when the device a terminal is connected to runs an older agent than the server ships, the terminal toolbar shows an "Agent update" button. It types the same one-line installer as the device's Agent tab into the input line, with a fresh one-time install code (valid for 30 minutes, usable once), but does not run it: review it and press Enter yourself, sudo may ask for a password. The command starts with a space, so shells that leave such lines out of their history (
HISTCONTROL=ignorespaceorignoreboth, as in the default user~/.bashrcon Debian and Ubuntu) do not keep it; where it is kept, the code stops working once the installer has used it, or after 30 minutes. Only sessions opened for a device or through a saved connection of a device get the button; a plain host address is never matched to a device. -
Agent install and update with saved SSH connections: the Agent tab of the device editor and the Agent Update Center can log in with a saved SSH connection (SSH → saved connections) instead of asking for a password every time. Only connections that log in with a stored key are offered, and only for their own device; the Update Center uses each device's connection and falls back to the user and password typed in for all others. The key is decrypted on the GravityLAN server only and never sent to the browser. For safety, the device's host key must already be confirmed in the SSH terminal: GravityLAN then only logs in to a server presenting exactly that key and refuses before logging in if it differs. Saved connections work from the logged-in web interface only, not with API tokens. A user other than root may need a sudo password, which can be entered for the run and is not stored. Package updates (patches) still ask for credentials.
Fixed
- Failed SSH logins were reported as an unreachable host: when the agent deploy or uninstall was refused because of a wrong password or key, the message said "SSH connection failed. Please check host availability and port." It now says that the authentication failed.
Security
- Install codes were written to the access log: the manual install and update command carries its one-time code in the URL (
…/install-sh/<id>?code=…), and the server's request log recorded it in plain text, also in the log viewer. The value ofcode=is now masked as[redacted]in logged request lines.
Docker: docker pull sleeperxr/gravitylan:0.3.16 (also :latest)
Full history: CHANGELOG.md