Omahub
← All plugins
G

My Network

by Gavin Nugent

Scans the local subnet and identifies every device on it: name, vendor, model and role inferred from mDNS, MAC vendor and open ports, plus a Tailscale peer list. Summon with: omarchy-shell shell toggle nosignal.network-scan

Security review

No obvious issues detected

Deterministic scan — not a security guarantee

None
Risk level
None
Analyzed commit
8f3503c
Scanned
1 month ago

No potentially dangerous behavior detected in the analyzed commit.

Automated analysis only — not a security guarantee.

AI advisory review

Review recommended

Language-model assessment · ~deepseek/deepseek-v4-flash-latest — advisory only

Low
AI risk level
Low
Recommendation
review
Model
~deepseek/deepseek-v4-flash-latest
Analyzed commit
8f3503c
Reviewed
1 month ago

The plugin is a transparent, non-elevated LAN scanner and Tailscale viewer; the deterministic scan found nothing, and there is no install-time code, obfuscation, exfiltration, or destructive behavior. The main review-worthy points are that opening the panel rewrites ~/.config/omarchy/shell.json to self-register, and the deep scan actively pings and probes the local subnet while reading ~/.ssh/config — all functional for the plugin's stated purpose, but worth a human look.

  • Panel.qml's ensureSelfRefScript rewrites ~/.config/omarchy/shell.json on first open via a temp-file replacement; this persistent config mutation is not mentioned in the README and should be confirmed as intended.
  • scan.sh deep mode actively ping-sweeps the local /24, probes 18 TCP ports, and reads SSH/HTTP banners from discovered hosts; this is disclosed in the README but is detectable network activity that may be inappropriate on networks the user does not control.
  • ~/.ssh/config is read to resolve SSH aliases; the data appears to stay local and is only used for UI/actions, but it is sensitive and the parsing code should be reviewed.
  • No obfuscation, root escalation, destructive commands, or obvious data exfiltration were found in the sampled source.
How this check works

This review combines the deterministic scan (the rule-based results above) with an independent look at the plugin's code by a language model. The model reads a trimmed sample of the repository's files, the manifest, and the README, then gives a plain-language risk level and a recommendation: install (no notable danger), review (look closer first), or avoid (clearly dangerous).

It runs on the same analyzed commit as the deterministic scan and is strictly advisory — it is not a security guarantee and never blocks a plugin by itself. A human moderator still reviews plugins before they are listed.

AI advisory only — automated analysis, not a security guarantee.

Install
$ omarchy plugin add https://github.com/28allday/omarchy-network-scan --enable
System #bar

My Network

An Omarchy shell plugin that scans your local subnet and works out what every device on it is — name, vendor, role and operating system — plus a list of your Tailscale peers. A bar icon and a keyboard-driven panel.

No agent, no daemon, no account, no nmap, no elevated privileges. Nothing runs while the panel is closed.

What it shows

Local network — one line per device, grouped by what the device is, with computers first:

The panel: devices grouped by type, with a Tailscale section below

Groups are Computers, Network, Storage, Media, Smart home, Printers & cameras, Phones & tablets, and Other. Empty groups are omitted, this machine heads Computers, and within a group devices are ordered by address.

Press e and every row expands with the rest:

Every row expanded, showing OS, vendor, ports, mDNS services and MAC

Field
OS with the evidence in brackets — macOS (mdns), Ubuntu (ssh), Windows (ttl 128)
Vendor from the MAC's OUI; randomised (locally administered) MACs are labelled as such
Model the mDNS model string, where one is advertised
Ports the open ports found
mDNS the service types the device advertises
MAC the hardware address

Tailscale — every peer in your tailnet with its name, *.ts.net address, OS and online state; exit nodes are marked. The section is hidden entirely if Tailscale isn't installed or you're logged out.

How devices are identified

Signals are ranked and the first match wins:

  1. Advertised mDNS services — _printer._tcp, _googlecast._tcp and so on.
  2. Distinctive open ports — :32400 Plex, :8123 Home Assistant, :9100 a printer.
  3. MAC vendor — Ubiquiti, Raspberry Pi, Sonos, Hikvision…
  4. Generic ports — :22, :80, :443.
  5. Naming convention, then PC hardware vendor — a host called …-MacBook-Pro or DESKTOP-…, or an Intel/Lenovo OUI.

Anything unmatched reads Unknown device rather than being guessed at.

A device's role is what it does; its group is what it is. A small x86 box running Jellyfin groups under Computers while its row still reads "Jellyfin server"; a purpose-built NAS stays under Storage.

OS detection

Every OS label carries the evidence that produced it:

Basis What it is
mdns the device's own model string (Mac15,10 → macOS)
ssh the SSH banner, which often names the distro (…OpenSSH_8.9p1 Ubuntu-3ubuntu0.10)
http the Server: header — decisive for IIS, and pins embedded firmware exactly
ttl <n> reply TTL: 64 = Linux/macOS/BSD, 128 = Windows, 255 = embedded
hostname a DESKTOP-* / WIN-* convention, always shown with a ?

A host that gives nothing gets no OS label at all, and the OS is hidden when the role already says it.

Windows is the hardest case: its firewall drops ICMP by default, so a Windows box with no open ports is identifiable only by its hostname. A Server: header naming a general-purpose web server is ignored, since it says nothing about the host OS, and a TimeCapsule* mDNS model is not treated as Apple — NAS firmware advertises it to attract Time Machine.

Kernel version, exact Windows release and stack fingerprinting (nmap -O) are out of reach without root.

Keys

Key Action
↑/↓ or k/j move — steps over group captions, and off the end of the device list into the Tailscale list
PgUp / PgDn jump a page
Home / End first device / last peer
e toggle full detail on every row (default: off)
↵ or click act on the device — see below
y copy the selected address to the clipboard
r / F5 rescan
Esc / q / click-outside close

Choosing between a device's web UI and SSH

↵ acts when there's something to act on, and asks when there's more than one way in. A device serving both a web UI and SSH raises a chooser listing every web port it answers on, most distinctive first (:8096 before :80), plus SSH. One option goes straight there; none does nothing. The row's right-hand tag says which you'll get, with open… meaning there's a choice.

SSH targets

On the LAN, SSH follows your ~/.ssh/config. If a Host block points at the device's address — or its alias matches the device's name — the panel offers the alias, so the configured User, Port and key apply. Otherwise it falls back to the address.

Tailscale peers stay on the tailnet. Where a peer has Tailscale SSH enabled, tailscale ssh is offered first. Otherwise it's plain SSH to the MagicDNS name. A ~/.ssh/config alias is used only if following it stays on the tailnet, since aliases for tailnet hosts often point at a public address.

The terminal is held open on a failed connection so you can read the error.

Layout

The two sections scroll independently, each showing roughly 8–10 rows. A section that overflows says so in its header and gets a slim scrollbar. The selection cursor runs as one sequence: ↓ off the last device lands on the first peer, and whichever list owns the selection is the one that scrolls.

With e on, the panel grows to 80% of the screen and the lists scroll further. Panel geometry changes only when you press e.

How the scan works

Two passes per open, both in scan.sh:

Pass Does Takes
fast neighbour (ARP) table + mDNS browse + Tailscale status + name cache ~1s
deep adds a /24 ping sweep, a TCP probe of 18 ports, and SSH/HTTP banner reads ~7s

The fast pass paints a list immediately; the deep pass replaces it. Every ping emits an ARP request first, so hosts that drop ICMP still appear in the neighbour table.

Names are remembered against the MAC, because router-provided reverse DNS answers only intermittently. A name reused from an earlier scan is labelled as such in the detail. The cache is $XDG_CACHE_HOME/omarchy-network-scan/names.tsv, capped at 500 entries; delete it to start cold.

Subnets wider than a /24 are swept as the local /24 only, and the header says so when that happens. This machine's own open ports come from ss filtered to LAN-reachable listeners.

This is an active scan

The deep pass sends ICMP to every address on your subnet and opens TCP connections to the hosts it finds. That's ordinary behaviour on a network you own, but it is traffic, and on a network you don't control it may show up in an IDS. Banner reads only touch ports already found open. Use the passive fast pass, or don't use the plugin, where that matters.

Requirements

Nothing is installed for you. Everything is checked at runtime and the panel says what's missing.

Needs For If absent
jq all parsing panel says so and stops
iproute2 (ip, ss) interfaces, ARP table, own listeners panel says so and stops
avahi (avahi-browse) mDNS names, models, service types falls back to reverse DNS / vendor
openbsd-netcat (nc) port probing, SSH/HTTP banners no ports, so role and OS fall back to vendor/TTL
hwdata (/usr/share/hwdata/oui.txt) MAC → vendor vendor blank
tailscale peer section section hidden entirely
wl-clipboard (wl-copy) y copy silently does nothing

ping needs no root — Linux grants unprivileged ICMP sockets via net.ipv4.ping_group_range.

Install

omarchy plugin add https://github.com/28allday/omarchy-network-scan.git
omarchy plugin update                        # fetches, shows a diff, fast-forwards
omarchy plugin remove nosignal.network-scan

add clones into ~/.config/omarchy/plugins/nosignal.network-scan/, validates the manifest and warns you first — plugins run as unsandboxed code inside omarchy-shell, so read it before you enable it. It then asks whether to enable, and which bar section to put the icon in, with right pre-selected. --yes skips every prompt and takes the defaults.

Bind a key in ~/.config/hypr/bindings.lua:

o.bind("SUPER + ALT + N", "My network", "omarchy-shell shell toggle nosignal.network-scan")

Licence

MIT — see LICENSE.