BIND9 w Dockerze jako secondary DNS i cache DNS – schemat działania

BIND9 w Dockerze może działać jednocześnie jako secondary DNS (slave) dla Twoich stref oraz jako cache DNS (rekurencja + cache) dla intranetu. Poniżej dostajesz gotowy, praktyczny setup oparty o obraz ubuntu/bind9:latest z konfiguracją w jednym pliku (named.conf) oraz danymi przykładowymi (zanonimizowanymi).
Najważniejsze założenie bezpieczeństwa: rekurencja działa wyłącznie dla zaufanych sieci, żeby serwer nie stał się otwartym resolverem.
Spis treści
- Wymagania
- Katalogi na hoście
- named.conf – secondary DNS + cache DNS w jednym pliku
- Uruchomienie kontenera
- Uprawnienia (UID/GID bind)
- Testy działania
- Tipy i pułapki
Wymagania
- Docker na serwerze (Linux).
- Porty 53/TCP i 53/UDP dostępne w sieci, z której pytają klienci.
- Na master DNS masz włączone transfery stref (AXFR/IXFR) dla secondary.
- Znasz sieci intranet/VPN, które mają prawo do rekurencji.
Uwaga o anonimizacji: w przykładach używam domen typu corp.example i adresów z puli dokumentacyjnej (192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24). Podmień na własne.
Katalogi na hoście
Trzymamy na hoście jeden plik konfiguracyjny oraz osobno cache i pliki stref slave.
sudo mkdir -p /srv/bind9
sudo mkdir -p /srv/bind9/cache
sudo mkdir -p /srv/bind9/cache/slaves
sudo nano /srv/bind9/named.conf
named.conf – secondary DNS + cache DNS w jednym pliku
Poniżej kompletna konfiguracja: ACL, rekurencja/caching, forwardery oraz strefy typu slave. Wszystko jest krótkie liniowo i nie „wyjeżdża” poza ramkę.
// /srv/bind9/named.conf
// BIND9: secondary DNS (slave) + cache DNS
// Dane przykładowe (zanonimizowane) – podmień na własne.
acl "trusted" {
127.0.0.1;
10.10.0.0/16;
192.168.50.0/24;
};
options {
directory "/var/cache/bind";
// Rekurencja i cache tylko dla intranetu
recursion yes;
allow-query { trusted; };
allow-recursion { trusted; };
allow-query-cache { trusted; };
// Forwardery upstream (przykładowe IP)
forwarders {
203.0.113.53;
198.51.100.53;
};
forward only;
dnssec-validation auto;
listen-on { any; };
listen-on-v6 { any; };
auth-nxdomain no;
};
// RFC1918 (standardowy plik w obrazie)
include "/etc/bind/zones.rfc1918";
// ---- Strefy secondary (slave) ----
zone "corp.example" {
type slave;
file "/var/cache/bind/slaves/db.corp.example";
masters { 203.0.113.10; };
allow-notify { 203.0.113.10; };
};
zone "50.168.192.in-addr.arpa" {
type slave;
file "/var/cache/bind/slaves/db.192.168.50";
masters { 203.0.113.10; };
allow-notify { 203.0.113.10; };
};
// Domyślne strefy (krótki include zamiast inline’owania długich nazw)
include "/etc/bind/named.conf.default-zones";
// Minimalne logowanie (ciszej)
logging {
category lame-servers { null; };
category edns-disabled { null; };
};
Dlaczego tak? To nadal jest „jednoplikowa konfiguracja” w sensie: wszystko, co konfigurujesz (secondary + cache), jest w jednym pliku. A długie, systemowe definicje default-zones zostają w obrazie — dzięki temu unikasz linii, których nie da się sensownie złamać.
Uruchomienie kontenera
Najważniejsze: montujemy tylko named.conf (read-only) oraz katalog cache. Dzięki temu pliki systemowe (named.conf.default-zones, zones.rfc1918, bazy db.*) zostają w kontenerze i nie musisz ich kopiować na hosta.
docker run -d \
--name bind9-container \
--restart unless-stopped \
-e TZ=Europe/Warsaw \
-p 53:53/tcp \
-p 53:53/udp \
-v /srv/bind9/named.conf:/etc/bind/named.conf:ro \
-v /srv/bind9/cache:/var/cache/bind \
ubuntu/bind9:latest
Jeśli wolisz Compose:
services:
bind9:
image: ubuntu/bind9:latest
container_name: bind9-container
restart: unless-stopped
environment:
- TZ=Europe/Warsaw
ports:
- "53:53/tcp"
- "53:53/udp"
volumes:
- /srv/bind9/named.conf:/etc/bind/named.conf:ro
- /srv/bind9/cache:/var/cache/bind
Uprawnienia (UID/GID bind)
Secondary zapisuje pliki stref do cache. Jeśli brakuje praw, zobaczysz błędy typu „permission denied”. Sprawdź UID/GID użytkownika bind w kontenerze i ustaw właściciela katalogu cache na hoście.
docker exec -it bind9-container id bind
Przykład (u Ciebie może być inny):
uid=101(bind) gid=101(bind) groups=101(bind)
Ustaw właściciela (podmień UID:GID z wyniku):
sudo chown -R 101:101 /srv/bind9/cache
docker restart bind9-container
Testy działania
1) Sprawdzenie składni
docker exec -it bind9-container \
named-checkconf /etc/bind/named.conf
2) Czy strefy slave się pobrały?
ls -la /srv/bind9/cache/slaves
docker logs --since=10m bind9-container
3) Test secondary (autorytatywnie)
dig @192.0.2.53 corp.example SOA \
+noall +answer
4) Test cache DNS (rekurencja)
dig @192.0.2.53 example.org A +stats
dig @192.0.2.53 example.org A +stats
Tipy i pułapki
- Nie montuj całego
/etc/bindz hosta, jeśli nie kopiujesz plików systemowych —
wtedy najczęściej „znika”named.conf.default-zonesizones.rfc1918. - Zawsze ogranicz rekurencję (
allow-recursion,allow-query-cache) do intranetu. - Jeśli master wysyła NOTIFY, dodaj
allow-notifytylko z IP mastera. - Chcesz twardsze bezpieczeństwo? Kolejny krok to TSIG między master ↔ secondary.
G
Tagi: DNS, Docker, konteryzacja, Linux