AdGuard Home na Raspberry Pi — ilustracja serwera DNS z Dockerem i ochroną sieci

AdGuard Home na Raspberry Pi z Dockerem – praktyczny poradnik

AdGuard Home na Raspberry Pi: po co mi go w domowej sieci?

Pierwsza wersja tego poradnika miała jeszcze ceny Raspberry Pi z 2021 roku, instalację przez curl | sh i – co dziś poprawiłbym w pierwszej kolejności – sugestię wystawienia panelu AdGuard Home na Internet przez przekierowanie portu 3000. Od tamtej pory sam AdGuard Home się zmienił, mój sposób jego używania też, a ceny i sens kupowania konkretnych płytek wyglądają dziś zupełnie inaczej. Zamiast dopisywać kolejne poprawki do starego tekstu, lepiej było napisać go od nowa.

Cel pozostał ten sam: chcę mieć jeden punkt w sieci domowej, który filtruje DNS dla telefonów, komputerów, telewizorów i innych urządzeń. Bez instalowania osobnego adblockera na każdym z nich. Do tego dochodzi Safe Search, listy bezpieczeństwa, blokowanie części telemetryki i bardzo przydatny Query Log, kiedy trzeba sprawdzić, dlaczego jakaś aplikacja nagle przestała działać.

AdGuard Home jest właśnie takim lokalnym serwerem DNS. W tym poradniku pokazuję mój obecny wariant: AdGuard Home na Raspberry Pi z Dockerem, ale ten sam serwer może działać też na zwykłym Linuksie, NAS-ie czy innym hoście z Dockerem. Raspberry Pi nadal jest bardzo wygodnym wyborem, bo może pracować 24/7 i nie potrzebuje do tego dużych zasobów.

Co AdGuard Home potrafi, a czego nie

Tu łatwo mieć złe oczekiwania: AdGuard Home filtruje ruch na poziomie DNS. Jeżeli aplikacja chce połączyć się z domeną znajdującą się na liście blokującej, lokalny DNS może tę domenę zablokować, zanim urządzenie w ogóle nawiąże z nią połączenie.

To dobrze działa w przypadku wielu sieci reklamowych, trackerów, domen telemetrycznych, phishingu czy części infrastruktury malware. Nie jest to jednak antywirus i nie zastąpi ochrony endpointu. Nie usunie też każdej reklamy. Jeżeli serwis dostarcza reklamę z tej samej domeny co właściwą treść, blokowanie całej domeny odcięłoby również sam serwis. Dlatego np. reklamy osadzone bezpośrednio w niektórych platformach wideo są zupełnie innym problemem niż klasyczne trackery reklamowe.

Dobrze o tym pamiętać przy dobieraniu filtrów. Więcej reguł nie zawsze oznacza lepszą ochronę. Czasem oznacza po prostu więcej rzeczy do diagnozowania.

Jaki sprzęt wybrać?

AdGuard Home nie potrzebuje mocnego komputera. Dla lekkiej, dedykowanej instalacji 1 GB RAM nadal może wystarczyć, ale jeśli kupowałbym dziś sprzęt specjalnie pod DNS, brałbym 2 GB. Powód nie jest taki, że sam AdGuard jest ciężki. Zapas przydaje się wtedy, gdy z czasem dochodzą większe listy filtrów, Docker i aktualizacje. W mojej obecnej konfiguracji liczba reguł idzie już w miliony i właśnie w takim scenariuszu nie chciałbym projektować nowego urządzenia „na styk”.

Informacja o afiliacji: część linków do sprzętu poniżej to linki partnerskie Amazon. Jako Partner Amazon zarabiam na kwalifikujących się zakupach. Nie pobieram od Ciebie żadnej dodatkowej opłaty za skorzystanie z takiego linku. Linkuję tylko elementy, które pasują do opisywanego zestawu; nie twierdzę, że osobiście testowałem każdy z tych konkretnych produktów.

Najprościej: gotowy zestaw Raspberry Pi 4 2 GB

Jeśli nie chcesz kompletować wszystkiego osobno, najprostsza droga to gotowy zestaw z Raspberry Pi 4 2 GB. Przykładem są dwa warianty db-tronic: czerwono-biały zestaw 2 GB / 64 GB oraz czarny zestaw 2 GB / 64 GB. Oba zawierają płytkę, zasilacz 15 W, obudowę, radiatory, kartę 64 GB i kabel micro-HDMI.

Do headless AdGuard Home kabel HDMI nie jest potrzebny, ale w gotowym zestawie po prostu zostaje jako zapas. Ważniejsza uwaga dotyczy karty: karta 64 GB dołączona do zestawu nie jest opisana jako High Endurance, więc nie traktuję jej jako odpowiednika karty przeznaczonej do długiej pracy z częstymi zapisami.

Wariant, który wybrałbym do pracy 24/7

Jeżeli wolisz złożyć zestaw sam, mój sensowny punkt wyjścia to Raspberry Pi 4 Model B 2 GB, oficjalny zasilacz USB-C 5,1 V / 3 A, pasywna aluminiowa obudowa Miuzei i SanDisk High Endurance 64 GB. Do urządzenia DNS używanego przez całą sieć wolę Ethernet niż Wi-Fi; jeśli potrzebujesz krótkiego patchcordu, przykładem jest Cat6a 1,5 m PremiumCord.

Cat6a nie jest tu wymaganiem. Raspberry Pi 4 ma Gigabit Ethernet i zwykły dobry Cat5e również wystarczy. Ten konkretny kabel podałem dlatego, że jest krótki, ekranowany i wykonany z miedzi, a nie dlatego, że AdGuard potrzebuje Cat6a.

Orange Pi Zero3 jako alternatywa

AdGuard Home nie jest przywiązany do Raspberry Pi. Może działać również na innych małych komputerach ARM. Alternatywą jest Orange Pi Zero3 2 GB. Technicznie nadaje się do tego zadania bardzo dobrze, ale nie zakładam z góry, że będzie tańszy od Raspberry Pi. Jeżeli w dniu zakupu oba zestawy kosztują podobnie, dla początkującego wybrałbym Raspberry Pi ze względu na bardziej przewidywalny ekosystem, dokumentację i dostępność gotowych instrukcji.

Do Orange Pi można dobrać pasywne aluminiowe chłodzenie/obudowę i zasilacz USB-C 5 V / 3 A. Wariant 1,5 GB istnieje i pamięciowo byłby dla typowego AdGuard wystarczający, ale obecnie ma znane problemy związane z obsługą tej konkretnej konfiguracji RAM w bootloaderze/systemach, więc nie polecam go jako pierwszego wyboru dla początkującego.

A co z cenami?

W starej wersji poradnika miałem tabelę z konkretnymi cenami. Tym razem świadomie jej nie powtarzam. Elektronika i oferty marketplace zmieniają się za szybko, a przy linkach Amazon PartnerNet nie chcę ręcznie przepisywać do artykułu kwot, które po kilku tygodniach mogą być nieaktualne. Aktualną cenę sprawdzisz po przejściu do konkretnego produktu.

To samo dotyczy kosztu prądu. Zamiast wpisywać jedną kwotę dla wszystkich, najuczciwiej zmierzyć własny zestaw watomierzem i policzyć: (W / 1000) × 24 × 365 × cena za kWh. Przy serwerze pracującym 24/7 taki pomiar ma więcej sensu niż katalogowa wartość zasilacza.

Przygotowanie Raspberry Pi bez monitora

Do serwera DNS nie potrzebuję pulpitu, monitora ani klawiatury. Instalację robię headless. Raspberry Pi oficjalnie zaleca do tego Raspberry Pi Imager, bo jeszcze przed pierwszym startem można ustawić hostname, konto użytkownika, sieć i SSH.

W Raspberry Pi Imager wybieram Raspberry Pi OS Lite (64-bit). W sierpniu 2026 Raspberry Pi OS 64-bit jest oparty na Debianie 13 (Trixie), a Raspberry Pi 4 jest wspierane. W ustawieniach obrazu nadaję urządzeniu nazwę, tworzę użytkownika z hasłem i włączam SSH. Jeśli urządzenie będzie podłączone przewodem – a dla domowego DNS właśnie to preferuję – konfiguracja Wi-Fi nie jest konieczna.

Po zapisaniu karty wkładam ją do Raspberry Pi, podłączam Ethernet i zasilanie. Po pierwszym uruchomieniu łączę się przez SSH, używając hosta ustawionego w Imagerze albo adresu IP z routera:

ssh USER@HOSTNAME.local

Na początku aktualizuję system:

sudo apt update
sudo apt full-upgrade -y
sudo reboot

Po restarcie loguję się ponownie przez SSH.

Docker Engine i Compose

Nie używam tutaj starego schematu „pobierz skrypt z Internetu i od razu przepuść go do shella”. Docker ma oficjalne repozytorium APT dla Debiana i to jest czytelniejsza ścieżka również dla 64-bitowego Raspberry Pi OS opartego na Debianie.

sudo apt update
sudo apt install -y ca-certificates curl

sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/debian/gpg \
  -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

sudo tee /etc/apt/sources.list.d/docker.sources >/dev/null <<EOF
Types: deb
URIs: https://download.docker.com/linux/debian
Suites: $(. /etc/os-release && echo "$VERSION_CODENAME")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io \
  docker-buildx-plugin docker-compose-plugin

Sprawdzam, czy Docker i Compose działają:

sudo docker run --rm hello-world
sudo docker compose version

Można później skonfigurować uruchamianie Dockera bez sudo, ale nie jest to potrzebne do samego AdGuard Home. W tym poradniku pozostaję przy jawnych poleceniach z sudo.

Instalacja AdGuard Home w Docker Compose

Najpierw tworzę katalog roboczy:

mkdir -p ~/docker/adguard
cd ~/docker/adguard
mkdir -p adguard/conf adguard/work

Następnie tworzę plik compose.yml:

services:
  adguard:
    image: adguard/adguardhome:latest
    container_name: adguard
    restart: unless-stopped

    ports:
      - "53:53/tcp"
      - "53:53/udp"

      # Panel po zakończeniu pierwszej konfiguracji
      - "12280:80/tcp"

      # Tylko do kreatora pierwszego uruchomienia
      - "3000:3000/tcp"

    volumes:
      - ./adguard/conf:/opt/adguardhome/conf
      - ./adguard/work:/opt/adguardhome/work

Uruchomienie:

sudo docker compose up -d

Uwaga o dostępie do portów: sekcja ports: publikuje porty na interfejsach hosta. W typowej sieci domowej za NAT-em nie jest to tym samym co przekierowanie portu z Internetu, ale nie traktuj samego Dockera jak firewalla. Jeśli host ma kilka interfejsów, publiczny adres IPv6 albo bardziej złożoną segmentację, ogranicz dostęp do panelu administracyjnego do zaufanej sieci i sprawdź reguły firewalla/Docker DOCKER-USER.

Oficjalna dokumentacja AdGuard Home używa portu 3000/TCP do pierwszej konfiguracji, 80/TCP do panelu WWW oraz 53/TCP i 53/UDP do zwykłego DNS. W przykładzie celowo nie wystawiam DHCP, DoT, DoQ, DNSCrypt ani serwera DoH, bo ich tutaj nie potrzebuję.

Ważne: port 3000 nie ma być przekierowywany na routerze z Internetu do Raspberry Pi. Kreator i późniejszy panel administracyjny mają być dostępne z sieci lokalnej. Jeśli kiedyś potrzebujesz administracji spoza domu, znacznie lepszym rozwiązaniem jest VPN albo poprawnie zabezpieczony reverse proxy.

Pierwsze uruchomienie

Po starcie kontenera otwieram w przeglądarce:

http://SERVER-IP:3000

W kreatorze ustawiam panel WWW na port 80, a DNS na port 53. Tworzę też osobne konto administratora. Po zakończeniu kreatora panel będzie dostępny przez port hosta zdefiniowany w compose, czyli w tym przykładzie:

http://SERVER-IP:12280
Kreator AdGuard Home z ustawieniem portu panelu WWW na 80 i serwera DNS na 53
1 — port panelu WWW 80; 2 — port DNS 53. Prywatny adres hosta testowego został trwale zasłonięty.
Ekran tworzenia konta administratora w kreatorze AdGuard Home
1 — nazwa użytkownika; 2 — hasło i jego potwierdzenie. Do publikacji używam pustego ekranu, bez realnych danych logowania.

Kiedy wszystko działa, usuwam z compose.yml tymczasową linię:

- "3000:3000/tcp"

i odtwarzam kontener:

sudo docker compose up -d

To drobiazg, ale po kilku miesiącach bardzo ułatwia życie: w compose zostają tylko porty, które faktycznie mają zastosowanie, więc nie trzeba później zgadywać, po co kiedyś wystawiłem 853, 784 albo 3000.

Najpierw zapewnij AdGuardowi stały adres w LAN

Serwer DNS nie powinien zmieniać adresu po restarcie routera. Najprościej zrobić w routerze rezerwację DHCP dla interfejsu Ethernet Raspberry Pi i przypisać mu stały adres, np. 192.168.1.10. Wolę rezerwację po stronie DHCP niż ręczne wpisywanie statycznej konfiguracji w systemie, bo wtedy cała adresacja nadal jest zarządzana w jednym miejscu.

Po zapisaniu rezerwacji sprawdź w routerze albo poleceniem ip addr, że urządzenie rzeczywiście dostało oczekiwany adres. Dopiero ten adres wpisuj później jako DNS dla klientów.

Ustawienie AdGuard Home jako DNS w sieci

Najwygodniej ustawić adres hosta z AdGuard Home jako DNS rozdawany klientom przez router lub DHCP. Wtedy telefony, laptopy, telewizory i większość urządzeń zaczyna korzystać z niego automatycznie.

Nie wpisuj obok AdGuarda publicznego resolvera typu 1.1.1.1 albo 8.8.8.8 jako „zapasowego DNS”, jeśli zależy Ci na konsekwentnym filtrowaniu. Klient nie musi traktować drugiego adresu wyłącznie jako awaryjnego i część zapytań może ominąć AdGuard Home. Jeśli potrzebujesz prawdziwej redundancji, lepszym rozwiązaniem jest drugi lokalny resolver.

Jeżeli w LAN działa IPv6, sprawdź również, jaki DNS router rozgłasza klientom po IPv6. Samo ustawienie lokalnego DNS po IPv4 nie pomoże, jeżeli urządzenia równolegle dostają od routera lub operatora zewnętrzny resolver IPv6 i wybierają właśnie jego.

Nie przekierowuję portu 53 z WAN do środka. To ma być DNS dla mojej sieci lokalnej, nie publiczny resolver dostępny z Internetu.

AdGuard Home Setup Guide z instrukcją ustawienia lokalnego DNS w routerze
1 — adres lokalnego DNS, zanonimizowany na kopii publikacyjnej; 2 — zakładka Router z instrukcją dla całej sieci.

Po zmianie robię jeden prosty test z dowolnego klienta, żeby nie zgadywać, czy DNS rzeczywiście trafia już do AdGuard Home:

dig @ADGUARD-IP example.com +stats

Jeżeli zapytanie pojawia się w Query Log, ścieżka klient → AdGuard Home działa.

Upstream DNS: dwa szyfrowane resolvery zamiast długiej listy

Przez dłuższy czas miałem skonfigurowanych kilka różnych upstreamów. Teoretycznie wyglądało to dobrze, ale przy trybie Load-balancing zdarzały mi się zauważalnie dłuższe odpowiedzi. Dlatego finalnie uprościłem konfigurację do dwóch resolverów DoH i zostawiłem tryb Parallel requests.

https://dns10.quad9.net/dns-query
https://cloudflare-dns.com/dns-query

W trybie Parallel requests, gdy odpowiedzi nie ma już w lokalnym cache, AdGuard wysyła zapytanie do obu skonfigurowanych upstreamów i wykorzystuje pierwszą odpowiedź. To może poprawić opóźnienia, ale ma też oczywisty koszt prywatności: oba resolvery widzą takie zapytanie. Przy ośmiu upstreamach ten kompromis robił się już dla mnie bez sensu; przy dwóch jest świadomy i prosty do zrozumienia.

Wybrałem tutaj wariant Quad9 dns10, czyli bez dodatkowego filtrowania zagrożeń po stronie Quad9. Od czerwca 2026 Quad9 włączył walidację DNSSEC również na tych endpointach, więc „bez threat blocking” nie oznacza dziś „bez DNSSEC”. Blokowanie chcę mieć w jednym miejscu – lokalnie w AdGuard Home – zamiast zastanawiać się później, czy domenę odciął mój filtr, Quad9 czy jeszcze coś po drodze.

Ustawienia DNS AdGuard Home z Quad9 dns10, Cloudflare DoH i trybem Parallel requests
1 — Quad9 dns10 przez DoH; 2 — Cloudflare przez DoH; 3 — tryb Parallel requests. Zrzut nie zawiera danych wymagających anonimizacji.

Bootstrap DNS może pozostać prosty, np.:

9.9.9.10
1.1.1.1

Listy blokujące: szeroko, ale z jakimś planem

Z listami blokującymi najłatwiej przesadzić. U mnie sieć nie służy tylko do przeglądania kilku polskich stron – są urządzenia Apple, Smart TV, różne serwisy zagraniczne i aplikacje, które potrafią być dość rozmowne. Dlatego wolę profil szerszy niż absolutne minimum.

Jednocześnie po pewnym czasie zauważyłem, że łatwo skończyć z kilkoma listami robiącymi niemal to samo. Usunąłem duplikaty i zostawiłem warstwy o konkretnym przeznaczeniu. Sensowny punkt wyjścia wygląda tak:

  • HaGeZi Pro++ jako szeroka główna lista reklam, trackerów i telemetryki;
  • HaGeZi Threat Intelligence Feeds jako osobna warstwa zagrożeń;
  • Dandelion Sprout’s Anti-Malware List jako dodatkowa lista bezpieczeństwa;
  • Smart-TV Blocklist, jeśli w sieci są telewizory i chcesz ograniczyć reklamową/telemetryczną część ich ruchu;
  • opcjonalne listy producentów lub regionalne tylko wtedy, gdy faktycznie masz dla nich powód.

Nie kopiowałbym bezmyślnie całej mojej listy. Agresywne filtry, listy całych podejrzanych TLD albo blokowanie infrastruktury VPN/proxy mogą być świetne w jednej sieci i kompletnie irytujące w innej. Najważniejsze jest to, żeby wiedzieć, po co dana lista została włączona.

Lista filtrów DNS w AdGuard Home z HaGeZi Pro++ i dodatkowymi listami bezpieczeństwa
1 — HaGeZi Pro++; 2 — Threat Intelligence Feeds; 3 — Smart-TV Blocklist; 4 — Dandelion Sprout’s Anti-Malware.

Safe Search i kilka ustawień, które u mnie mają sens

Safe Search mam włączony globalnie dla dostępnych wyszukiwarek i YouTube. Nie traktuję tego jako „kontroli rodzicielskiej załatwionej jednym checkboxem”, ale jest to rozsądna dodatkowa warstwa w sieci rodzinnej.

AdGuard Browsing Security również zostawiłem włączone. Globalnego Parental Control nie używam – jeśli kiedyś będę potrzebował ostrzejszych zasad dla konkretnego urządzenia, wolę zrobić to per-client zamiast zmieniać zachowanie całej sieci.

Po audycie ustawiłem też:

  • aktualizację filtrów co 1 dzień;
  • Query Log na 7 dni zamiast 90;
  • statystyki na 30 dni zamiast 24 godzin;
  • DNS cache 16 MiB;
  • Optimistic caching włączony;
  • DNSSEC włączony;
  • EDNS Client Subnet wyłączony.

Query Log zostawiam bez anonimizacji adresów klientów, bo przy diagnozowaniu problemów i reguł per-client chcę wiedzieć, które urządzenie wykonało zapytanie. Zrzuty do publikacji to inna sprawa – tam adresy prywatne trzeba oczywiście zanonimizować.

General settings AdGuard Home z włączonym Browsing Security i Safe Search
1 — AdGuard Browsing Security; 2 — Safe Search. Dolną część starego zrzutu z nieaktualną retencją logów świadomie wyciąłem.
Persistent client lab-client w AdGuard Home z ustawieniami per-client
1 — neutralny klient lab-client; 2 — ustawienia per-client. Jego rzeczywisty adres LAN został trwale zasłonięty.

Jeżeli chcesz mieć czytelniejsze logi albo inne zasady dla wybranych urządzeń, przydają się Persistent clients. Możesz nadać urządzeniu nazwę i później osobno ustawiać m.in. Safe Search, logowanie czy reguły per-client. Nie jest to wymagane do zwykłego blokowania DNS, więc nie komplikowałbym tym pierwszej instalacji.

Blocked Services: pełna lista dostępnych usług

AdGuard Home potrafi blokować całe usługi globalnie albo tylko dla konkretnego klienta. W tym setupie nie włączam globalnego Blocked Services — nie chcę wycinać serwisów tylko dlatego, że istnieje przełącznik. Jeśli kiedyś potrzebuję takiej polityki dla konkretnego urządzenia, zaczynam od pojedynczego persistent client, a nie od reguły dla całej sieci.

Blocked Services w AdGuard Home z wyłączonymi przełącznikami usług
Zrzut pokazuje fragment funkcji Blocked Services. Pełny snapshot usług widocznych w bieżącym interfejsie znajduje się poniżej.
Pokaż pełną listę: 139 usług w 12 kategoriach

To jest snapshot z bieżącego interfejsu AdGuard Home z 25.08.2026. Lista może zmieniać się wraz z kolejnymi wersjami AdGuard Home. Nazw samych usług nie tłumaczę, żeby odpowiadały temu, co widać w panelu.

  • Sztuczna inteligencja: ChatGPT, Claude, Copilot, DeepSeek, Google Gemini, Grok, Manus, Meta AI, Perplexity
  • Sieci dostarczania treści (CDN): Cloudflare
  • Serwisy randkowe: Grindr, Plenty of Fish, Tinder, Wizz
  • Hazard i zakłady: Betano, Betfair, Betway, Blaze, FDJ United
  • Gry: Activision Blizzard, Battle.net, Blizzard Entertainment, Electronic Arts, Epic Games, GOG, IO Interactive, League of Legends, Minecraft, Nintendo, Origin, PlayStation, Riot Games, Roblox, Rockstar Games, Shell Shockers, Steam, Ubisoft, Valorant, Wargaming, Warner Bros. Games, Xbox Live
  • Web hosting / przechowywanie plików: Box, Dropbox, Flickr, Imgur
  • Komunikatory: KakaoTalk, Kik, MAX, Microsoft Teams, Olvid, Signal, Skype, Slack, Telegram (Web), Viber, WeChat, WhatsApp
  • Narzędzia prywatności: iCloud Private Relay, Privacy, Proton
  • Zakupy: AliExpress, Amazon, CoolApk, eBay, Lazada, Mercado Libre, Shein, Shopee, Temu, Xiaohongshu
  • Sieci społecznościowe: 4chan, 500px, 9GAG, Amino, Bluesky, Clubhouse, Discord, Douban, Facebook, Instagram, KOOK, LINE, LinkedIn, Mail.ru, Mastodon, Odysee, OK.ru, OnlyFans, Pinterest, Reddit, Snapchat, TikTok, Tumblr, X (formerly Twitter), VK.com, Zhihu
  • Tworzenie oprogramowania: Nvidia, Google Play Store
  • Usługi streamingowe: Amazon Streaming, Apple Streaming, Bigo Live, Bilibili, Canais Globo, Claro, Crunchyroll, Dailymotion, Deezer, DirecTV Go, Discovery+, Disney+, ESPN, FIFA, Globoplay, HBO Max, Hulu, iHeartRadio, iQIYI, Lionsgate+, Looke, Nebula, Netflix, Paramount Plus, Peacock TV, Plex, Pluto TV, QQ, Rakuten Viki, Samsung TV Plus, SoundCloud, Spotify, Spotify Video, Tidal, Twitch, Vimeo, Vivo Play, Voot, Weibo, YouTube, YY

Custom filtering rules: miejsce, w którym najłatwiej zrobić sobie wyjątek na pół Internetu

To była najbardziej praktyczna lekcja podczas porządkowania konfiguracji.

Chciałem sprawdzić, czy googleads.g.doubleclick.net jest blokowane. Zapytanie przechodziło normalnie, mimo że przy moich listach powinno być odcięte. Powód nie leżał ani w HaGeZi, ani w upstreamach. Kilka miesięcy wcześniej sam dodałem wyjątki:

@@||googleads.g.doubleclick.net^
@@||doubleclick.net^

Druga reguła była szczególnie szeroka, bo wyjątek dla doubleclick.net obejmował również jego subdomeny. Obie linie zakomentowałem zamiast usuwać, żeby w razie problemu mieć prosty rollback. Po tej zmianie ten sam test zwrócił:

googleads.g.doubleclick.net.  10  IN  A  0.0.0.0

Czyli filtry działały od początku. To moja allowlista je omijała.

Od tej pory przy problemach z filtrowaniem zaczynam od Query Log i własnych wyjątków. Lista blokująca może być idealna, ale jedna stara reguła @@ potrafi zmienić wynik dla całego drzewa domen.

Z drugiej strony nie usuwam automatycznie każdego wyjątku. Część z nich powstała z konkretnego powodu – np. przez problemy z usługami Apple czy VPN. Jeżeli coś działa dobrze po świadomym wyjątku, wolę mieć udokumentowany kompromis niż „idealnie czystą” konfigurację, która psuje używane usługi.

Jak sprawdzam, czy blokowanie naprawdę działa

Do testu nie używam przypadkowej domeny reklamowej — może akurat nie być na aktywnej liście albo może mieć własny wyjątek. Pewniejszy test to chwilowo dodać neutralną regułę:

||ads.example.com^
Custom filtering rules AdGuard Home z neutralną regułą ads.example.com
1 — neutralna reguła testowa ||ads.example.com^. Dzięki niej test nie zależy od przypadkowej prawdziwej domeny reklamowej.

i zapytać własny AdGuard:

dig @ADGUARD-IP ads.example.com +stats

Przy domyślnym trybie blokowania dla rekordu A powinieneś zobaczyć 0.0.0.0. Potem regułę testową można usunąć.

Osobno sprawdzam zwykłą domenę:

dig @ADGUARD-IP example.com +stats

W moim teście normalne zapytania oraz blokowanie działały poprawnie po zmianie upstreamów, a część lokalnych odpowiedzi była raportowana przez dig jako 0 ms. Taki wynik jest zgodny z bardzo szybką odpowiedzią lokalną/cache, ale sam czas nie jest jeszcze dowodem, skąd dokładnie pochodziła odpowiedź.

Query Log AdGuard Home z neutralnym zapytaniem zablokowanym i przetworzonym
1 — ads.example.com zablokowane przez custom rule; 2 — example.com przetworzone normalnie. Adres klienta został zanonimizowany.
Dashboard AdGuard Home z neutralnym ruchem example i statystykami blokowania
1 — 42 zapytania DNS; 2 — 13 zablokowanych; 3 — neutralne domeny testowe. Prywatny adres klienta został zanonimizowany.

Gdy w Query Log wszystkie urządzenia wyglądają jak jeden klient

Docker potrafi ukryć oryginalny adres klienta za adresem bridge. Jeżeli w Query Log zamiast laptopa, telefonu i telewizora widzisz ciągle np. adres dockerowego gatewaya, nie jest to problem z filtrowaniem, tylko z widocznością źródłowego IP.

Oficjalna dokumentacja AdGuard Home sugeruje na Linuksie użycie sieci hosta, jeśli zależy Ci na zachowaniu oryginalnych adresów klientów. Nie zmieniałbym jednak trybu sieciowego w działającej instalacji tylko „bo tak jest w dokumentacji”. Przy host networking kontener korzysta bezpośrednio z sieci hosta, więc mapowania z ports: nie są potrzebne, a konflikt z usługą już nasłuchującą na porcie 53 staje się jeszcze bardziej oczywisty.

Jeżeli obecna konfiguracja pokazuje klientów poprawnie, zostaw ją w spokoju.

Co jeśli port 53 jest już zajęty?

To dość częsty problem na Linuksie. Zanim zaczniesz wyłączać losowe usługi, sprawdź kto faktycznie nasłuchuje:

sudo ss -lntup | grep ':53'

Na części dystrybucji port może zajmować systemd-resolved. AdGuard ma w dokumentacji osobną procedurę dla takiego przypadku. Warto przejść ją świadomie, bo zmiana lokalnego resolvera wpływa na DNS całego hosta.

Aktualizacje: dlaczego w przykładzie używam latest

W compose zostawiam:

image: adguard/adguardhome:latest

Powód jest prosty: ten artykuł nie będzie aktualizowany przy każdym wydaniu AdGuard Home. Oficjalna dokumentacja Dockera opisuje domyślny obraz jako najnowszą stabilną wersję. Dzięki temu ktoś, kto trafi tu za pół roku, nie zacznie instalacji od numeru wersji, który był aktualny tylko w dniu publikacji.

Jeżeli wolisz pełną kontrolę nad aktualizacjami, przypnij konkretny tag zamiast latest. Aktualne stabilne wydania znajdziesz na oficjalnej stronie AdGuard Home Releases. Zwróć tylko uwagę, aby wybrać wydanie stabilne, a nie oznaczoną jako pre-release wersję beta.

W Dockerze samo pojawienie się nowej wersji nie aktualizuje działającego kontenera. Aktualizację wykonuję świadomie:

sudo docker compose pull
sudo docker compose up -d

Przed większą zmianą robię kopię katalogów conf i work oraz zachowuję poprzedni plik compose.yml. To wystarcza do szybkiego cofnięcia większości zmian konfiguracyjnych. Przy aktualizacji obrazu dobrze też zanotować używaną wcześniej wersję/tag, jeśli zależy Ci na łatwym rollbacku.

Instalacja bez Dockera

Docker jest moim głównym wariantem tego poradnika, ale nie jest obowiązkowy. AdGuard Home publikuje gotowe archiwa dla wspieranych systemów. W wariancie natywnym pobierasz paczkę dla swojej architektury z oficjalnej strony wydań, rozpakowujesz ją i rejestrujesz program jako usługę.

Po wejściu do rozpakowanego katalogu AdGuardHome oficjalna komenda instalująca usługę to:

sudo ./AdGuardHome -s install

Status usługi można później sprawdzić poleceniem:

sudo ./AdGuardHome -s status

Przy pierwszym uruchomieniu AdGuard Home nasłuchuje na porcie 3000 i prowadzi przez ten sam kreator konfiguracji. Aktualne stabilne archiwa są na oficjalnej stronie Releases, a pełna instrukcja instalacji znajduje się w dokumentacji Getting started.

Nie wklejam do poradnika polecenia typu curl ... | sh jako domyślnej metody. Pobranie konkretnego wydania i uruchomienie jawnej binarki jest po prostu łatwiejsze do sprawdzenia i późniejszego odtworzenia.

Ograniczenia, o których dobrze wiedzieć wcześniej

Po pierwsze, DNS-level blocking nie zastępuje adblockera w przeglądarce. Jest świetny dla urządzeń, na których żadnego rozszerzenia nie zainstalujesz – telewizorów, części aplikacji mobilnych czy sprzętu IoT – ale nie rozwiąże każdego rodzaju reklamy.

Po drugie, nie wszystkie urządzenia muszą respektować DNS rozdawany przez router. Aplikacja może mieć własny DoH, urządzenie może używać VPN, a Apple Private Relay również zmienia zwykłą ścieżkę DNS. Jeśli naprawdę chcesz wymuszać lokalny resolver, sam AdGuard nie wystarczy – potrzebna jest też odpowiednia polityka na firewallu. Ja w tym poradniku tego nie robię, bo wolę nie komplikować działającej sieci tylko po to, żeby mieć „idealnie szczelny” diagram.

Po trzecie, agresywne listy czasem coś popsują. I właśnie wtedy największą zaletą AdGuard Home nie jest kolejny milion reguł, tylko Query Log. Widać w nim domenę, klienta i powód blokady, więc można naprawić konkretny problem zamiast wyłączać pół ochrony.

Jak ten setup wygląda po czasie

Sama instalacja AdGuard Home jest prosta. Więcej czasu zajęło mi dopiero dojście do konfiguracji, której nie trzeba co chwilę poprawiać: ograniczenie upstreamów do dwóch, przejście na DoH, uporządkowanie blocklist, skrócenie retencji Query Log i wyczyszczenie starych wyjątków.

Najlepszy przykład to DoubleClick. Na pierwszy rzut oka wyglądało, jakby filtry nie działały. Dopiero sprawdzenie własnych reguł pokazało, że problem zrobiłem sobie wcześniej sam przez szeroki wyjątek @@||doubleclick.net^. Po jego wyłączeniu ta sama domena wróciła jako 0.0.0.0. Taki przypadek jest dla mnie znacznie bardziej użyteczny niż kolejna lista „10 najlepszych filtrów”, bo dokładnie pokazuje, gdzie szukać, kiedy coś zachowuje się inaczej niż oczekujesz.

Gdybym stawiał AdGuard Home od zera dzisiaj, zrobiłbym to dokładnie w tej kolejności: mały komputer z Ethernetem, Raspberry Pi OS Lite, Docker, minimalny zestaw portów, jeden lub dwa szyfrowane upstreamy, rozsądny zestaw filtrów i dopiero później dodatkowe wyjątki. Nie zaczynałbym od kilku milionów reguł. Najpierw niech DNS działa stabilnie, a dopiero potem można go zaostrzać pod własną sieć.

Dokumentacja

Pomogła Ci ta instrukcja?

Jeśli zaoszczędziła Ci trochę czasu albo nerwów, możesz postawić mi kawę.