Files
router/README.md
T
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

15 KiB
Raw Blame History

narcissus – Router-Konfiguration

Dieses Repo dokumentiert die Router-Konfiguration des Servers narcissus (narcissus.fhi.mpg.de). Der Server hat zwei Netzwerkinterfaces und übernimmt für ein kleines internes Netz die Rollen Router, Default-Gateway, Nameserver und DHCP-Server.

Die Dateien unter config/ sind 1:1-Kopien der aktiven Konfiguration auf dem Server (Stand: siehe Git-Log). Das Repo ist reine Dokumentation/Backup – es gibt kein automatisches Deployment. Änderungen müssen manuell auf dem Server vorgenommen werden (siehe unten) und sollten danach hier eingecheckt werden, damit Doku und Realität übereinstimmen.

Statische Host-Einträge (feste IP/DHCP-Reservierung + DNS-Name) werden nicht mehr von Hand in dnsmasq.d gepflegt, sondern über das Tool ipadm (/usr/local/bin/ipadm auf narcissus), siehe tools/ipadm/README.md.

Netzwerk-Topologie

                    Internet
                        │
                enp3s0 (WAN, öffentlich)
              141.14.140.128/20
                Gateway: 141.14.128.128
                        │
              ┌─────────────────────┐
              │   narcissus (Router) │
              │  ip_forward=1, NAT   │
              └─────────────────────┘
                        │
                enp7s0 (LAN)
                 10.0.0.1/22
                        │
        ┌───────────────┼───────────────┬───────────────┐
        │               │               │               │
  10.0.0.0/24     10.0.1.0/24     10.0.2.0/24     10.0.3.0/24
   statisch      DHCP-Reserv.    dynamischer         Reserve
  (kein DHCP,      (per MAC,      DHCP-Pool        (unbenutzt)
   nur DNS)      via ipadm)      .10–.250
  • WAN: enp3s0, statische öffentliche IP, unverändert wie vorher.
  • LAN: enp7s0, 10.0.0.1/22 (seit 2026-08-21, davor /24), Router = Gateway = DNS für alle Clients im Netz. Details zur Aufteilung in vier /24-Zonen siehe IP-Adressschema unten.

IP-Adressschema

Das LAN ist ein 10.0.0.0/22 (Netzmaske 255.255.252.0, Adressen 10.0.0.0–10.0.3.255), aufgeteilt in vier gleich große /24-Zonen mit klar getrennten Zwecken:

Subnetz Zweck Vergabe
10.0.0.0/24 Statische Adressen — Geräte, die ihre IP selbst fest eingestellt haben (kein DHCP), bekommen hier nur einen DNS-Eintrag ipadm -a <name> (ohne MAC)
10.0.1.0/24 Feste DHCP-Reservierungen — Geräte, die per DHCP immer dieselbe IP bekommen sollen ipadm -a <name> <mac>
10.0.2.0/24 Dynamischer DHCP-Pool — alle anderen Clients (Laptops, Handys, Gäste) automatisch von dnsmasq, Bereich .10–.250
10.0.3.0/24 Reserve — aktuell nicht konfiguriert/genutzt –

10.0.0.1 (Router/Gateway) ist über das gesamte /22 hinweg reserviert und kann keinem Host zugewiesen werden.

Das Tool ipadm kennt diese Regel und wendet sie automatisch an: Hosts ohne MAC-Adresse landen in 10.0.0.0/24, Hosts mit MAC-Adresse in 10.0.1.0/24. Die IP wird beim Anlegen automatisch aus dem passenden Subnetz vergeben, wenn keine explizit angegeben wird; wird nachträglich eine MAC-Adresse hinzugefügt/entfernt (ipadm -m), verschiebt ipadm den Host automatisch in eine freie IP des jetzt passenden Subnetzes. Details siehe tools/ipadm/README.md.

Technisch ist das weiterhin ein LAN (eine Broadcast-Domain, ein Interface, eine Netzmaske /22) — die vier /24-Zonen sind reine Adress-Konventionen, keine getrennten physischen/VLAN-Netze. dnsmasq braucht dafür nur einen dhcp-range für den dynamischen Pool (10.0.2.10,10.0.2.250,255.255.252.0); dhcp-host-Reservierungen außerhalb dieses Bereichs (z.B. in 10.0.1.0/24) funktioniert trotzdem, solange sie im selben /22 liegen.

Was wurde eingerichtet

Bereich Was Datei auf dem Server Kopie in diesem Repo
LAN-Interface enp7s0 statisch auf 10.0.0.1/22 /etc/network/interfaces config/network-interfaces
IP-Forwarding net.ipv4.ip_forward=1, persistent über Reboot /etc/sysctl.d/99-router-forwarding.conf config/sysctl.d/99-router-forwarding.conf
NAT Masquerading 10.0.0.0/22 → raus über enp3s0 /etc/nftables.conf config/nftables.conf
Port-Forwarding-Include /etc/nftables.conf bindet /etc/nftables.d/*.conf ein (dort generiert ipadm die Port-Forward-Regeln) /etc/nftables.conf (Zeile am Ende) config/nftables.conf
DHCP + DNS dnsmasq: DHCP-Pool, Gateway/DNS-Option, DNS-Forwarding /etc/dnsmasq.d/lan.conf config/dnsmasq.d/lan.conf
DNS-Includes aktiviert eine Zeile in /etc/dnsmasq.conf einkommentiert: conf-dir=/etc/dnsmasq.d/,*.conf /etc/dnsmasq.conf – (Rest der Datei ist Debian-Standard, nicht gespiegelt)
DHCP-Logging log-dhcp aktiviert (zeigt DHCPDISCOVER/OFFER/REQUEST/ACK/NAK in journalctl -u dnsmasq) — war entscheidend, um am 2026-08-19 einen rogue DHCP-Server im LAN zu finden /etc/dnsmasq.d/90-logging.conf config/dnsmasq.d/90-logging.conf
Statische Hosts (DHCP-Reservierung + DNS) von ipadm generiert, nicht von Hand editieren /etc/dnsmasq.d/hosts.conf (generiert) + /etc/ipadm/hosts (Datenbank) – (live Daten, siehe tools/ipadm/)
Port-Forwards (WAN → LAN-Host) von ipadm generiert, nicht von Hand editieren /etc/nftables.d/portforward.conf (generiert) + /etc/ipadm/portforwards (Datenbank) – (live Daten, siehe tools/ipadm/)
dnsmasq-Resilienz Restart=on-failure (Default war no), damit dnsmasq bei einem Boot-Race mit enp7s0 nicht dauerhaft tot bleibt /etc/systemd/system/dnsmasq.service.d/override.conf config/systemd/dnsmasq.service.d/override.conf

Installiertes Paket: dnsmasq (übernimmt sowohl DHCP- als auch DNS-Server-Rolle). nftables war bereits installiert, wurde aber aktiviert (systemctl enable --now nftables).

Details zur dnsmasq-Konfiguration (config/dnsmasq.d/lan.conf)

  • interface=enp7s0 + bind-interfaces + except-interface=enp3s0: dnsmasq lauscht ausschließlich auf dem LAN-Interface. Das ist absichtlich so restriktiv, damit auf der öffentlichen WAN-Seite kein offener DNS-Resolver/DHCP-Server erreichbar ist (Missbrauchsrisiko, z.B. DNS-Amplification).
  • dhcp-range=10.0.2.10,10.0.2.250,255.255.252.0,12h: dynamischer DHCP-Pool in 10.0.2.0/24, 12h Lease. Die Netzmaske 255.255.252.0 (/22) sagt dnsmasq, dass das gesamte LAN ein einziges /22-Netz ist — siehe IP-Adressschema.
  • dhcp-option=option:router,10.0.0.1 / dhcp-option=option:dns-server,10.0.0.1: Clients bekommen den Router selbst als Gateway und als DNS-Server.
  • domain=fhi.mpg.de / server=141.14.128.1 / no-resolv: DNS-Anfragen aus dem LAN werden an den institutseigenen DNS-Server weitergeleitet (gleicher Resolver wie auf der WAN-Seite), interne fhi.mpg.de-Hosts bleiben auflösbar. no-resolv verhindert, dass dnsmasq zusätzlich /etc/resolv.conf als Upstream-Quelle einliest (Eindeutigkeit).

Details zur nftables-Konfiguration (config/nftables.conf)

  • table inet filter: unverändert (keine Regeln, Policy accept auf input/forward/output) – die WAN-Seite wurde bewusst nicht gehärtet/eingeschränkt, um die bestehende Erreichbarkeit des Servers nicht zu verändern.
  • table inet nat / chain postrouting: NAT-Masquerading für Traffic aus 10.0.0.0/22, der über enp3s0 rausgeht. Das ist die einzige Regel, die tatsächlich nötig ist, damit LAN-Clients ins Internet kommen.

Konfiguration anpassen

Alle Änderungen werden direkt auf dem Server in den Dateien unter /etc/... gemacht (Pfade siehe Tabelle oben), dann der jeweilige Dienst neu geladen (siehe Befehle unten). Bitte die Änderung danach auch hier ins Repo übernehmen (Datei in config/ anpassen + committen), damit die Doku aktuell bleibt.

DHCP-Pool / Lease-Zeit ändern

Der dynamische Pool liegt in 10.0.2.0/24. In /etc/dnsmasq.d/lan.conf die Zeile anpassen, z.B. größerer Pool oder andere Lease-Zeit:

dhcp-range=10.0.2.10,10.0.2.250,255.255.252.0,24h

Die Netzmaske (255.255.252.0 = /22) nicht verändern, solange das IP-Adressschema mit den vier /24-Zonen gilt — sie definiert, dass dnsmasq das ganze /22 bedient, nicht nur 10.0.2.0/24.

Danach: systemctl restart dnsmasq

Statischen Host anlegen (DNS und/oder feste DHCP-Reservierung per MAC)

Immer über ipadm, nicht von Hand in dnsmasq.d eintragen — das Tool kennt das IP-Adressschema und vergibt/prüft die IP im passenden Subnetz automatisch:

ipadm -a mein-server                          # nur DNS, IP aus 10.0.0.0/24 auto-vergeben
ipadm -a mein-server aa:bb:cc:dd:ee:ff         # + feste DHCP-Reservierung, IP aus 10.0.1.0/24 auto-vergeben
ipadm -u                                       # anwenden (dnsmasq neu starten)

Details, weitere Befehle (IP/MAC nachträglich ändern, Kommentar, Umbenennen, löschen) siehe tools/ipadm/README.md.

DNS-Upstream ändern (z.B. auf öffentliche Resolver)

In /etc/dnsmasq.d/lan.conf die server=-Zeile anpassen/ergänzen, z.B.:

server=9.9.9.9
server=1.1.1.1

Mehrere server=-Zeilen sind möglich (Round-Robin/Fallback). Danach: systemctl restart dnsmasq

Lokale Domain / eigene Hostnamen im LAN

dnsmasq kann zusätzlich als einfacher lokaler DNS-Server für das LAN dienen. Beispiel in /etc/dnsmasq.d/lan.conf:

address=/server1.lan/10.0.0.10

Oder Einträge über /etc/hosts-Syntax in einer eigenen Datei einbinden (addn-hosts=/etc/dnsmasq.d/lan-hosts).

Port-Forwarding (WAN → LAN-Host)

Wird über ipadm verwaltet, siehe tools/ipadm/README.md. Kurzform: Zielhost muss zuerst als Host in ipadm angelegt sein, dann:

ipadm -pa <hostname> <wan-port> [lan-port] [tcp|udp|both]
ipadm -u   # generiert /etc/nftables.d/portforward.conf neu + reloadet nftables

Nicht mehr von Hand in /etc/nftables.conf eintragen — die Datei bindet dafür /etc/nftables.d/*.conf ein, das ist der von ipadm verwaltete Teil.

⚠️ Falls künftig auch der WAN-Eingang gefiltert werden soll (aktuell bewusst offen gelassen), unbedingt zuerst SSH-Zugriff (und alle anderen aktiv genutzten Dienste) explizit erlauben, bevor eine restriktive policy drop auf chain input gesetzt wird – sonst sperrt man sich ggf. selbst aus.

LAN-Netz/IP-Bereich komplett ändern (z.B. auf einen anderen Adressraum)

  1. /etc/network/interfaces: address der enp7s0-Zeile anpassen.
  2. /etc/dnsmasq.d/lan.conf: dhcp-range und beide dhcp-option-Zeilen (Router/DNS-IP) anpassen.
  3. /etc/nftables.conf: ip saddr 10.0.0.0/22 in der NAT-Regel anpassen.
  4. Falls sich die Aufteilung der vier /24-Zonen ändert (nicht nur die Basis-Adresse): ipadms Env-Vars IPADM_STATIC_CIDR, IPADM_RESERVED_CIDR, IPADM_GATEWAY_IP entsprechend über /etc/systemd/system/ipadm.env o.ä. anpassen — siehe tools/ipadm/README.md (Default ist 10.0.0.0/24 / 10.0.1.0/24 / 10.0.0.1, fest im Binary einkompiliert als Fallback).
  5. Anwenden: Adresse live setzen (ip addr change <neue-ip>/<prefix> dev enp7s0 + alte Adresse mit ip addr del entfernen, falls sich die Präfixlänge ändert — sonst bleiben beide Adressen parallel aktiv), systemctl restart dnsmasq (ein reines reload reicht bei dhcp-range-Änderungen nicht, siehe Hinweis unten), nft -f /etc/nftables.conf. Alternativ komplett: ifdown enp7s0 && ifup enp7s0. Bestehende ipadm-Hosts danach mit ipadm -i <name> <neue-ip> einzeln umziehen und mit ipadm -u anwenden.

Befehle zum Anwenden von Änderungen

# dnsmasq-Konfig auf Syntaxfehler prüfen, dann neu laden
dnsmasq --test
systemctl restart dnsmasq   # NICHT "reload" (SIGHUP) — siehe Hinweis unten

# nftables-Konfig auf Syntaxfehler prüfen, dann neu laden
nft -c -f /etc/nftables.conf
nft -f /etc/nftables.conf
# bzw. systemctl reload nftables (lädt /etc/nftables.conf neu ein)

# Netzwerk-Interface-Änderungen anwenden (ifupdown)
ifdown enp7s0 && ifup enp7s0

# sysctl-Änderungen anwenden
sysctl --system

⚠️ systemctl reload dnsmasq (SIGHUP) genügt bei Config-Änderungen nicht. dnsmasq liest per SIGHUP nur /etc/hosts und einige spezielle Hosts-Dateien-Optionen neu — nicht die conf-dir-Dateien (/etc/dnsmasq.d/*.conf, also lan.conf und das von ipadm generierte hosts.conf). Änderungen dort (dhcp-range, host-record, dhcp-host, …) brauchen einen echten systemctl restart dnsmasq, sonst läuft der alte Stand unbemerkt weiter. ipadm -u macht das seit Version 1.2.0 automatisch richtig (restart statt reload) — bei manuellen Änderungen selbst dran denken.

Troubleshooting / nützliche Befehle

# Aktive nftables-Regeln anzeigen
nft list ruleset

# dnsmasq-Status und Logs
systemctl status dnsmasq
journalctl -u dnsmasq -f

# Wer bekommt gerade welche DHCP-Lease
cat /var/lib/misc/dnsmasq.leases

# DNS-Auflösung über den Router testen
dig @10.0.0.1 www.example.com

# Lauscht dnsmasq wirklich NUR auf enp7s0 (nicht auf der WAN-IP)?
ss -tulpn | grep -E ':53|:67'

# IP-Forwarding aktiv?
sysctl net.ipv4.ip_forward

# Interface-/Carrier-Status (z.B. wenn Kabel nicht erkannt wird)
ip -brief addr
ip link show enp7s0
cat /sys/class/net/enp7s0/carrier

Rogue DHCP-Server erkennen (z.B. "falscher Nameserver"-Symptom)

Am 2026-08-19 kam die Meldung "DHCP liefert falschen Nameserver aus". Ursache war kein Config-Fehler, sondern ein zweiter DHCP-Server im LAN (ein WLAN-Router, der noch im Router- statt Access-Point-Modus lief und parallel eigenes DHCP anbot). Erkennbar in journalctl -u dnsmasq (braucht log-dhcp, siehe oben) an folgendem Muster:

DHCPOFFER(enp7s0) 10.0.0.157 <mac>      ← unser Angebot
DHCPREQUEST(enp7s0) 10.0.0.151 <mac>    ← Client nimmt eine andere IP an
DHCPNAK(enp7s0) 10.0.0.151 <mac> wrong server-ID   ← wir lehnen zu Recht ab

Client hat also ein Angebot von einer fremden Quelle angenommen. Gerät mit aktiver Web-Verwaltung im LAN suchen (z.B. curl -I http://<verdächtige-ip>/) und dessen DHCP-Server deaktivieren / in Access-Point-Modus umschalten — narcissus soll der einzige DHCP-Server im 10.0.0.0/22-Netz sein.

Sicherheitshinweise

  • dnsmasq ist bewusst so konfiguriert, dass es nur auf enp7s0 lauscht (interface=, bind-interfaces, except-interface=enp3s0). Vor jeder Änderung an dieser Konfiguration prüfen, dass diese Einschränkung erhalten bleibt – sonst entsteht ein von außen erreichbarer DNS-/DHCP-Dienst.
  • Die WAN-Seite (enp3s0) wurde absichtlich nicht gefiltert/gehärtet, um die bestehende Erreichbarkeit (u.a. SSH) nicht zu verändern. Das war eine bewusste Entscheidung bei der Einrichtung, keine Vergesslichkeit.