問題
如果你喺屋企自行託管服務,大概率遇過呢個令人抓狂嘅問題:你嘅服務由外部訪問完全正常,但當你喺屋企,用域名去訪問嘅時候,卻點都唔通。
呢個就係所謂嘅Hairpin NAT問題(又叫NAT環回),下面係我最終解決佢嘅方法。
咩係Hairpin NAT?
當你由外部訪問humfurie.org嘅時候,請求會去到你嘅公網IP,再被轉發去內網伺服器,一切正常。但當你喺自己嘅網絡內部試同樣嘅操作嗰陣,你嘅路由器就會攪亂,流量走出去,又想轉返嚟,結果就出問題。
「正規」嘅解決方法係喺路由器上設定hairpin NAT規則。但事實證明呢個並唔可靠,尤其係喺MikroTik路由器上——一個叫fasttrack嘅功能會為已建立嘅連接繞過NAT規則,導致就算設定正確,hairpin NAT都會悄無聲息咁失效。
更好嘅解決方案:用AdGuard Home做DNS覆寫
與其同NAT規則死磕,更乾淨嘅方案係令你嘅本地網絡直接將域名解析去伺服器嘅內網IP。咁樣就完全唔需要hairpin喇。
第一步:安裝AdGuard Home
喺你嘅Ubuntu伺服器上,建立一個docker-compose.yml:
services:
adguardhome:
image: adguard/adguardhome
container_name: adguardhome
restart: unless-stopped
ports:
- "53:53/tcp"
- "53:53/udp"
- "3000:3000/tcp"
volumes:
- ./adguard/work:/opt/adguardhome/work
- ./adguard/conf:/opt/adguardhome/conf
labels:
- "traefik.enable=true"
- "traefik.http.routers.adguard.rule=Host(`adguard.yourdomain.com`)"
- "traefik.http.routers.adguard.entrypoints=websecure"
- "traefik.http.services.adguard.loadbalancer.server.port=80"
第二步:釋放53端口
Ubuntu預設喺53端口上使用systemd-resolved。先將佢停用:
sudo systemctl disable systemd-resolved
sudo systemctl stop systemd-resolved
sudo rm /etc/resolv.conf
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf
然後啟動AdGuard:
docker compose up -d
第三步:完成AdGuard設定
訪問http://your-server-ip:3000,完成設定精靈。設定完成後,將Traefik嘅標籤更新為使用80端口而唔係3000端口,然後重啟容器。
第四步:將MikroTik嘅DHCP指向AdGuard
喺MikroTik入面去到IP、DHCP Server、Networks,將DNS Server設定為你Ubuntu伺服器嘅IP(例如192.168.88.109)。咁樣網絡上所有裝置就會自動使用AdGuard。
第五步:喺AdGuard入面加入DNS重寫規則
去到Filters、DNS Rewrites,為每個域名加入項目——你需要同時加入根域名同子域名萬用字符:
| 域名 | 解析結果 |
|---|---|
| humfurie.org | 192.168.88.109 |
| *.humfurie.org | 192.168.88.109 |
| yourdomain.com | 192.168.88.109 |
| *.yourdomain.com | 192.168.88.109 |
注意: *.humfurie.org只涵蓋子域名,並唔涵蓋根域名本身,所以兩條都需要加入。
第六步:驗證
更新你嘅DHCP租約,並測試:
nslookup humfurie.org
回應中應該顯示你嘅內網IP,而唔係公網IP。
需要留意嘅坑
Tailscale: 如果你用緊Tailscale,佢會覆蓋你裝置上嘅DNS。請喺Tailscale嘅設定中關閉「Use Tailscale DNS settings」,否則你嘅裝置會完全無視AdGuard。
MikroTik嘅DNS快取: MikroTik會快取DNS回應。如果改完之後仲係唔生效,喺終端機入面清空快取:/ip dns cache flush
Docker同53端口: AdGuard嘅管理介面喺初始設定期間跑喺3000端口,之後會切換去80端口。設定完成後要相應更新你嘅Traefik設定。
結果
而家,所有自行託管服務無論由網絡內部定係外部訪問,都可以用同一個域名正常打開。作為附送,AdGuard Home仲畀你帶嚟全網範圍嘅廣告攔截同DNS查詢日誌功能。