Zentrales DHCP für komplexere Netze

In komplexeren Netzen kann/sollte, im Gegensatz zu kleinen flachen Netzen, meist nicht auf jedem Router oder Firewall ein DHCP-Server betrieben werden. Hier ist es einfacher und auch weniger fehleranfällig einen zentralen DHCP-Server zu betreiben und diesen dann im Failover-Verbund redundant zur Verfügung zu stellen.
In diesem Artikel wird gezeigt, wie das auf Basis zweier Debian- oder Ubuntu-Server mit dem ISC DHCP-Server implementiert werden kann. Einerseits sind diese Tools nicht nur  Open Source-Software, sehr gut getestet und kostenfrei, sondern auch sehr gut dokumentiert. ISC stellt neben dem DHCP-Server mit BIND den weltweit wohl am meisten verwendeten DNS-Server bereit. Selbst kommerziell vertriebene Appliances verwenden häufig den ISC DHCP-Server.

Ein DHCP-Client ist ein Gerät ohne eigene IP-Konfiguration. Um diese zu bekommen setzt er im Netzwerk einen Multicast ab, einen DHCPREQUEST. Ist auf der Firewall ein Server in Betrieb beantwortet diese das.In einem größeren Netzverbund ist dort ein DHCP-Relay konfiguriert, das den Request als Unicast an den zentralen DHCP-Server weiterleitet.
Der erkennt anhand der Relay-IP aus welchem Netzwerksegment der Request kommt und schickt eine entsprechende Konfiguration zurück. Diese Konfiguration ist zeitlich begrenzt und muss regelmäßig erneuert werden. Man nennt das ein Lease. Der DHCP-Server nutzt das und vergibt nicht mehr erneuerte Leases erneut an andere Geräte. Das ist z.B. in Gast-WLANs sehr interessant, weil es verhindert, dass ein IP-Bereich ‘überläuft’.

Startpunkt sind zwei installierte Linux-Systeme, in meinem Beispiel Ubuntu Server 20.04 LTS mit den festen IPs 172.16.199.11/24 und 172.16.199.12/24. Der Router ins Internet (Default Gateway) hat die IP 172.16.199.1, der Router zu den Client-Netzen  hat die IP 172.16.199.2. Die Clients kommen aus den Netzen 172.16.210.0/24, 172.16.211.0/24, 172.16.220.0/24 und 172.16.221.0/24. Deren Default-Gateways sind entsprechend immer die .1-Adressen. Die beiden DHCP-Server befinden sich also im Netz zwischen den beiden Routern.

Installation des DHCP-Daemon

Nach dem Login auf dem ersten Linux-Server wird zuerst das gesamte System aktualisiert.

sudo -i um Systemverwalterrechte zu bekommen
apt update Repos aktuell einlesen
apt dist-upgrade Update des gesamten Systems

Um sicher sein zu können, dass alle Aktualisierungen aktiviert sind, wird mittels reboot dass System neu gestartet. Danach loggt man sich neu ein und wechselt mittels sudo -i wieder in den root-Modus. Nun wird die Installation des DHCP-Servers gestartet.

apt install isc-dhcp-server

Damit ist der Server installiert und kann konfiguriert werden. Der Dienst muss an ein Interface gebunden werden und dies in die Konfigurationsdatei eingetragen werden.

ip address show -> Ermittlung des Interface-Namens
Interfacenamen-Namen eintragen in /etc/default/isc-dhcp-server bei INTERFACESv4
Z.B. INTERFACESv4="ens18"

Damit ist der Dienst an ein Interface gebunden und die eigentliche Arbeitsweise kann konfiguriert werden.
Die zentrale Konfigurationsdatei befindet sich in /etc/dhcp. Diese Datei wird als dhcpd.conf.orig gespeichert, danach wird dhcpd.conf als leere Datei neu angelegt.
Das Konzept ist, die Konfiguration zu splitten. In dhcp-server.conf werden die zentralen Definitionen abgelegt, in dhcp-ha.conf wird die Failover-Konfiguration abgelegt und in dhcp-networks.conf werden die auszuliefernden Konfigurationen abgelegt. In der dhcpd.conf stehen nur noch die Includes und kein weiterer Inhalt. Um später den Failover-Partner oder auch weitere Server synchron zu halten, muß so lediglich die Datei /etc/dhcp/dhcp-networks.con auf die jeweils anderen Server kopiert werden. Server-Optionen oder  auch Failover-Konfigurationen bleiben so immer unangetastet.

cd /etc/dhcp
mv dhcpd.conf dhcpd.conf.orig
touch dhcpd.conf
touch dhcp-server.conf
touch dhcp-ha.conf
touch dhcp-networks.conf

Eintrag in dhcpd.conf:
include "/etc/dhcp/dhcp-server.conf";
include "/etc/dhcp-ha.conf";
include "/etc/dhcp/dhcp-networks.conf";

Damit der Server ohne Fehler gestartet werden kann, muss das Netzwerk des gebundenen Interfaces in die dhcp-server.conf eingetragen werden.

nano /etc/dhcp/dhcp-server.conf

# IP-Netz des Ethernet-Interfaces
subnet 172.16.199.0 netmask 255.255.255.0 { }

Um kompatibel zu z.B. Windows zu sein, müssen noch zwei Dinge eingestellt werden.
Das Eine ist ein Eintrag in der hosts-Datei, das andere eine Route.

nano /etc/hosts
255.255.255.255 dhcp

apt install net-tools Um u.a. route zu installieren, dann
route add -host dhcp dev ens18

Damit ist die Grundkonfiguration des Dienstes komplett und er kann gestartet werden

systemctl start isc-dhcp-server startet den Dienst
systemctl status isc-dhcp-server zeigt an ob der Dienst läuft
systemctl enable isc-dhcp-server aktiviert den Autostart des Dienstes

systemctl status sollte nun etwa folgendes ausgeben:

root@dhcp2:~# systemctl status isc-dhcp-server 
● isc-dhcp-server.service - ISC DHCP IPv4 server 
    Loaded: loaded (/lib/systemd/system/isc-dhcp-server.service; enabled; vendor preset: enabled) 
    Active: active (running) since Sat 2020-10-31 15:04:43 CET; 8h ago 
      Docs: man:dhcpd(8) 
  Main PID: 118428 (dhcpd) 
     Tasks: 4 (limit: 4620) 
    Memory: 5.1M 
    CGroup: /system.slice/isc-dhcp-server.service 
            └─118428 dhcpd -user dhcpd -group dhcpd -f -4 -pf /run/dhcp-server/dhcpd.pid -cf /etc/dhcp/dhcpd.conf

Dies wird noch um die letzten Log-Einträge des dhcpd ergänzt. Wichtig dabei ist der Status ‘active (running)’.
Dieser Teil ist nun fertig und wir können die Installation der Admin-GUI beginnen.

  • Es hat sich im Nachhinein eine Eigenart der Ubuntu-Installation ergeben, die verhindert, dass das pid-File geschrieben werden kann. Wie das korrigiert werden kann ist hier beschrieben.

Installation Webmin

Webmin ist ein graphisches Frontend, mit dem ein Linux-Server und seine Dienste (fast) vollständig administriert werden kann. Aus Sicherheitsgründen soll der Zugriff über https erfolgen, daher wird beim Ubuntu-Server noch die SSL-Bibliothek für Perl benötigt, da diese nicht mit installiert wird.

apt install -y libnet-ssleay-perl

Damit sind die Voraussetzungen für die Installation von Webmin geschaffen. Webmin selbst kann als tar-File von www.webmin.com geladen werden.
Nach dem Download wird die Installationsdatei per SFTP (z.B. mittels Filezilla) in das Home-Verzeichnis des Server-Users tranferiert. Nun  wird die Datei für die Installation vorbereitet.

chmod 777 /home/RACF/webmin......tar.gz gibt alle Berechtigungen auf die Datei
mv /home/RACF/webmin.....tar.gz /opt verschiebt die Datei in /opt
cd /opt
tar -xzvf webmin.....tar.gz entpackt die Datei in das versionierte Unterverzeichnis
rm webmin....tar.gz Löscht die Installationsdatei
cd webmin.....
./setup.sh startet die Installation

Dabei werden die Defaults übernnommen, außer dem Usernamen. Es ist ein starkes Passwort zu verwenden und https sowie Autostart beim Boot aktiviert.

Nach Abschluss der Installation erfolgt der Zugriff im Browser via:

https://172.16.199.11:10000
https://172.16.199.12:10000

Username und Passwort lauten wie in der Installation festgelegt.

Nach der Installation kann es vorkommen, dass im Dashboard angezeigt wird, dass man das OS aktualisieren soll.
Dazu wird unter Webmin -> Webmin Configuration der Pfad aktualisiert:

bin
/usr/bin
/sbin
/usr/sbin
/usr/local/bin

und den Systempfad einbeziehen (Checkbox unterhalb setzen.
Danach das Setup aus /opt/webmin-… erneut laufen lassen.
nun sollte das Problem gelöst sein.

Unter Hardware -> System Time -> Reiter Change Timezone die Zeitzone auf Europe/Berlin einstellen

Konfiguration DHCP in Webmin

unter Servers -> DHCP Server in der Module Config (Zahnrad-Icon oben links) folgende Anpassungen:
Display Subnets and Hosts: List
Display Leases Times : Local Time
Maximum Number of Hosts and Subnets to display: 20
Add new Subnets, Hosts and Groups to file: /etc/dhcp/dhcp-networks.conf

Sollte nach dem Speichern nur der Button Start Server vorhanden sein, und nicht Apply Changes und Stop Server muss der Pfad zum PID-File in der Modul-config angepasst werden. Welches Pid-File verwendet wird, steht in der Augabe von systemctl status isc-dhcp-server

Der zweite Server wird ebenso konfiguriert.

HA-Konfiguration zwischen zwei DHCP-Nodes (DHCP Failover)

Editieren /etc/dhcp/dhcp-ha.conf
Einfügen auf dem Primary DHCP-Server:

failover peer "Beispiel-System" {
primary;
address 172.16.199.11;
port 519;
peer address 172.16.199.12;
peer port 520;
max-response-delay 60;
max-unacked-updates 10;
mclt 3600;
split 255;
load balance max seconds 5;
}

omapi-port 7911;
omapi-key omapi_key;

key omapi_key {
algorithm hmac-md5;
secret Ofakekeyfakekeyfakekey==;
}

Auf dem Secondary in der /etc/dhcp/dhcp-ha.conf eintragen:

failover peer "Beispiel-System" {
secondary;
address 172.16.199.12;
port 520;
peer address 172.16.199.11;
peer port 519;
max-response-delay 60;
max-unacked-updates 10;
load balance max seconds 5;
}

omapi-port 7911;
omapi-key omapi_key;

key omapi_key {
algorithm hmac-md5;
secret Ofakekeyfakekeyfakekey==;
}

Die IPs, Ports und das Secret des OMAPI-Keys müssen natürlich angepasst werden.
mclt (Maximum Client LeadTime) und split (oder korrespondierent hba) werden nur auf dem Primary gesetzt.
split kann dabei zwischen 0 und 255 gesetzt werden. 0 bedeutet, dass der Primary passiv ist, 128 wäre ein 50/50 Loadbalancing und 255 ist ein Failover auf den Secondary bei Ausfall des Primary.

Damit das System funktioniert muss die Konfiguration in mindestens einem Adress-Pool (Datei /etc/dhcp/dhcp-networks.conf) angesprochen werden. Z.B. so:

# User Client A
subnet 172.16.210.0 netmask 255.255.255.0 {
option time-servers 192.168.10.20;
default-lease-time 900;
option subnet-mask 255.255.255.0;
option broadcast-address 172.16.210.255;
option routers 172.16.210.1;
option domain-name "clienta.digiliv.de";
option domain-name-servers 1.1.1.1 , 8.8.8.8;
pool {
range 172.16.210.10 172.16.210.19;
failover peer "Beispiel-System";
}
}

In der Webmin-GUI werden Subnetz, Client-Einstellungen und Pool wie abgebildet konfiguriert:

Ist das erledigt, können die /etc/dhcp/dhcp-networks.conf-Dateien gleichgezogen werden, indem sie vom
Primary auf den Secondary kopiert wird.

Nun kann das Failover aktiviert und auf beiden Servern systemctl ausgeführt werden:

systemctl restart isc-dhcp-server
systemctl status isc-dhcp-server

Beide Server sollten aktiv sein und im Systemprotokoll ihren Sync anzeigen.

Nov 1 00:04:55 dhcp2 dhcpd[118428]: balancing pool 55d6f7429ee0 172.16.220.0/24 total 10 free 4 backup 5 lts 0 max-own (+/-)1
Nov 1 00:04:55 dhcp2 dhcpd[118428]: balanced pool 55d6f7429ee0 172.16.220.0/24 total 10 free 4 backup 5 lts 0 max-misbal 1
Nov 1 00:04:55 dhcp2 dhcpd[118428]: balancing pool 55d6f7428970 172.16.210.0/24 total 10 free 4 backup 5 lts 0 max-own (+/-)1
Nov 1 00:04:55 dhcp2 dhcpd[118428]: balanced pool 55d6f7428970 172.16.210.0/24 total 10 free 4 backup 5 lts 0 max-misbal 1
Nov 1 00:10:34 dhcp2 dhcpd[118428]: Wrote 14 leases to leases file.

Als letzter Schritt muss dann sichergestellt werden, dass Client-Anfragen auf beide
Server verteilt werden können. Dazu wird für das jew. Clientnetz ein entsprechender
IP-Helper eingetragen. Z.B. so auf einem Cisco-Router:

interface GigabitEthernet0/1.10
description Client A VLAN10
encapsulation dot1Q 10
ip address 172.16.210.1 255.255.255.0
ip helper-address 172.16.199.11
ip helper-address 172.16.199.12

Als Test kann der DHCP-Server-Dienst auf dem Primary heruntergefahren werden.
Der Secondary zeigt im Protokoll Moving from Normal to Interrupted und übernimmt die
weitere Verteilung der Leases.
Wird nach einiger Zeit der Dienst auf dem Primary wieder gestartet, wird die Kommunikation
zwischen beiden Knoten wieder hergestellt und der Primary wird wieder aktiv.

Im Systemlog kann man auch die Kommunikation zwischen Client und Server verfolgen.

Oct 31 15:48:06 dhcp2 dhcpd[118428]: DHCPDISCOVER from 36:46:77:7d:08:04 (iPhone) via 172.16.221.1
Oct 31 15:48:07 dhcp2 dhcpd[118428]: DHCPOFFER on 172.16.221.31 to 36:46:77:7d:08:04 (iPhone) via 172.16.221.1
Oct 31 15:48:08 dhcp2 dhcpd[118428]: DHCPREQUEST for 172.16.221.31 (172.16.199.11) from 36:46:77:7d:08:04 (iPhone) via 172.16.221.1
Oct 31 15:48:08 dhcp2 dhcpd[118428]: DHCPACK on 172.16.221.31 to 36:46:77:7d:08:04 (iPhone) via 172.16.221.1

Wenn ein Client lediglich das Lease verlängern möchte, entfallen DHCPDISCOVER und DHCPOFFER und es tauchen lediglich DHCPREQUEST und DHCPACK im Log auf

 

Quellen: https://www.isc.org/dhcp/