Bądź na bieżąco - RSS

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

28 lutego, 2026 | Brak Komentarzy | Kategoria: Linux, Porady

BIND9 w Dockerze

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

  • 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/bind z hosta, jeśli nie kopiujesz plików systemowych —
    wtedy najczęściej „znika” named.conf.default-zones i zones.rfc1918.
  • Zawsze ogranicz rekurencję (allow-recursion, allow-query-cache) do intranetu.
  • Jeśli master wysyła NOTIFY, dodaj allow-notify tylko z IP mastera.
  • Chcesz twardsze bezpieczeństwo? Kolejny krok to TSIG między master ↔ secondary.

G

Tagi: , , ,