DNS - Domain Name System

DNS jest systemem hierarchicznym. Na samym szczycie owej hierarchii stoją tzw. TLD (Top Level Domains), czyli domeny najwyższego rzędu. Zaliczają się do nich takie domeny jak .com (komercyjne), .pl (krajowe), .net (sieci) i inne. Są to domeny powstałe na podstawie odpowiednich postanowień, opisane w specjalnych dokumentach. Każda z wymienionych (lub też nie wymienionych) tutaj TLD's posiada swoje subdomeny, np. pld-linux.org. Z kolei każda powstała w wyniku rejestracji danej nazwy domena może mieć swoje poddomeny, np. www.pld-linux.org. W ten sposób można tworzyć bardzo zagęszczone hierarchie w obrębie danej domeny. Niniejszy rozdział dotyczy implementacji Bind określanego czasem jako named - jednego z najpopularniejszych serwerów DNS.

Każda domena (zwana również strefą) musi mieć co najmniej dwa serwery DNS, jest to wymóg registrarów, czyli instytucji oferujących możliwość rejestracji domen. Jeden z serwerów określa się jako podstawowy (również master lub primary) a drugi jako zapasowy (slave lub secondary).

Wstęp

Bind w PLD dziala w środowisku chroot, w katalogu /var/lib/named, musimy o tym pamiętać, przy niektórych operacjach diagnostycznych. Głównym plikiem konfiguracyjnym jest /etc/named.conf, który jest symlinkiem do /var/lib/named/etc/named.conf. Struktura katalogu /var/lib/named wygląda następująco:

 

dev/
etc/
M/
S/
named.pid
root.hint

 

Podobnie jak w normalnym środowisku, jest obecny tutaj katalog /dev, w którym znajdują się urządzenia konieczne do działania demona: /dev/null oraz /dev/urandom. Katalog /etc jak zapewne się domyślasz, przechowuje pliki konfiguracyjne. U nas znajduje się w nim jedynie named.conf. Kolejne katalogi: M oraz S zostały przeznaczone do przechowywania plików stref, odpowiednio master i slave. Plik named.pid przechowuje numer procesu systemowego. Ostatni plik na liście - root.hint zawiera wpisy z adresami tzw. root serwerów, czyli głównych serwerów DNS. Jest on konieczny do przeszukiwania serwerów DNS w poszukiwaniu żądanych nazw, których nie utrzymuje nasz serwer.

Dodawanie stref DNS polega na definiowaniu obsługiwanych domen w pliku /etc/named.conf, oraz tworzenia plików konfiguracji stref.

Podstawowa konfiguracja

Głównym plikiem konfiguracyjnym serwera Bind jest /etc/named.conf. Znajdują się w nim podstawowe opcje usługi oraz informacje na temat obsługiwanych stref. Poniżej zamieszczono domyślne wpisy, które znajdują się w tym pliku

 

options {
        directory "/";
        pid-file "named.pid";
        auth-nxdomain yes;
        datasize default;
};                                                       
zone "localhost" IN {
        type master;
        file "M/localhost.zone";
        allow-update { none; };
        allow-transfer { any; };
};
zone "0.0.127.in-addr.arpa" IN {
        type master;
        file "M/127.0.0.zone";
        allow-update { none; };
        allow-transfer { any; };
};
zone "." IN {
        type hint;
        file "root.hint";
};

Na samym początku pliku konfiguracyjnego znajduje się sekcja options. Najbardziej istotną opcją jest tutaj directory. Wskazuje ona na główny katalog przechowywania plików stref. Być może zdziwi Cię nieco parametr powyższej opcji. Jak już wcześniej wspominałem Bind w PLD posiada własne chrootowane środowisko, dlatego można taki zapis zastosować.

Zanim przejdę do omawiania pozostałych wpisów, należy się jeszcze słowo wyjaśnienia na temat konstrukcji samego pliku. Na pierwszy rzut oka poszczególne wpisy są podzielone na sekcje. Te z kolei ograniczone są klamrami. Znak ; również pełni tutaj rolę ogranicznika dla poszczególnych opcji jak i całych sekcji ujętych w klamry. Warto o tym wiedzieć ze względu na ewentualne szukanie błędów powstałych na skutek edycji tego pliku.

Poniżej mamy zdefiniowane trzy sekcje stref zaczynających się słowem kluczowym zone. W powyższym przykładzie przedstawione są wpisy określające localhosta. Są one typu master. Plik strefy w każdej z nich wskazany jest opcją file. Strefa nie musi być aktualizowana, ani synchronizowana z serwerem slave, więc dwie pozostałe opcje mają parametr none oraz any. Ostatnia strefa służy do komunikacji naszego binda z Root serwerami o których była mowa we wstępie. Bez tej strefy nie mógłby on wyszukiwać nazw w internecie. Mówiąc w przenośni byłby ślepy.

Każdorazowe odpytywanie Root Servers może się okazać mało wydajne, ze względu na duże czasy odpowiedzi. Dlatego, jeżeli chcemy przyspieszyć ten proces powinniśmy sekcję option zmodyfikować o wpis taki jak poniżej

 

options {
forwarders { 194.204.159.1; 194.204.152.34; };
}

Oczywiście nie musimy posługiwać się takimi adresami jak w przykładzie. Możemy sobie wybrać takie serwery DNS, które będą nam odpowiadały najszybciej np. serwery naszego ISP.

W PLD zaleca się, aby wszystkie pliki stref w zależności od typu domeny były przechowywane w katalogach /var/lib/named/M oraz /var/lib/named/S. Tak naprawdę o ścieżce do tych katalogów decydują wpisy w named.conf. Struktura plików stref dla obu typów domen jest taka sama.

Przykładowa konfiguracja strefy typu primary

Zaczniemy od konfiguracji /etc/named.conf, budowa tego pliku była wyjaśniona w poprzedniej części tego rozdziału. Poniżej został zamieszczony przykładowy wpis dla strefy na serwerze podstawowym:

 

zone "example.net" {
        type master;
        file "M/example.net";
        allow-transfer { 123.45.67.89; };
        notify yes;
};

Poszczególne opcje tej sekcji zostały omówione już na początku tego rozdziału. Podsumujmy więc dostępne informacje skupiając się na powyższym przykładzie:

·         zone "example.net" - nazwa strefy

·         type master - rodzaj serwera

·         file "M/example.net" - nazwa pliku z konfiguracją strefy

·         allow-transfer { 123.45.67.89; } - adres serwera, który ma możliwość transferu całej strefy, Jeżeli posiadasz więcej niż jeden taki DNS, możesz je wpisać pomiędzy klamry pamiętając o tym, aby rozdzielić poszczególne adresy IP, znakiem ';'.

·         notify yes - opcja ta włącza powiadamianie zapasowego serwera DNS o zmianach w naszej domenie.

Musimy teraz utworzyć plik strefy dla domeny example.net wskazany przez opcję file. Poniżej zamieszczam treść przykładowego pliku strefy:

 

$TTL 86400
$ORIGIN example.net.
@       IN      SOA     ns1.example.net. root.example.net. (
        2004022300 ;; serial
        1200      ;; refresh
        1200       ;; retry
        2419200    ;; expire
        86400      ;; TTL
        )
@               IN      NS      ns1.example.net.
@               IN      NS      ns2.example.net.
@               IN      MX      10    mail.example.net.
@               IN      A       123.45.67.8
ns1             IN      A       123.45.67.8
ns2             IN      A       90.12.34.237
mail            IN      A       123.45.67.8
www             IN      A       34.5.6.78
ftp             IN      CNAME   www

Plik strefy można podzielić na trzy odrębne sekcje. Pierwsza określa nazwę domeny oraz okres ważności wpisów. Druga, kto tą domeną zarządza. W trzeciej znajduje się cała jej zawartość. Bardziej szczegółowy opis znajduje się w poniższym wykazie. Kilka zdań o wyrażeniach stosowanych w plikach stref. Warto o nich pamiętać. Wszystkie wpisy poprzedzone ;; będą ignorowane i traktowane jak komentarz. Kolejnym ważnym znakiem jest znak kropki. Jego znaczenie omówię poniżej w przykładzie.

 

@               IN      NS      ns1.example.net.

Jeżeli w powyższym wpisie pominęlibyśmy końcowy znak kropki, wówczas Bind dokleiłby na końcu nazwę domeny. Wówczas z ns1.example.net zrobiłby się wpis ns1.example.net.example.net, co oczywiście nie jest pożądane. następnym znakiem specjalnym na który warto zwrócić uwagę jest @. Otóż można go potraktować jako pewnego rodzaju zmienną, która przechowuje nazwę example.net. Jednym słowem, example.net i @ to to samo.

·         $TTL 86400 - czas ważności rekordów w domenie wyrażony w sekundach; 86400 s. to jedna doba

·         $ORIGIN example.net. - domena jaką będzie opisywał bieżący plik strefy.

·         @ IN SOA ns1.example.net. root.example.net. - Rekord typu SOA czyli Start Of Authority. Możemy się z niego dowiedzieć, kto zarządza domeną (root@example.net), jaki jest adres serwera primary DNS. Zwróć uwagę, że w adresie root@example.net zamiast znaku @ użyta została kropka. Rekord SOA posiada swoją własną strukturę o której poniżej. Zawarta jest ona pomiędzy znakami ( ).

·         2004022300 ;; serial - numer seryjny domeny. Powinien on być zwiększany wraz z każdą jej modyfikacją. W dobrym tonie jest utrzymywanie go w formacie YYYYMMDDnn czyli rok, miesiąc, dzień oraz numer modyfikacji w danym dniu.

·         1200 ;; refresh - To pole rekordu SOA definiuje jak często serwery slave mają sprawdzać czy dane o domenie nie zmieniły się na masterze. Według RFC 1035 wartość ta powinna się zawierać pomiędzy 1200 a 43200 (czyli od dwudziestu minut do dwunastu godzin). W praktyce najlepsza wartość zawiera się między 3600 a 7200 sekund.

·         1200 ;; retry - Czas po jakim secondary ma ponowić próbę kontaktu z masterem, gdy taka się nie powiedzie. Zalecana wartość pomiędzy 120 a 7200 sekund.

·         2419200 ;; expire - Ta wartość określa czas po jakim dane domeny mają zostać uznane za nieaktualne gdy serwer secondary nie będzie mógł się skontaktować z primary. Zalecana wartość zawiera się pomiędzy 1209600 a 2419200 sekund, czyli od dwóch do czterech tygodni.

·         86400 ;; TTL - Time To Live. Określa ile czasu informacja o danym rekordzie ma być ważna. Jest to okres przez jaki informacja o naszej domenie będzie przechowywana przez serwer DNS, który ją pobrał. Zalecana wartość zawiera się między 86400 a 432000 sekund, czyli przez okres od jednego do pięciu dni.

Bezpośrednio pod rekordem SOA definiujemy, które serwery DNS będą obsługiwały naszą domenę. Jeszcze raz przypominam aby właściwie zamknąć ten rekord. Bez tego nasza domena nie będzie działać. Do definiowania serwerów DNS służą wpisy typu IN NS.

 

@               IN      NS      ns1.example.net.
@               IN      NS      ns2.example.net.

Powyższy wpis mówi, że domenę example.net obsługuje serwer DNS ns1.example.net oraz ns2.example.net. Jeżeli obie nazwy dotyczą komputerów, które wcześniej nie pełniły roli serwerów DNS, powienieś dodać wpisy takie jak poniżej.

 

ns1             IN      A       123.45.67.8
ns2             IN      A       90.12.34.237

ns1 oczywiście może wskazywać na adres serwera DNS który zapewne konfigurujesz; ns2 powinien wskazywać na Twojego secondary. Zrobiliśmy to posługując się wpisami typu IN A. Jak zapewne pamiętasz, brak końcowej kropki powoduje doklejenie do wpisanej nazwy tego co znajduje się w zmiennej $ORIGIN. Możemy więc uznać to co widzisz w powyższym przykładzie za postać skróconą poniższego wpisu.

 

ns1.example.net.             IN      A       123.45.67.8
ns2.example.net.             IN      A       90.12.34.237

Wpisy typu IN A służą do określania, że właśnie ten adres IP ma przypisaną taką a nie inną nazwę. Oczywiście do jednego adresu IP możesz stworzyć kilka takich wpisów. Jeżeli posiadasz serwer poczty, powinieneś zrobić wpis mówiący o tym, że będzie on obsługiwał pocztę dla domeny example.net.

 

@               IN      MX      10    mail.example.net

Dokładnie tak jak wcześniej wspomniałem, poczta, dla domeny example.net kierowana jest do serwera mail.example.net o priorytecie 10. Jest on tzw. MX'em. Rekord typu IN MX służy właśnie do definiowania w DNS serwera poczty. Priorytet przydaje się wtedy, kiedy posiadasz kilka serwerów poczty w swojej domenie. Służy on do ustalenia porządku; do którego serwera poczta ma trafić w pierwszej kolejności. Mniejszy priorytet zapewnia pierwszeństwo.

Pozostałe wpisy dotyczą takich standardowych usług jak www czy ftp. Umieszczanie ich w pliku strefy nie jest obowiązkowe. Jednak domenę rejestruje się zazwyczaj na potrzeby www, ftp czy poczty, dlatego zostały one wymienione w przykładzie.

 

ftp             IN      CNAME   www

Powyżej umieszczono przykład rekordu typu IN CNAME, tworzy on dodatkową subdomenę dla hosta przypisanego już do innej nazwy. Specjaliści radzą by tego rodzaju rekordy wskazywały wyłącznie na rekordy typu IN A.

Po zakończeniu konfiguracji musimy jeszcze uruchomić usługę.

# /etc/rc.d/init.d/named start

Przykładowa konfiguracja strefy typu secondary

Konfiguracja serwera secondary sprowadza się do dokonania poniższego wpisu w pliku /etc/named.conf.

 

zone "example.net" IN {
        type slave;
        file "S/example.net";
        masters { 123.45.67.8; };
};

Jak widać wpis wygląda podobnie jak w przypadku serwera primary. Opcja type tym razem ma wartość slave. Musimy też wskazać serwer primary. Robimy to używając opcji masters, której wartość zawiera adres serwera primary DNS.

Obsługa protokołu IPv6

Podobnie jak większość usług w dystrybucji BIND posiada wsparcie dla protokołu IPv6 (IPng). Oczywiście wcześniej komputer musi być podłączony do tej sieci. W tej części rozdziału zostanie omówiona konfiguracja dla stref IN A oraz strefy odwrotnej. Narzędziem wspomagającym konfigurację będzie ipv6calc znajdujący się w pakiecie o tej samej nazwie. Jak sama nazwa wskazuje jest to kalkulator adresów IPv6.

·         IN AAAA

Odpowiednikiem w IPv6 strefy IN A jest wpis IN AAAA. Każda z dotychczasowych stref stworzona do tej pory dla protokołu IPv4 może mieć swój odpowiednik w sieci IPv6. Możemy również stworzyć zupełnie nowe wpisy, które będą widoczne jedynie w tej sieci.

 

moja           IN  AAAA       3ffe:1a:2b:3c::1

Umieszczenie powyższego wpisu w pliku strefy /var/lib/named/M/example.net spowoduje przypisanie nazwy moja.example.net adresowi 3ffe:1a:2b:3c::1. Aby wpis zaczął obowiązywać należy zrestartować usługę.

·         IN PTR

Konfigurację strefy odwrotnej zaczniemy od stworzenia odpowiedniego wpisu w pliku /etc/named.conf. Jak sama nazwa wskazuje będzie on przypominał lustrzane odbicie adresu w zwykłej postaci. Aby mieć pewność, że nasza strefa będzie poprawnie zapisana posłużymy się wspomnianym we wstępie narzędziem ipv6calc.

 

$ ipv6calc -r 3ffe:1a:2b:3c::/64
No input type specified, try autodetection...found type: ipv6addr
c.3.0.0.b.2.0.0.a.1.0.0.e.f.f.3.ip6.int.

Uzyskaliśmy w ten sposób informacje, że dla sieci o adresie 3ffe:1a:2b:3c::/64, strefa odwrotna posiada postać taką jak na powyższym listingu. Wystarczy teraz to zapisać w pliku konfiguracyjnym BIND'a.

 

zone "c.3.0.0.b.2.0.0.a.1.0.0.e.f.f.3.ip6.int" IN {
        type master;
        file "M/ipv6";
        allow-transfer {
               90.12.34.237;
        };
};

Jak widać na pierwszy rzut oka, konfiguracja niczym się praktycznie nie różni od konfiguracji strefy dla IPv4. Jako nazwę strefy podaliśmy to co nam zwrócił ipv6calc. Przyjrzyjmy się teraz jak powinien wyglądać plik dla tej strefy wskazany dyrektywą file.

 

$TTL    86400
$ORIGIN 0.1.0.0.e.2.0.0.c.0.0.4.e.f.f.3.ip6.int.

Pierwszy parametr to omawiany już wcześniej okres ważności rekordów. Jak widać na listingu wynosi on jeden dzień. Drugi z nich to de facto nazwa tej strefy. Sama opcja $ORIGIN to swojego rodzaju zmienna, której wartość jest podstawiana w miejsce @ oraz doklejana do tych nazw które nie posiadają na końcu specjalnego znaku kropki.

 

@               IN      SOA ns1.example.net. root.example.net. (
                2004050600
                3H
                15M
               1W
               1D )

Jak widać rekord IN SOA nie różni się niczym od tego dla domeny IPv4.

 

@                               IN      NS      ns1.example.net.
@                               IN      NS      ns2.example.net.

Określamy które serwery przechowują naszą domenę odwrotną. Również tutaj wszystko wygląda identycznie jak dla protokołu IPv4. Możemy teraz przystąpić do konfigurowania strefy odwrotnej.

 

1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0       IN PTR  moja.example.net.

Dlaczego tyle zer? Odpowiedź na to znajdziesz obliczając przy użyciu programu ipv6calc adres odwrotny dla 3ffe:1a:2b:3c::1. Robimy to w sposób identyczny do poprzedniego przykładu jego użycia. W wyniku obliczeń będzie on wyglądał tak: 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.c.3.0.0.b.2.0.0.a.1.0.0.e.f.f.3. Jak łatwo zauważyć, po ostatnim zerze w listingu nie postawiliśmy kropki, a więc zostanie doklejona po nim zawartość $ORIGIN.

Narzędziem pomocnym w odpytywaniu serwerów DNS, jest program host. Można nim również odpytywać o nazwy skonfigurowane dla protokołu IPv6. Jak by wyglądało zapytanie o nazwę moja.example.net?

 

$ host -n -i 3ffe:1a:2b:3c::1
1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.c.3.0.0.b.2.0.0.a.1.0.0.e.f.f.3.\
    ip6.int domain name pointer moja.example.net

Przełącznik -n oznacza, że będziemy odpytywali strefę odwrotną, natomiast -i, że jest to adres typu int. Domyślnie host szuka nazw typu arpa.

Rejestracja

Zanim zarejestrujemy domenę musimy mieć skonfigurowany podstawowy i zapasowy serwer nazw. Mamy możliwość zarejestrowania własnej domeny, bądź skorzystać z usług darmowego oddelegowania nam subdomeny zarejestrowanej już domeny. Ceny rejestracji domen spadły w ostatnich latach tak bardzo, że używanie "obcej" domeny stało się mało profesjonalne i warto zarejestrować własną.

Jeżeli nie posiadasz serwera secondary, możesz poszukać firmy lub organizacji, która za darmo utrzymuje zapasowe DNS-y. Możemy też umówić się z administratorem innej firmy na wzajemne prowadzenie serwerów secondary.

Diagnostyka

Jeśli chcemy przetestować poprawność składni pliku strefy, powinniśmy skorzystać z narzędzia named-checkzone. Program sprawdzi poprawność pliku strefy i poda w której linii wystąpił błąd np.:

 

# /usr/sbin/named-checkzone example.net /var/lib/named/M/example.net

Named generuje logi typu daemon, domyślnie syslogd umieszcza takie wpisy w pliku /var/log/daemon. Jeśli jednak nastąpił problem z uruchomieniem demona, uniemożliwiający mu pisanie do logów, to możemy sprawdzić co się dzieje uruchamiając go bez przejścia w tło i z wypisaniem komunikatów na standardowe wyjście:

 

/usr/sbin/named -g -t /var/lib/named

Aby ostatecznie sprawdzić poprawność konfiguracji możemy odpytać nasz serwer za pomocą protokołu DNS. Użyjemy do tego programu host z pakietu bind-utils np.:

 

# /usr/sbin/host -t mx example.net

Zakończenie

Uwaga! Named nie powinien być resolwerem nazw dla maszyny na której pracuje, powinien nim być inny serwer DNS aby nie powstawały zapętlenia zapytań. Wyjątek stanowią usługi pracujące w osobnych środowiskach chroot/vserver. Więcej o konfiguracji resolwera nazw znajdziemy w tym dokumencie.