Domain Name System (DNS)

Ondřej Vrablík, ondrada@mail.muni.cz


Obsah


Význam DNS

V IP sítích jsou připojená zařízení identifikována IP adresou. Tuto adresu má v síti přiděleno každé z připojených zařízení (respektive každé zařízení, které chceme z jiného zařízení prostřednictvím IP sítě "oslovit") a je v celé síti jedinečná, takže jednoznačně identifikuje daný prvek sítě. Je však nepříjemné, že jde o 32 bitů dlouhé číslo, které navíc nic nevypovídá o zařízení, jemuž je přiděleno. To je vcelku nepříjemná vlastnost, protože není jednoduché pamatovat si tak dlouhé číslo pro každý počítač v síti, který chci používat. V malých sítích o pár počítačích to sice možné je, ale v síti řádově desítek až stovek počítačů je to nemyslitelné. Proto vznikl DNS, což je systém, který umožňuje nazvat každý počítač libovolným jménem, a dokáže toto jméno převést na IP adresu, jejímž prostřednictvím je již možné v síti komunikovat. Přecijen je přijatelnější pamatovat si, že vyhledavač Google je na adrese "www.google.com", než abych musel vědět, že je na adrese "66.102.9.104".


Trocha historie

Požadavek na přijatelnější identifikaci počítačů než prostřednictvím IP adresy je snad stejně starý, jako IP sítě samotné. DNS však není prvním systémem, který tento problém vyřešil. Předchůdcem DNS je takzvaný soubor HOSTS (na Linuxových strojích /etc/hosts ), který (i přes svoji zastaralost) dá se říci funguje dodnes. Jde o soubor, ve kterém jsou napsány dvojice "IP_adresa doménové_jméno" nebo trojice "IP_adresa plné_doménové_jméno krátké_doménové_jméno". Tady je příklad linuxového souboru /etc/hosts. Tento soubor se dá i v dnešní době využít, například k "usnadnění práce" s psaním doménových adres (pokud do souboru zadáme například řádek "193.86.103.40 mobily", pak můžeme používat adresu mobily a dostaneme se na stejný stroj jako kdybychom psali www.mobilmania.cz), nebo v malých sítích kde je málo počítačů místo DNS.

Tento překlad jmen na IP adresy však brzy přestal stačit, zaprvé bylo nutné vytvořit nějakou hierarchii jmen (použitelná jednoslovná jména se brzy vyčerpají) a zadruhé s rostoucím počtem zařízení připojovaných do IP sítí (tedy i Internetu) rostla i velikost souboru HOSTS. Tento soubor musel být na každém počítači a obsahovat jména a IP adresy všech strojů v síti, které měly být volány jménem, takže při každé změně ve jménu nebo při připojení nového stroje musel být rozkopírován na všechny stroje v síti. Jistě si každý dovede představit, jaký vliv na zátěž sítě by mělo kopírování několikamegabajtového souboru (třeba i několikrát denně) i na několik desítek tisíc strojů, natož do všech strojů v Internetu. Proto vznikl systém DNS, který tyto problémy vyřešil.


Jak to funguje

DNS vlastně není nic jiného, než obrovská distribuovaná databáze, ve které jsou (zjednodušeně řečeno) uloženy dvojice jméno-IP_adresa. Je založena na modelu klient-server, kdy servery znají IP adresy přiřazené doménovým jménům, a klienti se na tyto adresy dotazují serverů. Servery následně klientům posílají odpovědi s IP adresou příslušející k danému doménovému jménu.

Plně kvalifikované doménové jméno se skládá z několika textových částí oddělených tečkami. Každá z částí může být dlouhá maximálně 63 znaků a celkově nesmí délka celého jména přesáhnout 255 znaků. Plně kvalifikovaným doménovým jménem stroje je tedy jméno, které jednoznačně ukazuje na konkrétní stroj (v Internetu tedy například www.seznam.cz, booyone.nasiti.cz a podobně). Jednotlivé části jména nejsou nijak náhodně poskládány, jsou uspořádány hierarchicky, a každá část je doménou. Poslední část je takzvaná doména prvního řádu (neboli top-level doména), předposlední je doména druhého řádu, třetí od konce je doména třetího řádu a tak dále. Pro jméno booyone.nasiti.cz tedy víme, že leží v top-level doméně "cz", v doméně cz je doména "nasiti" a v doméně "nasiti" je doména "booyone". Aby takový systém měl smysl, samozřejmě platí, že nesmí existovat dvě IP adresy, které mají ve stejné doméně přiřazeno stejné jméno (takže nesmí existovat dvě adresy se jménem "booyone.nasiti.cz", ale už může mít jedna jméno "booyone.nasiti.cz" a druhá třeba "booyone.netart.cz").

Takovéto uspořádání není náhodné, naopak je velmi důležité. Existuje totiž hierarchie DNS serverů, která odpovídá hierarchii doménových jmen. Platí totiž, že každá existující doména (tj. každá část plně kvalifikovaného doménového jména) musí mít minimálně jeden DNS server, který danou doménu obsluhuje. Tomuto serveru se říká "Primární DNS server". Majitel domény, pro kterou je DNS server vytvořen, pak rozhoduje o jeho konfiguraci, s doménou si může hospodařit jak chce (například může prostřednictvím tohoto DNS serveru vytvářet domény nižších řádů pod svojí doménou, pověřovat jiné lidi správou těchto subdomén a tak dále). Každá doména (ať už je kteréhokoliv řádu) tedy musí mít svůj primární DNS server, na němž jsou definovány všechny subdomény v doméně a jejich primární DNS servery, nebo přímo IP adresy, na které se mají dané subdomény překládat, jinak nebude žádné v ní definované jméno dostupné. Správce/majitel dané domény se správně nazývá "autorita", a může pověřovat další autority správou subdomén pod svojí doménou.

Tento model byl zvolen právě proto, že není možné aby všechna jména i s IP adresami byla na jednom stroji, takový stroj by byl permanentně přetížený. Jak ale tedy funguje dotazování na domény když je každá definována jinde? Je to jednoduché. Každý klient, který chce DNS využívat, má na svém stroji DNS resolver. Tento resolver mívají stroje přímo v sobě (respektive v implementaci sítě) takže nebývá nutné nic doinstalovávat. DNS Resolveru musíme říci IP adresu nejbližšího DNS serveru (případně několik adres blízkých DNS serverů, kdyby některý z nich vypadl). Od té chvíle resolver ví, kde se má ptát. Pokud tedy někdo zadá požadavek na překlad adresy, resolver vezme doménové jméno a pošle ho DNS serveru. Ten se na adresu podívá, a buď ji zná, a pošle klientovi odpověď rovnou, a nebo ji nezná, protože se klient dotazuje na jinou než jeho doménu. Pak mu nezbyde než dotaz vzít, a přeposlat ho jednomu z kořenových DNS serverů. Kořenové DNS servery jsou první uzel stromu DNS serverů. Jde o servery, které obsluhují Top-Level domény a nacházejí se v doméně "root-servers.net". V Internetu je jich několik, jsou odlišeny písmeny ("a.root-servers.net", "b.root-servers.net", "c.root-servers.net" atd.). Top-Level domény přiděluje organizace internic (www.internic.net), konfigurace kořenových DNS serverů je tedy v její kompetenci. Tyto servery převezmou dotaz, podívají se na něj a odpoví "nevím, ale tuto top-level doménu spravuje ten a ten DNS server, zeptej se tam". Tato odpověď se vrátí DNS serveru, kterého se ptal klient, a ten znovu pošle rotaz na klientem zadanou doménu, tentokrát ovšem nikoliv kořenovému DNS serveru, ale DNS serveru který dostal v odpovědi od kořenového DNS serveru. Tento buď odpoví IP adresou stroje, jemuž je přiřazena doména, nebo zase pošle adresu DNS serveru pro nižší doménu, a tak se klientův DNS server ptá a ptá až se dobere poslední domény, na niž by měl jako odpověď dostat IP adresu stroje. Tuto adresu pak pošle klientovi jako odpověď.

Nejlepší asi bude vysvětlení na příkladu. Představme si, že chceme přeložit adresu "booyone.nasiti.cz". DNS resolver pošle požadavek našemu DNS serveru (tomu, který jsme mu nastavili). Ten se na ni podívá, zjistí že ji nezná a pošle požadavek kořenovému DNS serveru. Kořenový DNS server odpoví "Nevím, ale doménu .cz spravuje DNS server xxx.xxx.xxx.xxx". Náš DNS server tedy pošle požadavek na překlad domény booyone.nasiti.cz DNS serveru, který dostal v odpovědi. Ten opět odpoví "Nevím, ale doménu nasiti v doméně cz spravuje DNS server yyy.yyy.yyy.yyy". Náš DNS server tedy opět pošle serveru yyy.yyy.yyy.yyy požadavek na doménu booyone.nasiti.cz a ten už odpoví "Ano, v mé doméně je subdoména booyone, stroj, ke kterému patří ma IP adresu zzz.zzz.zzz.zzz" Tato adresa se následně vrátí DNS resolveru na našem počítači.

Ještě jsme nezmínili dvě důležité věci. Takovýto překlad funguje, problém ale nastane, pokud dojde k výpadku některého z DNS serverů. Pak se na doménu, kterou obsluhuje, není koho ptát a překlad selže. Proto existují také sekundární DNS servery, a je doporučeno, aby každá doména měla alespoň jeden primární a jeden sekundární DNS server. Sekundární DNS server by měl být umístěn na jiné síti než primární DNS server a měl by automaticky zrcadlit obsah primárního DNS serveru, změny v konfiguraci tedy stačí dělat jen na primárním DNS serveru. Primární a sekundární DNS servery patří do skupiny registrovaných DNS serverů (jsou registrovány u nadřazeného primárního DNS serveru).

Existuje ještě jeden významný typ DNS serveru, říká se mu Cache-Only a není registrovaný v žádné doméně. Tento DNS server slouží vlastně jen k přeposílání dotazů k vyšším DNS serverům a může ho provozovat každý i bez vlastnictví domény. Také urychluje vyřizování dotazů a snižuje zátěž sítě i ostatních DNS serverů, protože si u vyřízených dotazů chvíli pamatuje, že doména ta a ta se překládá na IP adresu tu a tu a pokud přijde požadavek na doménu, která je v cache, okamžitě vrátí její IP adresu aniž by se ptal nadřazených DNS serverů.

Odpověď, kterou klient dostane od serveru, může být dvou typů: Autoritativní (authoritative) a neautoritativní (non-authoritative). Rozdíl mezi nimi je ten, že autoritativní odpověď je odpověď, která byla získána postupným dotazováním se DNS serverů, kdežto neautoritativní odpověď je odpověď, která byla získána z některého z nameserverů (a může se tedy stát že už není platná). Pokud klient dostane neautoritativní odpověď, má možnost si od DNS serveru explicitně vyžádat odpověď autoritatvní.


Jak na překlad jmen v Linuxu?

Pokud chceme použít služby DNS serverů v Linuxu (chceme se dotazovat jaká IP adresa přísluší ke jménu), musíme korektně zkonfigurovat DNS resolver. Toto se provádí v souboru /etc/resolv.conf (příklad). Soubor je složen s řádků, které začínají jedním z následujících klíčových slov:


domain doména - říká, v jaké doméně se nachází náš stroj. Pokud napíšeme adresu bez domény, doplní se zde doména zadaná (například je-li řádek "domain fi.muni.cz" a my chceme přeložit jméno "aisa", bude se překládat aisa.fi.muni.cz)
nameserver IP_adresa - specifikuje název DNS serveru, kterého se budeme dotazovat (např. "nameserver 147.251.48.1", znamená to že se budeme dotazovat DNS serveru, který běží na stroji 147.251.48.1, tj. na Aise. Může být zapsáno více takových řádků.
search doména - výsledek je stejný jako u "domain", vlastně jen přidává další domény které se mají prohledat při zadání krátkého doménového jména
sortlist IP_adresa[/maska_podsítě] IP_adresa[/maska_podsítě]... - umožňuje třídit vrácené IP adresy, může být zadáno až 10 párů IP_adresa/maska_podsítě. Pokud maska není zadána, použije se maska té podsítě, do které adresa přísluší.
options volba - specifikuje další volby pro resolver - volba může být debug (ladící režim) nebo ndots:n (n specifikuje počet teček v doménovém jméně - pokud jich je méně než n, hledá se nejprve s doplněním domény specifikované v řádku search, je-li teček stejně nebo více než n, nejprve se pošle zadaná adresa a až poté se k ní zkouší doplňovat jména ze search. Výchozí hodnota je 1).

Jak na vlastní linuxový DNS server?

Existuje několik implementací DNS serveru pro OS Linux. Jednoznačně nejznámější a nejpoužívanější implementace je BIND (Berkeley Internet Name Domain), a proto se s ní budeme dále zabývat. Tato implementace vznikla v 80. letech a je součástí mnoha Linuxových distribucí. Domovská stránka tohoto projektu je http://www.isc.org/sw/bind/. Asi druhou nejznámější implementací je DJBDNS (D. J. Bernstein DNS), která má oproti BINDu výhodu ve vyšší bezpečnosti a složení z menších utilitek. Homepage: http://cr.yp.to/djbdns.html


Konfigurace BINDu

Hlavní konfigurační soubor BINDu se jmenuje named.conf a nachází se v adresáři /etc. Jeho nejdůležitější parametry jsou options a zone:

options {...} - tato sekce obsahuje základní globální volby BINDu. Patří mezi ně tyto nejdůležitější:
directory "cesta_k_adresáři" - určuje adresář, kde bude BIND hledat soubory s popisem jednotlivých zón
auth-nxdomain {yes|no} - určuje, zda server může dát autoritativní odpověď o neexistenci domény
forwarders {ip_adresa;ip_adresa} - specifikuje IP adresy DNS serverů, kterým se mají přeposílat dotazy. Za IP adresou může být ještě "port číslo_portu" které určuje port, na kterém vzdálený DNS server běží - například pro DNS server 123.4.56.7 kde server běží na síťovém portu 126 bychom zadali jako parametr "123.4.56.7 port 126".
forward {only|first} - určuje, jestli má náš server pouze přeposílat dotazy DNS serverům definovaným ve forwarders (volba only), nebo se snažit hledat odpověď, pokud nadřazený DNS neodpoví (volba first)
allow-query {ip_adresa[/podsíť];ip_adresa[/podsíť];...} - určuje stroje, které se mohou tohoto DNS serveru dotazovat
allow-transfer {ip_adresa[/podsíť];ip_adresa[/podsíť];...} - určuje stroje, které mohou z tohoto serveru kopírovat informace o doménách

zone "zona" in {...} - určuje pravidla pro konkrétní zónu (bind umí obsluhovat více domén), nejčastěji má tyto parametry:
type {master|slave|hint|stub|forward} - určuje, v jakém režimu je server pro konkrétní zónu
file "soubor" - definuje konfigurační soubor pro zónu, soubor se bude hledat v adresáři specifikovaném v sekci options parametrem directory masters {ip_adresa;ip_adresa;...} - udává adresy master DNS serverů - použije se když je tento server pro zónu v režimu slave

Parametrů je mnohem více, všechny včetně popisu můžete nalézt například na adrese http://www.zytrax.com/books/dns/ch7/.

Nastavení named.conf máme tedy probráno, nyní ještě musíme pro každou zónu nastavit domény, které v ní mají být. K tomu slouží soubory v adresáři, který je definován v souboru named.conf v sekci options parametrem directory. Pro každou zónu musí být vytvořen zvláštní soubor.

Zóna představuje doménu, kterou tento nameserver spravuje, nebo reverzní záznamy pro své adresy. Reverzní záznamy jsou záznamy, které umožňují z IP adresy získat doménové jméno stroje. Tyto záznamy jsou ve speciální zóně in-addr.arpa tak, že například pro síť 192.168.0.0/24 budou v zóně "0.168.192.in-addr.arpa". To znamená, že musíme mít zónu pro každou doménu, kterou má DNS server znát, a pro každou síť, pro kterou má poskytovat reverzní záznamy.

Praktickou konfiguraci bude nejlépe pochopit z okomentovaných příkladů:
Konfigurace BINDu: named.conf
Dopředný soubor pro zónu int.rudna.net: int.rudna.net.zone
Reverzní soubor pro zónu 10.0.0.0/8: 10.zone
Dopředný soubor pro zónu localhost: localhost.zone
Reverzní soubor pro zónu localhost: 127.0.0.zone
Soubor pro "svět" (kořenové nameservery): root.hint

Podle konfigurace v named.conf z příkladu by soubory .zone musely být v adresáři /var/lib/named. Soubor root.hint se často mění a je dobré ho čas od času stáhnout z ftp.internic.net. Pokud někoho zajímá, v době psaní recenze aktuální verze je vystavena výše ;-)


BIND a Chroot

V rámci bezpečnosti bychom měli spouštět BIND v chrootovaném prostředí, protože pak chyba v implementaci a následné nabourání serveru není tak nebezpečné. Stejnětak je dobré BIND spouštět pod jiným uživatelem než rootem - například mít uživatele named pro spouštění BINDu. Například BIND s root adresářem /var/lib/named pod uživatelem named se spustí příkazem "named -t /var/lib/named -u named". Pro spuštění v chrootovaném prostředí je nutné mít v adresáři, na který měníme root, vytvořenu jistou adresářovou strukturu. Na tuto činnost mívají distribuce napsány skripty které toto udělají automaticky (například u SuSE Linuxu skript /etc/init.d/named). Jak úspěšně spustit BIND v chrootovaném prostředí bez jejich asistence je popsáno například zde: http://www.losurs.org/docs/howto/Chroot-BIND.html

BIND také dovede obsloužit dva signály: Pokud dostane signál SIGHUP, znovu načte konfiguraci, a pokud dostane signál SIGINT, uloží záznamy z cache.


Další informační zdroje:

BIND v chrootovaném prostředí:
http://www.losurs.org/docs/howto/Chroot-BIND.html
Mnoho informací o DNS a BINDu: http://www.zytrax.com/books/dns/
Jednoduché nastavení DNS: http://www.abclinuxu.cz/clanky/show/15213
Pro ty, které zajímá DJBDNS: http://www.root.cz/clanek/628
Různá RFC, která se vztahují k DNS: http://www.dns.net/dnsrd/rfc/
man named
man resolv.conf


Mnou použité zdroje:
Výše uvedené
www.google.com
vybrané konfigurační soubory stroje gate.rudna.net