Skip to main content

Nový Návod: Redundantní DNS Servery (Pi-hole + Unbound) na Raspberry Pi 5 s Automatickou Synchronizací

Nový Návod: Redundantní DNS Servery (Pi-hole + Unbound) na Raspberry Pi 5 s Automatickou Synchronizací

Tento návod ti pomůže nastavit dva nezávislé DNS servery, které se budou navzájem zálohovat a udržovat synchronizovanou konfiguraci. Získáš tak maximální dostupnost a spolehlivost blokování reklam a bezpečné DNS resolvingu ve tvé síti.

 

Cílová architektura:

 

  • Primární server (DNS1): Raspberry Pi 5 s IP adresou 192.168.54.2

  • Sekundární server (DNS2): Raspberry Pi 5 s IP adresou 192.168.54.3

  • Oba servery: Každý poběží Pi-hole a Unbound v Docker kontejnerech. Unbound bude fungovat jako rekurzivní resolver, Pi-hole jako ad-blocker.

  • Synchronizace: Konfigurace Pi-hole (blacklisty, whitelisty, adlisty) se bude automaticky synchronizovat z DNS1 na DNS2 pomocí rsync přes SSH.

  • Časová synchronizace: Operační systémy na obou RPi budou synchronizovat čas s robustní sadou českých NTP serverů pro optimální spolehlivost DNSSEC.


 

Předpoklady (Pro oba Raspberry Pi):

 

Než začneme, ujisti se, že pro oba Raspberry Pi máš splněno následující:

  • Dvě Raspberry Pi 5: Každé s vlastní SD kartou/SSD (doporučeno pro rychlost a životnost).

  • 64-bitový Raspberry Pi OS Lite (nebo Desktop): Nainstalovaný a aktualizovaný.

  • Statické IP adresy:

    • DNS1: 192.168.54.2

    • DNS2: 192.168.54.3

    • Ujisti se, že tyto IP adresy jsou mimo rozsah DHCP serveru tvého routeru, aby nedošlo ke kolizi.

  • SSH přístup: Povoleno a funkční na obou RPi.

  • Uživatel s sudo právy: Na obou RPi (např. výchozí uživatel pi).

  • Nainstalovaný Docker a Portainer: Postup pro instalaci Dockeru a Portaineru najdeš v původním návodu na Zelina.eu, případně zde je rychlý postup:

# Instalace Dockeru
curl -sSL https://get.docker.com | sh
sudo usermod -aG docker pi # Přidej uživatele 'pi' do skupiny docker pro práci bez sudo
newgrp docker # Nebo se odhlas a znovu prihlas

# Instalace Docker Compose pluginu
sudo apt install -y docker-compose-plugin

# Instalace Portaineru
docker volume create portainer_data
docker run -d -p 9000:9000 -p 9443:9443 --name portainer --restart always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest

Po instalaci Portaineru se k němu připoj přes prohlížeč (např. https://192.168.54.2:9443) a dokonči jeho prvotní nastavení.

Krok 1: Základní Příprava Systému (Oba Raspberry Pi)

 

Opakuj tento krok pro oba servery (DNS1 a DNS2).

  1. Přihlas se přes SSH k danému Raspberry Pi.

  2. Aktualizuj systém a nainstaluj základní nástroje:

sudo apt update && sudo apt upgrade -y
sudo apt install -y wget rsync nano

Vytvoř adresáře pro data Pi-hole a Unbound:

sudo mkdir -p /opt/unbound/etc/unbound/
sudo mkdir -p /opt/pihole/etc-pihole/
sudo mkdir -p /opt/pihole/etc-dnsmasq.d/

Stáhni root.hints soubor pro Unbound:

sudo wget -O /opt/unbound/etc/unbound/root.hints https://www.internic.net/domain/named.root

 

  1. Tento soubor je nezbytný pro rekurzivní DNS, protože obsahuje adresy kořenových DNS serverů.


 

Krok 2: Konfigurace NTP Časové Synchronizace (Oba Raspberry Pi)

 

Toto je klíčové pro DNSSEC. Zajistíme, že oba servery budou mít vždy přesný čas synchronizovaný s ověřenými českými a evropskými NTP servery.

Opakuj pro oba servery (DNS1 a DNS2).

  1. Otevři konfigurační soubor timesyncd:

sudo nano /etc/systemd/timesyncd.conf

Uprav nebo přidej následující řádky do sekce [Time] (odkomentuj NTP= a přidej servery):

[Time]
NTP=ntp.cesnet.cz tik.cesnet.cz tak.cesnet.cz 0.cz.pool.ntp.org 1.cz.pool.ntp.org 2.cz.pool.ntp.org 0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org
FallbackNTP=time.google.com time.cloudflare.com
    • NTP: Zde jsou preferované české a obecné pool.ntp.org servery.

    • FallbackNTP: Záložní servery pro případ, že by české nebyly dostupné.

  • Ulož a zavři soubor (Ctrl+X, Y, Enter).

  • Restartuj službu systemd-timesyncd:

sudo systemctl restart systemd-timesyncd

Ověř stav synchronizace:

timedatectl status

 

  1. Měl bys vidět:

    • System clock synchronized: yes

    • NTP service: active

    • Případně RTC in local TZ: no je v pořádku.


 

Krok 3: Unbound Konfigurace (Oba Raspberry Pi)

 

Toto je konfigurace rekurzivního resolveru. Bude identická pro oba servery.

Opakuj pro oba servery (DNS1 a DNS2).

  1. Vytvoř konfigurační soubor Unboundu:

sudo nano /opt/unbound/etc/unbound/unbound.conf

Vlož následující obsah:

server:
    # Povoluje přístup z localhostu a Docker sítě
    access-control-oresolved: 127.0.0.1/32 allow
    access-control-oresolved: 172.20.0.0/24 allow # Pro Docker síť

    # Základní nastavení
    verbosity: 1
    port: 5335 # Unbound bude naslouchat na tomto portu, Pi-hole ho bude používat

    # Soukromí a bezpečnost
    do-not-query-localhost: no # Nezbytné pro Unbound uvnitř Dockeru
    hide-identity: yes
    hide-version: yes
    harden-glue: yes
    harden-dnssec-stripped: yes
    use-caps-for-id: yes
    edns-buffer-size: 1472
    prefetch: yes # Zlepšuje výkon přednačítáním
    num-threads: 2 # Počet vláken, pro RPi5 můžeš zkusit i 4 pro max. výkon
    # Optimalizace cache (přizpůsobeno pro RPi5 s dostatkem RAM)
    msg-cache-size: 128m # Velikost cache pro DNS zprávy
    rrset-cache-size: 256m # Velikost cache pro DNS záznamy (doporučeno min 2x msg-cache)
    cache-min-ttl: 3600 # Minimální TTL pro záznamy v cache (1 hodina)
    cache-max-ttl: 86400 # Maximální TTL pro záznamy v cache (24 hodin)
    do-tcp: yes
    do-udp: yes

    # Rebinding ochrana (velmi důležité pro domácí sítě)
    private-address: 192.168.0.0/16
    private-address: 10.0.0.0/8
    private-address: 172.16.0.0/12

    # Logging
    log-queries: no
    log-replies: no

    # DNSSEC
    auto-trust-anchor-file: "/etc/unbound/root.hints"
    • num-threads: Pro RPi5 můžeš zkusit num-threads: 4 pro využití všech jader, ale 2 je bezpečný výchozí bod.

    • msg-cache-size a rrset-cache-size: Tyto hodnoty jsou vhodné pro RPi5 s jeho RAM.

  1. Ulož a zavři soubor.


 

Krok 4: Deployment Pi-hole & Unbound Stacku (Oba Raspberry Pi)

 

Použijeme Portainer k nasazení Docker stacku.

Opakuj pro oba servery (DNS1 a DNS2).

  1. Přihlas se do Portaineru (https://<IP_ADRESA_RPi>:9443).

  2. Přejdi na Stacks > Add stack.

  3. Pojmenuj stack například dns-resolver.

  4. Zkopíruj následující docker-compose.yml kód do webového editoru Portaineru. DŮLEŽITÉ: V ports sekci Pi-hole změň IP adresu na skutečnou IP adresu daného RPi, na kterém stack nasazuješ (tedy 192.168.54.2 pro DNS1 a 192.168.54.3 pro DNS2).

version: "3.8"

services:
  unbound:
    container_name: unbound
    image: mvance/unbound:latest
    restart: unless-stopped
    networks:
      dns_network:
        ipv4_address: 172.20.0.10
    volumes:
      - /opt/unbound/etc/unbound:/etc/unbound/
    command: -c /etc/unbound/unbound.conf
    healthcheck:
      test: ["CMD", "unbound-control", "healthcheck"]
      interval: 10s
      timeout: 5s
      retries: 3
    environment:
      TZ: Europe/Prague # Nebo tvá časová zóna
    ports:
      - "5335:5335/tcp" # Interní port pro Pi-hole, externí pro Unbound (pro testování)
      - "5335:5335/udp"

  pihole:
    container_name: pihole
    image: pihole/pihole:latest
    restart: unless-stopped
    networks:
      dns_network:
        ipv4_address: 172.20.0.11 # Interní IP pro Pi-hole
    ports:
      # --- DŮLEŽITÉ: ZDE ZMĚŇ IP ADRESU NA AKTUÁLNÍ IP RASPBERRY PI ---
      # Příklad pro DNS1: "192.168.54.2:53:53/tcp"
      # Příklad pro DNS2: "192.168.54.3:53:53/tcp"
      - "TVOJE_IP_RPi:53:53/tcp"
      - "TVOJE_IP_RPi:53:53/udp"
      - "TVOJE_IP_RPi:80:80/tcp" # Webové rozhraní Pi-hole (HTTP)
      # Pokud máš reverzní proxy pro HTTPS (doporučeno), nemusíš mapovat port 443 zde
      # Tvá reverzní proxy se bude starat o 443 a přesměrování na port 80 Pi-hole.
      # - "TVOJE_IP_RPi:443:443/tcp" # Povolení portu, ale vyžaduje další konfiguraci SSL/TLS certifikátů
      - "67:67/udp" # Pouze pro DHCP, pokud jej budeš používat
    environment:
      TZ: Europe/Prague # Nebo tvá časová zóna
      WEBPASSWORD: "TvéSilnéHesloPihole" # Změň na silné a komplexní heslo!
      DNSMASQ_LISTENING: "all"
      PIHOLE_DNS_: "172.20.0.10#5335" # Přeposílání dotazů na interní Unbound
      DNSSEC: "true"
      REV_SERVER: "true" # Povolí Conditional Forwarding pro lokální jména
      REV_SERVER_CIDR: "192.168.54.0/24" # Změň na rozsah TVÉ LOKÁLNÍ SÍTĚ! (např. 192.168.1.0/24)
      REV_SERVER_TARGET: "192.168.54.1" # IP adresa tvého routeru (nebo lokálního DHCP serveru)
      REV_SERVER_DOMAIN: "local" # Tvůj lokální doménový název (např. .local, .lan)
      # NTP servery pro Pi-hole - české a záložní
      PIHOLE_NTP_SERVERS: "ntp.cesnet.cz,tik.cesnet.cz,tak.cesnet.cz,0.cz.pool.ntp.org,1.cz.pool.ntp.org,2.cz.pool.ntp.org,0.pool.ntp.org,1.pool.ntp.org,2.pool.ntp.org"
    volumes:
      - /opt/pihole/etc-pihole/:/etc/pihole/
      - /opt/pihole/etc-dnsmasq.d/:/etc/dnsmasq.d/
    depends_on:
      - unbound

networks:
  dns_network:
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.0.0/24 # Interní Docker síť pro kontejnery

  1. Pečlivě zkontroluj a uprav:

    • TVOJE_IP_RPi: Změň na 192.168.54.2 pro DNS1 a 192.168.54.3 pro DNS2!

    • WEBPASSWORD: Nastav silné heslo pro webové rozhraní Pi-hole.

    • TZ: Nastav svou správnou časovou zónu (např. Europe/Prague).

    • REV_SERVER_CIDR: Změň na rozsah TVÉ DOMÁCÍ SÍTĚ, kde jsou tvá zařízení (např. 192.168.54.0/24 je tvoje síť).

    • REV_SERVER_TARGET: Nastav na IP adresu TVÉHO ROUTERU nebo lokálního DHCP serveru (většinou brána sítě, např. 192.168.54.1).

    • REV_SERVER_DOMAIN: Nastav lokální doménový název (např. local).

  2. Klikni na "Deploy the stack" v Portaineru na obou RPi.


 

Krok 5: Konfigurace Pi-hole (Pouze na Primárním Serveru DNS1)

 

Tento krok provádíš POUZE na primárním serveru (DNS1 - 192.168.54.2). Všechny provedené změny se později synchronizují na sekundární server.

  1. Přihlas se do webového rozhraní Pi-hole: http://192.168.54.2/admin

  2. Přidej blacklisty:

    • V Pi-hole UI jdi do Group Management > Adlists.

    • Přidej doporučené české a slovenské seznamy, např.:

      • https://raw.githubusercontent.com/notracking/tr-ads-and-tracking/master/all.txt

      • https://raw.githubusercontent.com/jdcasey/pihole-blocklist-czech-and-slovak/main/cz-sk-ads.txt

    • Přidej také robustní globální seznamy jako OISD:

      • https://https://raw.githubusercontent.com/oisd/abp/master/abp.txt

    • Nezapomeň na security listy pro malware/viry! Např. z Firebog.net (výběr úrovně Ticked nebo Non-tracked je dobrý start).

    • Důležité: Přidávej seznamy postupně a testuj! Přehnané blokování může způsobit problémy s některými weby.

    • Po přidání všech seznamů klikni na Save.

  3. Aktualizuj Gravity:

    • Jdi na Tools > Update Gravity.

    • Klikni na Update. Tím se stáhnou a aktivují nově přidané seznamy.

  4. Další nastavení (volitelné): Můžeš přidat vlastní domény na Whitelist/Blacklist, nastavit skupiny klientů, prohlédnout si logy atd.


 

Krok 6: Synchronizace Pi-hole Konfigurace (Primární DNS1 -> Sekundární DNS2)

 

Toto je srdce redundance. Nastavíme automatickou synchronizaci pomocí rsync a cron.

Tento krok provádíš POUZE na primárním serveru (DNS1 - 192.168.54.2).

  1. Nastavení SSH klíčů pro bezpečný rsync bez hesla:

    • Přihlas se přes SSH na DNS1 (192.168.54.2).

    • Vygeneruj SSH klíč (pokud ještě nemáš, stiskni Enter pro výchozí cesty a bez heslové fráze):

ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_pihole_sync -N ""

Zkopíruj veřejný klíč na sekundární RPi (DNS2 - 192.168.54.3). Nahraď pi svým uživatelským jménem na DNS2 (pokud jsi ho nezměnil, pi je výchozí):

ssh-copy-id -i ~/.ssh/id_rsa_pihole_sync.pub pi@192.168.54.3
    • Při prvním spuštění budeš muset zadat heslo pro uživatele pi na DNS2. Poté už se nebude vyžadovat.

  • Vytvoření synchronizačního skriptu:

    • Vytvoř nový skript na DNS1 (např. /home/pi/sync_pihole.sh):

nano /home/pi/sync_pihole.sh

Vlož následující obsah:

#!/bin/bash

# Adresáře s daty Pi-hole na primárním serveru
PRIMARY_PIHOLE_DIR="/opt/pihole/etc-pihole"
PRIMARY_HOLE_DB="${PRIMARY_PIHOLE_DIR}/pihole-FTL.db"
PRIMARY_GRAVITY_DB="${PRIMARY_PIHOLE_DIR}/gravity.db"
PRIMARY_DNSMASQ_DIR="${PRIMARY_PIHOLE_DIR}/dnsmasq.d" # Dnsmasq konfigurační soubory
PRIMARY_SETUPVARS="${PRIMARY_PIHOLE_DIR}/setupVars.conf" # Hlavní konfigurační soubor Pi-hole

# Sekundární server
SECONDARY_USER="pi" # Nahraď tvým uživatelským jménem na sekundárním RPi
SECONDARY_HOST="192.168.54.3" # IP adresa sekundárního RPi
SECONDARY_PIHOLE_DIR="/opt/pihole/etc-pihole"
SECONDARY_DNSMASQ_DIR="/opt/pihole/etc-dnsmasq.d"

# SSH klíč pro autentizaci
SSH_KEY="/home/pi/.ssh/id_rsa_pihole_sync"

echo "--- $(date '+%Y-%m-%d %H:%M:%S') - Spouštím synchronizaci Pi-hole dat z ${PRIMARY_HOST} na ${SECONDARY_HOST} ---"

# Vypnutí Pi-hole FTL na sekundárním serveru před synchronizací
echo "Zastavuji Pi-hole FTL na sekundárním serveru..."
ssh -i ${SSH_KEY} ${SECONDARY_USER}@${SECONDARY_HOST} "docker stop pihole" || { echo "Chyba zastavení pihole kontejneru na sekundárním serveru. Přeskočeno."; }

# Synchronizace klíčových databázových souborů a konfigurace
echo "Synchronizuji pihole-FTL.db..."
rsync -avz --delete -e "ssh -i ${SSH_KEY}" "${PRIMARY_HOLE_DB}" "${SECONDARY_USER}@${SECONDARY_HOST}:${SECONDARY_PIHOLE_DIR}/" || { echo "Chyba synchronizace pihole-FTL.db"; }

echo "Synchronizuji gravity.db..."
rsync -avz --delete -e "ssh -i ${SSH_KEY}" "${PRIMARY_GRAVITY_DB}" "${SECONDARY_USER}@${SECONDARY_HOST}:${SECONDARY_PIHOLE_DIR}/" || { echo "Chyba synchronizace gravity.db"; }

echo "Synchronizuji setupVars.conf..."
rsync -avz --delete -e "ssh -i ${SSH_KEY}" "${PRIMARY_SETUPVARS}" "${SECONDARY_USER}@${SECONDARY_HOST}:${SECONDARY_PIHOLE_DIR}/" || { echo "Chyba synchronizace setupVars.conf"; }

# Synchronizace vlastních DNSMasq konfiguračních souborů (pokud existují)
echo "Synchronizuji custom DNSMasq configs..."
rsync -avz --delete -e "ssh -i ${SSH_KEY}" "${PRIMARY_DNSMASQ_DIR}/" "${SECONDARY_USER}@${SECONDARY_HOST}:${SECONDARY_DNSMASQ_DIR}/" || { echo "Chyba synchronizace custom DNSMasq configs"; }

# Znovu spuštění Pi-hole FTL na sekundárním serveru a aktualizace Gravity databáze
echo "Spouštím Pi-hole FTL na sekundárním serveru a aktualizuji Gravity..."
ssh -i ${SSH_KEY} ${SECONDARY_USER}@${SECONDARY_HOST} "docker start pihole && docker exec pihole pihole -g" || { echo "Chyba spuštění pihole nebo aktualizace gravity na sekundárním serveru. Přeskočeno."; }

echo "--- $(date '+%Y-%m-%d %H:%M:%S') - Synchronizace dokončena ---"
    • Uprav:

      • SECONDARY_USER: Ujisti se, že je to správné uživatelské jméno na sekundárním RPi (většinou pi).

    • Ulož a zavři soubor.

  • Nastav spustitelná práva pro skript:

chmod +x /home/pi/sync_pihole.sh

Nastav Cron pro automatické spouštění synchronizace:

  • Otevři cron tabulku:

crontab -e
  • Přidej následující řádek na konec souboru. Tento příklad spouští synchronizaci každých 10 minut. Můžeš si interval upravit.
*/10 * * * * /home/pi/sync_pihole.sh >> /var/log/pihole_sync.log 2>&1
    • Ulož a zavři soubor.

    • Log synchronizace se bude ukládat do /var/log/pihole_sync.log. Pravidelně ho kontroluj!


 

Krok 7: Konfigurace Reverzní Proxy pro HTTPS (Volitelné, pokud ji máš)

 

Pokud máš reverzní proxy (jako Nginx Proxy Manager, Traefik, Caddy atd.), nastav ji takto:

  1. Vytvoř nový Proxy Host (nebo ekvivalent) pro tvé Pi-hole webové rozhraní.

  2. Domain Names: Nastav doménu, kterou budeš používat pro přístup (např. pihole.local, dnsadmin.lan nebo vlastní doména, pokud ji máš).

  3. Scheme: Nastav na http.

  4. Forward Hostname / IP: Zadej IP adresu tvého primárního Pi-hole serveru (192.168.54.2).

  5. Forward Port: Nastav na 80 (port, na kterém Pi-hole kontejner interně naslouchá).

  6. SSL/HTTPS: V záložce SSL/HTTPS povol SSL a vygeneruj nebo nahraj certifikát. Přesměrování HTTP na HTTPS je také dobrá praxe.

Tím zajistíš bezpečný přístup k Pi-hole webovému rozhraní přes HTTPS.


 

Krok 8: Nastavení DNS Klientů v Síti

 

Toto je nejdůležitější krok pro to, aby tvá zařízení ve síti začala používat tvé nové DNS servery.

Na svém routeru (doporučeno, protože to ovlivní všechna zařízení) nebo na každém zařízení individuálně, nastav jako DNS servery obě IP adresy tvých Raspberry Pi:

  • Primární DNS server: 192.168.54.2

  • Sekundární DNS server: 192.168.54.3

Většina zařízení a operačních systémů automaticky vyzkouší primární DNS server a pokud ten neodpoví (např. při výpadku proudu), automaticky se přepne na sekundární.


 

Krok 9: Testování

 

  1. Otestuj Pi-hole na DNS1 (192.168.54.2):

    • Na klientovi nastav DNS jen na 192.168.54.2.

    • Navštiv testovací stránky (např. https://ads-blocker.com/testing/, https://blockads.fivefilters.org/simple.html). Reklamy by se neměly zobrazovat.

    • Otestuj DNSSEC: https://dnssec.works/. Měl bys vidět zelené fajfky.

    • Zkontroluj logy v Pi-hole rozhraní na http://192.168.54.2/admin.

  2. Otestuj Pi-hole na DNS2 (192.168.54.3):

    • Na klientovi nastav DNS jen na 192.168.54.3.

    • Proveď stejné testy jako výše. Počkej, až proběhne první synchronizace z DNS1 (nebo ji spusť ručně pomocí skriptu na DNS1: bash /home/pi/sync_pihole.sh). Konfigurace a blacklisty by měly být stejné jako na DNS1.

  3. Otestuj redundanci:

    • Nastav na klientovi oba DNS servery (DNS1 jako primární, DNS2 jako sekundární).

    • Vytáhni napájení z primárního RPi (DNS1).

    • Zkus procházet internet a navštěvovat weby s reklamami. Mělo by to stále fungovat a reklamy by měly být blokovány, protože se automaticky přepnulo na DNS2.

    • Zapoj DNS1 zpět a ověř, že se opět bez problémů zapojí do sítě.

  4. Otestuj synchronizaci:

    • Na Pi-hole UI na DNS1 přidej nějakou novou doménu na Blacklist (např. example.com).

    • Počkej 10 minut (nebo spusť synchronizační skript ručně na DNS1).

    • Zkontroluj webové rozhraní Pi-hole na DNS2 (http://192.168.54.3/admin), zda se nová doména objevila v blacklistu.


S tímto návodem bys měl mít plně funkční, redundantní a bezpečné DNS řešení ve tvé domácí síti.