Files
mikeandClaude Sonnet 5 c135f205fa Expand LAN to 10.0.0.0/22 with static/reserved/dynamic/spare zones
Splits the LAN into four /24 zones: 10.0.0.0/24 static (no DHCP, DNS
only), 10.0.1.0/24 fixed DHCP reservations by MAC, 10.0.2.0/24 dynamic
DHCP pool, 10.0.3.0/24 spare/unused. ipadm now derives the required
subnet from whether a host has a MAC, auto-assigns free IPs, and
auto-migrates a host's IP when its MAC is added/removed. Migrated the
existing archerc80 reservation from 10.0.0.2 to 10.0.1.2.

Also fixes a latent bug found while doing this: dnsmasq's SIGHUP
(`systemctl reload`) only re-reads /etc/hosts, not the conf-dir files
ipadm writes to, so config changes were silently not applied on
reload. ipadm now restarts dnsmasq instead.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 08:57:58 +02:00
..

ipadm

Kleines Go-CLI-Tool zur Verwaltung statischer Hosts (DHCP-Reservierung + DNS-Eintrag) und WAN→LAN-Port-Forwards für den dnsmasq/nftables-Router auf narcissus. Ersetzt/lehnt sich an das Original-Tool ipadm (dhcp/bind management, mwx'2021) an, arbeitet aber gegen unseren dnsmasq/nftables-Stack statt isc-dhcp-server/bind9 (siehe ../../README.md).

Installiert auf dem Server unter /usr/local/bin/ipadm.

IP-Adressschema

Das LAN ist ein 10.0.0.0/22, aufgeteilt in vier /24-Zonen (Details siehe ../../README.md#ip-adressschema):

  • 10.0.0.0/24 — statische Adressen (kein DHCP, nur DNS), für Hosts ohne MAC-Adresse in der ipadm-Datenbank.
  • 10.0.1.0/24 — feste DHCP-Reservierungen (per MAC), für Hosts mit MAC-Adresse in der ipadm-Datenbank.
  • 10.0.2.0/24 — dynamischer DHCP-Pool (nicht von ipadm verwaltet).
  • 10.0.3.0/24 — Reserve, unbenutzt.

ipadm wendet diese Regel bei jeder IP-Zuweisung automatisch an: welches Subnetz erlaubt ist, entscheidet allein, ob der Host eine MAC-Adresse hat oder nicht — nicht der Nutzer. Details siehe unten.

Funktionsweise

  • Pflegt eine flache Textdatei /etc/ipadm/hosts (eine Zeile pro Host: name<TAB>ip<TAB>mac<TAB>comment, mac ist - wenn nicht gesetzt) als Datenbank für statische Hosts, und /etc/ipadm/portforwards (wanport<TAB>proto<TAB>host<TAB>lanport) für Port-Forwards. Ein Port-Forward referenziert einen Hostnamen aus der Host-Datenbank statt einer festen IP, damit er automatisch der aktuellen IP des Hosts folgt.

  • ipadm -u generiert daraus zwei Dateien und wendet die zugehörigen Dienste neu an:

    • /etc/dnsmasq.d/hosts.conf (pro Host ein host-record= für DNS, plus dhcp-host= für Hosts mit MAC-Adresse für die DHCP-Reservierung), validiert mit dnsmasq --test, danach systemctl restart dnsmasq. Bewusst restart, nicht reload: dnsmasqs SIGHUP-Handler liest nur /etc/hosts neu, nicht die conf-dir-Dateien, in denen hosts.conf liegt — ein reines reload würde die Änderung nicht anwenden.
    • /etc/nftables.d/portforward.conf (eine eigene table inet portforward mit einer dnat-Regel pro Port-Forward, referenzierte Host-IP wird zum Generierungszeitpunkt aus der Host-DB aufgelöst), validiert mit nft -c -f /etc/nftables.conf (dafür bindet /etc/nftables.conf bereits include "/etc/nftables.d/*.conf" ein), danach systemctl reload nftables (dessen reload liest die komplette Config neu ein, das ist hier unproblematisch).

    Schlägt die jeweilige Validierung fehl, wird die vorherige generierte Datei automatisch wiederhergestellt und der betroffene Dienst nicht neu angewendet. Referenziert ein Port-Forward einen mittlerweile gelöschten Host, wird er beim Generieren übersprungen und als Warnung ausgegeben, statt den ganzen Lauf abzubrechen.

  • IP-Adressen werden bei -a/-i/im interaktiven Modus geprüft: müssen im zur MAC-Adresse passenden Subnetz liegen (10.0.0.0/24 ohne MAC, 10.0.1.0/24 mit MAC) und dürfen weder die Netz-/Broadcast-Adresse noch die Gateway-Adresse 10.0.0.1 sein.

  • Wird bei -a keine IP angegeben, vergibt ipadm automatisch die nächste freie IP im passenden Subnetz.

  • Wird bei -m eine MAC-Adresse hinzugefügt oder entfernt und der Host liegt dadurch im falschen Subnetz, verschiebt ipadm ihn automatisch auf eine freie IP im jetzt passenden Subnetz (mit Hinweis in der Ausgabe). -i dagegen validiert nur — eine manuell angegebene IP muss bereits zum (unveränderten) MAC-Status des Hosts passen.

  • Port-Forwards werden über (wan-port, protokoll) eindeutig identifiziert; both (= tcp+udp in einer Regel via meta l4proto { tcp, udp }) kollidiert dabei mit einem einzelnen tcp- oder udp-Eintrag auf demselben Port.

Usage

ipadm <hostname>                                      add/edit host (interactive)
ipadm -l                                              list hosts
ipadm -a [-f] <hostname> [ip address] [mac address]   add host (IP auto-assigned if omitted)
ipadm -c <hostname> <comment>                         set comment
ipadm -i <hostname> <ip address>                      change ip address
ipadm -m <hostname> <mac address>                     change mac address
ipadm -r <old hostname> <new hostname>                rename host
ipadm -d <hostname>                                   delete host
ipadm -pa [-f] <hostname> <wan-port> [lan-port] [tcp|udp|both]
                                                      add port-forward to a known host
ipadm -pl                                             list port-forwards
ipadm -pd <wan-port> [tcp|udp|both]                   delete port-forward
ipadm -u                                              update (regenerate dnsmasq+nftables config, reload)
ipadm -h                                              this help

(Output/messages of the tool itself are English; this README stays German like the rest of the repo.)

Beispiele:

ipadm -a webserver                    # Host ohne MAC anlegen, IP aus 10.0.0.0/24 auto-vergeben
ipadm -a heizung aa:bb:cc:dd:ee:ff     # Host mit MAC anlegen, IP aus 10.0.1.0/24 auto-vergeben
ipadm -a fixip 10.0.0.42               # Host mit expliziter IP (muss zum Subnetz passen)
ipadm -pa webserver 443 tcp           # WAN-Port 443/tcp -> webserver:443
ipadm -pa webserver 8080 80 tcp       # WAN-Port 8080/tcp -> webserver:80
ipadm -u                              # anwenden (dnsmasq + nftables)

Bei -a sind IP-Adresse und MAC-Adresse optional und in beliebiger Reihenfolge angebbar — das Tool erkennt selbst, welches Token eine IP und welches eine MAC ist. Fehlt die IP, wird automatisch die nächste freie IP im zur MAC passenden Subnetz vergeben.

lan-port und Protokoll bei -pa sind optional und ebenfalls in beliebiger Reihenfolge angebbar (Default lan-port = wan-port, Default Protokoll tcp) — das Tool erkennt selbst, ob ein Token eine Portnummer oder tcp/udp/both ist.

Nach jeder Änderung an der Host- oder Port-Forward-DB (-a, -c, -i, -m, -r, -d, -pa, -pd, interaktiv) muss ipadm -u ausgeführt werden, damit dnsmasq/nftables die Änderung tatsächlich übernehmen — das Tool weist nach jeder Änderung selbst darauf hin.

Bauen / Installieren

cd tools/ipadm
go build -o ipadm .
install -m 0755 -o root -g root ipadm /usr/local/bin/ipadm

Testen ohne die echte Server-Konfiguration anzufassen

Alle Pfade und das IP-Adressschema sind über Umgebungsvariablen überschreibbar:

export IPADM_DB=/tmp/test-hosts
export IPADM_PORTFWD_DB=/tmp/test-portforwards
export IPADM_DNSMASQ_HOSTS=/tmp/test-hosts.conf
export IPADM_NFT_PORTFWD=/tmp/test-portforward.conf
export IPADM_STATIC_CIDR=10.0.0.0/24
export IPADM_RESERVED_CIDR=10.0.1.0/24
export IPADM_GATEWAY_IP=10.0.0.1
export IPADM_WAN_IFACE=enp3s0
./ipadm -a testhost aa:bb:cc:dd:ee:ff
./ipadm -l

Achtung: ipadm -u ruft trotzdem dnsmasq --test bzw. nft -c -f /etc/nftables.conf auf (prüft die echte System-Konfiguration) und bei Erfolg systemctl restart dnsmasq/systemctl reload nftables, auch im Testmodus — das ist beabsichtigt (validiert, dass die generierte Datei mit der echten Umgebung zusammenspielt), aber es wendet die echten laufenden Dienste an (inkl. eines kurzen dnsmasq-Neustarts). IPADM_NFT_PORTFWD nur auf einen Pfad außerhalb von /etc/nftables.d/ zeigen lassen, sonst landet die Testdatei im echten Include und wird real aktiv.

Änderungshistorie (Kurzfassung)

  • v1.2.0 (2026-08-21): LAN auf 10.0.0.0/22 erweitert, Subnetz-Zonen eingeführt (IPADM_STATIC_CIDR/IPADM_RESERVED_CIDR statt IPADM_LAN_CIDR/IPADM_POOL_START/IPADM_POOL_END), automatische IP-Vergabe bei -a, automatisches Umziehen bei MAC-Änderung (-m), dnsmasq-Anwendung von reload auf restart korrigiert (siehe oben).
  • v1.1.0: Port-Forwarding-Verwaltung (-pa/-pl/-pd) ergänzt, komplett auf Englisch übersetzt, Hilfetext-Ausrichtung korrigiert.