Host je eigen DNS server in je labo
Oct 18 2023
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:
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
<servers> IN A <IP-adressen>
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.
<laatste octet van IP> IN PTR <Servers>.
Zorg er voor dat de named groep rechten heeft op het bestand.
sudo chgrp named -R /var/named
Vergeet niet de firewall aan te passen!
sudo firewall-cmd --add-service=dns --permanent
sudo firewall-cmd --reload
Controleer nu de configuratie.
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.
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 danip -br a
uit.
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 als je vast zit met deze bestanden.
---
- 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
- 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
{% for host in groups['all'] %}
{{ hostvars[host]['ansible_facts']['default_ipv4']['address'] }} {{ hostvars[host]['ansible_facts']['fqdn'] }} {{ hostvars[host]['ansible_facts']['hostname'] }}
{% endfor %}