Bind 9 telepítése (Jessie)

Innen: AdminWiki

Ez a leírás az ISC BIND DNS kiszolgáló (9.x verziójának) telepítését írja le publikus authoritatív vagy belső hálózati cache kiszolgáló feladatkörben, technikailag chroot fogdába zárva, és klasszikus, konfigurációs fájl alapú backend-et használva.

Nem publikus, gyorsítótár (cache-only) névszerver szolgáltatásra (amelyet rutinszerűen telepíthetünk minden publikus levelező szerverre, webkiszolgálóra, stb. - általában minden standalone kiszolgálóra) a monolitikus és terjedelmes BIND-9 helyett pl. a DNSmasq használatát javaslom.

Work in progress - még ne vedd komolyan!

Telepítés

Házirend szerint alaptelepített és biztosított szervergépre Debian csomagból telepíthetjük - teszteléshez és az adminisztráció megkönnyítésére az alapvető klienseket tartalmazó dnsutils csomagot is telepítsük:

apt-get install bind9 dnsutils # Plusz függőség könyvtárak

A telepítés elindítja a konfigurálatlan névszervert, ezt állítsuk le:

systemctl stop bind9

A chroot fogda beállítása

A jail-t egy írható és futtatható partícióra kell tenni, ez célszerűen külön lehet mount-olva, pl. a /srv/chroot/bind mountpoint-ra. TODO: bind-mount illetve a chroot-on belüli szigorítások meggondolása!

Rendezzük be a fogdát:

mkdir -p -m 755 /srv/chroot/bind
# etc
mkdir /srv/chroot/bind/etc
mv /etc/bind /srv/chroot/bind/etc
chown -R bind:bind /srv/chroot/bind/etc/bind
cp /etc/localtime /srv/chroot/bind/etc/localtime
ln -s /srv/chroot/bind/etc/bind /etc/bind # Security, stb. update-ek miatt
# dev
mkdir /srv/chroot/bind/dev
mknod /srv/chroot/bind/dev/null c 1 3
mknod /srv/chroot/bind/dev/random c 1 8
chmod 666 /srv/chroot/bind/dev/null /srv/chroot/bind/dev/random
# var
mkdir -p /srv/chroot/bind/var/cache/bind
mkdir -p /srv/chroot/bind/var/run/bind/run
chown -R bind:bind /srv/chroot/bind/var/*

A syslog-ng használata esetén a chroot-olt bind képes a syslog-ba írni, erre vonatkozó külön beállítás nem szükséges.

A fogda elkészítése után adjuk meg annak útvonalát a bind konfigurációs állományában:

-rw-r--r-- root root /etc/default/bind9

# BIND chrooted!
OPTIONS="-u bind -t /srv/chroot/bind"

és indítsuk el a démont:

systemctl start bind9; tail -f /var/log/syslog

A syslog-ban ellenőrizhető a démon indulása.

Általános beállítások

Nem authoritatív (cache) szolgáltatásra a bind alapbeállításai általában véve megfelelőek, így az /etc/bind9/named.conf.options állományban egyelőre csak két módosítást végzünk:

  • Tiltjuk az IPv6 használatát;
  • Tiltjuk a bind verziószámának publikus lekérdezését (minimális security in obscurity).
-rw-r--r-- bind bind /etc/bind/named.conf.options

options {
        [...]
        // IPv6 disabled.
        listen-on-v6 { none; };

        // Do not make public version of BIND.
        version none;
};

A módosítások a névszerver következő újraindításakor érvényesülnek.

Kérések és biztonsági riasztások naplózása

Alapértelmezésben a bind a syslog-ba naplóz, és a naplóban (nyilván terjedelmi okból) az egyes konkrét lekérések nem szerepelnek. Az egyes DNS kérések naplózása alapján lehet pl. a Munin segítségével monitorozni a szerver tevékenységét, a visszautasított kérések naplója pl. a fail2ban számára szükséges. Fentiek számára két új naplóállományt készítünk: a /var/log/bind9/query.log csak a lekéréseket tartalmazza, a /var/log/bind9/bind9.log minden mást.

A beállításhoz készítsünk egy új konfigurációs állományt a bind számára, és ebben írjuk elő a fentiek syslog-on keresztüli naplózását (ez alapértelmezésben nincs beállítva) és tiltsunk meg néhány feleslegesnek tűnő eseménynaplózást:

touch /etc/bind/named.conf.logging
chown bind:bind /etc/bind/named.conf.logging
mcedit /etc/bind/named.conf.logging
-rw-r--r-- bind bind /etc/bind/named.conf.logging

logging {
    channel b_query {
        syslog daemon;
        print-time yes;
        severity info;
    };

    category default { default_syslog; default_debug; };
    category queries { b_query; };
    // Disable some annoying log entries
    category edns-disabled { null; };
    category lame-servers {null; };
    category unmatched { null; };
};

A most elkészített konfigurációs állományt a /etc/bind/named.conf állomány részeként fogjuk bejegyezni:

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

[...]

include "/etc/bind/named.conf.options";
include "/etc/bind/named.conf.logging";
include "/etc/bind/named.conf.local";
include "/etc/bind/named.conf.default-zones";

A bind beállítása után módosítsuk a syslog-ng beállítását is, hogy ténylegesen két külön fájlba menjen az így keletkező napló - a destinations rész végére szúrjuk be az alábbiakat:

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

[...]
# Bind 9 separate logging
destination d_bind9_queries
    { file("/var/log/bind9/query.log" owner(root) group(adm)); };
destination d_bind9
    { file("/var/log/bind9/bind9.log" owner(root) group(adm)); };
[...]

A filters rész végére írjuk be az alábbiakat:

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

[...]
# Bind 9 separate logging
filter f_bind9_queries { facility(daemon) and match("named" value("PROGRAM")) and match("query:" value("MESSAGE")); };
filter f_bind9 { facility(daemon) and match("named" value("PROGRAM")); };
[...]

Végül a log paths rész elejére (így a final flag miatt csak az új logokban jelennek meg a named üzenetek, azaz nem zavarják a logcheck-et, stb.) szúrjuk be az alábbiakat:

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

[...]
# Bind 9 separate logging
log { source(s_src); filter(f_bind9_queries); destination(d_bind9_queries); flags(final); };
log { source(s_src); filter(f_bind9); destination(d_bind9); flags(final); };
[...]

A változtatásokat a syslog-ng és a bind9 újraindításával érvényesíthetjük:

mkdir -m 755 /var/log/bind9   # mert a syslog-ng nem hozza létre, bug
systemctl restart syslog-ng; systemctl restart bind9; tail -f /var/log/bind9/bind9.log

Gyorstesztként indítsunk egy lekérést, és nézzük meg, hogy bekerül-e a query.log-ba:

dig @localhost www.debian.org; tail -f /var/log/bind9/query.log

Gondoskodjunk az új naplók rotálásáról:

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

/var/log/bind9/*.log {
    daily
    rotate 7
    compress
    missingok
    create 0640 root adm
    postrotate
       systemctl reload bind9 > /dev/null 2>&1 || true
    endscript
}

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

A DNS szerver a bind Linux felhasználó nevében állandóan fut, í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_ValidUsers='[...]|bind|[...]'
[...]
Tiger_Listening_ValidProcs='[...]|named|[...]'
[...]
Tiger_Running_Procs='[...] /usr/sbin/named [...]'
[...]

Kérések monitorozása a Muninnal

A Debian terjesztésben a szükséges plugin szerepel, de az alapbeállításai nem megfelelőek, ezért készítsünk hozzá egy konfigurációs állományt:

-rw-r--r-- root root /etc/munin/plugin-conf.d/bind9

[bind9]
    user root
    env.statefile /var/lib/munin-node/plugin-state/bind9.state
    env.logfile /var/log/bind9/query.log

Ezután a szokott módon belinkelhetjük, és érvényesíthetjük a beállítást:

ln -s /usr/share/munin/plugins/bind9 /etc/munin/plugins/bind9
systemctl restart munin-node

Gyorsteszt:

dig @localhost www.debian.org
telnet localhost 4949
[...]
fetch bind9
>  query_A.value 1
>  query_other.value 0
>  .
quit

Helyi gyorsítótár használatba vétele

TODO: pontosítani!

A fentiek szerint telepített bind azonnal használható cache-only névszerverként, ha névkiszolgálóként történő használatát előírjuk a /etc/resolv.conf állományban:

-rw-r--r-- root root /etc/resolv.conf

[...]
nameserver 127.0.0.1
[...]

Amennyiben a telepítés alatt álló gép (bármelyik hálózati interface-én!) DHCP-n keresztül kap IP-címet, érdemes előírni a DHCP kliensnek, hogy ezt a beállítást hagyja meg elsőként használatos névszervernek (ellenkező esetben a következő IP lease megújításnál bejegyzésünk felülíródhat!). Ehhez módosítsuk a /etc/dhcp/dhclient.conf állományt (vegyük ki a commentet az alábbi sor elől):

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

[...]
prepend domain-name-servers 127.0.0.1;

Ezután kérjünk egy DNS feloldást a dig paranccsal, pl.

dig www.debian.hu
[...]
;; Query time: 62 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
[...]

A válasz végén látható, hogy az valóban a helyi névkiszolgálón keresztül érkezett (127.0.0.1) és megfigyelhető a válaszidő is. A kérés ismételt kiadása esetén ez a válaszidő (közel) 0 lesz, jelezve, hogy a feloldás a helyi cache-ből történt.

Publikus (authoritatív) DNS kiszolgálás

Ebben a szerepkörben a telepítés alatti szervergép egy vagy több zóna számára elsődleges vagy másodlagos névszerver lesz - az authoritatív kifejezés nagyjából azt jelenti, hogy ezen zónák mindenkori hiteles tartalmát a telepítés alatti névszerver szolgáltatja (a felettes zónák névszerverei ezt a gépet jelölik NS adatforrásként). Publikus authoritatív szolgáltatáshoz:

  • a csomagszűrő tűzfalon be kell engedni a DNS lekéréseket;
  • célszerű védekezni a túlterheléses támadások ellen;
  • engedélyezni kell a zónatranszfert az illetékes DNS regisztrátorok és a másodlagos névszerverek számára;
  • definiálni kell az általunk szolgáltatott zónákat.

A DNS kérés átengedése a névszerver tűzfalán

A kifelé menő DNS kérések a házirend szerinti tűzfal-szabályokban eleve engedélyezettek. Authoritatív szolgáltatóként (általában) bárhonnan beérkező DNS kéréseket fogadnunk kell; ehhez a Shorewall használata esetén vegyük fel az alábbi szabályt:

-rw-r----- root root /etc/shorewall/rules
[...]
DNS/ACCEPT        all    fw
[...]

Amennyiben szervergépünk csak a helyi hálózatra nézve authoritatív (belső DNS szerver), természetesen elegendő a DNS kéréseket helyi hálózat felől engedélyezni.

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

systemctl restart shorewall

Alapértelmezésben a rekurzió nem engedélyezett, így a fenti beállításokkal a névszerver csak azokra a kérésekre fog válaszolni, amelyekre nézve authoritatív.

fail2ban integráció

A házirend szerint korábban már telepített fail2ban segítségével a névszerver érvénytelen vagy illetéktelen lekérésekkel történő túlterhelése (DOS) ellen igyekszünk védekezni. Publikus szolgáltatás esetén célszerű ezt a védelmet beállítani.

Egészítsük ki a maintainer által biztosított, a named-re vonatkozó szabályokat úgy, hogy vonatkozzék a dinamikus update kísérletekre is:

-rw-r--r-- root root /etc/fail2ban/filter.d/named-refused.conf

[...]
failregex = [...]
            ^%(__line_prefix)s(\.\d+)?( error:)?\s*client <HOST>#\S+( \([\S.]+\))?: update '.*' denied\s*$
            [...]

Készítsünk egy új fail2ban beállító állományt, ebben adjuk meg a bind9.log naplót a fail2ban számára figyelendőnek, és rendeljük hozzá a megfelelő szabályokat; ha van megbízható (trusted) IP címünk tartományunk, amellyel szemben a védelmet szeretnénk mellőzni, definiáljuk azt is:

touch /etc/fail2ban/jail.d/bind9.conf; chmod 600 /etc/fail2ban/jail.d/bind9.conf
mcedit /etc/fail2ban/jail.d/bind9.conf
-rw------- root root /etc/fail2ban/jail.d/bind9.conf

# TCP only - see http://nion.modprobe.de/blog/archives/690-fail2ban-+-dns-fail.html
[named-refused-tcp]
enabled = true
logpath = /var/log/bind9/bind9.log
ignoreip = IP.IP.IP.IP IP.IP.IP.IP/MASK

Olvastassuk újra a fail2ban konfigurációját, és a naplóban ellenőrizzük, hogy megjelent-e a named-re vonatkozó jail:

systemctl restart fail2ban; tail -f /var/log/fail2ban.log  # Jail 'named-refused-tcp' started

Gyors tesztként TODO!

Zónatranszfer engedélyezése

Teljes zónák lekérdezése alapértelmezésben csak a localhost számára engedélyezett. Amennyiben authoritatív szolgáltatást nyújtunk, legalább az InterNIC-nek a helyi domain regisztrátorok által használt szerverei számára; master szolgáltatóként a slave-eink számára is engedélyeznünk kell a zónatranszfert.

A zónatranszfer engedélyezéséhez vegyünk fel egy, az alábbihoz hasonló szakaszt a named.conf.options állományba (magyarországi helyi beállítások):

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

options {
        [...]
        // During test phase only.
        //notify no;

        allow-transfer {
                127.0.0.0/16;
                193.6.27.63;        # www.nic.hu
                193.239.149.113;    # hureg.nic.hu
                193.239.149.97;     # hureg.nic.hu
                // our secondaries
                IP.IP.IP.IP;        # our 1st secondary
                IP.IP.IP.IP;        # our 2nd secondary
        };
}

A fenti beállításban szereplő notify no bejegyzést tesztelési időszakban érdemes a komment (//) eltávolításával bekapcsolni, így nem küldünk a secondary szervereinknek felesleges zónatranszfer felhívásokat. Éles üzemben természetesen szükségesek lesznek az értesítések!

A beállítás a bind újraindításával érvényesíthető - helyes beállítás esetén a naplóállományban nem szabad hibasoroknak megjelenniük:

systemctl restart bind9; tail -f /var/log/bind9/bind9.log

Zónadefiníciók elhelyezése

Ebben a leírásban az alábbi fájlszerkezetet használjuk az általunk kezelt zónák definiálására:

/etc/bind/                   # valójában -> /srv/chroot/bind/etc/bind
         master/             # master zónafájlok
          slave/             #  slave zónafájlok
         named.conf.master   # master zónák felsorolása
         named.conf.slave    #  slave zónák felsorolása

Master zónák definíciója

Amennyiben rendelkezünk master zónákkal, ezek definíciói számára jegyezzünk be egy include állományt a named.conf.local konfigurációba:

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

// Master zones
include "/etc/bind/named.conf.master";

Készítsük el a hivatkozott állományt, benne egy formális fejléccel:

echo -e "//Master zones\n//Keep the ABC order, please\n" > /etc/bind/named.conf.master
chown bind:bind /etc/bind/named.conf.master

Végül a konkrét zónafájlok számára készítsünk egy tároló könyvtárat:

mkdir -m 2755 /etc/bind/master
chown bind:bind /etc/bind/master

Master zóna felvétele

Egy master zóna felvételéhez szerkesszük meg ezt az állományt, és vegyünk fel benne egy, az alábbihoz hasonló zónadefiníciót:

-rw-r--r-- bind bind /etc/bind/named.conf.master
[...]

zone "mydomain.com" {
        type master;
        file "/etc/bind/master/mydomain.com";
};

Célszerű minden zóna (domain) számára külön zónafájlt használni, azonban a nyilvánvalóan alias domainek számára (pl. egy domain ékezet nélküli és ékezetes verziója, hosszabb és rövidített változata, stb.) számára definiálhatunk azonos tartamú file bejegyzést több zone bejegyzéshez is.

Készítsük el a tényleges zónafájlt a fenti definícióban megadott néven, és töltsük fel az alábbihoz hasonló, minimálisnak tekinthető kiinduló tartalommal:

-rw-r--r-- bind bind /etc/bind/master/mydomain.com

@               IN      SOA     ns0.mydomain.com.  dnsadmin.mydomain.com. (
                        YYYYMMDD01              ;Serial nr.
                        14400                   ;Refresh
                        7200                    ;Retry
                        86400                   ;Expire
                        3600                    ;TTL
                        )

@               IN      NS              ns0
@               IN      NS              secondary.somewhere.com.
@               IN      MX      10      mail.mydomain.com.

ns0             IN      A               IP.IP.IP.IP
mail            IN      A               IP.IP.IP.IP

;@              IN      A               UNKNOWN YET

A SOA (source of authority) bejegyzésben a névszerver megadása utáni elem egy e-mail cím, ahol a @ helyett is pont karakter áll. A névszerver és egy postmaster@ fiókot fogadó levelező szerver IP címének megadása (közvetlenül vagy közvetve) kötelező a DNS rekordban. A rekord sorszámát célszerű a fenti konvenció alapján képezni és azonos naptári napon belül is minden módosításkor inkrementálni. A példában szereplő időadatok az ajánlottnál rövidebbek, teszt időszakra méretezettek.

A beállítás a bind újraindításával érvényesíthető - helyes beállítás esetén a naplóállományban nem szabad hibasoroknak megjelenniük:

systemctl restart bind9; tail -f /var/log/bind9/bind9.log

Slave zónák definíciója

TODO!

Slave zóna felvétele

TODO!

Helyi hálózati (belső) DNS szolgáltatás

Még hiányos, ne vedd komolyan!

Rekurzív DNS kérések engedélyezése

Alapértelmezetten a BIND csak azokra a DNS kérésekre válaszol bárkinek (azaz nem a localhost-nak), amelyekre nézve authoritatív (azaz a válaszhoz nem kell további, külső lekérdezéseket indítania). Amennyiben a telepítés alatt álló gép dedikált DNS szerver valamely IP tartomány számára (pl. egy SOHO hálózat DNS szervere, azaz bármilyen innen érkező kérést ki kell szolgálnia), akkor ezt a viselkedést a /etc/bind/named.conf.options állományban engedélyezni kell:

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

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

A változtatást a BIND újraindításával érvényesíthetjük:

systemctl restart bind9; tail -f /var/log/bind9/bind9.log

Belső hálózati zóna kezelése

Opcionális beállítás; belső hálózati és nem kifejezetten DNS kiszolgáló gépeken alkalmazzuk.

Előfordulhat, hogy adott zónák adatait nem az alapértelmezett névkiszolgálókról szeretnénk megkapni - pl. a belhálózati neveket illetve reverse-eket a helyi DNS szerver(ek)ről szeretnénk megkapni (máshonnét nem is lehetne), de az általános DNS feloldásokat nem - azokat "saját hatáskörben" intéznénk. Ilyenkor a belső zónák és a belhálózati IP tartomány reverse-e számára forwarder bejegyzéseket érdemes definiálni a /etc/bind/named.conf.local állományban:

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

[...]
// local domain
zone "OFFICE.MYDOMAIN.COM" {
	type forward;
        forward only;
	forwarders {IP.IP.IP.IP; IP.IP.IP.IP;};
};

// RFC-1918 non-routable IP range (reverse)
zone "10.in-addr.arpa" {
	type forward;
        forward only;
	forwarders {IP.IP.IP.IP; IP.IP.IP.IP;};
};

ahol IP.IP.IP.IP a belső hálózati DNS szerver(ek) IP címei (a belhálózati domain nevet és az - RFC-1918 szerinti - IP tartományt módosítsuk az általunk használtra!).

A beállítás arra utasítja a named-et, hogy a megnevezett zóna illetve reverse IP tartomány feloldásait csak a felsorolt névszerver(ek)től kérje.

Irodalom