--- title: "Host je eigen DNS server in je labo" excerpt: "Een labo is heel leuk maar het wordt nog veel leuker als je lokaal een eigen DNS server hebt." date: "2023-10-18T12:00:00.000Z" author: Eli Winderickx hero_image: /Bind_Cover.png category: Bind,DNS,Linux --- ## Waarom willen we een eigen DNS server? Het is heel leuk als we onze eigen Gitlab server of Zabbix opzetten. Maar als alleenstaande installaties hebben we er niet zo veel aan. We kunnen wel in alle servers de `hosts` bestanden gaan aanpassen tot een paar servers. Daarna wordt het eigenlijk niet meer beheerbaar. Iedere server moet een entry krijgen en moet up to date gehouden worden. De DNS server kan ons niet alleen helpen om het beheer van die IP-adressen te centraliseren. Daarnaast is het ook fijn om met hostnamen te kunnen werken. Die onthouden toch iets beter dan een reeks IP-adressen. Een populaire keuze in de Linux wereld voor DNS is BIND. ## Installatie We hebben twee onderdelen nodig om deze service op te zetten: ```bash sudo dnf install bind bind-utils -y ``` Dit installeert de `named` service. Configuratie kan gemaakt worden in `/etc/named.conf`. Daar gaan we nu de configuratie doorvoeren. ## Configuratie Eerst moeten we instellen via welke weg we configuratie beschikbaar willen stellen. De poort staat vaak al goed. Daarnaast moeten we het IP-adres van de server nog toevoegen alsook wie verzoeken mag sturen. Hier heeft mijn server het IP-adres `192.168.124.115`. Andere servers in mijn labo bevinden zich in hetzelfde subnet dus die mogen verzoeken sturen; `192.168.124.0/24` ``` ... listen-on port 53 { 127.0.0.1; 192.168.124.115; }; ... allow-query { localhost; 192.168.124.0/24; } ``` Onderaan dat bestand kunnen we dan aangeven welke zones we gaan aanbieden. Doe dat net boven de `include` regel. Per zone kan je een domein configureren. Hier gaan we twee entries voorzien. De eerste is voor het forward domain zone en de tweede is voor de reverse DNS. Onthou goed wat je onder `file` noteert. Dat worden de namen van de bestanden voor de volgende stap. ``` ... zone "winderickx.me" IN { type master; file "forward.winderickx.me"; allow-update { none; }; }; zone "124.168.192.in-addr.arpa" IN { type master; file "reverse.winderickx.me"; allow-update { none; }; }; include "/etc/named.rfc1912.zones"; ... ``` Nu deze configuratie klaar staat, kunnen we de effectieve data invullen in de bestanden die we in de vorige stap hebben ingegeven. Deze bestanden staan standaard in `/var/named` map. > Domeinnamen in DNS eindigen altijd met een . om duidelijk het TLD (Top Level Domain) aan te geven. `forward.winderickx.me` ``` $TTL 86400 @ IN SOA dns.winderickx.me. root.winderickx.me. ( 2011071001 ;Serial 3600 ;Refresh 1800 ;Retry 604800 ;Expire 86400 ;Minimum TTL ) @ IN NS dns.winderickx.me. @ IN A 192.168.124.99 dns IN A 192.168.124.115 IN A ``` `reverse.winderickx.me` ``` $TTL 86400 @ IN SOA dns.winderickx.me. root.winderickx.me. ( 2011071001 ;Serial 3600 ;Refresh 1800 ;Retry 604800 ;Expire 86400 ;Minimum TTL ) @ IN NS dns.winderickx.me. @ IN PTR winderickx.me. dns IN A 192.168.1.115 115 IN PTR dns.winderickx.me. IN PTR . ``` Zorg er voor dat de named groep rechten heeft op het bestand. ```bash sudo chgrp named -R /var/named ``` > Vergeet niet de firewall aan te passen! ```bash sudo firewall-cmd --add-service=dns --permanent sudo firewall-cmd --reload ``` Controleer nu de configuratie. ```bash sudo named-checkconf /etc/named.conf sudo named-checkzone /var/named/forward.winderickx.me sudo named-checkzone /var/named/reverse.winderickx.me ``` Als daar geen fouten uitkomen, kan je nu de service starten. ```bash sudo systemctl restart named ``` ## Client configuratie We gaan er even van uit dat je gebruik maakt van `NetworkManager` voor jouw netwerk configuratie. Dit kan je dan gebruiken om jouw nieuwe DNS in te stellen op alle hosts. > Hier gebruik ik de connectie `enp1s0` om de aanpassingen op uit te voeren. Om te weten te komen welke connectie voor jou actief staat, voer dan `ip -br a` uit. ```bash sudo nmcli c m enp1s0 ipv4.dns "192.168.124.115" sudo nmcli c m enp1s0 ipv4.ignore-auto-dns yes sudo systemctl restart NetworkManager ``` Als dat goed gelukt is, ga je dit IP-adres terugvinden in `/etc/resolv.conf`. Dit is namelijk de plaats waar Linux de DNS server verwacht. Heb je dus geen `NetworkManager`, dan kan je ook hier manueel het IP-adres aanpassen. ## En nu Ansible! Omdat we productief lui zijn, doen we dit proces liefst zo automatisch mogelijk. Ik heb daarom dit hele proces ook in een Ansible playbook geschreven. Die kan je dus gewoon gebruiken. Mijn DNS server is een RHEL gebasseerde server. Als je een Debian gebasseerde server gebruikt, ga je mogelijk hinder ervaren. Je gaat nog steeds enkele bestanden moeten voorzien: - named.conf - Forward lookup bestand - reverse lookup bestand - resolv.conf Geef gerust een seintje via [LinkedIn](https://www.linkedin.com/in/eliwinderickx/) als je vast zit met deze bestanden. ```yml --- - name: Install DNS server hosts: dns vars: packages: - bind - bind-utils - firewalld tasks: - name: Install the required software ansible.builtin.dnf: name: "{{ item }}" state: latest loop: "{{ packages }}" - name: Enable and start firewall service ansible.builtin.service: name: firewalld state: started enabled: true - name: Allow DNS traffic on firewall ansible.posix.firewalld: service: dns state: enabled permanent: true immediate: true - name: Configure the BIND service ansible.builtin.copy: src: named.conf dest: /etc/named.conf owner: root group: named mode: 0640 notify: restart bind service - name: Prepare DNS zone files ansible.builtin.copy: src: "{{ item }}" dest: "/var/named/{{ item }}" owner: root group: named mode: 0644 loop: - forward.winderickx.me - reverse.winderickx.me notify: restart bind service handlers: - name: restart bind service ansible.builtin.service: name: named state: restarted - name: Configure DNS for hosts hosts: all vars: dns4: 192.168.124.115 conn_name: enp1s0 tasks: - name: Configure the correct DNS for the server community.general.nmcli: conn_name: "{{ conn_name }}" type: ethernet dns4: "{{ dns4 }}" dns4_ignore_auto: true state: present when: ansible_facts['distribution'] != "Debian" notify: reload NetworkManager - name: Configure the correct DNS for debian ansible.builtin.template: src: resolv.conf.j2 dest: /etc/resolv.conf owner: root group: root mode: 0644 when: ansible_facts['distribution'] == "Debian" handlers: - name: reload NetworkManager ansible.builtin.service: name: NetworkManager state: restarted ``` ## Bonus Wil je wel Ansible gebruiken maar geen eigen DNS server? Dan heb je hier een andere playbook die de inventory van jouw Ansible gebruikt om `/etc/hosts` op te vullen. Dit is een heel pak simplistischer dan heel de opzet hierboven maar we moeten bij iedere aanpassing wel deze playbook uitvoeren op ALLE servers in onze inventory en die inventory wordt ineens de `Single Source of Truth`. Hou daar dus zeker rekening mee als je toch voor deze optie gaat! `dns.yml` ```yml - name: /etc/hosts is up to date hosts: all gather_facts: yes tasks: - name: Deploy /etc/hosts ansible.builtin.template: src: templates/hosts.j2 dest: /etc/hosts ``` `hosts.j2` ```j2 {% for host in groups['all'] %} {{ hostvars[host]['ansible_facts']['default_ipv4']['address'] }} {{ hostvars[host]['ansible_facts']['fqdn'] }} {{ hostvars[host]['ansible_facts']['hostname'] }} {% endfor %} ```