====== 安裝 Pi-hole+Unbound 的 DNS (Docker) ======
* 因為之前安裝 Bind 的 DNS 管理成本很高, 最近上網廣告很多, 想直接透過 DNS 來阻絕廣告, 剛好看到這個 [[https://pi-hole.net/|Pi-hole]] + [[https://nlnetlabs.nl/projects/unbound/about/|Unbound]] 的方案
* 安裝環境 :
* VM : 1vCore, 1G RAM, 16G SSD
* OS : Alpine 3.21 + Docker Compose
* 參考 [[tech/alpine_docker]]
===== 安裝設定 =====
* 編輯 docker-compose.yml
networks:
dns_net:
driver: bridge
ipam:
config:
- subnet: 172.22.0.0/16
external: false
services:
pihole:
container_name: pihole
hostname: pihole
image: pihole/pihole:latest
#shm_size: '2gb'
networks:
dns_net:
ipv4_address: 172.22.0.6
ports:
- "53:53/tcp"
- "53:53/udp"
- "8080:80/tcp"
environment:
- 'TZ=Asia/Taipei'
- 'WEBPASSWORD=mypassword'
- 'DNS1=172.22.0.7#53'
- 'DNS2=1.1.1.1'
- 'DNSSEC=true'
- 'REV_SERVER=true'
- 'REV_SERVER_DOMAIN=local'
- 'REV_SERVER_TARGET=172.22.0.1'
- 'REV_SERVER_CIDR=172.22.0.0/16'
cap_add:
- NET_ADMIN
- SYS_NICE
volumes:
- './etc-pihole/:/etc/pihole/'
- './etc-dnsmasq.d/:/etc/dnsmasq.d/'
- '/etc/resolv.conf:/etc/resolv.conf:ro'
depends_on:
unbound:
condition: service_healthy
healthcheck:
test: ["CMD", "dig", "@127.0.0.1", "-p53", "pi.hole"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
#disable: true
restart: unless-stopped
unbound:
container_name: unbound
image: mvance/unbound:latest
networks:
dns_net:
ipv4_address: 172.22.0.7
volumes:
#- ./etc-unbound:/opt/unbound/etc/unbound
- ./etc-unbound/root.hints:/opt/unbound/etc/unbound/root.hints:ro
ports:
- "5053:53/tcp"
- "5053:53/udp"
healthcheck:
disable: false
restart: unless-stopped
* 啟動服務
docker compose up -d
===== 開始使用 =====
* Pi-hole 管理網址 - http://hostip:8080/admin (使用 mypassword 登入) \\ {{:tech:2023-11-02_021124.png?600|}} \\ {{:tech:2023-11-02_021218.png?600|}}
* 確認設定使用 unbound - 172.22.0.7#53 \\ {{:tech:2023-11-02_021355.png?600|}}
===== 驗證成效 =====
* 使用 https://d3ward.github.io/toolz/adblock.html 進行驗證 \\ {{:tech:2023-11-02_120722.png?600|}}
* 可以參考 https://firebog.net/ 加入 ADList 提高阻擋廣告的能力 \\ {{:tech:2023-11-03_103014_1.png?600|}}
* 可以參考 https://github.com/sefinek24/Sefinek-Blocklist-Collection/blob/main/lists/md/Pi-hole.md 加入 ADList 提高阻擋廣告能力
* 可以參考 [[tech/dnsperf]]
===== FAQ =====
- unbound 預設阻擋上游 DNS 回復私有網路保留 IP 網段 Exp. 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16 , 如果要開放這限制, 需要
- 複製 unbound 內的 /opt/unbound/etc/unbound 目錄出來成為 etc-ubound
docker cp unbound:/opt/unbound/etc/unbound .
mv unbound etc-unbound
- 修改 docker-compose.yml 將 volumes 註記取消, 讓 etc-ubound 可掛載起來
:
unbound:
container_name: unbound
image: mvance/unbound:latest
networks:
dns_net:
ipv4_address: 172.22.0.7
volumes:
- ./etc-unbound:/opt/unbound/etc/unbound
ports:
:
- 修改 ./etc-unbound/unbound.conf 將 private-address 設定註記掉 Exp.
:
# These private network addresses are not allowed to be returned for public
# private-address: 10.0.0.0/8
# private-address: 172.16.0.0/12
# private-address: 192.168.0.0/16
# private-address: 169.254.0.0/16
# private-address: fd00::/8
# private-address: fe80::/10
# private-address: ::ffff:0:0/96
:
- 重新啟動 docker compose
docker compose up -d
- 如何調整自動更新週期
* 參考 :
* [[https://discourse.pi-hole.net/t/auto-update-gravity-database/60375|將 /etc/cron.d/pihole 掛載出來]] **此方式會造成重啟時, dnsmasq 無法正常啟動**:-?
* [[https://github.com/pi-hole/docker-pi-hole/issues/107|在 host 使用 docker exec 執行更新]]
- 先確認可以在 host 執行更新
docker exec pihole pihole updateGravity
- 在 host 建立 crontab 定義更新週期
- 如何增加一筆 wildcard 的 DNS 紀錄 Exp. *.lab.ichiayi.com -> 192.168.11.30
* 參考網址 - https://hetzbiz.cloud/2022/03/04/wildcard-dns-in-pihole/
* 參考網址 - https://www.reddit.com/r/pihole/comments/1it0xm8/wildcard_dns_in_pihole_v6/?rdt=47952
* 其實是可以設定, 只是無法直接透過 GUI 來處理
* 在 pi-hole v6 之後, 需要再 GUI 勾選 **misc.etc_dnsmasq_d**
* Settings->All settings->Miscellaneous->**[√]misc.etc_dnsmasq_d**
* 手動處理程序如下:
- 在 /etc/dnsmasq.d/ 目錄, 也就是對應出來的 /etc-dnsmasq.d 目錄內建立一個檔案 Exp. 02-lab-wildcard-dns.conf
- 在檔案內加入 address=/lab.ichiayi.com/192.168.11.30
- 重啟 pihole-FTL 服務
docker compose restart pihole
- 透過 nslookup abc.lab.ichiayi.com 就可以看到回應的 IP 是 192.168.11.30
- 如何增加一筆 MX 的 DNS 紀錄 Exp. mail.ichiayi.com -> mail.ichiayi.com , 50
* 參考網址 - https://github.com/imp/dnsmasq/blob/master/dnsmasq.conf.example
* 其實是可以設定, 只是無法透過 GUI 來處理. 手動處理程序如下:
- 在 /etc/dnsmasq.d/ 目錄, 也就是對應出來的 /etc-dnsmasq.d 目錄內建立一個檔案 Exp. 03-mail.conf
- 在檔案內加入 mx-host=mail.ichiayi.com,mail.ichiayi.com,50
- 重啟 pihole-FTL 服務
docker compose restart pihole
- 透過 nslookup set type=mx mail.ichiayi.com 就可以看到回應
- 當發現 pi-hole 內的 nslookup 查詢速度很緩慢(/etc/resolv.conf -> nameserver 127.0.0.11)
* 參考 - https://stackoverflow.com/questions/64007727/docker-compose-internal-dns-server-127-0-0-11-connection-refused
- 將 docker-compose.yml 內的
:
ports:
- 53:53/udp
- 53:53/tcp
:
前面加上 host ip Exp. 172.16.0.245
:
ports:
- 172.16.0.245:53:53/udp
- 172.16.0.245:53:53/tcp
:
- 重啟 docker compse 即可解決
- 當大量查詢 pi-hole DNS 服務, 結果出現 FTL is not running 異常狀況
* 參考網址 - https://github.com/pi-hole/docker-pi-hole/issues/571
* docker compose logs -f 持續出現 Stopping pihole-FTL 的訊息
* docker exec pihole df -h | grep shm 出現 100% 表示 Share Memory 已經被大量 query 的紀錄塞爆
* 可以透過修改 docker-compose.yml 內將 shm_size(預設是 64MB)加大來解決, 但注意要確認不能超過主機記憶體大小
- 將 docker-compose.yml 內 #shm_size='2gb' 的 # 移除, 後面 2gb 可以改成實體主機記憶體大小的 70% 左右
- 重新啟動 docker compose docker compose up -d
- 確認修改是否成功
pve-dns:~# docker exec pihole df -h | grep shm
shm 2.0G 65M 2.0G 4% /dev/shm
- 當設定 LocalDNS 後查詢還會取用到外部 DNS 回傳的 IPv6 的 IP 問題的解法
* 參考 - https://github.com/pi-hole/pi-hole/issues/5158
- 當 pi-hole diagnosis 出現 Maximum number of concurrent DNS queries reached (max: 150) 這警告訊息
* 先查看發生時間時段 /var/log/pihole/pihole.log 的紀錄內容
* 如果確認有 Client 會正常大量查詢 DNS Exp. 監控系統 可以先將 Rate-limiting 調大
* 在 Settings->DNS->Advanced DNS settings->Rate-limiting 修改 Exp. \\ {{:tech:螢幕擷取畫面_2024-05-18_094245.png?600|}}
* 如果是出現大量內部 IP 反查紀錄 Exp. query[PTR] 51.173.43.10.in-addr.arpa from 10.20.2.218 可試著設定不要回覆私有 IP 的反查
* 在 Settings->DNS->Advanced DNS settings->Never forward reverse lookups for private IP ranges 打勾 \\ {{:tech:螢幕擷取畫面_2024-05-18_103208.png?600|}}
===== 參考網址 =====
* https://discourse.pi-hole.net/t/pihole-unbound-in-docker/62121
* https://hub.docker.com/r/mvance/unbound
* https://hub.docker.com/r/pihole/pihole
{{tag>dns adblock}}