netzwerke:dhcp

DHCP (Dynamic Host Configuration Protocol)

Das Dynamic Host Configuration Protocol (DHCP) ermöglicht mit Hilfe eines entsprechenden DHCP-Serverdienstes die dynamische Zuweisung einer IP-Adresse und weiterer Konfigurationsparameter an Computern in einem Netzwerk (z. B. Internet oder LAN). Da beim Adressbezug der Clientrechner ein Broadcast verschickt wird der nur im gleichen Subnetz empfangen werden kann, muss in jedem Subnetz ein DHCP-Server oder zumindest ein DHCP-Relay-Agent (siehe unten) stehen.

DHCP-Kommunikation, Lizenz public domain

Abgesehen von der Lease-dauer können Clients folgende Konfigurationsparameter übergeben werden:

  • IP-Adresse beziehen:
    sudo dhclient eth0
  • IP-Adresse freigeben (ähnlich zu ipconfig /release unter Windows):
    sudo dhclient -r eth0

Konfiguration von ISC DHCP3-Server unter Linux

Bei Ubuntu kann man das Paket dhcp3-server benutzen. In der Standardeinstellung wird erstmal kein Client bedient, zuerst müssen die Einstellungen vorgenommen werden.

Die Einstellungen findet man in der Datei

/etc/dhcpd.conf

Die Dokumentation befindet sich im Verzeichnis /usr/share/doc/dhcp3-server/, dort findet man auch eine Beispielkonfiguration. Grundsätzlich beginnen alle für Clients und das DHCP-Protokoll wichtigen Parameter mit dem Schlüsselwort option während die übrigen Einstellungen das Verhalten des Server regeln.

:!: Wenn der DHCP-Server der offizielle Server für das Subnetz ist, sollte unbedingt die Zeile

authoritative;

in der Konfiguration vorkommen. Diese Einstellung erlaubt es dem DHCP-Server einen DHCPNACK an falsch konfigurierte Clients (z.B. ein physisch umgezogener Rechner dessen Lease-Dauer noch nicht abgelaufen ist) zu senden.

Die IP des DHCP-Servers kann man auch gleich mit der Option „local-address“ an eine IP binden.

Die Konfiguration (z.B einzelnder Hosts) kann man auch in Einzeldateien auslagern:

host passacaglia {
  hardware ethernet 0:0:c0:5d:bd:95;
  filename "vmunix.passacaglia";
  server-name "toccata.fugue.com";
}

Diese Einzeldateien kann man mit

 include "/etc/pfad/datei";
 }

wieder in die Konfiguration aufnehmen.

Standardmäßig wird ins syslog protokolliert, man kann aber eigene Log-Dateien für den DHCP-Server anlegen lassen.

Wie man eigene Log-files erzeugt wird steht hier.

Die Standard-leasetime ist auf 600 Sekunden gesetzt (wenn der Client nicht danach fragt), falls der DHCP-Client mehr anfragt wird maximal die max-lease-time zugebilligt.

default-lease-time 600;
max-lease-time 7200;

Die Lease-dauer von 10 min bzw. max. 2h scheint mir etwas niedrig angesetzt, wenn die Rechnerzuordnung relativ statisch bleibt kann man zur Vermeidung unnötigen Datenverkehrs die Zeiten (deutlich) erhöhen.

:!: Die Lease-times können auch für einzelene Subnetze anders festgelegt werden.

Der ddns-update-style-Parameter kann drei mögliche Werte annehmen:

  1. interim: Wenn der eingesetzte DNS-Server DDNS beherrscht (die Namensauflösung der Rechner auf ihre aktuelle IP) sollte man die interim
  2. none: Wenn der eingesetzte DNS-Server kein DDNS beherrscht oder man es nicht benutzen will.
  3. ad hoc : veraltet, sollte nicht mehr benutzt werden!

Es muss also eine Zeile nach dem Muster

ddns-update-style none;

herauskommen.

Siehe auch Option ddns-updates.

:!: dem DHCP-Server die Möglichkeit zu geben, DNS-Einträge zu ändern ist ein potentielles Sicherheitsrisiko! Daher sollte man dem DHCP-Server ein shared-secret mitteilen, das der Server vorher generiert hat. Bind generiert dieses bereits bei der Installation (es steht in der Datei /etc/bind/rndc.key).

Näheres kann man in Handbuch (man dhcpd.conf) unter „DYNAMIC DNS UPDATE SECURITY“ nachlesen.

Die folgenden Einstellungen werden mit option eingeleitet und haben entweder lokale (auf das jeweilige Subnetz) oder globale Wirkung (auch alle Clients).

:!: Die Angabe des Domänennamens und die Nameserver haben eine globale Wirkung.

option domain-name "beispiel.beispieldomain.de";
option domain-name-servers IP1, IP2;

statt der IPs der Nameserver (durch Komma getrennt!) kann auch der Name (z.B. ns1.beispieldomain.de) angegeben werden.

  • IP-Adressenpool und Netzwerkmaske:

:!: Für jedes Subnetz im Netzwerk sollte ein Eintrag vorhanden sein, auch wenn keine DHCP-Clients hinein sollen (in diesem Fall lässt man zwischen den geschweiften Klammern einfach leer).

subnet 10.0.0.0 netmask 255.0.0.0 {
    range 10.0.0.10 10.0.0.200;
    }

FIXME Ausschlüsse?

  • Default-Gateway bzw. die Router
option routers IP1, IP2;

Alternativ ist auch die Angabe von Namen (router1.beispieldomain.de, router2.beispieldomain.de; durch Komma getrennt!) möglich.

  • Time-Server (NTP-Server)

Mit der Option time-servers kann man den Clients auch die IP-Adressen von NTP-Server mitgeben (nach Präferenz angeben!):

option time-servers ip-address [, ip-address...  ];
  • WINS-Server
option netbios-name-servers IP1, IP2;
option netbios-node-type 2;

Die Option „netbios-name-servers“ gibt die WINS-Server an, der „netbios-node-type“ legt das Verhalten der Clients fest:

Wert von „netbios-node-type“ Typ Beschreibung
1 b-node benutzt nur broadcasts statt den WINS-Server
2 p-node benutzt nur den WINS-Server
4 m-node versucht zuerst einen broadcast, dann den WINS-Server
8 h-node versucht zuerst den WINS-Server, dann einen broadcast

Die beiden Optionen müssen nicht global sein, sondern können auch nur in einem Subnetz gelten. Weitere Informationen zu WINS und Netbios bei Microsoft.

Dazu hat ValentinHaenel: Web Proxy Automatic Discovery einen guten Artikel geschrieben.

Um einzelnen Host eine (oder mehrere) feste IPs (anhand der MAC-Adresse) zuzuweisen:

host webserver {
  hardware ethernet 0:0:c0:5d:bd:95;
  fixed-address 10.0.0.3
}

Wenn mehrere IPs (mit Komma getrennt) angegeben werden, der Client bekommt dann die zum jeweiligen Subnetz passende (in dem er gebootet hat) bzw. wenn keine passt wird die Zuordnung ignoriert. Anstatt einer IP kann auch ein (auf ein oder mehrere IPs auflösbarer!) Name angegeben werden.

Es können auch feste Namen vergeben werden, dann sollte diese

server-name "webserver.beispieldomain.de";

FIXME (Unterschied zwischen: server-name „toccata.fugue.com“; und fixed-address fantasia.fugue.com; ???)

Gruppen aus (gleichförmigen) Rechnern können in spezielle Klassen eingeteilt

class "foo" {
  match if substring (option vendor-class-identifier, 0, 4) = "SUNW";
}

und diese dann in einen speziellen Bereich gesteckt werden (siehe /usr/share/doc/dhcp3-server/examples/dhcpd.conf).

Außerdem ist es auch möglich die maximale Anzahl der Clients, die ein gültigen Lease erhalten haben, anzugeben:

lease limit 4;

Die Schlüsselwörter

  • allow, deny und ignore FIXME
  • known-clients bzw. unknown-clients bezieht sich auf registrierte DHCP-Clients (d.h. Clients für die eine Host-Deklaration vorhanden ist).

Ohne gültige/korrekte IP-Adresse ist für Rechner keine Kommunikation über TCP/IP möglich. Deshalb ist ein funktionierender DHCP-Server enorm wichtig. Kleinere Ausfälle (maximal bis hin zur maximalen Lease-Dauer) können ohne Folgen bleiben wenn keine neuen Rechner hinzukommen, bleiben aber dennoch ein Risiko. Deshalb liegt es nahe hier eine Ausfallsicherheit durch die Einrichtung eines zweiten DHCP-Servers herzustellen.

Eine einfache Möglichkeit ist die Einrichtung eines zweiten DHCP-Servers mit einem eigenen Pool von IP-Adressen. Dabei schließt man jeweils die Adressen des anderen Servers aus und beim Ausfall hat der zweite Server (hoffentlich) noch genug Adressen für Rechner zur Verfügung. Allerdings sind immer dann Client-Rechner gezwungen ihre IP-Adresse zu ändern wenn der ursprüngliche DHCP-Server nicht mehr erreicht werden kann und die maximale Lease-Dauer abgelaufen ist. Dabei müssen alle bestehenden Verbindungen auf diesem Rechner beendet werden.

Sauberer ist eine Verteilung der Anfragen auf zwei ISC DHCP-Server, wobei der jeweils übrig gebliebende Server weiter die vorhandenen IP-Adressen (Leases) beider Server verlängert ohne das Client-Rechner ihre Adresse ändern müssen.

Auf der Windows-Plattform ist ein grob vergleichbares Setup übrigens nur mit Microsoft Server 2008 Enterprise möglich (siehe Design Option 2: DHCP Clusters wobei hier die Datenbank nicht redundant gehalten wird), ansonsten sind auch nur zwei eigenständige DHCP-Server möglich (siehe Design Option 1: Split Scopes). Alternativ sind (teuere) Drittanbieter-lösungen möglich wie Infoblox möglich.

Troubleshooting

Immer hilfreich sind die Handbücher:

  • man dhcpd3
  • man dhcpd.conf
  • man dhcp-options

Zum Analysieren von Fehler hier ein kompletter DHCP-Adressbezug zum nachlesen.

10.0.0.2 IP-Adresse des DHCP-Servers
dhcp-hostname „dhcp-hostname“ ist der Hostname des DHCP-Servers
eth0 Ethernet-Schnittstelle des DHCP-Servers
00:0b:db:ea:ba:d0 die MAC-Adresse des Clients
dhcp-client-name „dhcp-client-name“ ist der Hostname des DHCP-Clients

Ein korrekter Addressbezug sollte sich in vier Zeilen wiederfinden:

Aug 22 17:20:36 dhcp-hostname dhcpd: DHCPDISCOVER from 00:0b:db:ea:ba:d0 via eth0
Aug 22 17:20:37 dhcp-hostname dhcpd: DHCPOFFER on 10.254.239.20 to 00:0b:db:ea:ba:d0 (dhcp-client-name) via eth0
Aug 22 17:20:37 dhcp-hostname dhcpd: DHCPREQUEST for 10.254.239.20 (10.0.0.2) from 00:0b:db:ea:ba:d0 (dhcp-client-name) via eth0
Aug 22 17:20:37 dhcp-hostname dhcpd: DHCPACK on 10.254.239.20 to 00:0b:db:ea:ba:d0 (dhcp-client-name) via eth0

Die aktuellen Leases sollten auf dem DHCP-Server in der Datei /var/lib/dhcp/dhcpd.leases (unter Debian Lenny noch in /var/lib/dhcp3/dhcpd.leases) zu finden sein, in unserem Beispiel also:

lease 10.254.239.20 {
  starts 3 2007/08/22 15:20:37;
  ends 3 2007/08/22 17:00:37;
  binding state active;
  next binding state free;
  hardware ethernet 00:0b:db:ea:ba:d0;
  client-hostname "dhcp-client-name";
}

:!: Der Ort des Lease-files kann auch in der Konfigurationsdatei geändert sein:

lease-file-name "/var/db/dhcpd.leases";''

Auf dem Client in der Datei /var/lib/dhcp3/dhclient.eth0.leases:

lease {
  interface "eth0";
  fixed-address 10.254.239.20;
  server-name "";
  option subnet-mask 255.0.0.0;
  option routers 10.0.0.2;
  option dhcp-lease-time 6000;
  option dhcp-message-type 5;
  option domain-name-servers 10.0.0.2;
  option dhcp-server-identifier 10.0.0.2;
  option domain-name "stefan.intern";
  renew 3 2007/8/22 16:10:54;
  rebind 3 2007/8/22 16:48:27;
  expire 3 2007/8/22 17:00:57;
}

Das Paket dhcping biete die Abfrage von DHCP-Servern an:

sudo dhcping -s IP

sollte die Ausgabe

Got answer from: IP

erzeugen.

In den Log-Datein erkennt man, welcher Status gerade vorliegt bzw. wann wieder welche Aktion erfolgt (option ). Dazu muss man nur die Zahlen den einzelnen Zuständen zuordnen:

dhcp-message-type Bedeutung
1 DHCPDISCOVER
2 DHCPOFFER
3 DHCPREQUEST
4 DHCPDECLINE
5 DHCPACK
6 DHCPNAK
7 DHCPRELEASE
8 DHCPINFORM

siehe RFC2132

Eventuell ist DHCP durch eine Firewall blockiert:

$IPTABLES  -I INPUT -i $LAN_IFACE -p udp --dport 67:68 --sport 67:68 -j ACCEPT

DHCP Server finden

Das DHCP-Protokoll sieht leider keinerlei Sicherheitsmechanismen vor an denen ein Client erkennen kann ob er korrekt Daten vom korrekten Server erhalten hat(er vertraut der ersten Antwort). Deshalb ist das Finden vom nicht-authorisierten DHCP-Servern (ob absichtlich or versehentlich aktiviert) eine Standard-Aufgabe.

Folgende Programme listen die vorhandenen DHCP-Server auf1):

Download

DHCP Relay

Ein DHCP Relay umgeht den Zwang in jedem Subnetz ein DHCP-Server zu haben. Er konvertiert die (DHCP-Broadcast-) Anfragen indem er sie per unicast an den eigentlichen DHCP-Server weiterleitet. Dabei sollte man dann auch die IP des DHCP-Servers mit der Option „local-address“ an eine IP binden (an die man dann mit dem Relay-Agenten weiterleitet).

Bei der Installtion von Paket dhcp3-relay wird gleich die IP des DHCP-Server und die Schnittstelle (an der auf Anfragen „gelauscht“ wird) abgefragt.


1)
die man auch mittels eines Paket-Sniffers wie wireshark finden könnte, ist aber Anspruchsvoller