BIND+DNS over HTTPs

說明一下為什麼會要這樣作。

因為環境關係,DNS protocol 出不去,只有 A 主機可以透過 HTTP 出去。

因此方案如下:

  1. A 電腦安裝 squid,其他主機可將 HTTP proxy 設定為 A 主機,這樣 HTTP 請求就可透過 A 主機出去。
  2. 環境內原有 B 主機已經安裝 BIND,此主機就安裝 cloudflare 提供的 cloudflared ,使用 DNS over HTTPs 方式,讓 DNS 查詢可以用 HTTP 請求,透過 A 主機去查詢。

安裝與設定

cloudflared 蠻好安裝的,就一個執行檔,下載以後,改個權限就可以執行了 (安裝方式)

那如果要用 systemd 來啟動,也很容易,安裝方式裡就有提供範例:

[Unit]
Description=DNS over HTTPS (DoH) proxy client
Wants=network-online.target nss-lookup.target
Before=nss-lookup.target

[Service]
Environment=http_proxy=http://<proxy>:3128
Environment=https_proxy=http://<proxy>:3128
AmbientCapabilities=CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
DynamicUser=yes
ExecStart=/usr/local/bin/cloudflared proxy-dns --port 5533

[Install]
WantedBy=multi-user.target

設定好,用 firewall-cmd 設定好防火牆 (TCP 5533) 以後,就可以去調整 BIND 的設定 /etc/named.conf

修改既有的 forwarder 設定

forwarders { 127.0.0.1 port 5533; };

重新啟動 named 以後,就可以試試看了。

流程大致如下

--[DNS查詢]--> B 主機(53/UDP) ----> B 主機(5533/TCP) --[HTTP]--> A 主機(3128/TCP) --> 外部

參考資料

dnsdiag

想查詢用哪個 DNS 伺服器比較快,之前是查到用 namebench,但這專案沒在維護了,自行編譯使用,又遇到些問題,乾脆就放棄。

後來有看到 diadiag 這個套件,就想說來用看看。

在 Ubuntu 裡,用 apt 就可以安裝。

sudo apt install dnsdiag

dnsdiag 套件裏面有3個工具

  • dnsping
  • dnstraceroute
  • dnseval

dnsping 是測試連到 DNS 伺服器的時間。

dnstraceroute 是列出到 DNS 伺服器的路由,透過這個可以看 DNS 查詢到底有沒有繞路。

dnseval 是本文重點,也就是可以針對各個 DNS 伺服器去做評估,看哪個比較快。

首先要新增一個文字檔,命名為 public-dns-servers.txt,裏面放 DNS 伺服器的 IP。

1.1.1.1
8.8.8.8
168.95.1.1
94.140.14.14
61.31.1.1

然後執行

dnseval -f public-dns-servers.txt www.facebook.com

就可以看到結果了。

server           avg(ms)     min(ms)     max(ms)     stddev(ms)  lost(%)  ttl        flags                  response
--------------------------------------------------------------------------------------------------------------------
1.1.1.1          9.471       9.167       9.659       0.219       %20      3599       QR -- -- RD RA -- --   NOERROR             
8.8.8.8          10.621      8.588       13.036      1.961       %12      1002       QR -- -- RD RA -- --   NOERROR             
168.95.1.1       9.119       9.119       9.119       0.000       %50      2648       QR -- -- RD RA -- --   NOERROR             
94.140.14.14     0.000       0.000       0.000       0.000       %100     N/A        -- -- -- -- -- -- --   No Response         
61.31.1.1        8.215       8.132       8.298       0.118       %33      1366       QR -- -- RD RA -- --   NOERROR             

好了,有了這工具,就可以找出最適合的 DNS 伺服器了。

處理 AsusWRT-Merlin DNS 查找慢的問題

年初的時候有處理過,那時候感覺還沒這麼慢,最近這一兩個月,慢的感覺愈來愈明顯,看來不處理是不行了。

先進行觀察,通常是第一次查找時會特別慢,之後就會比較順暢。

回想年初的設定是讓 AsusWRT-Merlin 當作是主要 DNS,也有 Cache,當查找不到時才去外面找。那麼,看樣子就是外面的 DNS 伺服器太慢了,導致第一次查找慢。

從網頁管理介面找不到什麼設定可以調整,想到的解決方法是直接用 SSH 連進去改,於是就找到這篇:Asuswrt-merlin 自定義 dnsmasq 解析 │ 坂本 Sakamoto.blog – 探究科技未知領域

步驟如下:

  1. 點選左側的 Administration > System (系統管理 > 系統設定)
    1. Format JFES partiton at next boot -> No
    2. Enable JFFS custom scripts and configs -> Yes
    3. Enable SSH -> LAN only
    4. 把 ~/.ssh/id_rsa.pub 裡的內容複製起來,然後貼到「授權金鑰」欄裡。
  2. 選擇下方的套用
  3. LAN > DNSFilter
    1. Enable DNS-based Filtering 改為 OFF
  4. LAN > DHCP Server
    1. Advertise routers IP in addition to user specified DNS -> Yes
  5. 用 SSH 連線進去,使用者名稱是你登入 web 管理介面用的使用者名稱,例如:ssh root@192.168.1.1
  6. 附加 dnsmasq 設定
    1. touch /jffs/configs/dnsmasq.conf.add
    2. 填入 server=8.8.8.8 (若有多個,記得換行)
    3. 填入 min-cache-ttl=600 ,確保 cache 最少保留 600 秒 (10分鐘)
    4. 填入 max-cache-ttl=1800,確保 cache 最多就保留 1800 秒 (30分鐘)
  7. 加入 dnsmasq 事後設定腳本,這主要是把原有的 servers-file 拿掉。
    1. touch /jffs/scripts/dnsmasq.postconf
    2. 腳本內容請參考後面的腳本
    3. chmod +x /jffs/scripts/dnsmasq.postconf
  8. 重新啟動

經過這樣的設定之後,再來做測試,情況的確比之前好多了,繼續來觀察看看。

dnsmasq 事後設定腳本

#!/bin/sh
# /jffs/scripts/dnsmasq.postconf
CONFIG=$1
source /usr/sbin/helper.sh
pc_delete "servers-file=/tmp/resolv.dnsmasq" $CONFIG

其他參考資料