原本是照 jkgtw 大大這篇的教學做的,但我的需求不太一樣,我沒有用路由器在 WiFi 下直接指定 DNS 使用 AdGuard Home,因為這樣如果誤擋的話很難幫家人或裝置 debug 是不是 DNS 的問題。
因此我的需求變成了:用 Surge 在網路變化時,使用指定的 DNS,而不是單純的「開」或「關」而已。
方法跟 jkgtw 大大的教學差不多,只是模組我們改成需要建立兩個。我的情境是在家的時候直接用 IP 連家裡的 AdGuard Home,出外的時候則改用 DoH 去連回家裡的 AdGuard Home。
模組 1:
#!name=AdGuard Home #!desc=啟用 AdGuard Home 本地 DNS [General] dns-server = 192.168.1.100
模組 2(這裡用 FutaDNS 舉例):
#!name=AdGuard Home DoH #!desc=啟用 AdGuard Home DoH [General] doh-server = https://app.futa.gg/dns-query
然後 script 改成:
const dns_module_home = "AdGuard Home"; const dns_module_out = "AdGuard Home DoH"; const http_api = "localhost:6171"; const http_api_key = "YOUR_API_KEY"; let request = { url: `http://${http_api}/v1/modules`, headers: { "X-Key": http_api_key }, body: {}, } getModuleStatus(dns_module_home, dns_module_out).then(main) function getModuleStatus(dns_module_home, dns_module_out) { return new Promise(resolve => { $httpClient.get(request, (error, response, data) => { let enabled = JSON.parse(data).enabled; resolve([enabled.includes(dns_module_home), enabled.includes(dns_module_out)]); }); }); } function switchModule(enable_module_name, disable_module_name) { request.body[enable_module_name] = true; request.body[disable_module_name] = false; $httpClient.post(request, () => $done()); } function main(module_status) { let home = ($network.wifi.ssid == 'SSID1' || $network.wifi.ssid == 'SSID2'); if (home && (!module_status[0] || module_status[1])) { // 在家,用本地 DNS $notification.post("使用 AdGuard Home 本地 DNS", "", "") switchModule(dns_module_home, dns_module_out); } else if (!home && (module_status[0] || !module_status[1])) { // 不在家,使用 DoH $notification.post("使用 AdGuard Home DoH", "", "") switchModule(dns_module_out, dns_module_home); } else { // 重複觸發 => 結束 // $notification.post("重複觸發","","") $done(); } }
這篇文章 使用 Surge 在網路變化時,自動切換 DNS – 改 最早出現於 Hiraku Dev。