見出し画像

自宅のDNSをDnsmasqからPi-holeに移行


概要

自宅のDNS&DHCPサーバーのDNS部分をDnsmasqからPi-holeに移行しました。(DHCPサーバーはDnsmasqのまま)

移行理由はPi-holeのDNSレベルでの広告ブロック機能を使ってみたかったのと、ローカルDNSの設定などがWebUでできる部分に魅力を感じたからです。

広告ブロック

ブラウザ上に表示される広告をブロックする機能は、ブラウザの拡張機能やブラウザによっては標準で搭載されている機能です。

この方法だと全てのデバイス(PC、スマホ、タブレットなど)で拡張機能をインストールしたり、広告ブロック機能を持ったブラウザに乗り換える必要があり、とても面倒です。

DNSでのブロックの利点は、全デバイスで一切の設定が必要なく、一貫した広告ブロックを行うことが可能な点です。(ただし自宅のLANに接続している時だけ)

また広告だけではなく、悪意のあるウェブサイトやマルウェアを配信するサイト、不適切なコンテンツを含むサイトへのアクセスを簡単に防ぐことも可能です。

Pi-hole

Pi-holeは広告ブロック機能とWebUIを備えたオープンソースのDNS&DHCPサーバーで、バックエンドにはDnsmasqが使われています。

Pi-holeという名称からラズパイ専用のように見えますが、一般的なLinixOSで使えます。

インストール

今回は現行で動作しているDnsmasq(DHCPサーバー)との競合を避けるためDockerで動かすことにしました。

適当なディレクトリを作成し、その直下にetc-piholeディレクトリとetc-dnsmasq.dディレクトリを作成し、compose.yml ファイルを以下の内容で作成します。

services:
  pihole:
    container_name: pihole
    image: pihole/pihole:latest
    ports:
      - "53:53/tcp"
      - "53:53/udp"
      - "8080:80/tcp"
      #- "67:67/udp" # DHCP
    environment:
      TZ: 'Asia/Tokyo'
      FTLCONF_webserver_api_password: 'password'
    volumes:
      - './etc-pihole:/etc/pihole'
      - './etc-dnsmasq.d:/etc/dnsmasq.d'
    cap_add:
      - NET_ADMIN
    restart: unless-stopped

FTLCONF_webserver_api_password: 'password' はWebUIのパスワードです。


DnsmasqのDNSサーバーを無効にする

Dnsmasqを使用していない方はスキップしてください。

このままではDNSサーバー機能が競合するため、DnsmasqのDNSのサーバー機能を無効にします。

/etc/dnsmasq.conf の port=53 を port=0 に変更し、サービスを再起動します。

$ sudo systemctl restart dnsmasq

Pi-Holeの設定

現状のDnsmasqのDNS部分の設定(/etc/dnsmasq.conf)は以下の通り。

  • port=53 #DNSが使用するポート

  • domain-needed #完全修飾ドメイン名以外のクエリを上位DNSに転送しない

  • bogus-priv #プライベートIPアドレスの逆引きを上位DNSに問い合わせない

  • local=/home/ #homeドメインをローカルネットワークで解決

  • domain=home #デフォルトドメインをhomeに設定

  • expand-hosts #ホスト名に対してドメイン名を自動付加

  • strict-order #DNSサーバーを設定された順序で使用

上記のうち local= と strict-order 以外は、WebUIで設定が可能です。

WenUIで設定できない項目はconfファイルで設定できます。
etc-dnamasq.d/99-custom.conf ファイルを以下の内容で作成します。

local=/home/ #home
strict-order

WebUIで設定できる項目もconfファイルで指定することは可能です。

起動

準備が完了したらコンテナを起動します。

$ docker compose up -d

テスト

WebUI

以下のURLでWebUIにアクセスできるか確認します。

http://IPアドレス:8080/admin

DNS名前解決

「Local DNS Settings」に1件レコードを登録してpingしてみます。

$ ping app.home
PING app.home (192.168.1.29) 56(84) bytes of data.
64 bytes from app (192.168.1.29): icmp_seq=1 ttl=64 time=0.801 ms


他PCからpingしてみます。

ここで問題発生!
pingがエラーになります。

ログを確認してみると ignoring query from non-local とローカル以外のIPからのアクセスを拒否しています。

 $ docker logs pihole
2025-02-20 19:06:07.159 JST [201/F57] WARNING: WARNING in dnsmasq core: ignoring query from non-local network 192.168.1.27

ここでいうローカルとはコンテナ内のローカルアドレスのこと。
192.168.1.29 はコンテナ内から見ればローカルアドレスとは見なされないわけです。

そこでローカル以外からのアクセスを許可します。
具体的には DNSMASQ_LISTENING: all をcompose.ymlの中で指定します。

    environment:
      DNSMASQ_LISTENING: all

これでうまくいくと思っていましたが、全く解決しません・・・
ローカル以外からのアクセスが許可されないままです。

gitの公式ドキュメントを読み込んでいてようやく見つけました。
環境変数が変更になっていました。
DNSMASQ_LISTENING  が FTLCONF_dns_listeningMode に。

最終的な compose.yml は以下のようになります。

services:
  pihole:
    container_name: pihole
    image: pihole/pihole:latest
    ports:
      - "53:53/tcp"
      - "53:53/udp"
      - "8080:80/tcp"
      #- "67:67/udp" # DHCP
    environment:
      TZ: 'Asia/Tokyo'
      FTLCONF_webserver_api_password: 'password'
      FTLCONF_dns_listeningMode: all
    volumes:
      - './etc-pihole:/etc/pihole'
      - './etc-dnsmasq.d:/etc/dnsmasq.d'
    cap_add:
      - NET_ADMIN
    restart: unless-stopped

これで他のPCからのpingも通るようになり、動作OKです。

あとがき

一応動作するようになりましたが、広告カットの検証などはまだなので、しばらく運用しながらいろいろと試していこうと思っています。

問題なければDHCP機能もPi-hpleに移行し一元化しようかと考えています。


いいなと思ったら応援しよう!

R-Y-O
そのお心がありがたいです。