自宅でローカルネットワーク用のサーバーを複数運用しているのですが「自分で建てたあのサービスってIPアドレスなんだっけ?」となることが多々あります。(ウェブブラウザのブックマーク機能使えよ)
元々.local
を使いmDNSで名前解決していたのですが、各々のサーバーに設定しなければならずApple製品がこの.local
をつかうことがあるらしく気になっていました。1
ということで今回 192.168.XXX.XXX
➡️ homenas.lan
といったようにサブドメイン無しで名前解決ができるDNSサーバーPi-hole
を建てます。
Pi-hole (https://registry.hub.docker.com/r/pihole/pihole/) (https://github.com/pi-hole/docker-pi-hole/)
技術選定#
Pi-holeと決めるに調べたDNSサーバーのソフトウェアを表にまとめます。
DockerとGUIで簡単に運用管理できる点で選定しました。
PowerDNS | 権威DNSのAuth、キャッシュサーバーのRecursor、GUIのAdminと分かれていてDockerで使えるけど難しそう。 |
CoreDNS | あんまり調べてない。 |
Dnsmasq | GUIがない。 |
Technitium | 情報が少ない。 |
BIND | 古くて複雑。キャッシュサーバー機能があるのにキャッシュサーバーのUnboundと併用推奨らしい。 |
NSD | GUIがない。 |
Pi-hole | 情報も多くてGUI、Dockerでつかえる。Dnsmasqをベースにしてる。 広告ブロック、DHCPサーバー機能もある。(いらないけど) |
ネットワークイメージ図#
これが完成図です。今回、手を加えるのはデスクトップPC、クライアントPC、ルーターです。
環境#
OS | Ubuntu 22.04 |
Pi-hole version | 2024.07.0 |
準備#
systemd-resolvedの無効#
Ubuntuなら
systemd-resolved
がポート53をつかっているので無効にしてください。下記コマンドは公式の方法にしたがってます。- ポート53をつかっているか確認、ないなら下記のコマンドは不要です。
sudo lsof -i :53
systemd-resolvedがポート53をつかっていることが確認できます。
設定ファイルの書き換え
sudo sed -r -i.orig 's/#?DNSStubListener=yes/DNSStubListener=no/g' /etc/systemd/resolved.conf
- シンボリックリンクの変更
sudo sh -c 'rm /etc/resolv.conf && ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf'
- 再起動
systemctl restart systemd-resolved
インストール#
Docker Compose#
ディレクトリをつくってその中にcompose.yml
ファイルをつくります。
mkdir pihole && touch pihole/compose.yml
公式のcompose.ymlを元に自分用のpihole/compose.yml
を作成しました。ポートやパスワードは適宜変更してください。
# More info at https://github.com/pi-hole/docker-pi-hole/ and https://docs.pi-hole.net/
services:
pihole:
container_name: pihole
image: pihole/pihole:latest
# For DHCP it is recommended to remove these ports and instead add: network_mode: "host"
ports:
- "53:53/tcp"
- "53:53/udp"
#- "67:67/udp" #DHCPサーバーはつかわないので無効
- "8082:80/tcp"
environment:
TZ: 'Asia/Tokyo'
WEBPASSWORD: 'xxxx' #'set a secure password here or it will be random'
# Volumes store your data between container upgrades
volumes:
- './etc-pihole:/etc/pihole'
- './etc-dnsmasq.d:/etc/dnsmasq.d'
#DHCPサーバーはつかわないので無効
#https://github.com/pi-hole/docker-pi-hole#note-on-capabilities
#cap_add:
#- NET_ADMIN # Required if you are using Pi-hole as your DHCP server, else not needed
restart: unless-stopped
作成したディレクトリの中に移動しPi-holeをDocker Composeでインストールします。
sudo docker compose up -d
立ち上がっているかの確認#
インストールしたデスクトップPCからダッシュボードに接続できるか確認します。
curl
コマンド又はウェブブラウザで下記にアクセスしてください。(Docker Composeで"8082:80/tcp"
と設定しているので8082)
http://0.0.0.0:8082/admin
http://0.0.0.0:8082/admin/login.php
うまく立ち上がっているならダッシュボードが表示されます。
設定#
ファイアウォールの設定#
ローカルネットワーク内のマシンからアクセスできるようにファイアウォールの設定をします。
DNS用ポートを解放。
sudo ufw allow 53
ダッシュボードのhttp用ポートを解放。(Docker Composeで"8082:80/tcp"
と設定しているので8082)
sudo ufw allow 8082
Pi-Holeの設定#
ネットワークイメージ図の③部分の設定をします。 クライアントPCからアクセス(http://192.168.1.20:8082/admin)できるはずです。
ウェブブラウザからPi-holeのDNS設定をします。
パスワードはcompose.ymlのWEBPASSWORD:
で設定した値です。(今回だとxxxx
)

Local DNS
> DNS Records
から設定。
DNSサーバーの確認#
ローカルネットワーク内からコマンドで直接名前解決ができるか確認します。
Windowsならnslookup
、Linuxならdig
コマンドです。nslookup <解決したいURL> <DNSサーバーのIPアドレス>
PS C:\Users\clientPC> nslookup nas.lan 192.168.1.20
サーバー: pi.hole
Address: 192.168.1.20
名前: nas.lan
Address: 192.168.1.10
ルーターの設定#
ネットワークイメージ図の②部分の設定をします。
私のルーターはYAMAHA RTX830
なのでそのGUI画面で説明します。
詳細設定
>DNSサーバー
>中継先DNSサーバーの一覧
へ移動。IPアドレス指定
に今回インストールしたDNSサーバーのIPアドレス(192.168.1.20)を指定。オプションの設定
のレコード種別
をIPv4なのでAレコード
で設定。問い合わせの内容
に自分の設定したいTLD.lan
を記述。
アクセス#
ここまでの設定で、ネットワークイメージ図の
① ローカルネットワーク内のマシンからルーターへnas.lan
の問い合わせをする。
② ルーターは.lan
の問い合わせのときだけPi-holeのインストールされている192.168.1.20
のポート53に問い合わせをする。
③ ポート53からきた問い合わせにPi-holeがnas.lan
のIPアドレスは192.168.1.10
と返答する。
④ ①で問い合わせをしたマシンがnas.lan
が192.168.1.10
と名前解決でき無事にnas.lan
へアクセスできる。
の流れができました。
クライアントPCでnas.lan
アクセスして表示できれば成功です。

最後に#
ポートで分かれてるコンテナーへの個別アクセスにはNginx
をつかわなきゃいけないことをすっかり忘れてた……
まぁ、これを機にルーターの設定を見直しできたのでヨシ!!
マシン分けたほうがスマートだと思いRaspi2B+で構築し直しちゃった🥺