AdGuard Homeを家庭内DNSへ向ける前に、広告が消えるかではなく、上流DNSを誤ったときにどう止まるかを隔離環境で観測しました。元記録から復元できたのは、正常応答、ブロック後の0.0.0.0、上流断のtimeout、永続化の差、外部DNSへ直問い合わせしたときのSERVERです。上流を戻した後の正常なdig出力は残っていないため、復旧完了までは主張しません。
検証済みの範囲
- 使い捨て検証VM上のDocker 29.6.0
- AdGuard Home v0.107.77(検証時の
latest) dig9.18.49- 専用bridge
adg-verify-net - 観測日:2026-06-26 UTC
本番ルーターと既存DNSは変更していません。記事中の応答先IPとTTLは観測時の値で、現在値を保証するものではありません。
隔離ネットワークと設定を用意する
実行コマンドと出力は分けます。
docker --version
docker network create adg-verify-net
mkdir -p /tmp/adg-lab/work /tmp/adg-lab/conf
docker network ls --filter name=adg-verify-net
Docker version 29.6.0, build fb59821
NETWORK ID NAME DRIVER SCOPE
c1305d58b1ab adg-verify-net bridge local
/tmp/adg-lab/conf/AdGuardHome.yamlには、元記録に残る最小設定を置きました。
http:
address: 0.0.0.0:3000
users: []
dns:
bind_hosts:
- 0.0.0.0
port: 53
upstream_dns:
- 9.9.9.9
bootstrap_dns:
- 1.1.1.1
upstream_mode: load_balance
filtering:
protection_enabled: true
filtering_enabled: true
user_rules: []
filters: []
schema_version: 20
docker run -d --name adg-verify --network adg-verify-net \
-v /tmp/adg-lab/work:/opt/adguardhome/work \
-v /tmp/adg-lab/conf:/opt/adguardhome/conf \
adguard/adguardhome:latest
docker logs adg-verify | head -40
起動ログはconfig_migratorによる更新を経てwebapi: initializingまで進みました。ログ全文は元記録に残っていないため、ここでは終端だけを示します。
正常時はANSWERとSERVERを同時に読む
ADG_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' adg-verify)
dig @"$ADG_IP" example.com
私設IPは掲載せず、復元できた実出力の構造と値だけを残します。
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 55198
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; ANSWER SECTION:
example.com. 19 IN A 104.20.23.154
example.com. 19 IN A 172.66.147.243
;; Query time: 4 msec
;; SERVER: <ADGUARD_CONTAINER_IP>#53(<ADGUARD_CONTAINER_IP>) (UDP)
status: NOERRORだけでなく、ANSWERが2件あることと、SERVERがAdGuard Homeを指すことを一組で確認します。
ブロック適用後はstatusではなくANSWERが変わる
カスタムルール||doubleclick.net^の適用前は、元記録で次の応答が残っています。
142.251.24.100
142.251.24.102
142.251.24.138
...
ルール適用後の実出力は次の範囲です。
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 641
;; ANSWER SECTION:
doubleclick.net. 10 IN A 0.0.0.0
この構成ではブロック時もNOERRORです。成否はstatusだけでなく、ANSWERが0.0.0.0へ変わったことで判断します。
上流DNSを誤ると、53番が生きていても回答が返らない
上流をRFC 5737の文書用アドレス192.0.2.1へ変え、1回・3秒で問い合わせました。
dig @"$ADG_IP" example.org +time=3 +tries=1
;; communications error to <ADGUARD_CONTAINER_IP>#53: timed out
; (1 server found)
;; no servers could be reached
digの終了コードは9でした。AdGuard Homeの待受に到達していても、上流から回答が戻らなければ同じように名前解決は止まります。
復旧後の出力は未取得なので、ここで検証範囲を止める
上流設定を9.9.9.9へ戻す操作は行いましたが、その後のNOERROR、ANSWER、SERVERを同時に示す出力は保存されていません。したがって本記事が示すのは「誤設定でtimeoutになるところ」までです。常用判断には、復旧後に同じdigを再実行し、新しい正常応答を保存する工程が別途必要です。
永続化と経由先を別々に確認する
再起動後も設定ファイルが残るか
永続化なしの別コンテナでは、起動直後も再起動後もconfが空でした。ホスト側confをマウントした構成では、約3.6KBのAdGuardHome.yamlが残りました。家庭内DNSに使うならworkとconfをともに永続化し、再作成後に読み直します。
端末がAdGuard Homeを通っているか
外部DNSへ直接問い合わせた実出力では、SERVERが外部リゾルバを指しました。
dig @9.9.9.9 doubleclick.net | grep -E 'HEADER|status|SERVER'
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 21206
;; SERVER: 9.9.9.9#53(9.9.9.9) (UDP)
ブロックが見えないときは、リストを増やす前にSERVER行を確認します。
今回の結論
| 断面 | 観測できたこと | 未確認 |
|---|---|---|
| 正常系 | NOERROR、ANSWER 2件、AdGuardのSERVER、4ms | 現在の再実測 |
| ブロック | NOERRORのままAが0.0.0.0 | 別のブロック方式 |
| 上流断 | timeout、終了コード9 | 復旧後の正常応答 |
| 永続化 | mountありでYAMLが残る | 長期運用 |
| 経由確認 | SERVER行で外部DNS直を識別 | 各家庭端末の設定 |
コンテナの更新前後で同じ確認を組み立てる場合は、ステージングから切り戻しまでの診断ハブへ戻れます。
この検証を回している環境
この検証は、自宅の常設ラボ(使い捨てVM/LXCを回す母艦+GPU+VLAN分離ネットワーク)で動かしています。使っている機材と選定理由、全体構成は1本にまとめています。
ラボ構成のまとめを見る →