DHCP-DDNS telepítése (Wheezy)

Innen: AdminWiki
A lap korábbi változatát látod, amilyen KZoli (vitalap | szerkesztései) 2018. május 29., 22:01-kor történt szerkesztése után volt. (Új oldal, tartalma: „Ebben a leírásban belső hálózati DHCP kiszolgálót telepítünk, amely a kiosztott IP cím - hostnév párosokkal azonnal frissíti is az azonos kiszolgálóra te…”)
(eltér) ← Régebbi változat | Aktuális változat (eltér) | Újabb változat→ (eltér)

Ebben a leírásban belső hálózati DHCP kiszolgálót telepítünk, amely a kiosztott IP cím - hostnév párosokkal azonnal frissíti is az azonos kiszolgálóra telepített DNS szolgáltatás megfelelő zónáját (dinamikus DNS). Az így kialakított DHCP-DDNS adatbázisaként opcionálisan, a klasszikus konfigurációs állományok helyett, LDAP backend-et is használunk.

Még ne vedd komolyan!

Tartalomjegyzék

Célkitűzés

Ebben a leírásban egy (talán) tipikus kisirodai topológiát alakítunk ki: egyetlen fizikai helyi hálózaton két, IP címtartományban elkülönülő logikai hálózat (office VLAN és guest VLAN) működik. A két VLAN-t azonos infrastruktúra (közös switchek, WiFi AP-ok, stb.) szolgálja ki. A DHCP klienseket előzetes manuális regisztráció alapján soroljuk be ezekbe a VLAN-okba: fő szabályként az ismert, regisztrált kliens az office VLAN, mindenki más a guest VLAN beállításait kapja.

Soho halozat vazlat.png


Szolgáltatás office VLAN guest VLAN
IP kapcsolat
  • NAT/MASQ - office gateway
  • állapottartó csomagszűrő tűzfal
  • VPN, SSH/RDP, port forward lehetőség
  • NAT/MASQ - guest gateway
  • állapottartó csomagszűrő tűzfal
  • QoS korlátozások
DHCP, DNS
  • fix vagy dinamikus belső IP cím interface-enként
  • fix vagy automatikusan regisztrálható DDNS hostnév az office. aldomainben
  • publikus DNS
  • fix vagy dinamikus belső IP cím interface-enként
  • fix vagy automatikusan regisztrálható DDNS hostnév a guest. aldomainben
  • publikus DNS
Egyéb szolgáltatás
  • TFTP

Előfeltételek

  • Házirend szerint telepített és beállított Debian (Wheezy) szervergép;
  • Házirend szerint beállított és tesztelt router szolgáltatás a belső hálózat(ok) számára (legyen engedélyezett a DHCP is);
  • Házirend szerint telepített Bind9 névszerver, amely a belső hálózato(ka)t korlátlanul kiszolgálja (allow-recursion beállítva);
  • Opcionálisan, házirend szerint telepített LDAP kiszolgáló, vagy hozzáférés használható LDAP szerverhez.

Telepítés

Debian csomagból, a DHCP-szerver LDAP-képes változatát telepítjük:

apt-get install isc-dhcp-server-ldap # függőség: isc-dhcp-server

A maintainer által biztosított konfigurációval a telepített DHCP szerver (szándékosan) nem indul el (a /etc/default/isc-dhcp-server állományban az INTERFACES opció üres), így nem ütközhet más, a hálózatunkon lévő DHCP szolgáltatással.

Beállítások

Mielőtt tovább lépünk, gondosan ellenőrizzük, hogy a telepítés alatt álló szervergép belső hálózati interface-e hálózatán nincsen más DHCP szolgáltatás (szükség esetén tegyük át ezt az interface-t egy teszt hálózatra)!

Alapbeállítás teszteléshez

Teszteléshez egy nagyon egyszerű, a broadband routereknél szokásos DHCP szolgáltatást állítunk üzembe: bárkinek adunk dinamikus, belső hálózati IP-t egy 90 címből álló pool-ból, és mind gateway-ként mint DNS szerverként a telepítés alatt álló hálózatvezérlőt adjuk meg. Ehhez mentsük el a maintainer által biztosított /etc/dhcp/dhcpd.conf állományt, és készítsünk egy újat:

mv /etc/dhcp/dhcpd.conf /etc/dhcp/dhcpd.conf.bak
mcedit /etc/dhcp/dhcpd.conf

az alábbi tartalommal:

-rw-r--r-- root root /etc/dhcp/dhcpd.conf

# Configuration file for ISC dhcpd on Debian Wheezy.

# We're the official DHCP server for defined subnets.
authoritative;

# BOOTP isn't supported now.
deny bootp;

# One lease per client, renew in 10 minutes.
one-lease-per-client true;
min-lease-time 300;
default-lease-time 600;
max-lease-time 600;

# Log settings.
log-facility local7;

###################################
# Dinamically updated DNS settings.
#

ddns-update-style none;

###########################
# Subnet definitions below.
#

subnet IP.IP.IP.IP netmask MASK.MASK.MASK.MASK {
    range IP.IP.IP.10 IP.IP.IP.99;
    option routers IP.IP.IP.1;
    option domain-name-servers IP.IP.IP.1
}

Ügyeljünk arra, hogy a felvett subnet adatai egyezzenek meg a teszteléshez használt fizikai(!) interface-nek (pl. eth0) a /etc/network/interface-ben megadott adataival, illetve hogy a range essék ebbe a subnetbe. Az IP bérleti idejét (default-lease-time) a tesztelés miatt állítottuk szokatlanul rövidre.

Ezután adjuk meg a belső hálózat felőli fizikai interface-t (az esetleges aliasokat nem kell felsorolni) a /etc/default/isc-dhcp-server állományban:

-rw-r--r-- root root /etc/default/isc-dhcp-server

[...]
# On what interfaces should the DHCP server (dhcpd) serve DHCP requests?
#       Separate multiple interfaces with spaces, e.g. "eth0 eth1".
INTERFACES="eth0"
[...]

majd indítsuk el a DHCP szervert:

/etc/init.d/isc-dhcp-server start; tail -f /var/log/syslog

és egy, a belső hálózatra csatlakoztatott munkaállomással vagy más DHCP kliens eszközzel ellenőrizzük a működést:

  • a syslog-ban meg kell jelennie a DHCP kéréseknek és válaszoknak;
  • a /var/lib/dhcp/dhcpd.leases állományban meg kell jelennie a kiadott IP bérlet(ek)nek;
  • a csatlakoztatott eszköznek IP címet kell kapnia és a hálózatvezérlőn keresztül ki kell látnia a külső hálózatra.
Pipa.jpg
Sikeres teszt esetén rendelkezünk egy kb. broadband router funkcionalitású eszközzel :-).

A dhcpd bejegyzése a Tiger által ismert démonok közé

A root nevében futó dhcp szerver állandóan fut és jogosan figyel néhány UDP porton, így a biztonsági figyelmeztetések elkerülése érdekében be kell azt jegyezni a tigerrc állományba:

-rw-r--r-- root root /etc/tiger/tigerrc

[...]
Tiger_Listening_ValidProcs='[...]|dhcp|[...]'
[...]
Tiger_Running_Procs='[...] /usr/sbin/dhcpd [...]'
[...]

A dhcpd log átirányítása

Érdemes elkülöníteni a terjedelmes DHCP logokat a többiektől; erre lehetőséget ad a fentebb beállított local-7 syslog facility, amelyet más nem használ. Az elkülönítéshez készítsünk egy log könyvtárat a dhcpd számára:

mkdir -m 750 /var/log/dhcp; chown root:adm /var/log/dhcp

Ezután szerkesszük meg a /etc/syslog-ng/syslog-ng.conf file-t, és szúrjuk be a Destinations section végére:

-rw-r--r-- root root /etc/syslog-ng/syslog-ng.conf

[...]
# DHCP separate logging
destination d_dhcp
    { file("/var/log/dhcp/dhcp.log" owner(root) group(adm)); };

Ugyanitt a Filters section végére:

-rw-r--r-- root root /etc/syslog-ng/syslog-ng.conf

[...]
# DHCP separate logging
filter f_dhcp
    { facility(local7); };

Végül a Log paths section elejére (így a flags(final); direktíva miatt a syslogba nem kerül kimenet):

-rw-r--r-- root root /etc/syslog-ng/syslog-ng.conf

[...]
# DHCP separate logging
log { source(s_src); filter(f_dhcp); destination(d_dhcp); flags(final); };

Az új logok rotálásához készítsünk egy /etc/logrotate.d/dhcp állományt:

-rw-r--r-- root root /etc/logrotate.d/dhcp

/var/log/dhcp/*.log {
    daily
    rotate 7
    compress
    missingok
    create 0640 root adm
}

A változtatások érvényesítésére indítsuk újra a syslog-ng-t és a DHCP szervert is:

/etc/init.d/syslog-ng restart
/etc/init.d/isc-dhcp-server restart; tail -f /var/log/dhcp/dhcp.log

Látható, hogy a DHCP események már az új logba (és nem a /var/log/syslog-ba) kerülnek.

Logcheck módosítások

A DHCP szolgáltatás során normálisan is keletkező (elsősorban kernel eredetű) logsorokat érdemes kivenni a logcheck kimenetéből.

  • Martian source/destination jelentésének kiszűrése

Nyilvános hálózatot kiszolgáló DHCP szerver esetén mindennaposak az idegen hálózati címet tartalmazó ("marslakó") csomagok - pl. egy újonnan érkező DHCP kliens általában először a korábbi hálózatban érvényes címét próbálja visszaszerezni(?). Emiatt a kern.log martian bejegyzéseit opcionálisan érdemes teljesen kiszűrni:

touch /etc/logcheck/ignore.d.server/kernel-martians
chown root:logcheck /etc/logcheck/ignore.d.server/kernel-martians
chmod 640 /etc/logcheck/ignore.d.server/kernel-martians
mcedit /etc/logcheck/ignore.d.server/kernel-martians
-rw-r----- root logcheck /etc/logcheck/ignore.d.server/kernel-martians

^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ kernel:( \[ *[[:digit:]]+\.[[:digit:]]+\])? martian source
^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ kernel:( \[ *[[:digit:]]+\.[[:digit:]]+\])? martian destination

TODO!

A dhcpd monitorozása a Muninnal

Amennyiben telepítve van a munin-addons csomag (vagy más módon beszereztük és a /usr/local/share/munin/plugins könyvtárban elhelyeztük a dhcp-pool plugint), a kiosztott/kiosztható DHCP címek arányának (a pool-ok kihasználtságának) monitorozása pl. az alábbi parancsokkal vehető használatba:

cp -p /usr/local/share/munin/plugin-conf.d/dhcp-pool /etc/munin/plugin-conf.d/  # beállító állomány átmásolása
ln -s /usr/local/share/munin/plugins/dhcp-pool /etc/munin/plugins/dhcp-pool     # plugin symlinkelése
/etc/init.d/munin-node restart

Gyorsteszt:

telnet localhost 4949
[...]
fetch dhcp-pool
> IP_IP_IP_10.value 0.0
> .
quit

Szofisztikáltabb monitorozás: TODO!

A dinamikus DNS beállítása

Ebben a leírásban a dinamikus DNS technikailag (nagyjából :-)) úgy valósul meg, hogy minden lease kiadásakor a dhcpd automatikusan, a Bind adminisztrációs interface-én (TCP localhost:953) keresztül megkísérli egy A rekord bejegyzését a kiadott IP címhez tartozó forward, és egy PTR rekord bejegyzését a vonatkozó reverse zónába; a lease felszabadításakor vagy lejáratakor ezeket a bejegyzéseket megkísérli eltávolítani. A szolgáltatás beállításához (a kommunikáció engedélyezésén túl) legalább azt meg kell határozni, hogy egy lease kiadásakor melyik DNS zóná(k)ba kerüljön bejegyzés, és az milyen hostnevet tartalmazzon (pl. elfogadjuk-e a kliens által hirdetett gépnevet; ha igen, mit teszünk névütközés esetén, vagy ha a kliens nem küld gépnevet).

Ebben a leírásban egyelőre az alábbi konvenciókat fogjuk alkalmazni:

  • A DNS-t csak a DHCP szerver aktualizálhatja, a kliensek közvetlenül nem.
  • Egy DHCP subnet feleljen meg egy DDNS zone-nak.
  • A reverse zone-(oka)t IPv4 osztályok szerint kezeljük (pl. ha a pool-unk a 192.168.0.0/23 érintkező C osztályokból áll, akkor a teljes 192.168.0.0/16 B osztály reverse-ét lefoglaljuk), azaz ebben a leírásban nem alkalmazunk pl. az RFC2317 szerinti classless IN-ADDR.ARPA delegation-t (TODO!).
  • A DHCP lease time felének megfelelő DNS TTL-t alkalmazunk (szofisztikáltabban: TODO!);
  • Ha a gépnév nem deríthető ki, generálunk egy egyedi DNS hostnevet;
  • Névütközés esetén az ütköző (később kért, azonos) nevet nem jegyezzük be (TODO!).

A kommunikációs kulcs elkészítése

A DHCP - DNS kommunikációra a Bind adminisztrációs szolgáltatását használjuk, amely azonban bármely, a localhoston futó folyamat (akár egy malignus webalkalmazás) számára is elérhető. Ezért a kommunikációt egy olyan kulccsal titkosítjuk, amelyet csak a Bind-ot futtató bind és a dhcpd-t futtató root Linux felhasználók láthatnak.

Az alábbi (root-ként kiadott) parancsokkal létrehozzuk a kulcsot:

cd /root/tmp # Munkakönyvtár :-)
dnssec-keygen -a HMAC-MD5 -b 128 -r /dev/urandom -n USER DDNS_UPDATE
cat *ddns_update*.private | grep -i 'key:'

# Kiírja az elkészített privát kulcsot (szövegfájlba másolható Base64 kódolással)
# Key: SSBsb3ZlIHlvdSwgS2F0YSE=

A dnssec-keygen egy aszimmetrikus titkosításhoz is használható (privát és publikus) kulcspárt hoz létre, de most ennek csak a privát kulcsát fogjuk felhasználni szimmetrikus titkosításra - ezt a kulcsot írja ki az utolsó parancssor. Készítsünk egy, a Bind és a dhcpd számára egyaránt érthető kulcs definíciós állományt, amelyet mindkettő beállításaiba include-olhatunk:

mcedit ddns.key

key DDNS_UPDATE {
        algorithm HMAC-MD5.SIG-ALG.REG.INT;
        secret "SSB[...]SE=";
};

ahol az idézőjelek közé az imént kiírt (Base64 kódolású) kulcsot másoljuk. Ebből az állományból két példányra van szükség, ezeket pl. az alábbi paranccsal másolhatjuk a helyükre (egyben megfelelően beállítva a jogosultságokat is):

install -o root -g bind -m 0640 ddns.key /etc/bind/ddns.key
install -o root -g root -m 0640 ddns.key /etc/dhcp/ddns.key

A fentebb gyártott kulcsokat a munkakönyvtárból törölhetjük:

rm *ddns_update* ddns.key

A ddns-purge script elkészítése

Noha a megfelelően beállított dhcpd-nek egy lease felszabadítása vagy lejárta esetén gondoskodnia kellene mind a forward mind a reverse DNS bejegyzés törléséről, előfordulhat, hogy ez elmarad (TODO!). Ennek javítására készítünk egy scriptet, amely a kommunikációs kulcsot használva, az nsupdate utility hívásával a törlést elvégzi:

touch /etc/dhcp/ddns-purge
chown root:root /etc/dhcp/ddns-purge
chmod 750 /etc/dhcp/ddns-purge

mcedit /etc/dhcp/ddns-purge
-rwxr-x--- root root /etc/dhcp/ddns-purge


#!/bin/bash
#
# Simple script to call nsupdate utility for delete DDNS records of a host.
# License: public domain - Author: Z. Kovács <kovacs.zoltan@kzoli.hu>

GREP="/bin/grep"                                # grep command call
KEYFILE="/etc/dhcp/ddns.key"                    # TSIG key definition file
NSUPDATE="/usr/bin/nsupdate"                    # nsupdate command call
SED="/bin/sed"                                  # sed command call

# Requires nsupdate binary.
if [ ! -x "$NSUPDATE" ]; then exit 1; fi
# Gets and checks the fully qualified hostname to purge from DDNS.
fqhn="$1"; shift
if [ -z "$fqhn" ]; then exit 1; fi
if [ ! -z "`echo $fqhn | $SED "s/\(\([0-9a-zA-Z_-]\)\+\.\?\)\+//"`" ]; then exit 1; fi
# Gets TSIG key.
if [ -r "$KEYFILE" ]; then
    keyname=`cat $KEYFILE  | $GREP -e '^key '`
    keyname=`echo $keyname | $SED "s/^key \([a-zA-Z0-9_-]*\).*$/\1/"`
    secret=`cat $KEYFILE   | $GREP -e 'secret '`
    secret=`echo $secret   | $SED "s/\s*secret \"\?\([a-zA-Z0-9\+\/=]*\).*$/\1/"`
fi
if [ -z "$keyname" -o -z "$secret" ]; then exit 1; fi
# Let's go with nsupdate!
$NSUPDATE <<EOF
server localhost
key $keyname $secret
update delete $fqhn
send
EOF
# That's all.

A root-ként futtatandó script egyetlen paramétereként a törlendő rekordset-et várja, pl.:

/etc/dhcp/ddns-purge myhost.mydomain.com       # forward törlése
/etc/dhcp/ddns-purge IP.IP.IP.IP.in-addr.arpa. # reverse törlése

A scriptet hívhatjuk konzol parancsként manuálisan, vagy más programból (pl. a dhcpd eseményvezérlőjéből) is. Ügyeljünk arra, hogy a script a paraméterét csak minimálisan ellenőrzi (akár egy egész zóna is letörölhető vele), így fokozott figyelemmel használjuk!

A Bind9 beállítása a frissítések fogadásához

A dinamikus frissítés használatához a névszerver beállításaiban:

  • elő kell írnunk a kommunikációs kulcs használatát;
  • be kell állítanunk a nyilvános szolgáltatást (ha még nem lenne beállítva);
  • engednünk kell a rekurzív lekérést (azaz nemcsak az authoritív adatok kiszolgálását) a belső hálózat(ok) felé (ha még nem lenne beállítva);
  • létre kell hoznunk logikai(!) alhálózatonként egy-egy forward dinamikus zónát, amelyeket a dhcpd frissíthet. Jelenleg egy forward zónánk van (a példában legyen office.mydomain.com);
  • létre kell hoznunk fizikai(!) alhálózatonként egy-egy reverse dinamikus zónát, amelyet a dhcpd frissíthet. Jelenleg egy, a teljes inland subnet-et lefedő reverse zónánk van (ami - C osztályt feltételezve - legyen IP.IP.IP.in-addr.arpa; ügyeljünk a fordított byte sorrendre, pl. a 192.168.1.0/24 C osztályhoz 1.168.192.in-addr.arpa írandó!);

A kommunikációs kulcs beillesztése

A kulcs beillesztéséhez az /etc/bind/named.conf.local állomány elejére írjuk a következőket:

-rw-r--r-- bind bind /etc/bind/named.conf.local

[...]
// TSIG key for DDNS update authentication.
include "/etc/bind/ddns.key";
[...]

Nyilvános szolgáltatás engedélyezése

Ha még nem lenne engedélyezve, a nyilvános szolgáltatást a tűzfalon kell engedélyeznünk - a házirend szerinti Shorewall használata esetén:

-rw-r----- root root /etc/shorewall/rules

[...]
DNS/ACCEPT        ZONE    fw
[...]

A változtatás érvényesítéséhez a Shorewall-t újra kell indítani:

/etc/init.d/shorewall restart

Rekurzív lekérések engedélyezése

Ha még nem lenne engedélyezve, a belső hálózat(ok) számára a rekurzív lekéréseket a /etc/bind/named.conf.options állományban engedélyezhetjük:

-rw-r--r-- root bind /etc/bind/named.conf.options

options {
[...]
        allow-recursion { IP.IP.IP.IP/MASK; localhost; };
};

A dinamikus zónák beállítása

A dinamikus zónák adatait a (chroot-olt) Bind9 munkakönyvtárában létrehozott zónafájlokban fogjuk tárolni úgy, hogy ezeket a bind felhasználó képes legyen módosítani. Az egyszerűség kedvéért készítsünk egy alkalmas symlinket:

ln -s ../../var/cache/bind  /srv/chroot/bind/etc/bind/dynamic
chown -h bind:bind /etc/bind/dynamic # csak szépség :-)

így a dinamikus zónafájlok könyvtárára a beszédesebb /etc/bind/dynamic névvel hivatkozhatunk. Készítsük el a zónafájlokat:

# Töltsük ki!
touch /etc/bind/dynamic/db.office.mydomain.com;   chown bind:bind /etc/bind/dynamic/db.office.mydomain.com
touch /etc/bind/dynamic/db.IP.IP.IP.in-addr.arpa; chown bind:bind /etc/bind/dynamic/db.IP.IP.IP.in-addr.arpa

Megjegyzés: ezeket a fájlokat futás közben a Bind9 nem közvetlenül, hanem a változtatásokat tartalmazó naplófájl használatával fogja módosítani, és csak a named újraindításakor aktualizálja magát a zónafájlt. Ezért a dinamikus zónafájlokat inicializálás után már ne változtassuk; ha muszáj bennük manuálisan módosítani, használjuk az nsupdate segédprogramot!

Jegyezzük be a két (jelenleg még üres) zónafájlt a /etc/bind/named.conf.local állományba, megengedve a kommunikációs kulcs használatával történő módosítást:

-rw-r--r-- bind bind /etc/bind/named.conf.local

[...]
// DDNS updated by DHCP

zone "office.mydomain.com" {
    type master;
    notify no;
    file "/etc/bind/dynamic/db.office.mydomain.com";
    allow-update { key DDNS_UPDATE; };
};

zone "IP.IP.IP.in-addr.arpa" {
    type master;
    notify no;
    file "/etc/bind/dynamic/db.IP.IP.IP.in-addr.arpa";
    allow-update { key DDNS_UPDATE; };
};

Inicializáljuk ezeket a zónákat, példaképpen statikusan bejegyezve a példánkban IP.IP.IP.1 című hálózatvezérlőt is:

-rw-r--r-- bind bind /etc/bind/dynamic/db.office.mydomain.com

@       IN      SOA     office.mydomain.com.  sysadmin.mydomain.com. (
                        1           ; Serial
                        300         ; Refresh
                        60          ; Retry
                        600         ; Expire
                        300         ; Minimum TTL
                        )
        IN      NS      router.office.mydomain.com.

router  IN      A       IP.IP.IP.1

A reverse zóna:

-rw-r--r-- bind bind /etc/bind/dynamic/db.IP.IP.IP.in-addr.arpa

@       IN      SOA     localhost.  sysadmin.mydomain.com. (
                        1           ; Serial
                        300         ; Refresh
                        60          ; Retry
                        600         ; Expire
                        300         ; Minimum TTL
                        )
        IN      NS      router.office.mydomain.com.

1       IN      PTR     router.office.mydomain.com.

A zónák inicializálásánál tetszőleges számú statikus bejegyzést felvehetünk. A zónafájl tördelése és megjegyzései a frissítések során elvesznek, ezért a tetszetős formázással nem kell törődnünk :-). Megjegyzendő, hogy a manuális zónafájl karbantartásnál szokásos YYYYMMDDNN formátumú sorozatszámot (Serial) itt nem érdemes használni, mert ezt a számot minden dinamikus zónafrissítés (a dátumkonvenciót figyelmen kívül hagyva) egyszerűen inkrementálni fogja.

A dinamikus frissítések elkülönített naplózása

A DDNS frissítések számára érdemes külön naplóállományt készíteni, amely pl. a Muninnnal monitorozható, illetve így a frissítések logsorai a logcheck által figyelt syslog-ból kivehetőek. Ehhez egészítsük ki a /etc/bind/named.conf.logging állományt egy új csatornával:

-rw-r--r-- bind bind /etc/bind/named.conf.logging

logging {
    [...]
    channel b_update {
        syslog daemon;
        print-category yes;
        print-time yes;
        severity info;
    };
    [...]
    category update { b_update; };
    category update-security { b_update; };
    [...]

illetve kezeljük ezt a syslog-ng konfigurációjában is a named-re vonatkozó destination, filter és log bejegyzések kiegészítésével:

-rw-r--r-- root root /etc/syslog-ng/syslog-ng.conf

[...]
# Bind 9 separate logging
[...]
destination d_bind9_updates
    { file("/var/log/bind9/update.log" owner(root) group(adm)); };
[...]
# Bind 9 separate logging
[...]
filter f_bind9_updates
    { facility(daemon) and match("named" value("PROGRAM")) and match("update" value("MESSAGE")); };
[...]
# Bind 9 separate logging
[...]
log { source(s_src); filter(f_bind9_updates); destination(d_bind9_updates); flags(final); };

A nem használt privát zónák reverse-ének beállítása

Célszerű, ha az RFC 1918-ban meghatározott belhálózati IP tartományokra vonatkozó reverse DNS kéréseket nem engedjük ki a nagyvilágba, hiszen onnan ezekre értelmes válasz nem kapható. Ennek legegyszerűbb módja a maintainer által biztosított /etc/bind/zones.rfc1918 állomány beillesztése, amely fentiek bármelyikére negatív választ ad. Ehhez vegyük ki a kommentet a /etc/bind/named.conf.local vonatkozó sora elől:

-rw-r--r-- bind bind /etc/bind/named.conf.local

[...]
// Consider adding the 1918 zones here, if they are not used in your
// organization
include "/etc/bind/zones.rfc1918";
[...]

Saját, a fentiekben dinamikusan frissítettnek beállított reverse zónáinkra azonban nem szeretnénk automatikus negatív választ adni, ezért ezeket kommentezzük ki a beillesztett állományban - pl. ha belhálózatunk a 192.168.IP.IP/24 C osztályt használja, kommentezzünk az alábbiak szerint:

-rw-r--r-- bind bind /etc/bind/zones.rfc1918

[...]
zone "31.172.in-addr.arpa"  { type master; file "/etc/bind/db.empty"; };

//zone "168.192.in-addr.arpa" { type master; file "/etc/bind/db.empty"; };

Bind9 gyorsteszt

Valamennyi fenti beállítást a named és a syslog-ng újraindításával érvényesíthetjük:

/etc/init.d/syslog-ng restart; /etc/init.d/bind9 stop; /etc/init.d/bind9 start; tail -f /var/log/bind9/bind9.log

Gyorstesztként TODO!

Pipa.jpg
Sikeres teszt esetén a dinamikus zónáink a kommunikációs kulcs használatával frissíthetőek. A továbbiakban a dhcpd-t állítjuk be úgy, hogy ezeket a frissítéseket el is végezze.

A dhcpd beállítása a DNS frissítések elvégzéséhez

Általános DDNS beállítások

A dinamikus DNS frissítés általános paramétereinél alapértelmezésként:

  • előírjuk a DNS frissítését DHCP-statikus (fixed-address) IP címeknél is;
  • tiltjuk a DHCP-kliensektől jövő esetleges DNS frissítési kísérleteket (meggondolni - TODO!);
  • beállítunk egy relatív rövid alapértelmezett DNS rekord TTL-t;
  • a DNS-be írandó hostnévnél elfogadjuk a kliens által küldöttet; ennek hiányában a DHCP konfigurációban beállítottat használjuk; ennek hiányában a kiadott IP címből képezünk egy dhcp-IP-IP-IP-IP alakú technikai hostnevet;
  • előírjuk a korábban elkészített ddns-purge script meghívását a vonatkozó forward és reverse DNS bejegyzésre minden lease felszabadításakor vagy lejáratakor (szükségességét meggondolni - TODO!);
  • beillesztjük a kommunikációs kulcsot.

Fentiekhez a /etc/dhcp/dhcpd.conf állomány már meglévő Dinamically updated DNS settings szakaszát cseréljük az alábbiakra:

-rw-r--r-- root root /etc/dhcp/dhcpd.conf

[...]
###################################
# Dinamically updated DNS settings.
#

ddns-update-style interim;
update-static-leases on;
ignore client-updates;
ddns-ttl 300;
# Host name conventions: from client, from declaration, created from IP.
ddns-hostname =
    pick-first-value (
        option fqdn.hostname,
        option host-name,
        host-decl-name,
        concat("dhcp-", binary-to-ascii (10, 8, "-", leased-address))
    );
# Bugfix: by default DDNS seems to be not updated on release or expiry.
on release or expiry {
    if (defined(ddns-fwd-name)) { execute ("/etc/dhcp/ddns-purge", ddns-fwd-name); }
    if (defined(ddns-rev-name)) { execute ("/etc/dhcp/ddns-purge", ddns-rev-name); }
}
# TSIG key for DDNS update authentication.
include "/etc/dhcp/ddns.key";
[...]

TODO: a ddns-hostname jelen beállításával nem tudjuk kezelni a névütközéseket, azaz amikor egy kliens fentiek szerint kiválasztott hostneve már szerepel a DNS-ben egy másik klienshez (MAC address-hez) rendelve. Ebben az esetben a dhcpd a később jelentkező klienst sem a forward, sem a reverse DNS-be nem jegyzi be.

Szerviz beállítások

Opcionálisan definiálhatunk egy DHCP osztályt (named-client), amelynek egyes alosztályait az azonos host-name DHCP opciót jelentő kliensek alkotják (a gyakorlatban egy-egy alosztály egy-egy gép különböző interface-eiből áll, pl. egy-egy notebook Ethernet és WiFi interface-éből). Ez a besorolás jelenleg nem használatos, a későbbiekben itt lehetne pl. korlátozni az egy gépre kiadott IP-k számát (TODO!). Ehhez a /etc/dhcp/dhcpd.conf állományba írjuk be az alábbiakat:

-rw-r--r-- root root /etc/dhcp/dhcpd.conf

[...]
#######################################
# Administrative class (not yet in use)
# subclasses are interfaces of a particular client.
#
class "named-client" {
    spawn with option host-name;
}
[...]

A konkrét DHCP kliensekre vonatkozó bejegyzéseket érdemes logikai egységenként csoportosítva külön-külön állományban (a dhcpd.conf állományból kiemelve) tartani. Készítsünk elő egy üres (később megszerkesztendő), példánkban az office alhálózatra vonatkozó bejegyzések tárolására szolgáló, dhcpd.office nevű állományt:

touch /etc/dhcp/dhcpd.office

és írjuk elő ennek beillesztését:

-rw-r--r-- root root /etc/dhcp/dhcpd.conf

[...]
###############################
# Hosts and classes to include.
#

include "/etc/dhcp/dhcpd.office";
[...]

Fontos, hogy ez az include a konfigurációs állományban a subnet definíciók elé kerüljön! Később, a kibővített DHCP szolgáltatás beállításánál több ilyen definíciós állományt is fogunk használni.

Subnet beállítások

A példánkban szereplő egyetlen subnet beállításánál írjuk elő egyrészt a teljes inland IP-tartományunkra vonatkozó reverse DNS karbantartását (classless delegation - TODO!), másrészt a subnet-en belül a forward DNS karbantartását:

-rw-r--r-- root root /etc/dhcp/dhcpd.conf

[...]
###########################
# Subnet definitions below.
# 

# One reverse for whole inland (TODO!)
zone IP.IP.IP.in-addr.arpa. {
    primary 127.0.0.1;
    key "DDNS_UPDATE";
}

subnet IP.IP.IP.IP netmask MASK.MASK.MASK.MASK {
    range IP.IP.IP.10 IP.IP.IP.99;
    option routers IP.IP.IP.1;
    option domain-name-servers IP.IP.IP.1
    #
    ddns-domainname "office.mydomain.com";
    zone office.mydomain.com. {
        primary 127.0.0.1;
        key "DDNS_UPDATE";
    }
    #
}
[...]

dhcpd gyorsteszt

Valamennyi fenti beállítást a dhcpd újraindításával érvényesíthetjük:

/etc/init.d/isc-dhcp-server restart; tail -f /var/log/dhcp/dhcp.log
Pipa.jpg
A logban nem szabad hibaüzenetnek megjelennie.

DHCP-DDNS gyorsteszt

Listáztassuk ki a dinamikus DNS zónákat pl. az alábbi parancsokkal (a Bind9 alapértelmezéseiben a zónatranszfer a localhost számára engedélyezett). A forward zónában (az adminisztratív bejegyzések mellett) csak a zónafájl inicializálásakor a router számára bejegyzett statikus A rekordot, a reverse zónában csak az ennek megfelelő PTR rekordot kell látnunk:

dig office.mydomain.com axfr | grep -iv ';' | sort

router.office.mydomain.com. 300	IN	A	IP.IP.IP.1
[...]
dig IP.IP.IP.in-addr.arpa axfr | grep -iv ';' | sort

1.IP.IP.IP.in-addr.arpa.    300	IN	PTR	router.office.mydomain.com.
[...]

Ezután csatlakoztassunk a belső hálózatra egy munkaállomást (vagy más, DHCP kliens eszközt) és ellenőrizzük a működést:

  • a /var/log/dhcp/dhcp.log-ban meg kell jelennie a DHCP kéréseknek és válaszoknak;
  • a /var/lib/dhcp/dhcpd.leases állományban meg kell jelennie a kiadott IP bérlet(ek)nek;
  • a csatlakoztatott eszköznek IP címet kell kapnia és a hálózatvezérlőn keresztül ki kell látnia a külső hálózatra;
  • a zónatranszferek kimeneteiben a routerhez tartozó bejegyzések mellett látszania kell az eszközhöz tartozó DDNS rekordoknak is:
dig office.mydomain.com axfr | grep -iv ';' | sort

router.office.mydomain.com. 300	IN	A	IP.IP.IP.1
TESZT.office.mydomain.com.  300	IN	A	IP.IP.IP.10
TESZT.office.mydomain.com.  300	IN	TXT	"31[...]b"
[...]
dig IP.IP.IP.in-addr.arpa axfr | grep -iv ';' | sort

1.IP.IP.IP.in-addr.arpa.    300	IN	PTR	router.office.mydomain.com.
10.IP.IP.IP.in-addr.arpa.   300	IN	PTR	TESZT.office.mydomain.com.
[...]

Megjegyzés: a technikai TXT rekordokat figyelmen kívül hagyhatjuk, azokat a dhcpd a kliens azonosítására használja.

  • A csatlakoztatott eszközt kikapcsolva, a lejárati időt követően, vagy az eszközön a DHCP bérletet (Windows kliens esetén pl. az ipconfig /release paranccsal) megszüntetve azonnal, az eszközhöz tartozó adatoknak a zónákból el kell tűnniük;
  • A fenti DNS frissítésekről konzisztens naplósoroknak kell megjelenniük a /var/log/dhcp/dhcp.log és /var/log/bind9/update.log naplóállományokban.
Pipa.jpg
Sikeres teszt esetén rendelkezünk egy alapszintű DHCP-DDNS szolgáltatással, amelyet a Kibővített DHCP szolgáltatás részben alkalmassá teszünk több fizikai és logikai alhálózat kezelésére, illetve azonosított kliensek ezekbe történő besorolására is.

Kibővített DHCP szolgáltatás

Ebben a szakaszban a dhcpd további konfigurálásával fenti alapszolgáltatást kiterjesztjük úgy, hogy biztosítsa a célkitűzés szerinti, szofisztikáltabb funkciókat is. A dhcpd beállítására továbbra is a /etc/dhcp könyvtár konfigurációs állományait használjuk, azaz (még) nem térünk át az LDAP használatára.

Előzetes megfontolások

DHCP és VLAN

Pontatlan definícióval fizikai hálózatnak (LAN) tekintjük a hálózatvezérlő egy fizikai (gateway) interface-éhez tartozó hálózat (layer 2 szintű) forgalmát, míg logikai alhálózatnak (VLAN) az ugyanezen fizikai interface (és esetleges alias-ai) IP tartományaihoz tartozó (layer 3 szintű) forgalmakat. A DHCP szolgáltatás nagyon gyakran csak egyetlen fizikai (egyben logikai al-) hálózatot használ, azonban opcionálisan érdemes lehet több VLAN-t is kialakítani, pl. azonos infrastruktúrán osztozó különböző cégek vagy részlegek esetén, illetve az esetleges vendég hálózat szeparálására. Így az egyes VLAN-ok forgalma (valamelyest) elkülöníthető, számukra külön DNS (al)domainek definiálhatóak, forgalmuk különböző publikus IP címeken (akár különböző ISP-k felé) uplinkelhető, QoS alkalmazható, stb.

Ebben a leírásban a fizikai- és logikai alhálózatokat az alábbiak szerint feleltetjük meg DHCP objektumoknak:

Hálózat OSI szint Gateway interface DHCP objektum
fizikai hálózat (LAN1) layer 2 ethX shared network (lan1)
logikai alhálózat (VLAN1.1) layer 3 ethX subnet
logikai alhálózat (VLAN1.2) layer 3 ethX:0 subnet

azaz a LAN-okat shared network-ként, a VLAN-okat subnet-ként reprezentáljuk. Amennyiben az alhálózat egyetlen VLAN-ból áll, a shared network definiálása elhagyható.

DHCP címválasztás

A technikai részleteket mellőzve és nagyon pontatlanul fogalmazva :-), alább csak azt tekintjük át, hogyan határozza meg a DHCP szolgáltatás azt, hogy milyen IP címet ajánljon fel a hozzá forduló kliensnek. Megjegyzendő, hogy a DHCP szolgáltatás esetében a kliens egy távoli hálózati interface-nek felel meg (egy host = egy MAC address), vagyis ha egy kliensgépnek két hálózati interface-e is van (pl. egy LAN és egy WiFi), akkor az a gép két különböző host-ként (DHCP kliensként) jelenhet meg.

A cím felajánlásánál a kiszolgáló figyelembe veszi a beérkező kérés tartalmát és azt, hogy a kérés milyen hálózatból érkezett.

A beérkező kérés tartalma (általában a küldött MAC address) alapján a kliens azonosítható. Az azonosított kliens lehet:

  • hostként regisztrált, ha azonosítója a DHCP konfigurációban host azonosításaként szerepel;
  • osztályba sorolt, ha azonosítója alapján a DHCP konfiguráció legalább egy osztályt (címkét) rendel hozzá;
  • ismeretlen, ha azonosítója a DHCP konfigurációban nem szerepel.

Ezen kívül bármely kliens lehet visszatérő, ha korábban már kapott IP címet, és ez ismert.

A kérés forrása kijelöl egy hálózatot (shared-network vagy subnet), amely megfelel a DHCP kiszolgáló egy fizikai vagy logikai alhálózatának. Bármely kérésre a DHCP szerver csak az abban a hálózatban érvényes címet fog felajánlani.

A címválasztás lépései nagyjából a következőek:

  • Ha a kliens hostként regisztrált és van hozzá rendelt fix IP cím, amely a kérés hálózatában érvényes, a DHCP szerver ezt az IP címet fogja felajánlani (fixed-address, DHCP-statikus IP cím).
  • Ha a kliens visszatérő és korábban használt IP címe szabad, vagy ha a kliens egy konkrét IP címet kér; és ez az IP cím a kérés hálózatában érvényes és a konfigurációs állományokban megadott szabályok betartásával a kliensnek kiadható, akkor a DHCP szerver ezt az IP címet fogja felajánlani (kvázistatikus IP cím).
  • Egyébként a DHCP szerver a kérés hálózatában érvényes szabad IP címek közül fog felajánlani egyet, a konfigurációs állományokban megadott szabályok szerint.

A kiadható IP címek range-ekben (folytonos IP-tartomány - pl. 192.168.0.10-20) állnak rendelkezésre. A range-ek opcionálisan összefoghatók pool-okba, amelyekben akár különböző hálózatokhoz tartozó range-ek is lehetnek (pl. 192.168.0.10-20, 172.16.1.30-40). Mind az egyes range-ekhez, mind az egyes pool-okhoz felvehetők szabályok, amelyek engedik vagy tiltják azt, hogy egy-egy lekérés tartalma alapján az adott range-ből IP cím felajánlható legyen. Lényeges, hogy a DHCP-statikus IP címek nem számítanak ide, azokat range-ben szerepeltetni nem szabad!

Az IP cím kiadása (bérlet, lease) határozott időre szól. A bérletek nyilvántartására a szerver egy szöveges adatbázist (/var/lib/dhcp/dhcp.leases) vezet. A cím elfogadása után a kliens a bérletet bármikor felmondhatja, de a protokoll explicit nem kötelezi erre, azaz a kliensnek nem kell szólnia, ha a cím használatát befejezi (mert pl. a gépet kikapcsolják vagy azon a WiFi használatát letiltják, stb.). Így a bérleti idő alatt a szerver úgy tekinti, hogy a címet a kliens használja, ezért ezt a címet másnak nem adja ki. Ha a bérlet lejárt (azt a kliens nem újította meg), adatait a szerver továbbra is nyilvántartja és a címet csak akkor adja ki, ha kifogyott az egyéb kiadható címekből. Így, ha a pool elég nagy, a kliens későbbi jelentkezésekor ugyanezt az IP címet kaphatja vissza.

DHCP és DNS

A DNS DHCP általi módosításánál meg kel határozni, hogy a módosítás melyik zóna melyik rekordját érintse.

forward rekordok frissítése

A forward DNS frissítésénél a zóna meghatározása nem egyértelmű, többféle eljárás lehetséges:

  • A frissítendő zónát a kliens IP-címe, a rekordot a klienshez rendelt hostnév határozza meg.

Az egyszerű példában ezt az eljárást alkalmaztuk: a frissítendő zóna a DHCP subnet beállításában van meghatározva, és a kliens hostneve az általa kért (ennek hiányában a szerver által generált) hostnév. Az eljárás alkalmazásához nem szükséges a kliens regisztrálása, sőt, hostnevet sem kell küldenie. Az eljárás hátránya, hogy ha a kliens másik subnet-re (pool-ba, range-be) kerül, a DNS neve megváltozhat (pl. mymachine.office.mydomain.com-ról mymachine.store.mydomain.com-ra).

  • A frissítendő zónát és rekordot is a (MAC address-sel azonosított) kliens kiléte határozza meg, de a DNS csak akkor frissül, ha a kliens a hálózatvezérlőtől kapott IP címet.

Ebben az esetben a kliensnek állandó DNS neve van, legyen bárhol is a hálózatainkban. Ehhez a frissítendő zónát a DHCP klienst (és nem hálózatot) azonosító beállításában (group, host vagy class) célszerű meghatározni. Szükséges, hogy a kliens ismert legyen.

  • A frissítendő zónát és rekordot a (MAC address-sel azonosított) kliens kiléte határozza meg, bármilyen hálózatban van és bármilyen IP-vel rendelkezik.

Ez az eset hasonlít a NoIP jellegű szolgáltatások megközelítéséhez: pl. a mymachine.mydomain.com hostnév a kliens(gép) utolsó ismert IP címére oldódik fel, így a kliensnek állandó DNS neve van, legyen bárhol is a világon. Ennek érdekében a kliensgép az aktuális IP cím megszerzésekor megkísérli a mydomain.com dinamikus DNS zónában saját bejegyzésének frissítését. A frissítést azért kell a kliensnek kezdeményezni, mert ilyenkor a DHCP szerver és a DNS szerver különböző (egymásról általában nem is tudnak). Ezzel a megközelítéssel a jelen leírásban nem foglalkozunk.

A továbbiakban az ismert kliensek esetén a második, az ismeretlen kliensek esetén az első eljárást alkalmazzuk.

reverse rekordok frissítése

A reverse DNS frissítésénél a kliens által kapott IP cím a frissítendő zónát meghatározza. A reverse zónák (az IP.IP.IP.IP.in-addr.arpa konvenció szerint) IPv4 osztályonként könnyen, egyébként csak nehézkesen reprezentálhatóak. Amennyiben a DNS-ben nem használjuk a classless IN-ADDR.ARPA delegation-t (TODO!), lényegében két lehetőségünk van:

  • A lehető legkevesebb zónát vesszük fel shared-network illetve subnet szinten úgy, hogy a teljes befoglaló B vagy A osztályt kezeljük (pl. ha a pool-unk a 192.168.0.0/23 érintkező C osztályokból áll, akkor a teljes 192.168.0.0/16 B osztály reverse-ét lefoglaljuk);
  • A lehető legtöbb zónát vesszük fel úgy, hogy nem készítünk C osztálynál nagyobb range-eket, és a frissítendő zónát range szinten adjuk meg.

A második eljárás pontosságára talán csak akkor van szükség, ha a befoglaló osztályban másik hálózatvezérlő hatáskörébe tartozó IP tartomány is szerepel. Jelen leírásban feltételezzük, hogy ilyen nincsen, és az első eljárást alkalmazzuk.

Biztonság

Biztonsági szempontból ebben a leírásban együttműködő klienseket tételezünk fel, de az esetleges rosszindulatú klienseket igyekszünk kiszűrni (TODO!).

DHCP kliensek besorolása - példa

A fentebb leírt elvek gyakorlati bemutatásához példa konfigurációs állományokat készítünk MAC address-sel azonosított DHCP kliensek besorolására.

Tételezzük fel, hogy 172.16.0.0/19 (172.16.0.0 - 172.16.31.255 azaz 32 db. érintkező C osztály) office hálózatunkon vannak:

  • szervergépek, melyek fix IP címmel rendelkeznek és nem használnak DHCP-t;
  • menedzselt hálózati eszközök (pl. switch, access point), amelyek DHCP-statikus IP címet kapnak a 172.16.0.0/24 egyszeres C osztályból;
  • IP telefonok, amelyek dinamikus IP címet kapnak a 172.16.2.0/23 dupla C osztályból;
  • regisztrált eszközök (notebook, tablet, okostelefon), amelyek dinamikus IP címet kapnak a 172.16.4.0/22 négyszeres C osztályból;
  • vendég eszközök, amelyek dinamikus IP címet kapnak a 172.16.8.0/22 négyszeres C osztályból;
  • a többi IP címet (most) nem használjuk.

Néhány példa klienst az alábbi táblázat sorol fel:

Kliens MAC address Hostnév IP range Megjegyzés
Hálózatvezérlő szervergép [érdektelen] router 172.16.0.1 DHCP szerver; fix IP címmel és statikus DNS rekorddal rendelkezik.
WiFi AP ethernet 00:00:00:00:00:01 AP0001 172.16.0.60 Hálózati eszköz; fix IP címet kap, host-ként azonosítjuk.
IP telefon ethernet 00:11:22:33:44:55 - 172.16.2.0/23 "A" típusú IP telefonkészülék, a DHCP kliens nem küld hostnevet.
Dinamikus IP címet kap a telefonoknak fenntartott range-ből, osztályba sorolással azonosítjuk.
IP telefon ethernet 00:99:88:77:66:55 B6655 172.16.2.0/23 "B" típusú IP telefonkészülék.
Dinamikus IP címet kap a telefonoknak fenntartott range-ből, osztályba sorolással azonosítjuk.
Notebook ethernet
Notebook WiFi
00:aa:bb:cc.dd:ee
00:aa:bb:cc:dd:ef
MyMachine
MyMachine
172.16.4.0/22 Hordozható munkaállomás, interface-eire egy-egy dinamikus IP címet kap a munkaállomásoknak fenntartott range-ből, osztályba sorolással azonosítjuk.
Vendég eszköz [ismeretlen] [ismeretlen] 172.16.8.0/22 Még sosem látott eszköz (vendég notebook, okostelefon, tablet, stb.)
Dinamikus IP címet kap a vendégeknek fenntartott range-ből, nem azonosítjuk.

Azokat a klienseket, amelyeknek fix IP címet szeretnénk adni, a host direktívával azonosítjuk, míg azokat a klienseket, amelyeknek nem feltétlenül szeretnénk fix IP címet adni, de meg szeretnénk határozni, hogy melyik pool-ból vagy range-ből kapjanak IP-t, vagy milyen (nem a subnet-től függő) egyéb DHCP beállításokkal rendelkezzenek, osztályba sorolással (felcímkézéssel) fogjuk kezelni. Erre a célra az előzőekben üresen hagyott /etc/dhcp/dhcpd.office konfigurációs állományt fogjuk használni.

Figyelem: ha tényleges tesztre készülünk, a konfigurációkban a saját eszközeink MAC addresseit kell használnunk!

dhcpd.office példa

A táblázatban foglaltakat pl. az alábbi bejegyzésekkel írhatjuk le:

-rw-r--r-- root root /etc/dhcp/dhcpd.office

# Include file for dhcpd.conf containing 'office' hosts declerations.

###################################
# Office clients, fixed addresses.
# Double check to avoid collisions!

group {
    # Global settings for DHCP-static clients here (if any).

    # Wifi AP
    host AP0001 {
        hardware ethernet 00:00:00:00:00:01;
        fixed-address 172.16.0.60;
    }
}

#############################
# Office clients, "A" phones.

class "office-phone-a" {
    match hardware;
    # Settings for type "A" phones here (if any)
}
# List of type "A" phones below.
subclass "office-phone-a" 1:00:11:22:33:44:55; # extension 123, John Doe

#############################
# Office clients, "B" phones.

class "office-phone-b" {
    match hardware;
    # Settings for type "B" phones here (if any)
}
# List of type "B" phones below.
subclass "office-phone-b" 1:00:11:22:33:44:55; # extension 124, Jane Doe

###############################
# Office clients, workstations.

class "office-ws" {
    match hardware;
    # Settings for all workstations here (if any)
}

# MyMachine, John Doe's notebook
group {
    subclass "office-ws" 1:00:aa:bb:cc.dd:ee; # Ethernet
    subclass "office-ws" 1:00:aa:bb:cc.dd:ef; # WiFi
    # Settings for this machine here (if any)
}

A fenti konfigurációs állomány előnye, hogy abban minden kliens MAC addresse csak egy helyen szerepel, világosan látható, hova kell a további klienseket felvenni és a megjegyzések mutatják, hol lehet az alapértelmezéseket felüldefiniáló egyéni beállításokat megadni az egyes klienseknek vagy kliens csoportoknak.

dhcpd.conf példa

Az előzőekben elhelyezett címkéknek megfelelő dinamikus IP kiosztást a /etc/dhcp/dhcpd.conf állománynak az office subnet-jét leíró részében állíthatjuk be:

-rw-r--r-- root root /etc/dhcp/dhcpd.conf

[...]
###############################
# Hosts and classes to include.
#

include "/etc/dhcp/dhcpd.office";

###########################
# Subnet definitions below.
#

# One reverse for whole inland (TODO!)
zone 16.172.in-addr.arpa. {
    primary 127.0.0.1;
    key "DDNS_UPDATE";
}

# office VLAN (eth0)
subnet 172.16.0.0 netmask 255.255.224.0 {
    option routers 172.16.0.1;
    option broadcast-address 172.16.31.255;
    option domain-name "office.mydomain.com";
    option domain-name-servers 172.16.0.1;
    #
    ddns-domainname "office.mydomain.com";
    ddns-ttl 3600;
    zone office.mydomain.com. {
        primary 127.0.0.1;
        key "DDNS_UPDATE";
    }
    #
    # 172.16.0.0/24 for common net devices (static)
    # 172.16.1.0/24 for servers (static)
    # 172.16.2.10-172.16.3.255 for IP phones
    pool {
        allow members of "office-phone-a";
        allow members of "office-phone-b";
        range 172.16.2.11 172.16.3.254;
    }
    # 172.16.4.10-172.16.7.254 for workstations
    pool {
        allow members of "office-ws";
        range 172.16.4.10 172.16.7.254;
    }
    # 172.16.8.10-172.16.11.254 for guests
    pool {
        deny members of "office-phone-a";
        deny members of "office-phone-b";
        deny members of "office-ws";
        range 172.16.8.10 172.16.11.254;
    }
}
[...]

Ügyeljünk arra, hogy az osztályokat definiáló dhcpd.office állományt az ezeket felhasználó subnet leírása elé illesszük be (include direktíva)!

Figyelem: ha tényleges tesztre készülünk, a saját fizikai, illetve logikai alhálózatunkat és a saját domainünket kell beállítanunk!

Bind9 módosítások

Ellenőrizzük, szükség szerint módosítsuk a Bind9 korábban beállított dinamikus zónáit! Ebben a példában valamennyi klienst (hálózati eszközt, telefont, munkaállomást, vendég készüléket egyaránt) az office.mydomain.com forward zónába fogunk regisztrálni, reverse-ként a 16.172.in-addr.arpa dinamikus zóna frissítése lesz szükséges.

Figyelem: ha tényleges tesztre készülünk, a saját fizikai alhálózatunk reverse-ét és a saját domainünket kell beállítanunk!

Gyorsteszt az első példához

Induljunk tiszta lappal:

  • kapcsoljuk le a belhálózatra csatlakozó eszközöket;
  • állítsuk le a DHCP szervert és töröljük a kiadott lease-eket (ez egy kivételes lépés, üzem közben ilyet ne tegyünk!):
/etc/init.d/isc-dhcp-server stop; 
head /var/lib/dhcp/dhcpd.leases -n3 >/var/lib/dhcp/dhcpd.leases.empty # üres lease adatbázis
cp /var/lib/dhcp/dhcpd.leases.empty /var/lib/dhcp/dhcpd.leases        # tiszta lappal indulunk
  • zónatranszferrel ellenőrizzük a DNS-t és töröljünk minden, a fenti eszközökre vonatkozó forward és reverse rekordot, pl.:
 dig office.mydomain.com axfr | grep -iv ';' | sort
/etc/dhcp/ddns-purge myhost.office.mydomain.com  # forward zone

 dig IP.IP.IP.in-addr.arpa axfr | grep -iv ';' | sort
/etc/dhcp/ddns-purge IP.IP.IP.IP.in-addr.arpa # reverse zone

A beállításokat a Bind9 és a DHCP szerver újraindításával érvényesíthetjük:

/etc/init.d/bind9 restart; tail -f /var/log/bind9/bind9.log
/etc/init.d/isc-dhcp-server restart; tail -f /var/log/dhcp/dhcp.log
Pipa.jpg
A naplókban nem szabad hibaüzenetnek megjelennie. Csatlakoztassuk a teszt hálózathoz a konfigurációban megjelölt DHCP klienseket, valamint egy vendégnek minősülő eszközt is, eközben figyeljük a /var/log/dhcp.log és a /var/log/bind9/update.log állományokat! Az eszközöknek megfelelő hálózati környezetet kell kapniuk. A DNS-ben, zónatranszferrel ellenőrizve, helyes forward és reverse rekordokat kell látnunk.

Gyakorlati megfontolások

  • A regisztrált eszközeinkre vonatkozó pool-okat érdemes az oda tartozó eszközök várható számánál "kicsit nagyobbra" választani, így "soha" nem telik be, és az eszközök mindig az elsőként megszerzett IP címet kapják vissza (kvázistatikus IP). A vendég eszközök pool-ját az egyszerre kiszolgálni kívánt vendég kliensek számának megfelelőre érdemes állítani - ha egyszerre 100 vendég klienst szeretnénk (vagyunk képesek) kiszolgálni, akkor ennyi IP címet hagyjunk a pool-ban. A vendég pool telítettségét kezdetben gyakran ellenőrizzük (pl. a Munin grafikonján); kivételes esetekben (pl. rendezvény alkalmával) méretét szükséges lehet megváltoztatni.
  • A regisztrált eszközök lease-time-ja (és ezzel együtt a DNS TTL-je) a példában írtnál hosszabbra (akár egy naposra is) állítható - a pool sosem merül ki, és az eszköz-IP hozzárendelés változás gyors elterjesztésének ritkán van jelentősége. Vendégek esetében a pool szűkös lehet, ezért a vendég távozásáról mielőbb szeretnénk értesülni. Kisvállalati környezetben a 10-30'-es lease-time (hozzá igazított DNS TTL-lel) racionálisnak tűnik.

Több VLAN kialakítása

Alább az előző példában szereplő vendég hálózatot külön VLAN-ként alakítjuk ki. Ehhez úgy módosítjuk a DHCP konfigurációt, hogy a vendég besorolású kliensek gateway-ként a hálózatvezérlőnk eth0:1 virtuális interface-ét és a 172.16.32.0/19 alhálózatot használják.

DHCP módosítások több VLAN esetén

Az áttekinthetőség kedvéért érdemes valamennyi VLAN - így a guest VLAN számára is - készíteni egy, az office VLAN-hoz hasonló konfigurációs állományt:

-rw-r--r-- root root /etc/dhcp/dhcpd.guest

# Include file for dhcpd.conf containing 'guest' hosts declerations.

amelyben érdemi bejegyzések egyelőre nem lesznek (de itt határozhatnánk meg pl. egy vendégek számára használható hálózati nyomtató konfigurációját, stb.). Ezután a /etc/dhcp/dhcpd.conf állományban:

  • include-oljuk ezt a beállító állományt is;
  • shared-network-ként definiáljuk az inland fizikai hálózatot;
  • készítünk egy új subnet-et a második VLAN számára, ebbe helyezzük át a vendég pool-t a számára előírt gateway, stb. beállításokkal és rövid lejárati idővel.

Figyelem: az állományban természetesen a saját fizikai, illetve logikai alhálózatunkat és a saját domainünket kell beállítanunk!

-rw-r--r-- root root /etc/dhcp/dhcpd.conf

[...]
###############################
# Hosts and classes to include.
#

include "/etc/dhcp/dhcpd.office";
include "/etc/dhcp/dhcpd.guest";

###########################
# Subnet definitions below.
#

shared-network inland {

    # One reverse for whole inland (TODO!)
    zone 16.172.in-addr.arpa. {
        primary 127.0.0.1;
        key "DDNS_UPDATE";
    }

    # office VLAN (eth0)
    [...]

    # guest VLAN (eth0:1)
    subnet 172.16.32.0 netmask 255.255.224.0 {
        option routers 172.16.32.1;
        option broadcast-address 172.16.63.255;
        option domain-name "guest.mydomain.com";
        option domain-name-servers 172.16.32.1;
        #
        ddns-domainname "guest.mydomain.hu";
        ddns-ttl 300;
        zone guest.mydomain.com. {
            primary 127.0.0.1;
            key "DDNS_UPDATE";
        }
        #
        default-lease-time 600;
        max-lease-time 600;
        pool {
            # Deny all registered clients.
            deny members of "office-phone-a";
            deny members of "office-phone-b";
            deny members of "office-ws";
            # Welcome, guests :-)
            allow unknown clients;
            range 172.16.34.10 172.16.34.254;
        }
    }
}
[...]

A beillesztés (include) sorrend fontos: a vendég deklarációkat illesszük be utoljára, mert így a tágabb (vendég) besorolás a szűkebb (office) besorolás után értékelődik ki. A vendég subnet pool-jában azért tiltunk minden regisztrált klienst, hogy a korábban vendégként csatlakoztatott, ám ezután regisztrált kliens számára a vendég pool a regisztráció után már ne legyen elérhető.

Bind9 módosítások több VLAN esetén

Amennyiben a VLAN számára új (al)domaint definiáltunk, a DNS-ben a korábban tárgyalt módon elő kell írnunk az ennek megfelelő (példánkban guest.mydomain.com) forward zóna kezelését és fogadását. Ebbe a zónába érdemes statikusan felvenni a hálózatvezérlő vendég hálózati IP címét, valamint a reverse zónába érdemes statikusan bejegyezni a hálózatvezérlő vendég alhálózatbeli IP címének feloldását is.

TODO!

Gyorsteszt a második példához

Az első példánál leírtak szerint induljunk tiszta lappal:

  • kapcsoljuk le a belhálózatra csatlakozó eszközöket;
  • állítsuk le a DHCP szervert és töröljük a kiadott lease-eket (ez egy kivételes lépés, üzem közben ilyet ne tegyünk!):
/etc/init.d/isc-dhcp-server stop; 
head /var/lib/dhcp/dhcpd.leases -n3 >/var/lib/dhcp/dhcpd.leases.empty # üres lease adatbázis
cp /var/lib/dhcp/dhcpd.leases.empty /var/lib/dhcp/dhcpd.leases        # tiszta lappal indulunk
  • zónatranszferrel ellenőrizzük a DNS-t és töröljünk minden, a fenti eszközökre vonatkozó forward és reverse rekordot, pl.:
 dig office.mydomain.com axfr | grep -iv ';' | sort
/etc/dhcp/ddns-purge myhost.office.mydomain.com  # forward zone

 dig IP.IP.IP.in-addr.arpa axfr | grep -iv ';' | sort
/etc/dhcp/ddns-purge IP.IP.IP.IP.in-addr.arpa # reverse zone

A beállításokat a Bind9 és a DHCP szerver újraindításával érvényesíthetjük:

/etc/init.d/bind9 restart; tail -f /var/log/bind9/bind9.log
/etc/init.d/isc-dhcp-server restart; tail -f /var/log/dhcp/dhcp.log
Pipa.jpg
A naplóban nem szabad hibaüzenetnek megjelennie. Csatlakoztassuk a teszt hálózathoz a konfigurációban megjelölt DHCP klienseket, valamint egy vendégnek minősülő eszközt is, eközben figyeljük a /var/log/dhcp.log és a /var/log/bind9/update.log állományokat! Az eszközöknek megfelelő hálózati környezetet kell kapniuk, a vendég eszköznek a vendég hálózatra kell kerülnie. A DNS-ben (a korábban leírt zónatranszferrel ellenőrizve) helyes forward és reverse rekordokat kell látnunk.

LDAP backend beállítása

Ebben a részben a fentebb konfigurációs állományokkal beállított DHCP-DDNS szolgáltatást LDAP backenddel valósítjuk meg. Az LDAP használata opcionális, a cost-benefit döntéshez az alábbiakat érdemes figyelembe venni:

  • (-) Az LDAP kiszolgáló egy külön telepítendő, karbantartandó szolgáltatás.
  • (+) Nagyszámú host kezelése konfigurációs állományokkal nehézkes lehet; könnyebb hibázni, mint a strukturáltabb directory tetszőleges grafikus klienssel történő karbantartása során.
  • (+) A konfigurációs állományokkal definiált adatbázis karbantartásához vagy konzolos hozzáférés (és a szolgáltatások újraindításához root jog), vagy alkalmas web/CGI frontend szükséges. Ezzel szemben az LDAP backendet a szolgáltatások úgy használják, hogy a változások érvényesítéséhez nem kell azok újraindítása, így távoli LDAP adminisztráció esetén nincs szükség konzolos belépésre és root jogra.

TODO!

A DHCP címtár inicializálása

A DHCP címtár használatba vételéhez a kiszemelt LDAP szerveren:

  • be kell töltenünk a DHCP-specifikus DIT definícióját (séma);
  • készítenünk kell egy DHCP adatbázist;
  • hozzá kell rendelnünk legalább egy, ennek kezelésére jogosult felhasználó objektumot vagy LDAP adatbázis accountot.

A DHCP séma betöltése

Ellenőrzésképpen listáztassuk ki a betöltött sémákat:

ldapsearch -LLLQY EXTERNAL -H ldapi:/// -b cn=schema,cn=config -s one dn  # Csak a következő szint DN-jeit keressük

# Alapértelmezésben ilyen választ kapunk:
dn: cn={0}core,cn=schema,cn=config
dn: cn={1}cosine,cn=schema,cn=config
dn: cn={2}nis,cn=schema,cn=config
dn: cn={3}inetorgperson,cn=schema,cn=config

Ha fenti listában a cn=dhcp[...] séma nem szerepel, akkor csomagoljuk ki az isc-dhcp-server-ldap csomaggal szállított DHCP sémát a /etc/ldap/schema könyvtárba:

cat /usr/share/doc/isc-dhcp-server-ldap/dhcp.schema.gz | gunzip >/etc/ldap/schema/dhcp.schema

A sémát betöltés előtt LDIF formátumba kell konvertálnunk, ami sajnos némi trükközést igényel (TODO!) - egy dummy konfigurációs állományba include-juk a sémát és ezt fordíttatjuk le a slaptest segédprogrammal:

echo "include /etc/ldap/schema/dhcp.schema" >/root/tmp/ldap.conf; slaptest -f /root/tmp/ldap.conf -F /root/tmp
cp /root/tmp/cn=config/cn=schema/cn={0}dhcp.ldif /etc/ldap/schema/dhcp.ldif    # Csak erre van szükség
chmod 644 /etc/ldap/schema/dhcp.ldif
rm /root/tmp/ldap.conf; rm /root/tmp/cn=config.ldif; rm -R /root/tmp/cn=config # Takarítás

A fenti sorok lefuttatása után keletkező /etc/ldap/schema/dhcp.ldif állományt betöltés előtt még meg kell szerkesztenünk:

  • módosítanunk kell a DN és CN attribútumot, hogy sémánk a cn=schema,cn=config alá kerüljön, és ne {0} indexű, hanem a sorrendben következő sémaként;
  • törölnünk kell a konvertáláskor generált technikai attribútumokat.
-rw-r--r-- root root /etc/ldap/schema/dhcp.ldif

[...]
dn: cn=dhcp,cn=schema,cn=config
[...]
cn: dhcp

[... alábbiak törlendők ...]
structuralObjectClass: olcSchemaConfig
entryUUID: [...]
creatorsName: cn=config
createTimestamp: [...]
entryCSN: [...]
modifiersName: cn=config
modifyTimestamp: [...]

Az így módosított LDIF-et adjuk hozzá a konfigurációs adatbázishoz (előtte gondosan nézzük át, mert ez a lépés nem egykönnyen vonható vissza!):

ldapadd -QY EXTERNAL -H ldapi:/// -f /etc/ldap/schema/dhcp.ldif
Pipa.jpg
Siker esetén a DHCP séma is megjelenik a sémák listájában:
ldapsearch -LLLQY EXTERNAL -H ldapi:/// -b cn=schema,cn=config -s one dn

dn: cn={0}core,cn=schema,cn=config
dn: cn={1}cosine,cn=schema,cn=config
dn: cn={2}nis,cn=schema,cn=config
dn: cn={3}inetorgperson,cn=schema,cn=config
dn: cn={4}dhcp,cn=schema,cn=config

A DHCP adatbázis elkészítése

Ebben a leírásban egyetlen logikai DHCP szolgáltatást feltételezünk, amelyet egy cn=dhcp gyökerű DIT-ként valósítunk meg, hdb backendet használva (részletesebben meggondolni, általánosítani: TODO!).

Készítsünk az adatbázis számára egy adatkönyvtárat (célszerűen a /var/lib/dhcp alatt), és adjuk az openldap Linux felhasználó tulajdonába:

mkdir -m 750 /var/lib/dhcp/ldap
chown openldap:root /var/lib/dhcp/ldap

Az adatbázishoz csak a root Linux felhasználónak és egy jelszóval védett LDAP adatbázis accountnak (cn=admin,cn=dhcp) fogunk (teljes körű) jogosultságot adni (R/O account: meggondolni, TODO!). Ez utóbbi számára készítsünk egy random jelszót (szöveges és SSHA hash formában) pl. az alábbi parancsokkal:

PW=$(pwgen -n -s -c 12 1); echo $PW; slappasswd -s $PW -h {SSHA}; PW=  # Nem kerül a history-ba, csak a képernyőre :-)

WVDPZLYJL8NY
{SSHA}+OjMch4VxNcORw4iljLt1ZUdroIiNzos

Jegyezzük fel a szöveges jelszót, majd készítsünk egy LDIF állományt, amely létrehozza az adatbázist és beállítja a célszerű indexeket, valamint a fenti jogosultságokat. Ügyeljünk a generált hash pontos bemásolására (NE használjuk a példa adatait!):

mcedit /root/tmp/ldap-add.ldif

# Create DHCP database
dn: olcDatabase=hdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcHdbConfig
olcDatabase: hdb
olcDbDirectory: /var/lib/dhcp/ldap
olcSuffix: cn=dhcp
# Useful indices
olcDbIndex: objectClass eq
olcDbIndex: cn eq,sub
olcDbIndex: dhcpHWAddress eq
olcDbIndex: dhcpClassData eq  
# Actually commented: read access to everyone - use with caution!
#olcAccess: to dn.base="" by * read
# Full access for Linux root.
olcAccess: to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=a
# Full access for an LDAP account.
olcRootDN: cn=admin,cn=dhcp
olcRootPW: {SSHA}+Qj[...]zos

Futtassuk le, és ellenőrizzük az eredményt (siker esetén az LDIF állomány törölhető):

ldapadd -QY EXTERNAL -H ldapi:/// -f /root/tmp/ldap-add.ldif
ldapsearch -LLLQY EXTERNAL -H ldapi:/// -b "cn=config" -s sub "(objectClass=olcDatabaseConfig)" dn # Összes adatbázis listája
ldapsearch -LLLQY EXTERNAL -H ldapi:/// -b "cn=config" -s sub "(olcSuffix=cn=dhcp)"                # A DHCP adatbázis adatai

rm /root/tmp/ldap-add.ldif

Készítsük el a fenti adatbázissal reprezentált címtár dhcpService osztályú cn=dhcp gyökér elemét:

mcedit /root/tmp/ldap-add.ldif

# Create root DN
dn: cn=dhcp
cn: dhcp
objectClass: top
objectClass: dhcpService

Futtassuk le, és ellenőrizzük az eredményt (siker esetén az LDIF állomány törölhető):

ldapadd -QY EXTERNAL -H ldapi:/// -f /root/tmp/ldap-add.ldif
ldapsearch -LLLQY EXTERNAL -H ldapi:/// -b "cn=dhcp"

rm /root/tmp/ldap-add.ldif
Pipa.jpg
Ha minden rendben van, az elkészített (jelenleg lényegében még üres) címtárhoz (távelérés birtokában, grafikus LDAP klienssel) az alábbi beállításokkal kapcsolódhatunk:
base DN:      cn=dhcp
felhasználó:  cn=admin,cn=dhcp
jelszó:       A fentebb beállított jelszó szöveges formában

A DHCP címtár feltöltése

Irodalom

DHCP - DDNS

DHCP - LDAP

TFTP, PXE

Egyebek