- předchozí článek - následující článek - obsah - úvodní stránka -

Linuxové noviny 03-04/2001

BIND a bezpečnost?

David Häring, 25. února 2001

Bind je bezesporu nejrozšířenějším softwarem implementujícím službu DNS (Domain Name System, základy implementace DNS nalezneme např. v RFC 1034 a 1035). Také není pochyb o tom, že dlouhodobě obsazuje nejvyšší příčky v nepopulárních žebříčcích aplikací, které obsahují závažné bezpečnostní chyby a jejichž provozování má ve svém důsledku na svědomí nemalou část úspěšných průniků do systémů nebo útoků způsobujících znepřístupnění služby (DoS, tzv. "Denial of Service" útok). Zároveň ovšem dodejme, že k této situaci přispívá v nemalé míře fakt, že mnoho administrátorů podceňuje rizika spojená s provozováním nejen bindu na systémech přístupných z Internetu a že nevěnují dostatečnou pozornost opravám, které pravidelně vycházejí. Dokladem budiž například starší článek na serveru underground.cz. Tento článek, který mapoval použití různých verzí bindu v doméně .cz sice vyšel více než před půl rokem, nicméně ukázal, že i někteří provozovatelé frekventovaných nameserverů jsou s opravami pozadu. Když pak během ledna letošního roku bylo publikováno několik dalších chyb v bindu, následovalo opět období, kdy se konference hemžily zprávami o úspěšných průnicích, přitom opravené verze bindu byly na webu ISC k dispozici poměrně rychle po publikování chyb. Přehled verzí bindu bindu s popisem chyb, které obsahují je k dispozici na www stránkách ISC.

Jaké tedy má administrátor provozující name server možnosti, chce-li předejít bezpečnostnímu incidentu? Příznivci DJB navrhnou jako alternativu použít djb-dns, (Life With djbdns). Podrobně se instalací djb-dns zabývali např. na serveru Root.cz. Djb-dns nepochybně je kvalitní náhradou bindu, má ovšem také zcela odlišnou architekturu a filozofii. Co tedy zbývá administrátorům, kteří na djb-dns přejít nemohou anebo nechtějí? Další možností by bylo přejít na bind verze 9.1, který je ovšem stále poměrně mladý. V tomto článku se zaměříme na několik zásad, které se týkají bezpečnosti instalace a konfigurace bindu verze 8.2.3-REL, což je v době sestavování tohoto článku poslední stabilní verze řady 8.2.

Bezpečnější instalace - chroot, uid, gid

Bind obsahuje několik mechanismů pro zajištění bezpečnosti: umí běžet v chroot prostředí, umožňuje volbu uživatele a skupiny, pod kterými poběží. Tyto možnosti bychom měli v každém případě využít. V řadě standardních instalací linuxových distribucí těchto možností nebývalo využito, což pak vedlo ke snadnému kompromitování celého systému v případě úspěšného útoku.

Chroot prostředí v podstatě znamená, že určitá aplikace je uzamčena v určité vyhrazené části souborového systému, kterou považuje za kořenový adresář a mimo něj nevidí. V případě, že dojde k bezpečnostnímu incidentu, útočník může přistupovat pouze k datům v rámci adresářové struktury, která je přístupná v rámci daného prostředí chroot a možnost infiltrace ostatních částí systému je mizivá. Je samozřejmé, že aplikace přitom nesmí běžet s oprávněním uživatele či skupiny root. (Uživatel root může např. pomocí volání jádra mknod vytvořit potřebná speciální zařízení, přes která pak může přistupovat k diskům apod.)

Existuje několik způsobů, jak libovolnou aplikaci spouštět v chroot prostředí. Jednou z možností je použít volání jádra chroot v dané aplikaci (detaily použití viz manuálová stránka), což ovšem vyžaduje úpravu zdrojového kódu aplikace. Druhou možností je použít nějaký "wrapper", např. utilitu chroot z balíčku sh-utils. Bind ovšem s možností běhu v prostředí chroot počítá, a proto není potřeba do něj zasahovat, stačí vše patřičně nakonfigurovat a spustit jej s příslušnými volbami (-t, -g a -u).

Dejme tomu, že chceme name server provozovat v adresáři /bindroot a dále, že bind poběží pod za tímto účelem vytvořeným uživatelem dns ve skupině dns. Aby to mohlo fungovat, je potřeba aby v adresáři /bindroot byly obsažena veškerá data a adresářové struktury, které bind ke svému běhu potřebuje. Rovněž je třeba upravit přístupová práva tak, aby s daty mohl uživatel dns pracovat (t.j. např. nastavit rekurzívně v adresáři /bindroot/var/named, kde budou umístěna data týkající se jednotlivých zón, vlastníka na uživatele a skupinu dns, dále named potřebuje zapsat PID do souboru /bindroot/var/run/named.pid a pokud k logování nepoužijeme syslog, potřebuje práva k zápisu do adresáře, kde jsou logy umístěny).


/bindroot
|-- dev
|   +-- null
|-- etc
|   |-- group
|   |-- localtime
|   |-- named.conf
|   +-- passwd
|-- usr
|   +-- sbin
|       |-- named
|       +-- named-xfer
+-- var
    |-- log
    |   |-- named.log
    |   +-- named_stats.log
    |-- named
    |   |-- d.domena.cz
    |   |-- d.reverz-domena.cz
    |   |-- named.ca
    |   +-- secondary
    |       +-- d.domena2.cz
    +-- run
        |-- named.pid
        +-- ndc

Soubory passwd a group v prostředí chroot by měly pochopitelně obsahovat pouze záznam o uživateli a skupině dns. Na uživatelský účet bindu by také mělo být zakázáno přihlašování se jakýmkoliv způsobem.

Proč používat acl?

Bind umí pracovat s ACL seznamy (Access Control List), takže není problém upravit přístup k jednotlivým zónám nebo typům údajů na základě IP adres. Tuto možnost bychom rozhodně neměli podceňovat, protože řada bezpečnostních chyb v bindu se týkala okrajových situací, kterým lze zabránit správnou konfigurací.

Konfigurace acl

Dejme tomu, že náš name server slouží jednak jako primární pro doménu "domena.cz", sekundární pro doménu domena2.cz a dále slouží jako "caching" name server pro firemní síť, která se skládá z počítačů 11.22.33.41 až 45. Dále předpokládejme, že sekundární name server pro naši doménu domena.cz je na stroji ns.nekdejinde.cz s IP adresou 22.33.44.55.

Definujeme dva ACL seznamy: seznam "trusted_query", který obsahuje IP adresy firemních pracovních stanic pro které fungujeme jako "caching" name server. Dále definujeme druhý seznam "trusted_axfr", který bude obsahovat počítače, které smí provádět transfer zón - tento bude zahrnovat stroj, který funguje jako sekundární server pro doménu domena.cz a dále bude zahrnovat stroje CZ NICu, ze kterých jsou prováděny kontroly nastavení DNS. (Jména a adresy těchto strojů na požádaní CZ NIC sdělí, zde v příkladu uvedený seznam by měl být dostačující).

// seznam strojů kterým je povolen transfer zón
acl trusted_axfr {
// sekundární nameserver
22.33.44.55    // ns.nekdejinde.cz;
// CZ-NIC
193.85.1.12;   // ns.eunet.cz
193.85.3.130;  // cz.eunet.cz
193.85.7.100;  // ns.o.cz
};

// seznam strojů které se mohou dotazovat // bez omezení acl trusted_query { localhost; // nase stroje 11.22.33.41 11.22.33.42 11.22.33.43 11.22.33.44 11.22.33.45 };

U direktivy options pak v konfiguračním souboru uvedeme, že transfer zón mohou provádět pouze stroje ze seznamu "trusted_axfr" a standardně dotazy omezíme pouze na stroje ze seznamu "trusted_query":

options {
        directory "/var/named";
        pid-file "/var/run/named.pid";
        allow-transfer { trusted_axfr; };
        allow-query { trusted_query; };
        allow-recursion { trusted_query; };
};

U deklarací jednotlivých zón, pro které je náš nameserver autoritativní a na dotazy, v rámci nichž musí server odpovídat všem bez rozdílu, pak v konfiguračním souboru explicitně dotazy zvenčí povolíme direktivou allow-query:

// master zóna
zone "domena.cz" {
        type master;
        file "d.domena.cz";
        allow-update   { none; }; 
        allow-query { any; };
};

// sekundární zóna zone "domena2.cz" { type slave; file "secondary/d.domena2.cz"; allow-query { any; }; masters { 22.33.44.55; }; };

Možností jak zabezpečit vlastní přenosy zón je použití autentizace serverů při přenosu zón pomocí podpisů (TSIG, transaction signatures). K tomu je potřeba vygenerovat klíč utilitou dns-keygen. Takto např. vygenerujeme do souboru Ktransferkey* MD5 klíč o délce 128 bitů:

server$ dnskeygen -H 128 -h -n transferkey.
Generating 128 bit HMAC-MD5 Key for transferkey.

Generated 128 bit Key for transferkey. id=0 alg=157 flags=513

V konfiguračním souboru pak přiřadíme klíče jednotlivým serverům, které jej budou používat:

key transferkey {
        algorithm hmac-md5;
        secret "srJPgeDYD42yitdbexG3Vg==";
};

server 22.33.44.55 { keys { transferkey ; }; };

Logování

Aplikace do systémového logu zapisují přes schránku (socket), který je zpravidla umístěn v /dev/log. Jestliže provozujeme aplikaci v chroot prostředí, musíme zajistit způsob, jakým komunikaci aplikace se syslogd zprostředkujeme. Poslední verze syslogd mohou mít otevřených více schránek. Pokud používáme klasický syslogd, řešením je spustit jej s volbou -a s uvedením cesty k další schránce (viz ukázka části souboru /etc/rc.d/init.d/syslog v distribuci Red Hat). Pokud to verze syslogd neumožňuje, můžeme použít utilitu holelogd. Ta funguje tak, že otevře schránku na určeném místě a příchozí zprávy kopíruje do standardní schránky syslogu v /dev/log.

case "$1" in
  start)
        echo -n "Starting system logger: "
        # otevřeme další socket v /bindroot/dev/log
        daemon syslogd -m 0 -a /bindroot/dev/log
        # anebo pokud používáme holelogd použijeme následující řádek
        # daemon /usr/local/sbin/holelogd /bindroot/dev/log
        RETVAL=$?
        echo
        echo -n "Starting kernel logger: "
        daemon klogd
        echo
        [ $RETVAL -eq 0 ] && touch /var/lock/subsys/syslog
        ;;

Výpis: ukázka části souboru /etc/rc.d/init.d/syslog

Pokud chceme zprávy bindu oddělit od zpráv ostatních démonů, můžeme v konfiguračním souboru bindu zvolit jakou kategorii zpráv ("facility") a prioritu má bind pro zápis do syslogu použít.

logging {
        channel eventlog {
                syslog local5;
                severity info;
        };
        category default { eventlog; };
};

Další možností je syslog nepoužívat vůbec a nechat logovat přímo bind. Rovněž je možné potlačit vypisování některých druhů zpráv, anebo je třeba zapisovat odděleně do několika souborů. Následující příklad ukazuje konfiguraci, při které budou statistiky zapisovány odděleně od ostatních zpráv. Zprávy některých kategorií, které informují o chybách v konfiguraci cizích domén budou ignorovány.

logging {

        channel statlog {
                file "/var/log/named_stats.log";
                severity info;
                print-time yes;
        };

        channel eventlog {
                file "/var/log/named.log";
                severity info;
                print-time yes;
                print-category yes;
        };

        category default { eventlog; };
        category statistics { statlog; };
        category lame-servers { null; };
        category cname { null; };
};

Instalace

Samozřejmě existují i RPM balíčky s bindem připraveným pro běh v chroot prostředí. Další možností je podle výše popsaných zásad vytvořit chroot instalaci buď ze stávající instalace bindu anebo vyjít přímo ze zdrojových kódů.

Pokud instalujeme bind ze zdrojových kódů, můžeme se rozhodnout, jestli chceme, aby výsledný spustitelný soubor byl linkován staticky anebo dynamicky. Přehlednější je kompilovat staticky, protože instalujeme-li dynamicky linkovanou aplikaci do prostředí chroot, musíme tam také doplnit sdílené knihovny, které aplikace k běhu potřebuje (utilita ldd vypíše seznam knihoven, které daná aplikace vyžaduje). Implicitně se sestaví bind linkovaný dynamicky, pokud to chceme změnit, musíme před kompilací upravit soubor Makefile.set v adresáři src/port/linux (nastavení proměnné CDEBUG, např. CDEBUG=-O2 -g -static).

Poznámka ke kompilaci: v posledních distribucích zpravidla nelze bind staticky přeložit kvůli konfliktu symbolů stejného jména v bindu a glibc. Pomůže upravit první řádek v souboru Makefile.set např. následujícím způsobem:

CC=gcc -D_GNU_SOURCE\
 -D__res_randomid=__res_randomidmy

Shrnutí

Cílem tohoto článku bylo ukázat na možnosti konfigurace bindu, které velmi ovlivňují bezpečnost celého systému, na kterém je bind provozován. Vzhledem k tomu, že nástroje pro detekci a využití bezpečnostních děr v bindu jsou velmi populární a rozšířené, je v podstatě nemyslitelné jej provozovat jinak než v chroot prostředí pod zvláštním uživatelem a skupinou a co nejvíce jej tak oddělit od ostatních částí systému. Rovněž používání ACL seznamů pro omezení přístupu k jednotlivým funkcím či druhům informací, které bind poskytuje, lze rozhodně doporučit. Další informace, týkající se provozování bindu v chroot prostředí, či tipy na zabezpečení instalací lze nalézt např. v následujících odkazech: http://www.psionic.com/papers/dns/dns-linux http://securityportal.com/direct.cgi?/closet/closet19991124.html http://securityportal.com/cover/coverstory20001002.html. *


- předchozí článek - následující článek - obsah - úvodní stránka -