mdns-wildcard-server

command module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 30, 2026 License: MIT Imports: 16 Imported by: 0

README

mdns-wildcard-server

A small mDNS server that answers .local hostnames — including wildcards — from a static config file. No upstream lookup, no service discovery: just fast, authoritative answers for the names you configure.

Think of it as a tiny proxy responder: it can answer .local queries for hosts that don't speak mDNS themselves or live in a different subnet (similar in spirit to a Bonjour proxy). Handy to make a whole namespace like *.apps.local resolvable on your LAN without per-host configuration.

Features

  • Wildcards: *.apps.local answers grafana.apps.local, a.b.apps.local, …
  • Static config, no upstream DNS dependency.
  • Hot reload: edit the config and it's picked up instantly (fsnotify) — or send SIGHUP. An invalid config is rejected and the previous one stays active.
  • IPv4 (A) and IPv6 (AAAA) records, auto-detected.
  • Correct mDNS behaviour: QU-bit / legacy-unicast handling, cache-flush bit, valid source address.
  • Coexists with avahi / other mDNS software on port 5353 (SO_REUSEPORT).
  • Single small static binary (Go).

Build

go build -o mdns-wildcard-server .

Configuration

records.conf (copy from records.conf.example):

# <pattern>  <ip>
nas.local        192.168.1.10     # exact name
*.apps.local     192.168.1.20     # wildcard: grafana.apps.local, a.b.apps.local, ...
  • *.X matches X itself and any number of sub-labels before it.
  • IPv4 → A record, IPv6 → AAAA, detected automatically.
  • First matching rule wins.
  • Hot reload: save the file → applied immediately; or kill -HUP <pid>.

Keep patterns narrow (e.g. *.apps.local). A broad *.local would answer every .local query and can clash with real mDNS devices (printers, Chromecasts, host announcements). Use it only if you really mean to.

Running

./mdns-wildcard-server -config records.conf -iface eth0 -ttl 120 -v
Flag Default Meaning
-config records.conf Path to the records file (hot-reloaded)
-iface (auto) Network interface to use (recommended on multi-interface hosts)
-ttl 120 Answer TTL in seconds (legacy-unicast is capped at 10s)
-v off Log every answered query

Does it need root?

No. Port 5353 is unprivileged and joining the multicast group needs no special capabilities — run it as an unprivileged user. The provided systemd unit uses DynamicUser=yes (no root at runtime) and starts at boot, which is the recommended way to run it as a server. It can also run as a systemd --user service, but that only runs while the user is logged in (unless lingering is enabled).

systemd

See mdns-wildcard-server.service. Run one instance per subnet (mDNS is link-local and not routed).

[Unit]
Description=mDNS wildcard server
After=network-online.target
Wants=network-online.target

[Service]
ExecStart=/usr/local/bin/mdns-wildcard-server -config /etc/mdns-wildcard-server/records.conf -iface eth0
Restart=on-failure
RestartSec=2
DynamicUser=yes
ReadOnlyPaths=/etc/mdns-wildcard-server
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes

[Install]
WantedBy=multi-user.target

Notes & limitations

  • Link-local: mDNS multicast is not routed → run one instance per L2 subnet, on a host that lives in that subnet.
  • Port 5353 coexistence: runs alongside avahi etc. As long as you only serve patterns no real device owns, there are no conflicts.
  • No probing / conflict defence: intentionally a pure proxy responder for names you "own".
  • IPv4 multicast group only for now (224.0.0.251); the IPv6 group (ff02::fb) is not joined yet.

License

MIT

Documentation

Overview

mdns-wildcard-server — a tiny mDNS server (proxy responder).

Answers mDNS queries (.local, multicast 224.0.0.251:5353 and ff02::fb:5353) for configured names/wildcards from a static config (NO upstream lookup). The config is hot-reloaded automatically via fsnotify.

Purpose: make a namespace such as *.apps.local resolvable on the LAN even though the target host doesn't speak mDNS itself or lives in a different subnet (a classic proxy responder, in the spirit of a Bonjour proxy).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL