DHCP failover mit Linux

Für eine erweiterte Redundanz möchte man einen zweiten DHCP-Server installieren und diese im failover Modus betreiben.
Ich werde hier einen sauberen Weg für ein solches Setup unter Ubuntu beschreiben; es kann aber praktisch unverändert auch für andere Linux wie CentOS verwendet werden.

Alternativ könnte man dieses Setup auch zum loadbalancing verwenden, auch wenn dies wohl selten „nötig“ sein wird.

Inhalt

Installation

Zunächst mal wird auf beiden Servern der ISC DHCP Server installiert:

apt install isc-dhcp-server

Als nächstes muss man einen der Server zum „primären“ machen und der andere zum „sekundären“, da die Konfiguration sich nicht automatisch synchronisiert.
Jeder Server besitzt zwei Dateien, eine /etc/dhcp/dhcpd.conf in der die spezifischen Angaben des jeweiligen Nodes stehen und eine inkludierte /etc/dhcp/dhcpd.example.net.conf, welche für beide Nodes gleich ist und die allgemeine DHCP-Konfiguration enthält.
Diese Datei wird dann auch per cronjob vom primären auf den sekundären Host synchronisiert.

Zu den Servernamen die hier verwendet werden, heissen die beiden DHCPs dhcp01.example.net (192.168.1.10) und dhcp01.example.net (192.168.1.20).

Primärer DHCP node

/etc/dhcp/dhcpd.conf

authoritative;
log-facility local1;
 
failover peer "dhcp.example.net" {
  primary;
  address dhcp01.example.net;
  port 647;
  peer address dhcp02.example.net;
  peer port 847;
  max-response-delay 60;
  max-unacked-updates 10;
  mclt 3600;
  # Nur Failover
  split 255;
  # Failover und Loadbalancing
  #split 128;
  load balance max seconds 3;
}
 
omapi-port 7911;
omapi-key omapi_key;
 
key omapi_key {
     algorithm hmac-md5;
     secret Ofakekeyfakekeyfakekey==;
}
 
include "/etc/dhcp/dhcpd.example.net.conf";
  • Der Name bei failover peer ist egal, er muss einfach bei beiden DHCP Servern gleich sein. Möglich wäre z.B. auch „failover-partner“ oder etwas in der Art
  • Bei address muss entweder der Hostname oder IP Adresse des ersten- und bei peer address des zweiten DHCP-Servers stehen.
  • Der „Split„-Wert legt fest wie sich die Server die herausgabe der Adresse aufteilen. 255 bedeutet, dass der primäre DHCP Server 100% des IP Pools verwaltet, d.h. so lange beide laufen gibt nur der primäre IP addressen heraus (reines failover).
    Bei einem Wert von 128 würden beide DHCP Server je die Hälfte des IP Pools verwalten (failover + loadbalancing).
    Sofern man nicht seeeehr viele DHCP clients hat, ist es übersichtlicher, wenn ein Server die „obehrand“ hat und der zweite nur beim Ausfall des ersten übernimmt.
  • Der key omapi_key kann beispielsweise mit dem Programm dnssec-keygen aus dem bind-Paket generiert werden:
    dnssec-keygen ‐a HMAC‐MD5 ‐b 512 ‐n USER DHCP_OMAPI

In diesem Setup ist der primäre Server grundsätzlich zuständig für alle IP-Adressen. Sollte dieser ausfallen übernimmt der sekundäre alle leases und den IP-Pool, so lange bis der Primäre wieder online ist; danach erfolgt eine „Rückgabe“ an den primären Server.

/etc/dhcp/dhcpd.example.net.conf

subnet 192.168.1.0 netmask 255.255.255.0
{
  # Global options
  default-lease-time 3600;              # 1 hour
 
  # DHCP options
  option subnet-mask 255.255.255.0;
  option routers 192.168.1.1;
  option domain-name-servers 192.168.1.10, 192.168.1.20;
  option netbios-name-servers 192.168.1.10, 192.168.1.20;
  option netbios-node-type 8;
  option domain-name "ad.example.net";
  option domain-search "ad.example.net", "lan.example.net";
 
  # DHCP Pool
  pool
  {
    failover peer "dhcp.example.net"; 
    range 192.168.1.100 192.168.1.200;
  }
}
 
# Static IPs
host fixed-client01
{
  hardware ethernet 00:00:00:00:00:00;
  fixed-address 192.168.1.11;
}

Dies ist ein einfaches Beispiel einer DHCP-Konfiguration.
Hinweis: Wie man sieht müssen die statischen IP Adressen ausserhalb des Subnets sein.

Diese Datei wird dann initial auf den sekundären Server kopiert:

scp /etc/dhcp/dhcpd.example.net.conf  dhcp02.example.net:/etc/dhcp/dhcpd.example.net.conf

DHCP Replikation

Da dhcpd derzeit noch keine automatische Replikation unterstützt wird die DHCP-Konfigurationsdatei mittels rsync synchronisiert.
Dazu wird auf dem primären DHCP ein rsync-server eingerichtet:

/etc/xinetd.d/rsync

service rsync
{
  disable               = no
  only_from             = 192.168.1.20
  socket_type           = stream
  wait                  = no
  user                  = root
  server                = /usr/bin/rsync
  server_args           = --daemon
  log_on_failure        += USERID
}

Danach noch xinetd neu starten:

systemctl restart xinetd

Dazu die rsync Konfiguationsdatei:
/etc/rsyncd.conf

[dhcpd]
path = /etc/dhcp/
comment = dhcpd configuration
uid = root
gid = root
read only = yes
auth users = dhcpd-repl
secrets file = /etc/rsync.secret

Und das dazugehörige secrets file:
/etc/rsync.secret

dhcpd-repl:geheim

Dieses noch absichern:

chmod -v 600 /etc/rsync.secret

Sekundärer DHCP node

Zunächst wird das node-spezifische file erstellt:

/etc/dhcp/dhcpd.conf

authoritative;
log-facility local1;
 
failover peer "dhcp.example.net" {
  secondary;
  address dhcp02.example.net;
  port 847;
  peer address dhcp01.example.net;
  peer port 647;
  max-response-delay 60;
  max-unacked-updates 10;
  load balance max seconds 3;
}
 
omapi-port 7911;
omapi-key omapi_key;
 
key omapi_key {
     algorithm hmac-md5;
     secret Ofakekeyfakekeyfakekey==;
}
 
include "/etc/dhcp/dhcpd.example.net.conf";

Replikation konfigurieren

Nun wird der sekundäre Server so konfiguriert, dass er sich per Script die gemeinsame DHCP-Konfigurationsdatei vom primären Server holt, vergleicht und nur falls sich diese geändert hat den DHCP Server neu lädt.

rsync Konfigurieren

Zuerst die Datei mit dem rsync Passwort anlegen:

echo "geheim" > /etc/rsync.pass
chmod -v 600 /etc/rsync.pass

Synchronisationsscript anlegen

Nun wird das folgende Script hinzugefügt:

/usr/local/lib/dhcpd/sync-dhcpd-config.sh

#!/bin/bash
 
# updates the dhcpd.conf file from the primary cluster node,
# checks if it changed and restarts when neccessary
 
SCRIPT_NAME=$(basename $0)
FILE_CHECK=/etc/dhcp/dhcpd.example.net.conf.md5
MD5_CURRENT=$(cat "$FILE_CHECK")
MD5_NEW=""
 
/usr/bin/rsync -XAavz --delete-after --password-file=/etc/rsync.pass rsync://dhcpd-repl@zh-v-dc01/dhcpd/dhcpd.example.net.conf /etc/dhcp/dhcpd.example.net.conf  > /dev/null 2>&1
MD5_NEW=$(/usr/bin/md5sum /etc/dhcp/dhcpd.example.net.conf | awk '{print $1}')
 
if [ "$MD5_NEW" != "$MD5_CURRENT" ]; then
  logger -p local1.notice -t $SCRIPT_NAME -i "dhcpd configuration on master changed, restarting dhcpd (Current md5sum: $MD5_CURRENT / New md5sum: $MD5_NEW)"
  # Check config before reloading
  /usr/sbin/dhcpd -t > /dev/null 2>&1
  RC=$?
  if [ "$RC" -eq 0 ]; then
    systemctl restart isc-dhcp-server
    /usr/bin/md5sum /etc/dhcp/dhcpd.example.net.conf | awk '{print $1}' > $FILE_CHECK
  else
    logger -p local1.warning -t $SCRIPT_NAME -i "WARNING: configuration check failed, will NOT restart dhcpd!"
  fi
fi
# Can be turned on, optionally, but fills the logs with "OK" messages
#else
#  echo "Nothing changed, no restart required"
#fi

cronjob für die Replikation erstellen

*/5 * * * * /usr/local/lib/dhcpd/sync-dhcpd-config.sh

Danach noch auf beiden Servern den DHCP-Server starten und fertig ist das faiover-setup. 🙂

Quellen

  • kb.isc.org: A Basic Guide to Configuring DHCP Failover
  • Published by

    Steven Varco

    Steven ist ein Redhat RHCE- und Kubernetes CKA Zertifizierter Linux-Crack und ist seit über 20 Jahren sowohl beruflich wie auch privat auf Linux spezialisiert. In seinem Keller steht ein Server Rack mit diversen ESX und Linux Servern.

    6 thoughts on “DHCP failover mit Linux”

    1. Sehr hilfreicher Artikel. Bei der Konfiguration auf unseren DHCP-Servern gelang es nicht die im „failover peer“ Abschnitt angegebenen „address“ Zeilen als FQDN auszuführen. Der dhcpd startet dann nicht und meldet als Fehler „failover peer failover-partner: invalid argument“
      Diesen „Bug ?“ findet man auch in anderen Publikationen

      Noch ein Verbesserungsvorschlag: Wenn die dhcp-Konfiguration in mehrere Files modularisiert ist ist ein
      "cat /etc/dhcp/dhcpd.example.net.conf weitereconfig.conf | md5sum | awk '{print $1}'" zu verwenden und natürlich per rsync auch entsprechende Files zu kopieren.

    2. Danke für deinen Artikel. Damit hat der Failover endlich geklappt – nach einem vergeblichen Versuch letzten Sommer.

      Nun möchte ich noch die automatische Replikation in Angriff nehmen. Ich setze rsync bereits oft für Backups ein, allerdings gehe ich immer über SSH. So spare ich mir den Betrieb des zusätzlichen rsync-servers.

      Wie müsste man das Skript anpassen, um rsync via ssh statt über den rsync-Server laufen zu lassen?

      1. Einfach die Zeile: /usr/bin/rsync -XAavz --delete-after --password-file=/etc/rsync.pass rsync://dhcpd-repl@zh-v-dc01/dhcpd/dhcpd.example.net.conf /etc/dhcp/dhcpd.example.net.conf > /dev/null 2>&1 ändern in: /usr/bin/rsync -XAavz --delete-after zh-v-dc01:/dhcpd/dhcpd.example.net.conf /etc/dhcp/dhcpd.example.net.conf > /dev/null 2>&1

    3. Danke für deine Antwort.
      Ich habe jetzt übrigens doch deine rsync-Server-Lösung übernommen.
      Denn bei SSH müsste ich im Prinzip ja „root“ Zugriff erlauben, und mit rsync gibt es doch eine Schranke mehr.

    Schreibe einen Kommentar zu Ralf Schenk Antworten abbrechen

    Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert