Homelab Pi-hole DNS
Pi-hole 是一種網路層級的 DNS 廣告阻擋器,可在 Raspberry Pi 或任何 Linux 主機上執行。 您網路上所有裝置會自動獲得廣告與惡意軟體網域封鎖功能,無需安裝瀏覽器擴充功能。
使用時機
- 在 Raspberry Pi 或 Linux 主機上安裝 Pi-hole
- 將 Pi-hole 設定為家庭網路的 DNS 伺服器
- 新增或管理封鎖清單
- 設定 DNS-over-HTTPS(DoH)上游解析器
- 建立本機 DNS 記錄(例如
nas.home.lan、pi.home.lan) - 排解安裝 Pi-hole 後部分裝置無法上網的問題
- 配合或取代 DHCP 執行 Pi-hole
Pi-hole 運作原理
運作流程(未使用 Pi-hole):
裝置 → 請求 ads.tracker.com → ISP DNS → 真實 IP → 廣告載入
使用 Pi-hole:
裝置 → 請求 ads.tracker.com → Pi-hole DNS → 封鎖(回傳 0.0.0.0)→ 無廣告
所有 DNS 查詢都會先經過 Pi-hole。
Pi-hole 會比對封鎖清單。
被封鎖的網域回傳空回應 — 廣告/追蹤器永不載入。
允許的網域則會被轉發到您的上游解析器(Cloudflare、Google 等)。
安裝
Docker(建議)
Docker 是安裝 Pi-hole 最簡單的方式,可讓更新和備份變得簡單直觀。
# docker-compose.yml
services:
pihole:
image: pihole/pihole:<pinned-release-tag>
container_name: pihole
ports:
- "53:53/tcp"
- "53:53/udp"
- "80:80/tcp" # Web 管理介面
environment:
TZ: "America/New_York"
WEBPASSWORD: "${PIHOLE_WEBPASSWORD}" # 透過 .env 檔案或 secret 設定
PIHOLE_DNS_: "1.1.1.1;1.0.0.1"
DNSMASQ_LISTENING: "all"
volumes:
- "./etc-pihole:/etc/pihole"
- "./etc-dnsmasq.d:/etc/dnsmasq.d"
restart: unless-stopped
cap_add:
- NET_ADMIN # 僅在 Pi-hole 提供 DHCP 服務時需要
在部署前,將 <pinned-release-tag> 替換為當前的 Pi-hole 發行標籤。
對於長期執行的 DNS 基礎架構,請避免使用 latest,以便每次升級都經過審慎規劃與審查。
在 docker-compose.yml 旁邊的 .env 檔案中設定 PIHOLE_WEBPASSWORD,將其權限設為 600,並確保它不會被納入 Git 版本控制 — 請勿直接將密碼寫入 compose 檔案中。
透過以下網址存取 Web 管理介面:http://<pi-ip>/admin
裸機安裝(Raspberry Pi OS / Debian / Ubuntu)
安裝 Pi-hole 前需先設定靜態 IP。
# 步驟 1:指定靜態 IP(在 Pi OS 上編輯 /etc/dhcpcd.conf)
sudo nano /etc/dhcpcd.conf
# 在檔案底部新增:
interface eth0
static ip_address=192.168.3.2/24
static routers=192.168.3.1
static domain_name_servers=192.168.3.1
# 步驟 2:執行前先下載並檢視安裝程式。
# 建議優先使用 Pi-hole 針對您的作業系統/版本所提供的套件或安裝程式路徑。
curl -sSL https://install.pi-hole.net -o pi-hole-install.sh
less pi-hole-install.sh # 執行前先檢查內容
# 步驟 3:執行
bash pi-hole-install.sh
# 依循互動式安裝程式的指示:
# 1. 選擇網路介面(eth0 有線網路 — 建議)
# 2. 選擇上游 DNS(Cloudflare 或保留預設值 — 之後可修改)
# 3. 確認靜態 IP
# 4. 安裝 Web 管理介面(建議)
# 5. 記下最後顯示的管理員密碼
將您的網路指向 Pi-hole
# 方法 1:在路由器 DHCP 設定中更改 DNS(建議)
路由器管理 UI → DHCP 設定 → DNS 伺服器
主要 DNS:192.168.3.2(Pi-hole IP)
次要 DNS:若需嚴格封鎖則留空,或使用第二台 Pi-hole。
在佈署期間,使用公用備援(例如 1.1.1.1)可提高可用性,
但用戶端可能會查詢它,導致封鎖被繞過。
所有裝置在下次 DHCP 續約時會自動取得 Pi-hole 作為 DNS。
強制續約:重新連線 Wi-Fi;在 Linux 上執行 'sudo dhclient -r && sudo dhclient'
# 方法 2:個別裝置 DNS(在全面佈署前用於測試很實用)
Windows:控制台 → 網路介面卡 → IPv4 內容 → 手動設定 DNS
macOS:系統設定 → 網路 → 詳細資訊 → DNS → 手動設定
Linux:/etc/resolv.conf 或 NetworkManager
# 方法 3:Pi-hole 作為 DHCP 伺服器(取代路由器 DHCP)
Pi-hole 管理介面 → 設定 → DHCP → 啟用
請先停用路由器的 DHCP — 同一個網路上有兩台 DHCP 伺服器會導致衝突
優點:主機名稱解析會自動生效(裝置會註冊其名稱)
封鎖清單管理
# Pi-hole 管理介面 → 廣告清單 → 新增廣告清單
# 建議的封鎖清單:
https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
# 預設 — 超過 200k 個網域
https://blocklistproject.github.io/Lists/malware.txt
# 惡意軟體網域
https://blocklistproject.github.io/Lists/tracking.txt
# 追蹤/遙測
# 新增清單後:
工具 → 更新 Gravity(下載並編譯所有封鎖清單)
# 若某個不該被封鎖的網站被封鎖(誤判):
Pi-hole 管理介面 → 白名單 → 新增網域
範例:api.my-legitimate-service.com
# 即時查看哪些項目正在被封鎖:
儀表板 → 查詢記錄(即時 DNS 查詢串流,顯示封鎖/允許狀態)
DNS-over-HTTPS 上游
DNS-over-HTTPS 會加密您的 DNS 查詢,讓您的 ISP 無法得知您解析哪些網站。
# 安裝 cloudflared(Cloudflare 的 DoH 代理程式)。
# 建議使用 Cloudflare 的套件儲存庫以進行自動簽署套件驗證。
# 若您直接下載二進位檔,請鎖定特定發行版本並驗證其 checksum。
CLOUDFLARED_VERSION="<pinned-version>"
curl -LO "https://github.com/cloudflare/cloudflared/releases/download/${CLOUDFLARED_VERSION}/cloudflared-linux-arm64"
# 在安裝前,請從 Cloudflare 的發行說明中驗證 checksum/簽章。
sudo mv cloudflared-linux-arm64 /usr/local/bin/cloudflared
sudo chmod +x /usr/local/bin/cloudflared
# 建立 cloudflared 設定檔
sudo mkdir -p /etc/cloudflared
sudo tee /etc/cloudflared/config.yml << EOF
proxy-dns: true
proxy-dns-port: 5053
proxy-dns-upstream:
- https://1.1.1.1/dns-query
- https://1.0.0.1/dns-query
EOF
# 建立 systemd 服務
sudo cloudflared service install
sudo systemctl start cloudflared
sudo systemctl enable cloudflared
# 現在將 Pi-hole 指向本機 DoH 代理程式:
# Pi-hole 管理介面 → 設定 → DNS → 自訂上游 DNS
# 設定為:127.0.0.1#5053
# 取消勾選所有其他上游解析器
本機 DNS 記錄
讓您的服務可以透過名稱存取(例如 nas.home.lan、grafana.home.lan)。
網域名稱注意事項:
.home.lan在家庭實驗室中被廣泛使用且實際可行。 IETF 為本機用途保留的後綴是.home.arpa(RFC 8375)— 若要遵循標準,請使用該後綴。 避免在 Pi-hole DNS 記錄中使用.local,因為它會與 mDNS/Bonjour 衝突。
# Pi-hole 管理介面 → 本機 DNS → DNS 記錄
網域 IP
nas.home.lan 192.168.30.10
pi.home.lan 192.168.30.2
grafana.home.lan 192.168.30.3
proxmox.home.lan 192.168.30.4
# 從網路上的任何裝置:
ping nas.home.lan → 192.168.30.10
http://grafana.home.lan → 您的 Grafana 儀表板
# 若需要子網域,請新增 CNAME:
Pi-hole 管理介面 → 本機 DNS → CNAME 記錄
網域:portainer.home.lan → 目標:pi.home.lan
疑難排解
# Pi-hole 封鎖了不該封鎖的內容
pihole -q example.com # 檢查網域是否被封鎖以及屬於哪個清單
pihole -w example.com # 立即加入白名單
# DNS 完全無法解析
pihole status # 檢查 pihole-FTL 是否正在執行
dig @192.168.3.2 google.com # 直接對 Pi-hole 測試 DNS
# 重新啟動 Pi-hole DNS
pihole restartdns
# 檢查特定裝置的查詢記錄
pihole -t # 即時檢視所有查詢
# 或者在 Web 管理介面的查詢記錄中按用戶端過濾
# Pi-hole gravity 更新(重新整理封鎖清單)
pihole -g
反模式
# 不良:僅依賴一台 Pi-hole,沒有復原方案
# 若 Pi-hole 當機或 Pi 斷電,DNS 可能停止運作
# 良好:在設定過程中保留一個已記錄的路由器備援方案以進行回退
# 更佳:執行兩台 Pi-hole 以實現備援;若需嚴格封鎖,請避免使用公用備援 DNS
# 不良:未設定靜態 IP 就安裝 Pi-hole
# 若 Pi 取得新的 DHCP IP,所有裝置都會失去 DNS
# 良好:先設定靜態 IP,再安裝 Pi-hole
# 不良:啟用 Pi-hole DHCP 前未先關閉路由器的 DHCP
# 同一個網路上有兩台 DHCP 伺服器會發放衝突的 IP
# 良好:先停用路由器 DHCP,再啟用 Pi-hole DHCP
# 不良:從未更新 gravity(封鎖清單)
# 新的廣告和惡意軟體網域持續累積 — 過時的清單會漏掉它們
# 良好:排定每週 gravity 更新:pihole -g(或在「設定」→「API」中啟用)
最佳實務
- 在安裝 Pi-hole 前,為 Pi 設定靜態 IP 或 DHCP 保留
- 將 Pi-hole 用作主要 DNS;若需備援,請新增第二台 Pi-hole 而非公用解析器以實現嚴格封鎖
- 使用 cloudflared 啟用 DoH(DNS-over-HTTPS)以加密上游查詢
- 將
home.lan設定為您的本機網域,並為所有服務建立 DNS 記錄 - 偶爾檢視查詢記錄 — 被封鎖的查詢能讓您了解裝置正在做什麼
相關技能
- homelab-network-setup
- homelab-vlan-segmentation
- homelab-wireguard-vpn