Konfiguracja serwera DNS w Linuxie – BIND9 krok po kroku

by Patryk

W poprzednich artykułach skonfigurowaliśmy adresację IP, nazwy hostów, routing oraz podstawowe usługi sieciowe. Dzięki temu nasze laboratorium jest już gotowe do uruchamiania kolejnych elementów infrastruktury. Jednym z najbardziej naturalnych następnych kroków jest własny serwer DNS, który pozwoli centralnie zarządzać rozwiązywaniem nazw w całym środowisku.

W tym artykule nie tworzę nowego laba od zera. Zamiast tego wykorzystuję dokładnie to samo środowisko, które zostało przygotowane wcześniej.

W tej konfiguracji:

  • Debian będzie serwerem DNS nadrzędnym (master),
  • Ubuntu będzie serwerem DNS podrzędnym (slave),
  • CentOS pozostanie routerem między podsieciami,
  • Windows CL1 i Windows CL2 posłużą jako klienci testujący rozwiązywanie nazw.

Synchronizacja strefy między Debianem i Ubuntu działa dzięki wcześniej skonfigurowanemu routingowi, a klienci po obu stronach topologii mogą korzystać z DNS, który mają ustawiony. CL1 będzie korzystał z serwera DNS na Debianie a CL2 z serwera DNS na Ubuntu.

Rola serwera master i slave w DNS


W tym laboratorium serwer master będzie przechowywał główną, edytowalną wersję strefy firma.local. To właśnie na nim będziemy dodawać rekordy, zmieniać numer seryjny strefy i definiować całą logikę nazw.

Serwer slave będzie przechowywał kopię tej strefy w trybie tylko do odczytu. Nie wprowadzamy na nim zmian ręcznie – jego zadaniem jest pobranie danych z serwera nadrzędnego i udzielanie odpowiedzi klientom, nawet jeśli master chwilowo będzie niedostępny.

Instalacja BIND9 na Debianie i Ubuntu


Na obu serwerach instalujemy BIND9 oraz podstawowe narzędzia diagnostyczne:

sudo apt install -y bind9 dnsutils

Po instalacji możesz sprawdzić status usługi:

sudo systemctl status bind9

Te dwa hosty stają się teraz kolejną warstwą naszego labu. Wcześniej umiały się ze sobą komunikować po IP i przez routing, a teraz zaczną rozwiązywać nazwy dla całego środowiska.

Najważniejsze pliki konfiguracyjne BIND9


W tym artykule będziemy pracować głównie na kilku plikach:

  • /etc/bind/named.conf.default-zones – Zawiera domyślne strefy, takie jak localhost i 127.0.0.1, które powinny być dostępne na każdym serwerze DNS.
  • /etc/bind/named.conf.local – tutaj najlepiej definiować własne strefy DNS, takie jak firma.local
  • /etc/bind/named.conf.options – Służy do konfiguracji globalnych opcji DNS. Przykładowo w tym pliku można wyłączyć obsługę zapytań rekurencyjnych.
  • /etc/bind/ – miejsce, w którym będziemy trzymać pliki stref głównych
  • /var/cache/bind/ – dobre miejsce do zapisu strefy podrzędnej pobranej przez serwer slave

Zezwolenie na zapytania DNS z naszych sieci


Na początku warto ograniczyć, kto w ogóle może zadawać pytania do naszego DNS-a. W naszym labie sensownie będzie dopuścić tylko hosty z trzech podsieci używanych wcześniej:

- 172.16.10.0/24
- 172.16.20.0/24
- 192.16.0.0/24

Na Debianie i Ubuntu edytuj plik:

sudo mcedit /etc/bind/named.conf.options

i dodaj lub zmodyfikuj sekcję:

options {  
directory "/var/cache/bind";  
  
allow-query { localhost; 172.16.10.0/24; 172.16.20.0/24; 192.16.0.0/24; };  
  
dnssec-validation auto;  
  
listen-on-v6 { any; };  
};

Takie ustawienie oznacza, że z naszego DNS-a mogą korzystać tylko hosty z laboratorium i sam localhost. To dobra praktyka, bo nie udostępniasz serwera nazw szerzej, niż jest to potrzebne.

Po zmianach sprawdź składnię plików dns, jeśli będą jakieś błędy wówczas poniższe polecenie zwróci błędy:

sudo named-checkconf

Jeśli nie ma żadnych błędów, zrestartuj usługę bind9 poniższym poleceniem:

sudo systemctl restart bind9

Konfiguracja strefy nadrzędnej na Debianie


Definicja strefy firma.local

Na Debianie, który będzie serwerem master, dodaj strefę w pliku /etc/bind/named.conf.local:

zone "firma.local" {  
    type master;  
    file "/etc/bind/db.firma.local";  
    allow-transfer { 172.16.20.11; };  
    notify yes;  
    also-notify { 172.16.20.11; };  
};

Ta konfiguracja mówi BIND-owi, że:

  • Debian jest serwerem master dla strefy firma.local,
  • plik strefy znajduje się w /etc/bind/db.firma.local,
  • Ubuntu może pobierać transfer strefy,
  • po zmianach Debian wyśle powiadomienie do serwera podrzędnego.

Tworzenie pliku strefy

Tworzymy wcześniej zadeklarowany plik db.firma.local:

touch /etc/bind/db.firma.local

Następnie edytuj go wklejając poniższą zawartość

$TTL    604800  
@       IN      SOA     dns1.firma.local. admin.firma.local. (  
				              3            ; Serial  
                              604800       ; Refresh  
                              86400        ; Retry  
                              2419200      ; Expire  
                              604800 )     ; Negative Cache TTL  
  
@       IN      NS      dns1.firma.local.  
@       IN      NS      dns2.firma.local.  
  
dns1    IN      A       172.16.10.1  
dns2    IN      A       172.16.20.11  
  
debian  IN      A       172.16.10.1  
ubuntu  IN      A       172.16.20.11  
centos  IN      A       172.16.20.1  
  
cl1     IN      A       172.16.10.10  
cl2     IN      A       172.16.20.10

W tym pliku:

  • SOA opisuje podstawowe informacje o strefie,
  • NS wskazują serwery nazw,
  • rekordy A mapują nazwy hostów na adresy IPv4.

Warto od razu zwrócić uwagę na numer seryjny Serial. To on decyduje, czy serwer podrzędny uzna, że strefa na masterze jest nowsza i czy ma pobrać jej aktualną wersję.

Sprawdzenie poprawności strefy

Przed restartem usługi sprawdź konfigurację:

named-checkzone firma.local /etc/bind/db.firma.local

Jeśli wynik nie pokazuje błędów, zrestartuj usługę:

sudo systemctl restart bind9

Na CL1 to dobry moment, żeby sprawdzić, czy sam master odpowiada poprawnie, zanim przejdziesz do konfiguracji serwera slave. W ustawieniach karty sieciowej ustaw najpierw DNS, z którego ma korzystać klient na adres serwera master.

Najprostszym sposobem będzie użycie polecenia ping. Serwer master powinien odpowiedzieć, ponieważ jest już wstępnie skonfigurowany. Serwer podrzędny na ten moment nie odpowie, ponieważ nie skonfigurowaliśmy jeszcze na nim strefy.

Konfiguracja strefy podrzędnej na Ubuntu


Definicja strefy slave

Czas na konfiguracje strefy podrzędnej. Służy do tego ten sam plik co wcześniej. Na Ubuntu edytuj plik /etc/bind/named.conf.local i dodaj w nim następującą strefę:

zone "firma.local" {  
    type slave;  
    masters { 172.16.10.1; };  
    file "/var/cache/bind/db.firma.local";  
    masterfile-format text;  
};

Ta konfiguracja mówi, że:

  • Ubuntu jest strefą podrzędną dla strefy firma.local,
  • ma pobierać dane z Debiana pod adresem 172.16.10.1,
  • kopia strefy ma być zapisana w /var/cache/bind/db.firma.local.

Parametr masterfile-format text; jest bardzo wygodny, bo sprawia, że pobrana strefa będzie zapisana w czytelnej postaci tekstowej, a nie w mniej wygodnym formacie binarnym.

Restart usługi i sprawdzenie transferu strefy

Na Ubuntu wykonaj:

sudo named-checkconf  
sudo systemctl restart bind9

Następnie sprawdź, czy plik strefy się pojawił:

ls -l /var/cache/bind/db.firma.local

Jeżeli plik istnieje, to znaczy, że serwer podrzędny poprawnie pobrał strefę z Debiana. Możesz też wykonać test korzystając z polecenia dig i sprawdzić czy są zwracane rekordy z tej strefy.

Testowanie DNS z klientów w laboratorium


Windows CL1 jako klient mastera

Na Windows CL1 ustaw ręcznie serwer DNS na 172.16.10.1. Następnie sprawdź rozwiązywanie nazw:

nslookup dns1.firma.local 172.16.10.1  
nslookup ubuntu.firma.local 172.16.10.1  
ping ubuntu.firma.local

Windows CL1 znajduje się w tej samej sieci co Debian, więc ten test pokazuje odpowiedzi bezpośrednio z serwera master. Ponadto widać, że ping do ubuntu.firma.local również dochodzi.

Windows CL2 jako klient slave’a

Na Windows CL2 ustaw ręcznie serwer DNS na 172.16.20.11. Następnie wykonaj:

nslookup dns1.firma.local 172.16.20.11  
nslookup cl1.firma.local 172.16.20.11  
ping dns1.firma.local

U mnie w trakcie testów okazało się, że host Windows CL2 potrafił wysyłać zapytania DNS do serwera Ubuntu, ale nie otrzymywał odpowiedzi. Potwierdziłem to poleceniem tcpdump, które pokazało, że zapytania z adresu 172.16.20.10 docierają do 172.16.20.11:53, jednak odpowiedzi nie wracają do klienta.

Dodatkowo lokalny test na Ubuntu wykonany poleceniem:

dig @172.16.20.11 dns1.firma.local

zwracał poprawną odpowiedź, co oznaczało, że sama strefa DNS i usługa named działały poprawnie. Problem nie leżał więc w konfiguracji strefy firma.local, tylko w filtrowaniu ruchu sieciowego na samym serwerze slave.

W moim przypadku winowajcą okazały się aktywne reguły nftables. Po wykonaniu polecenia:

sudo nft flush ruleset

serwer Ubuntu zaczął od razu odpowiadać na zapytania DNS od klientów w sieci. Oznacza to, że aktywny ruleset nftables blokował odpowiedzi DNS

Poniższy test pokazuje, że Ubuntu jako serwer podrzędny poprawnie odpowiada klientom po swojej stronie topologii.

Dlaczego numer seryjny w strefie jest tak ważny


Żeby pokazać, po co zmienia się numer seryjny, dodaj na Debianie nowy rekord do db.firma.local, na przykład:

www     IN      A       172.16.10.1

Ale nie zmieniaj jeszcze numeru seryjnego. Zrestartuj bind na Debianie i Ubuntu, a potem sprawdź z Windowsa CL2:

ping www.firma.local

Najprawdopodobniej nowy rekord się nie pojawi, bo Ubuntu nie uznało strefy za nowszą. Teraz zwiększ numer seryjny, np. z 3 na 4.

Zrestartuj ponownie usługę na Debianie i Ubuntu. Parametr refresh jest ustawiony na 5min, po tym czasie serwer slave powinien pobrać nową wersję strefy i rekord www.firma.local zacznie się rozwiązywać.

Ten przykład pokazuje, że w DNS nie wystarczy tylko zmienić plik strefy, trzeba jeszcze zadbać o poprawną numerację wersji.

Dodawanie rekordów A i CNAME

Załóżmy, że chcesz utworzyć rekordy dla usług działających pod nazwami:

Do takiej konfiguracji najczęściej wykorzystuje się rekordy A i CNAME. Rekord A wskazuje bezpośrednio adres IPv4 hosta, dlatego używa się go wtedy, gdy dana nazwa ma prowadzić wprost do konkretnego serwera. Rekord CNAME nie przechowuje adresu IP, tylko tworzy alias do innej nazwy DNS, dzięki czemu kilka różnych nazw może wskazywać tę samą usługę bez konieczności duplikowania adresów.

W praktyce jest to bardzo wygodne. Jeśli przykładowo Twoja aplikacja działa fizycznie na jednym serwerze, ale chcesz udostępnić ją użytkownikom pod kilkoma nazwami, wystarczy utworzyć jeden rekord A jako nazwę główną, a pozostałe nazwy dodać jako aliasy CNAME. Dzięki temu późniejsza zmiana adresu IP wymaga poprawienia tylko jednego wpisu, a nie całej grupy rekordów.

Na Debianie, w pliku /etc/bind/db.firma.local, możesz więc mieć zarówno rekordy NS dla całej strefy, jak i rekordy A/CNAME dla konkretnych usług:

sklep        IN      A       172.16.10.1  
www.sklep    IN      CNAME   sklep  
portal       IN      CNAME   sklep

Po zmianach pamiętaj o zwiększeniu numeru seryjnego i restarcie bind9:

sudo systemctl restart bind9

Po kilku minutach możesz przetestować działanie z hosta CL2:

ping sklep.firma.local  
ping www.sklep.firma.local  
ping portal.firma.local

Jeśli wszystko zostało skonfigurowane poprawnie, każda z tych nazw powinna zostać rozwiązana na ten sam adres IP.

Dodawanie rekordów MX i SRV


W pliku strefy możesz dodać również rekordy MX i SRV, które służą do bardziej praktycznych zastosowań niż zwykłe mapowanie nazwy hosta na adres IP. Rekord MX jest używany do wskazania, który serwer obsługuje pocztę dla danej domeny, natomiast rekord SRV pozwala opisać konkretną usługę działającą na określonym porcie i hoście.

Do czego służy rekord MX

Rekord MX określa, gdzie mają trafiać wiadomości e-mail dla danej domeny. Gdy ktoś wysyła pocztę na adres w domenie firma.local, serwer pocztowy najpierw sprawdza rekordy MX, aby dowiedzieć się, który host odpowiada za odbiór wiadomości.

Warto zwrócić uwagę, że rekord MX nie powinien wskazywać bezpośrednio adresu IP. Zamiast tego wskazuje nazwę hosta, a ta nazwa powinna mieć osobny rekord A lub AAAA. Dzięki temu konfiguracja jest bardziej czytelna i zgodna z typowym sposobem działania DNS.

Dodatkowo przy rekordach MX podaje się priorytet. Im niższa liczba, tym wyższy priorytet serwera. Oznacza to, że serwer z wartością 10 będzie traktowany jako główny, a serwer z wartością 20 jako zapasowy.

Do czego służy rekord SRV

Rekord SRV służy do wskazywania konkretnej usługi działającej na danym serwerze. To rozwiązanie często spotyka się przy usługach takich jak SIP, LDAP, Kerberos czy XMPP. Dzięki rekordowi SRV klient nie musi wiedzieć „na sztywno”, na jakim porcie działa dana usługa – może odczytać to bezpośrednio z DNS.

W zapisie rekordu SRV:

  • pierwsza liczba oznacza priorytet,
  • druga oznacza wagę,
  • trzecia to port,
  • na końcu podajesz host docelowy, który powinien mieć własny rekord A lub AAAA.

Na Debianie, w pliku /etc/bind/db.firma.local, możesz dodać na przykład takie wpisy:

@       IN      MX      10 mail  
mail    IN      A       172.16.20.11  
  
@       IN      MX      20 mail2  
mail2   IN      A       172.16.10.1  
  
_sip._udp       IN      SRV     10 5 5060 centos.firma.local.

Taka konfiguracja oznacza, że:

  • głównym serwerem pocztowym dla domeny firma.local jest host mail.firma.local,
  • zapasowym serwerem pocztowym jest mail2.firma.local,
  • usługa SIP działająca po UDP znajduje się na hoście centos.firma.local i nasłuchuje na porcie 5060.

W praktyce to bardzo wygodne. Jeśli kiedyś zmienisz adres IP serwera pocztowego albo centosa, wystarczy poprawić rekord A dla hosta docelowego, a nie wszystkie rekordy korzystające z tej nazwy.

Po zmianach zwiększ numer seryjny i zrestartuj bind9. Następnie z Ubuntu albo Windowsa sprawdź:

dig @172.16.20.11 firma.local MX  
dig @172.16.20.11 _sip._udp.firma.local SRV

Jeśli wszystko zostało skonfigurowane poprawnie, pierwszy test pokaże serwery pocztowe przypisane do domeny, a drugi zwróci informacje o usłudze SIP: jej priorytecie, wadze, porcie oraz hoście docelowym.

Wyłączenie zapytań rekurencyjnych


Jeśli chcesz, żeby Twój serwer DNS odpowiadał tylko za własną strefę, na przykład firma.local, a nie rozwiązywał nazw z Internetu, możesz wyłączyć rekurencje. W takiej konfiguracji serwer działa wyłącznie jako serwer autorytatywny dla własnych rekordów i nie próbuje „szukać dalej” odpowiedzi dla domen, których sam nie obsługuje.

To ważne rozróżnienie. Serwer autorytatywny zna odpowiedzi tylko dla stref, za które odpowiada, natomiast resolver rekurencyjny potrafi dodatkowo odpytwać inne serwery DNS i zwracać odpowiedzi dla nazw spoza własnej strefy, takich jak google.com. Jeśli wyłączysz rekurencje, Twój DNS nadal poprawnie odpowie na pytania o firma.local, ale odmówi rozwiązywania nazw internetowych.

Na Debianie w pliku /etc/bind/named.conf.options ustaw:

recursion no;

Na Debianie w pliku /etc/bind/named.conf.options ustaw:

sudo systemctl restart bind9

Od tego momentu klient korzystający z tego serwera powinien poprawnie rozwiązywać:

  • rekordy z domeny firma.local,
  • ale nie np. rekordów spoza własnej strefy, takich jak google.com.

Warto przetestować to dwoma poleceniami:

dig @172.16.10.1 dns1.firma.local  
dig @172.16.10.1 google.com

W pierwszym przypadku serwer powinien zwrócić poprawną odpowiedź, ponieważ jest autorytatywny dla strefy firma.local. W drugim przypadku zobaczysz brak odpowiedzi dla domeny internetowej albo komunikat podobny do tego ze screena

Warunkowe przekazywanie dalej


Załóżmy teraz, że Ubuntu ma własną, osobną strefę intranet.local, a Debian ma jedynie przekazywać zapytania dotyczące tej domeny właśnie do Ubuntu. Taka konfiguracja przydaje się wtedy, gdy jedna część infrastruktury odpowiada za własną strefę DNS, ale chcesz, aby klienci korzystający z innego serwera również mogli rozwiązywać nazwy z tej domeny.

To rozwiązanie nazywa się warunkowym przekazywaniem dalej. W praktyce oznacza to, że Debian nie musi być autorytatywny dla intranet.local i nie musi przechowywać lokalnie jej rekordów. Wystarczy, że będzie wiedział, do którego serwera ma przekazać pytanie o tę konkretną domenę.

Tworzenie strefy intranet.local na Ubuntu

Na Ubuntu, w pliku named.conf.local, dodaj definicję nowej strefy:

zone "intranet.local" {  
    type master;  
    file "/etc/bind/db.intranet.local";  
};

Następnie utwórz plik strefy: /etc/bind/db.intranet.local i dodaj do niego poniższą zawartość

$TTL    604800  
@       IN      SOA     intranet.firma.local. admin.intranet.local. (  
                              4  
                              300  
                              60  
                              2419200  
                              604800 )  
  
@       IN      NS      intranet.firma.local.  
@       IN      A       172.16.20.11  
www     IN      A       172.16.20.11

Taka konfiguracja oznacza, że Ubuntu jest serwerem autorytatywnym dla strefy intranet.local, a nazwa www.intranet.local wskazuje bezpośrednio na adres 172.16.20.11. Dzięki temu każdy klient, który zapyta o ten rekord właściwy serwer DNS, otrzyma poprawną odpowiedź.

Po zapisaniu zmian zrestartuj usługę BIND:

sudo systemctl restart bind9

Konfiguracja warunkowego forwardingu na Debianie

Warunkowe przekazywanie dalej w BIND działa w ramach obsługi zapytań rekurencyjnych. Jeśli wcześniej wyłączyliśmy rekurencję, to przed skonfigurowaniem strefy type forward trzeba ją ponownie włączyć, najlepiej tylko dla zaufanych sieci z naszego laboratorium. Tę zmianę wprowadza się w pliku /etc/bind/named.conf.options.

Zahashuj opcje rekurencji i ustaw dnssec-validation na no.

Następnie na Debianie, w pliku named.conf.local, dodaj:

zone "intranet.local" {  
    type forward;  
    forward only;  
    forwarders { 172.16.20.11; };  
};

Taki wpis mówi Debianowi, że nie ma samodzielnie odpowiadać za strefę intranet.local, tylko ma przekazywać wszystkie pytania o tę domenę do serwera Ubuntu. Parametr forward only oznacza, że Debian nie będzie próbował szukać odpowiedzi inną drogą – jeśli Ubuntu nie odpowie, zapytanie zakończy się niepowodzeniem.

Po zapisaniu zmian zrestartuj usługę DNS. Jeśli konfiguracja jest poprawna, Debian przekaże zapytanie do Ubuntu, a klient otrzyma odpowiedź tak, jakby Debian znał tę strefę lokalnie.

Forwardery do Internetu


Forwardery działają podobnie do warunkowego przekazywania dalej, ale zamiast jednej konkretnej domeny dotyczą wszystkich nazw, których serwer nie potrafi rozwiązać samodzielnie. Dzięki temu Debian może obsługiwać lokalną strefę firma.local, a jednocześnie przekazywać pytania o domeny internetowe do zewnętrznych resolverów.

To przydatne wtedy, gdy chcesz, aby jeden serwer DNS był centralnym punktem dla klientów w sieci. W takim układzie hosty pytają tylko Debiana, a on w razie potrzeby pyta dalej publiczne serwery DNS.

Konfiguracja forwarderów na Debianie

Jeśli chcesz, aby Debian przekazywał pozostałe zapytania do zewnętrznych resolverów, dodaj w named.conf.options:

forwarders {  
    1.1.1.1;  
    9.9.9.9;  
};

Po zapisaniu zmian zrestartuj usługę bind9. Od tego momentu Debian będzie przekazywał zapytania o domeny zewnętrzne do wskazanych resolverów.

Testowanie forwarderów

Teraz możesz przetestować z klienta:

dig @172.16.10.1 bank.pl

Jeśli odpowiedź zostanie zwrócona poprawnie, oznacza to, że Debian nie rozwiązał tej nazwy samodzielnie, tylko przekazał pytanie do jednego z forwarderów. W praktyce właśnie tak często działa lokalny DNS w małych firmach – obsługuje własne strefy, a resztę pytań przekazuje dalej.

Strefa wyszukiwania odwrotnego (reverse DNS)


DNS może działać nie tylko w kierunku nazwa → adres IP, ale również odwrotnie, czyli adres IP → nazwa hosta. Taki mechanizm nazywa się reverse DNS i opiera się na rekordach PTR.

Reverse DNS nie jest wymagany do zwykłego działania pingu po nazwie czy podstawowego routingu. Jest jednak bardzo przydatny tam, gdzie adres IP sam w sobie niewiele mówi, a nazwa hosta pozwala szybciej zrozumieć, z jaką maszyną masz do czynienia.

Dla sieci 172.16.10.0/24 na Debianie dodaj do pliku named.conf.local definicję strefy odwrotnej:

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

Nazwa 10.16.172.in-addr.arpa wynika z odwrócenia oktetów sieci 172.16.10.0. W strefach reverse DNS zapisuje się adresację właśnie w takiej postaci.

Następnie utwórz plik strefy odwrotnej /etc/bind/db.172.16.10. W pliku strefy umieść poniższą zawartość:

$TTL    604800  
@       IN      SOA     dns1.firma.local. admin.firma.local. (  
                              5  
                              300  
                              60  
                              2419200  
                              604800 )  
  
@       IN      NS      dns1.firma.local.  
  
1       IN      PTR     dns1.firma.local.  
10      IN      PTR     cl1.firma.local.

Taka konfiguracja oznacza, że:

  • adres 172.16.10.1 ma być rozwiązywany jako dns1.firma.local
  • adres 172.16.10.10 ma być rozwiązywany jako cl1.firma.local

W reverse DNS nie wpisujesz całego adresu IP, tylko ostatni oktet hosta, ponieważ sama sieć została już określona w nazwie strefy 10.16.172.in-addr.arpa.

Testujemy w systemie windowsowym za pomocą polecenia nslookup czy adresy są rozwiązywane na nazwy

Po zapisaniu pliku tradycyjnie zrestartuj usługę DNS. Przetestuj w systemie windowsowym CL1 za pomocą polecenia nslookup czy adresy są rozwiązywane na nazwy

You may also like

Leave a Comment