DHCP: Subnet/Netzmaske/Gateway immer aus System-Netzwerkkonfiguration ableiten
- Neue Helfer _list_network_interfaces() (echte Interfaces aus /sys/class/net) und _detect_interface_network() (IPv4/Prefix per "ip addr show", Gateway per "ip route show default") — Subnet/ Netzmaske/Router werden dadurch bei jeder Anzeige/Generierung live vom System gelesen statt manuell gepflegt zu werden. - dhcp_subnet/dhcp_netmask als manuelle Settings entfernt; Interface ist jetzt ein Dropdown mit den tatsächlich vorhandenen Interfaces statt Freitext, serverseitig zusätzlich gegen die echte Liste validiert. - _dhcp_reservation_candidates()/_render_kea_config() nehmen jetzt das erkannte Netz (ipaddress.IPv4Network) bzw. net_info entgegen statt Subnet/Netzmaske aus der Konfiguration zu lesen; Router kommt vom erkannten Gateway (Fallback: erster DNS-Eintrag, wie zuvor). - UI zeigt das erkannte Netz (IP/Prefix, Subnet, Gateway) read-only an; Schreiben/Vorschau werden blockiert bzw. liefern eine leere Reservierungsliste, wenn die Erkennung fehlschlägt, statt eine mit Sicherheit falsche Konfiguration zu erzeugen. - Live getestet: Erkennung liefert korrekt das tatsächliche WSL-NAT-Netz (172.25.64.0/20) samt Gateway; generierte Config besteht kea-dhcp4 -t; ein Testgerät mit IP im erkannten Netz erscheint korrekt als Reservierung, Geräte außerhalb werden weiterhin sauber übersprungen. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -59,30 +59,44 @@
|
||||
<div class="section-head" style="margin-bottom:16px;">
|
||||
<div>
|
||||
<h2 style="font-size:16px;">Netzwerk-Konfiguration</h2>
|
||||
<div class="hint">Grundlage für die generierte Subnet- und Reservierungs-Deklaration.</div>
|
||||
<div class="hint">Subnet, Netzmaske und Gateway werden immer live aus der System-Netzwerkkonfiguration des gewählten Interfaces übernommen — nicht manuell gepflegt, damit sie nie aus dem Ruder laufen können.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if net_info.ok %}
|
||||
<div class="flex gap-2" style="align-items:center; margin-bottom:16px; flex-wrap:wrap;">
|
||||
<span class="pill online">Erkannt</span>
|
||||
<span class="mono" style="font-size:12.5px;">{{ net_info.ip }}/{{ net_info.prefix }} (Netz {{ net_info.network }})</span>
|
||||
{% if net_info.gateway %}<span class="text-faint mono" style="font-size:12px;">Gateway {{ net_info.gateway }}</span>{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="flex gap-2" style="align-items:center; margin-bottom:16px;">
|
||||
<span class="pill offline">Nicht erkannt</span>
|
||||
<span class="text-faint" style="font-size:12px;">{{ net_info.error }}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if can_edit %}
|
||||
<form method="post">
|
||||
<input type="hidden" name="save_dhcp_config" value="1">
|
||||
<div class="field"><label>Interface</label>
|
||||
<input type="text" name="dhcp_interface" value="{{ cfg.dhcp_interface }}">
|
||||
</div>
|
||||
<div class="field"><label>Subnet</label>
|
||||
<input type="text" name="dhcp_subnet" value="{{ cfg.dhcp_subnet }}">
|
||||
</div>
|
||||
<div class="field"><label>Netzmaske</label>
|
||||
<input type="text" name="dhcp_netmask" value="{{ cfg.dhcp_netmask }}">
|
||||
<select name="dhcp_interface">
|
||||
{% for iface in interfaces %}
|
||||
<option value="{{ iface }}" {% if iface == cfg.dhcp_interface %}selected{% endif %}>{{ iface }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<div class="field-hint">Subnet/Netzmaske/Gateway oben werden für das hier ausgewählte Interface erkannt.</div>
|
||||
</div>
|
||||
<div class="field"><label>Range Start</label>
|
||||
<input type="text" name="dhcp_range_start" value="{{ cfg.dhcp_range_start }}">
|
||||
</div>
|
||||
<div class="field"><label>Range Ende</label>
|
||||
<input type="text" name="dhcp_range_end" value="{{ cfg.dhcp_range_end }}">
|
||||
<div class="field-hint">Muss innerhalb des oben erkannten Netzes liegen.</div>
|
||||
</div>
|
||||
<div class="field"><label>DNS-Server</label>
|
||||
<input type="text" name="dhcp_dns" value="{{ cfg.dhcp_dns }}">
|
||||
<div class="field-hint">Kommagetrennt, falls mehrere. Der erste Eintrag wird auch als Router/Gateway verwendet.</div>
|
||||
<div class="field-hint">Kommagetrennt, falls mehrere. Router/Gateway kommt vom erkannten Netz oben; nur falls dort keins gefunden wird, wird ersatzweise der erste DNS-Eintrag verwendet.</div>
|
||||
</div>
|
||||
<div class="field"><label>Domain</label>
|
||||
<input type="text" name="dhcp_domain" value="{{ cfg.dhcp_domain }}">
|
||||
@@ -173,7 +187,7 @@
|
||||
<div class="hint">
|
||||
{{ reservations|length }} aktive{{ ' Clients' if reservations|length != 1 else 'r Client' }} mit gültiger MAC + IP im konfigurierten Subnet.
|
||||
{% if skipped_count %}{{ skipped_count }} aktive{{ ' Clients' if skipped_count != 1 else 'r Client' }} ohne MAC/IP übersprungen.{% endif %}
|
||||
{% if out_of_subnet_count %}{{ out_of_subnet_count }} aktive{{ ' Clients außerhalb' if out_of_subnet_count != 1 else 'r Client außerhalb' }} des konfigurierten Subnets „{{ cfg.dhcp_subnet }}“ übersprungen — Kea lehnt Reservierungen außerhalb ihres Subnets ab.{% endif %}
|
||||
{% if out_of_subnet_count %}{{ out_of_subnet_count }} aktive{{ ' Clients außerhalb' if out_of_subnet_count != 1 else 'r Client außerhalb' }} des erkannten Netzes{% if net_info.network %} „{{ net_info.network }}“{% endif %} übersprungen — Kea lehnt Reservierungen außerhalb ihres Subnets ab.{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% if can_edit %}
|
||||
|
||||
Reference in New Issue
Block a user