luci-app-mosdns: init at 97867ea

This commit is contained in:
xinyangli 2024-05-24 00:40:16 +08:00
parent 6c536e3c19
commit 90cc8ca0d2
Signed by: xin
SSH key fingerprint: SHA256:qZ/tzd8lYRtUFSrfBDBMcUqV4GHKxqeqRA3huItgvbk
44 changed files with 2546 additions and 0 deletions

20
luci-app-mosdns/Makefile Normal file
View file

@ -0,0 +1,20 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-mosdns
PKG_VERSION:=1.5.20
PKG_RELEASE:=1
LUCI_TITLE:=LuCI Support for mosdns
LUCI_PKGARCH:=all
LUCI_DEPENDS:=+mosdns +jsonfilter +luci-compat +curl +v2ray-geoip +v2ray-geosite +v2dat
define Package/$(PKG_NAME)/conffiles
/etc/config/mosdns
/etc/mosdns/cache.dump
/etc/mosdns/config_custom.yaml
/etc/mosdns/rule
endef
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature

View file

@ -0,0 +1,53 @@
local sys = require "luci.sys"
local http = require "luci.http"
module("luci.controller.mosdns", package.seeall)
function index()
if not nixio.fs.access("/etc/config/mosdns") then
return
end
local page = entry({"admin", "services", "mosdns"}, alias("admin", "services", "mosdns", "basic"), _("MosDNS"), 30)
page.dependent = true
page.acl_depends = { "luci-app-mosdns" }
entry({"admin", "services", "mosdns", "basic"}, cbi("mosdns/basic"), _("Basic Setting"), 1).leaf = true
entry({"admin", "services", "mosdns", "rule_list"}, cbi("mosdns/rule_list"), _("Rule List"), 2).leaf = true
entry({"admin", "services", "mosdns", "update"}, cbi("mosdns/update"), _("Geodata Update"), 3).leaf = true
entry({"admin", "services", "mosdns", "log"}, cbi("mosdns/log"), _("Logs"), 4).leaf = true
entry({"admin", "services", "mosdns", "status"}, call("act_status")).leaf = true
entry({"admin", "services", "mosdns", "get_log"}, call("get_log")).leaf = true
entry({"admin", "services", "mosdns", "clear_log"}, call("clear_log")).leaf = true
entry({"admin", "services", "mosdns", "geo_update"}, call("geo_update")).leaf = true
entry({"admin", "services", "mosdns", "flush_cache"}, call("flush_cache")).leaf = true
end
function act_status()
local e = {}
e.running = sys.call("pgrep -f mosdns >/dev/null") == 0
http.prepare_content("application/json")
http.write_json(e)
end
function get_log()
http.write(sys.exec("cat $(/usr/share/mosdns/mosdns.sh logfile)"))
end
function clear_log()
sys.call("cat /dev/null > $(/usr/share/mosdns/mosdns.sh logfile)")
end
function geo_update()
local e = {}
e.updating = sys.call("/usr/share/mosdns/mosdns.sh geodata >/dev/null") == 0
http.prepare_content("application/json")
http.write_json(e)
end
function flush_cache()
local e = {}
e.flushing = sys.call("/usr/share/mosdns/mosdns.sh flush >/dev/null") == 0
http.prepare_content("application/json")
http.write_json(e)
end

View file

@ -0,0 +1,243 @@
local fs = require "nixio.fs"
local sys = require "luci.sys"
if fs.access("/usr/bin/mosdns") then
mosdns_version = sys.exec("/usr/share/mosdns/mosdns.sh version")
else
mosdns_version = "Unknown Version"
end
m = Map("mosdns")
m.title = translate("MosDNS") .. " " .. mosdns_version
m.description = translate("MosDNS is a plugin-based DNS forwarder/traffic splitter.")
m:section(SimpleSection).template = "mosdns/mosdns_status"
s = m:section(TypedSection, "mosdns")
s.addremove = false
s.anonymous = true
s:tab("basic", translate("Basic Options"))
o = s:taboption("basic", Flag, "enabled", translate("Enabled"))
o.rmempty = false
o = s:taboption("basic", ListValue, "configfile", translate("Config File"))
o:value("/var/etc/mosdns.json", translate("Default Config"))
o:value("/etc/mosdns/config_custom.yaml", translate("Custom Config"))
o.default = "/var/etc/mosdns.json"
o = s:taboption("basic", Value, "listen_port", translate("Listen port"))
o.datatype = "and(port,min(1))"
o.default = 5335
o:depends("configfile", "/var/etc/mosdns.json")
o = s:taboption("basic", ListValue, "log_level", translate("Log Level"))
o:value("debug", translate("Debug"))
o:value("info", translate("Info"))
o:value("warn", translate("Warning"))
o:value("error", translate("Error"))
o.default = "info"
o:depends("configfile", "/var/etc/mosdns.json")
o = s:taboption("basic", Value, "log_file", translate("Log File"))
o.placeholder = "/var/log/mosdns.log"
o.default = "/var/log/mosdns.log"
o:depends("configfile", "/var/etc/mosdns.json")
o = s:taboption("basic", Flag, "redirect", translate("DNS Forward"), translate("Forward Dnsmasq Domain Name resolution requests to MosDNS"))
o.default = true
o = s:taboption("basic", Flag, "prefer_ipv4", translate("Remote DNS prefer IPv4"), translate("IPv4 is preferred for remote DNS resolution of dual-stack addresses, and is not affected when the destination is IPv6 only"))
o:depends( "configfile", "/var/etc/mosdns.json")
o.default = true
o = s:taboption("basic", Flag, "custom_local_dns", translate("Custom China DNS"), translate("Follow WAN interface DNS if not enabled"))
o:depends( "configfile", "/var/etc/mosdns.json")
o.default = false
o = s:taboption("basic", Flag, "apple_optimization", translate("Apple domains optimization"), translate("For Apple domains equipped with Chinese mainland CDN, always responsive to Chinese CDN IP addresses"))
o:depends("custom_local_dns", "1")
o.default = false
o = s:taboption("basic", DynamicList, "local_dns", translate("China DNS server"))
o:value("119.29.29.29", translate("Tencent Public DNS (119.29.29.29)"))
o:value("119.28.28.28", translate("Tencent Public DNS (119.28.28.28)"))
o:value("223.5.5.5", translate("Aliyun Public DNS (223.5.5.5)"))
o:value("223.6.6.6", translate("Aliyun Public DNS (223.6.6.6)"))
o:value("114.114.114.114", translate("Xinfeng Public DNS (114.114.114.114)"))
o:value("114.114.115.115", translate("Xinfeng Public DNS (114.114.115.115)"))
o:value("180.76.76.76", translate("Baidu Public DNS (180.76.76.76)"))
o:value("https://doh.pub/dns-query", translate("Tencent Public DNS (DNS over HTTPS)"))
o:value("quic://dns.alidns.com", translate("Aliyun Public DNS (DNS over QUIC)"))
o:value("https://dns.alidns.com/dns-query", translate("Aliyun Public DNS (DNS over HTTPS)"))
o:value("h3://dns.alidns.com/dns-query", translate("Aliyun Public DNS (DNS over HTTPS/3)"))
o:value("https://doh.360.cn/dns-query", translate("360 Public DNS (DNS over HTTPS)"))
o:depends("custom_local_dns", "1")
o = s:taboption("basic", DynamicList, "remote_dns", translate("Remote DNS server"))
o:value("tls://1.1.1.1", translate("CloudFlare Public DNS (1.1.1.1)"))
o:value("tls://1.0.0.1", translate("CloudFlare Public DNS (1.0.0.1)"))
o:value("tls://8.8.8.8", translate("Google Public DNS (8.8.8.8)"))
o:value("tls://8.8.4.4", translate("Google Public DNS (8.8.4.4)"))
o:value("tls://9.9.9.9", translate("Quad9 Public DNS (9.9.9.9)"))
o:value("tls://149.112.112.112", translate("Quad9 Public DNS (149.112.112.112)"))
o:value("tls://208.67.222.222", translate("Cisco Public DNS (208.67.222.222)"))
o:value("tls://208.67.220.220", translate("Cisco Public DNS (208.67.220.220)"))
o:depends("configfile", "/var/etc/mosdns.json")
o = s:taboption("basic", ListValue, "bootstrap_dns", translate("Bootstrap DNS servers"), translate("Bootstrap DNS servers are used to resolve IP addresses of the DoH/DoT resolvers you specify as upstreams"))
o:value("119.29.29.29", translate("Tencent Public DNS (119.29.29.29)"))
o:value("119.28.28.28", translate("Tencent Public DNS (119.28.28.28)"))
o:value("223.5.5.5", translate("Aliyun Public DNS (223.5.5.5)"))
o:value("223.6.6.6", translate("Aliyun Public DNS (223.6.6.6)"))
o:value("114.114.114.114", translate("Xinfeng Public DNS (114.114.114.114)"))
o:value("114.114.115.115", translate("Xinfeng Public DNS (114.114.115.115)"))
o:value("180.76.76.76", translate("Baidu Public DNS (180.76.76.76)"))
o:value("8.8.8.8", translate("Google Public DNS (8.8.8.8)"))
o:value("1.1.1.1", translate("CloudFlare Public DNS (1.1.1.1)"))
o.default = "119.29.29.29"
o:depends("configfile", "/var/etc/mosdns.json")
s:tab("advanced", translate("Advanced Options"))
o = s:taboption("advanced", Value, "concurrent", translate("Concurrent"), translate("DNS query request concurrency, The number of upstream DNS servers that are allowed to initiate requests at the same time"))
o.datatype = "and(uinteger,min(1),max(3))"
o.default = "2"
o:depends("configfile", "/var/etc/mosdns.json")
o = s:taboption("advanced", Value, "idle_timeout", translate("Idle Timeout"), translate("DoH/TCP/DoT Connection Multiplexing idle timeout (default 30 seconds)"))
o.datatype = "and(uinteger,min(1))"
o.default = "30"
o:depends("configfile", "/var/etc/mosdns.json")
o = s:taboption("advanced", Flag, "enable_pipeline", translate("TCP/DoT Connection Multiplexing"), translate("Enable TCP/DoT RFC 7766 new Query Pipelining connection multiplexing mode"))
o.rmempty = false
o.default = false
o:depends("configfile", "/var/etc/mosdns.json")
o = s:taboption("advanced", Flag, "insecure_skip_verify", translate("Disable TLS Certificate"), translate("Disable TLS Servers certificate validation, Can be useful if system CA certificate expires or the system time is out of order"))
o.rmempty = false
o.default = false
o:depends("configfile", "/var/etc/mosdns.json")
o = s:taboption("advanced", Flag, "enable_ecs_remote", translate("Enable EDNS client subnet"))
o.rmempty = false
o.default = false
o:depends("configfile", "/var/etc/mosdns.json")
o = s:taboption("advanced", Value, "remote_ecs_ip", translate("IP Address"), translate("Please provide the IP address you use when accessing foreign websites. This IP subnet (0/24) will be used as the ECS address for Remote DNS requests") .. '<br />' .. translate("This feature is typically used when using a self-built DNS server as an Remote DNS upstream (requires support from the upstream server)"))
o.datatype = "ipaddr"
o:depends("enable_ecs_remote", "1")
o = s:taboption("advanced", Flag, "dns_leak", translate("Prevent DNS Leaks"), translate("Enable this option fallback policy forces forwarding to remote DNS"))
o.rmempty = false
o.default = false
o:depends("configfile", "/var/etc/mosdns.json")
o = s:taboption("advanced", Value, "cache_size", translate("DNS Cache Size"), translate("DNS cache size (in piece). To disable caching, please set to 0."))
o.datatype = "and(uinteger,min(0))"
o.default = "8000"
o:depends("configfile", "/var/etc/mosdns.json")
o = s:taboption("advanced", Value, "lazy_cache_ttl", translate("Lazy Cache TTL"), translate("Lazy cache survival time (in second). To disable Lazy Cache, please set to 0."))
o.datatype = "and(uinteger,min(0))"
o.default = "86400"
o:depends("configfile", "/var/etc/mosdns.json")
o = s:taboption("advanced", Flag, "dump_file", translate("Cache Dump"), translate("Save the cache locally and reload the cache dump on the next startup"))
o.rmempty = false
o.default = false
o:depends("configfile", "/var/etc/mosdns.json")
o = s:taboption("advanced", Value, "dump_interval", translate("Auto Save Cache Interval"))
o.datatype = "and(uinteger,min(0))"
o.default = "3600"
o:depends("dump_file", "1")
o = s:taboption("advanced", Value, "minimal_ttl", translate("Minimum TTL"), translate("Modify the Minimum TTL value (seconds) for DNS answer results, 0 indicating no modification"))
o.datatype = "and(uinteger,min(0),max(604800))"
o.default = "0"
o:depends("configfile", "/var/etc/mosdns.json")
o = s:taboption("advanced", Value, "maximum_ttl", translate("Maximum TTL"), translate("Modify the Maximum TTL value (seconds) for DNS answer results, 0 indicating no modification"))
o.datatype = "and(uinteger,min(0),max(604800))"
o.default = "0"
o:depends("configfile", "/var/etc/mosdns.json")
o = s:taboption("advanced", Flag, "adblock", translate("Enable DNS ADblock"))
o:depends("configfile", "/var/etc/mosdns.json")
o.default = false
o = s:taboption("advanced", DynamicList, "ad_source", translate("ADblock Source"), translate("When using custom rule sources, please use rule types supported by MosDNS (domain lists).") .. '<br />' .. translate("Support for local files, such as: file:///var/mosdns/example.txt"))
o:depends("adblock", "1")
o.default = "geosite.dat"
o:value("geosite.dat", "v2ray-geosite")
o:value("https://raw.githubusercontent.com/privacy-protection-tools/anti-AD/master/anti-ad-domains.txt", "anti-AD")
o:value("https://raw.githubusercontent.com/Cats-Team/AdRules/main/mosdns_adrules.txt", "Cats-Team/AdRules")
o:value("https://raw.githubusercontent.com/neodevpro/neodevhost/master/domain", "NEO DEV HOST")
o = s:taboption("basic", Button, "_reload", translate("Restart-Service"), translate("Restart the MosDNS process to take effect of new configuration"))
o.write = function()
sys.exec("/etc/init.d/mosdns reload")
end
o:depends("configfile", "/etc/mosdns/config_custom.yaml")
o = s:taboption("basic", TextValue, "config_custom", translate("Configuration Editor"))
o.template = "cbi/tvalue"
o.rows = 25
o:depends("configfile", "/etc/mosdns/config_custom.yaml")
function o.cfgvalue(self, section)
return fs.readfile("/etc/mosdns/config_custom.yaml")
end
function o.write(self, section, value)
value = value:gsub("\r\n?", "\n")
fs.writefile("/etc/mosdns/config_custom.yaml", value)
end
-- codemirror
o = s:taboption("basic", DummyValue, "")
o.template = "mosdns/mosdns_editor"
s:tab("cloudflare", translate("Cloudflare Options"))
o = s:taboption("cloudflare", Flag, "cloudflare", translate("Enabled"), translate("Match the parsing result with the Cloudflare IP ranges, and when there is a successful match, use the 'Custom IP' as the parsing result (experimental feature)"))
o.rmempty = false
o.default = false
o:depends("configfile", "/var/etc/mosdns.json")
o = s:taboption("cloudflare", DynamicList, "cloudflare_ip", translate("Custom IP"))
o.datatype = "ipaddr"
o:depends("configfile", "/var/etc/mosdns.json")
o = s:taboption("cloudflare", TextValue, "cloudflare_cidr", translate("Cloudflare IP Ranges"))
o.description = translate("IPv4 CIDR") .. [[<a href="https://www.cloudflare.com/ips-v4" target="_blank">https://www.cloudflare.com/ips-v4</a>]] .. '<br />' .. translate("IPv6 CIDR") .. [[<a href="https://www.cloudflare.com/ips-v6" target="_blank">https://www.cloudflare.com/ips-v6</a>]]
o.template = "cbi/tvalue"
o.rows = 15
o:depends("configfile", "/var/etc/mosdns.json")
function o.cfgvalue(self, section)
return fs.readfile("/etc/mosdns/rule/cloudflare-cidr.txt")
end
function o.write(self, section, value)
value = value:gsub("\r\n?", "\n")
fs.writefile("/etc/mosdns/rule/cloudflare-cidr.txt", value)
end
s:tab("api", translate("API Options"))
o = s:taboption("api", Value, "listen_port_api", translate("API Listen port"))
o.datatype = "and(port,min(1))"
o.default = 9091
o:depends("configfile", "/var/etc/mosdns.json")
o = s:taboption("api", Button, "flush_cache", translate("Flush Cache"), translate("Flushing Cache will clear any IP addresses or DNS records from MosDNS cache"))
o.rawhtml = true
o.template = "mosdns/mosdns_flush_cache"
o:depends("configfile", "/var/etc/mosdns.json")
s:tab("geodata", translate("GeoData Export"))
o = s:taboption("geodata", DynamicList, "geosite_tags", translate("GeoSite Tags"), translate("Enter the GeoSite.dat category to be exported, Allow add multiple tags") .. '<br />' .. translate("Export directory: /var/mosdns"))
o:depends("configfile", "/etc/mosdns/config_custom.yaml")
o = s:taboption("geodata", DynamicList, "geoip_tags", translate("GeoIP Tags"), translate("Enter the GeoIP.dat category to be exported, Allow add multiple tags") .. '<br />' .. translate("Export directory: /var/mosdns"))
o:depends("configfile", "/etc/mosdns/config_custom.yaml")
return m

View file

@ -0,0 +1,5 @@
m = Map("mosdns")
m:append(Template("mosdns/mosdns_log"))
return m

View file

@ -0,0 +1,99 @@
local datatypes = require "luci.cbi.datatypes"
local white_list_file = "/etc/mosdns/rule/whitelist.txt"
local block_list_file = "/etc/mosdns/rule/blocklist.txt"
local grey_list_file = "/etc/mosdns/rule/greylist.txt"
local hosts_list_file = "/etc/mosdns/rule/hosts.txt"
local redirect_list_file = "/etc/mosdns/rule/redirect.txt"
local local_ptr_file = "/etc/mosdns/rule/local-ptr.txt"
local ddns_list_file = "/etc/mosdns/rule/ddnslist.txt"
m = Map("mosdns")
s = m:section(TypedSection, "mosdns", translate("Rule Settings"))
s.anonymous = true
s:tab("white_list", translate("White Lists"))
s:tab("block_list", translate("Block Lists"))
s:tab("grey_list", translate("Grey Lists"))
s:tab("ddns_list", translate("DDNS Lists"))
s:tab("hosts_list", translate("Hosts"))
s:tab("redirect_list", translate("Redirect"))
s:tab("local_ptr_list", translate("Block PTR"))
o = s:taboption("white_list", TextValue, "whitelist", "", "<font color='red'>" .. translate("These domain names allow DNS resolution with the highest priority. Please input the domain names of websites, every line can input only one website domain. For example: hm.baidu.com.") .. "</font>" .. "<font color='#00bd3e'>" .. translate("<br>The list of rules only apply to 'Default Config' profiles.") .. "</font>")
o.rows = 15
o.wrap = "off"
o.cfgvalue = function(self, section) return nixio.fs.readfile(white_list_file) or "" end
o.write = function(self, section, value) nixio.fs.writefile(white_list_file , value:gsub("\r\n", "\n")) end
o.remove = function(self, section, value) nixio.fs.writefile(white_list_file , "") end
o.validate = function(self, value)
return value
end
o = s:taboption("block_list", TextValue, "blocklist", "", "<font color='red'>" .. translate("These domains are blocked from DNS resolution. Please input the domain names of websites, every line can input only one website domain. For example: baidu.com.") .. "</font>" .. "<font color='#00bd3e'>" .. translate("<br>The list of rules only apply to 'Default Config' profiles.") .. "</font>")
o.rows = 15
o.wrap = "off"
o.cfgvalue = function(self, section) return nixio.fs.readfile(block_list_file) or "" end
o.write = function(self, section, value) nixio.fs.writefile(block_list_file, value:gsub("\r\n", "\n")) end
o.remove = function(self, section, value) nixio.fs.writefile(block_list_file, "") end
o.validate = function(self, value)
return value
end
o = s:taboption("grey_list", TextValue, "greylist", "", "<font color='red'>" .. translate("These domains are always resolved using remote DNS. Please input the domain names of websites, every line can input only one website domain. For example: google.com.") .. "</font>" .. "<font color='#00bd3e'>" .. translate("<br>The list of rules only apply to 'Default Config' profiles.") .. "</font>")
o.rows = 15
o.wrap = "off"
o.cfgvalue = function(self, section) return nixio.fs.readfile(grey_list_file) or "" end
o.write = function(self, section, value) nixio.fs.writefile(grey_list_file, value:gsub("\r\n", "\n")) end
o.remove = function(self, section, value) nixio.fs.writefile(grey_list_file, "") end
o.validate = function(self, value)
return value
end
o = s:taboption("ddns_list", TextValue, "ddns", "", "<font color='red'>" .. translate("These domains are always resolved using local DNS. And force TTL 5 seconds, DNS resolution results will not enter the cache. For example: myddns.example.com.") .. "</font>" .. "<font color='#00bd3e'>" .. translate("<br>The list of rules only apply to 'Default Config' profiles.") .. "</font>")
o.rows = 15
o.wrap = "off"
o.cfgvalue = function(self, section) return nixio.fs.readfile(ddns_list_file) or "" end
o.write = function(self, section, value) nixio.fs.writefile(ddns_list_file, value:gsub("\r\n", "\n")) end
o.remove = function(self, section, value) nixio.fs.writefile(ddns_list_file, "") end
o.validate = function(self, value)
return value
end
o = s:taboption("hosts_list", TextValue, "hosts", "", "<font color='red'>" .. translate("Hosts For example: baidu.com 10.0.0.1") .. "</font>" .. "<font color='#00bd3e'>" .. translate("<br>The list of rules only apply to 'Default Config' profiles.") .. "</font>")
o.rows = 15
o.wrap = "off"
o.cfgvalue = function(self, section) return nixio.fs.readfile(hosts_list_file) or "" end
o.write = function(self, section, value) nixio.fs.writefile(hosts_list_file, value:gsub("\r\n", "\n")) end
o.remove = function(self, section, value) nixio.fs.writefile(hosts_list_file, "") end
o.validate = function(self, value)
return value
end
o = s:taboption("redirect_list", TextValue, "redirect", "", "<font color='red'>" .. translate("The domain name to redirect the request to. Requests domain A, but returns records for domain B. example: a.com b.com") .. "</font>" .. "<font color='#00bd3e'>" .. translate("<br>The list of rules only apply to 'Default Config' profiles.") .. "</font>")
o.rows = 15
o.wrap = "off"
o.cfgvalue = function(self, section) return nixio.fs.readfile(redirect_list_file) or "" end
o.write = function(self, section, value) nixio.fs.writefile(redirect_list_file, value:gsub("\r\n", "\n")) end
o.remove = function(self, section, value) nixio.fs.writefile(redirect_list_file, "") end
o.validate = function(self, value)
return value
end
o = s:taboption("local_ptr_list", TextValue, "local_ptr", "", "<font color='red'>" .. translate("These domains are blocked from PTR requests") .. "</font>" .. "<font color='#00bd3e'>" .. translate("<br>The list of rules only apply to 'Default Config' profiles.") .. "</font>")
o.rows = 15
o.wrap = "off"
o.cfgvalue = function(self, section) return nixio.fs.readfile(local_ptr_file) or "" end
o.write = function(self, section, value) nixio.fs.writefile(local_ptr_file, value:gsub("\r\n", "\n")) end
o.remove = function(self, section, value) nixio.fs.writefile(local_ptr_file, "") end
o.validate = function(self, value)
return value
end
local apply = luci.http.formvalue("cbi.apply")
if apply then
luci.sys.exec("/etc/init.d/mosdns reload")
end
return m

View file

@ -0,0 +1,37 @@
m = Map("mosdns")
s = m:section(TypedSection, "mosdns", translate("Update GeoIP & GeoSite dat"))
s.addremove = false
s.anonymous = true
o = s:option(Flag, "geo_auto_update", translate("Enable Auto Database Update"))
o.rmempty = false
o = s:option(ListValue, "geo_update_week_time", translate("Update Cycle"))
o:value("*", translate("Every Day"))
o:value("1", translate("Every Monday"))
o:value("2", translate("Every Tuesday"))
o:value("3", translate("Every Wednesday"))
o:value("4", translate("Every Thursday"))
o:value("5", translate("Every Friday"))
o:value("6", translate("Every Saturday"))
o:value("7", translate("Every Sunday"))
o.default = "3"
o = s:option(ListValue, "geo_update_day_time", translate("Update Time"))
for t = 0, 23 do
o:value(t, t..":00")
end
default = 3
o = s:option(Value, "github_proxy", translate("GitHub Proxy"), translate("Update data files with GitHub Proxy, leave blank to disable proxy downloads."))
o:value("https://gh-proxy.com", translate("https://gh-proxy.com"))
o:value("https://ghps.cc", translate("https://ghps.cc"))
o.rmempty = true
o.default = ""
o = s:option(Button, "geo_update_database", translate("Database Update"))
o.rawhtml = true
o.template = "mosdns/mosdns_geo_update"
return m

View file

@ -0,0 +1,21 @@
<%+cbi/valueheader%>
<script src="/luci-static/resources/mosdns/lib/codemirror.js"></script>
<script src="/luci-static/resources/mosdns/addon/fold/foldcode.js"></script>
<script src="/luci-static/resources/mosdns/addon/fold/foldgutter.js"></script>
<script src="/luci-static/resources/mosdns/addon/fold/indent-fold.js"></script>
<script src="/luci-static/resources/mosdns/mode/yaml/yaml.js"></script>
<link rel="stylesheet" href="/luci-static/resources/mosdns/addon/fold/foldgutter.css" />
<link rel="stylesheet" href="/luci-static/resources/mosdns/lib/codemirror.css" />
<link rel="stylesheet" href="/luci-static/resources/mosdns/theme/dracula.css" />
<script type="text/javascript">//<![CDATA[
var editor = CodeMirror.fromTextArea(document.getElementById("cbid.mosdns.config.config_custom"), {
mode: "text/yaml",
styleActiveLine: true,
lineNumbers: true,
theme: "dracula",
lineWrapping: true,
matchBrackets: true
}
);//]]>
</script>
<%+cbi/valuefooter%>

View file

@ -0,0 +1,34 @@
<%+cbi/valueheader%>
<script type="text/javascript">//<![CDATA[
function flush_cache(btn, dataname)
{
btn.disabled = true;
btn.value = '<%:Flushing...%> ';
st=dataname;
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "mosdns", "flush_cache")%>',
{ set:st },
function(x,data)
{
var tb = document.getElementById(dataname+'-status');
if (tb)
{
switch (data.flushing)
{
case true:
tb.innerHTML = "<font color='green'>" + "<%:Flushing Success%>" + "</font>";
break;
case false:
tb.innerHTML = "<font color='red'>" + "<%:Flushing Failed, Please check if MosDNS is enabled%>" + "</font>";
break;
}
}
btn.disabled = false;
btn.value = '<%:Flush Cache%>';
}
);
return false;
}
//]]></script>
<input type="button" class="btn cbi-button-action" value="<%:Flush Cache%>" onclick="return flush_cache(this,'<%=self.option%>')" />
<span id="<%=self.option%>-status"><em><%=self.value%></em></span>
<%+cbi/valuefooter%>

View file

@ -0,0 +1,34 @@
<%+cbi/valueheader%>
<script type="text/javascript">//<![CDATA[
function update_data(btn, dataname)
{
btn.disabled = true;
btn.value = '<%:Updating...%> ';
st=dataname;
XHR.get('<%=luci.dispatcher.build_url("admin", "services", "mosdns", "geo_update")%>',
{ set:st },
function(x,data)
{
var tb = document.getElementById(dataname+'-status');
if (tb)
{
switch (data.updating)
{
case true:
tb.innerHTML = "<font color='green'>" + "<%:Update success%>" + "</font>";
break;
case false:
tb.innerHTML = "<font color='red'>" + "<%:Update failed, Please check the network status%>" + "</font>";
break;
}
}
btn.disabled = false;
btn.value = '<%:Check And Update%>';
}
);
return false;
}
//]]></script>
<input type="button" class="btn cbi-button-action" value="<%:Check And Update%>" onclick="return update_data(this,'<%=self.option%>')" />
<span id="<%=self.option%>-status"><em><%=self.value%></em></span>
<%+cbi/valuefooter%>

View file

@ -0,0 +1,33 @@
<script type="text/javascript">
//<![CDATA[
function clear_log(btn) {
XHR.get('<%=url([[admin]], [[services]], [[mosdns]], [[clear_log]])%>', null,
function(x, data) {
if(x && x.status == 200) {
var log_textarea = document.getElementById('log_textarea');
log_textarea.innerHTML = "";
log_textarea.scrollTop = log_textarea.scrollHeight;
}
location.reload();
}
);
}
var scrolled = false;
XHR.poll(2, '<%=url([[admin]], [[services]], [[mosdns]], [[get_log]])%>', null,
function(x, data) {
if(x && x.status == 200) {
var log_textarea = document.getElementById('log_textarea');
log_textarea.innerHTML = x.responseText;
if (!scrolled) {
log_textarea.scrollTop = log_textarea.scrollHeight;
scrolled = true;
}
}
}
);
//]]>
</script>
<fieldset class="cbi-section" id="_log_fieldset">
<input class="btn cbi-button-action" type="button" onclick="clear_log()" value="<%:Clear logs%>" style="margin-left: 10px; margin-top: 10px;">
<textarea id="log_textarea" class="cbi-input-textarea" style="width: calc(100% - 20px); height: 645px; margin: 10px;" data-update="change" rows="5" wrap="off" readonly="readonly"></textarea>
</fieldset>

View file

@ -0,0 +1,28 @@
<script type="text/javascript">
//<![CDATA[
XHR.poll(3, '<%=url([[admin]], [[services]], [[mosdns]], [[status]])%>', null,
function(x, data) {
var tb = document.getElementById('mosdns_status');
if (data && tb) {
if (data.running) {
var links = '<em><b style=color:green>MosDNS <%:RUNNING%></b></em>';
tb.innerHTML = links;
} else {
tb.innerHTML = '<em><b style=color:red>MosDNS <%:NOT RUNNING%></b></em>';
}
}
}
);
//]]>
</script>
<style>
.mar-10 {
margin-left: 50px;
margin-right: 10px;
}
</style>
<fieldset class="cbi-section">
<p id="mosdns_status">
<em><%:Collecting data...%></em>
</p>
</fieldset>

View file

@ -0,0 +1,398 @@
msgid "Basic Setting"
msgstr "基本设置"
msgid "Basic Options"
msgstr "基本选项"
msgid "Advanced Options"
msgstr "高级选项"
msgid "Cloudflare Options"
msgstr "Cloudflare 选项"
msgid "API Options"
msgstr "API 选项"
msgid "MosDNS is a plugin-based DNS forwarder/traffic splitter."
msgstr "MosDNS 是一个插件化的 DNS 转发/分流器。"
msgid "RUNNING"
msgstr "运行中"
msgid "NOT RUNNING"
msgstr "未运行"
msgid "Collecting data..."
msgstr "获取数据中..."
msgid "Enabled"
msgstr "启用"
msgid "Listen port"
msgstr "监听端口"
msgid "API Listen port"
msgstr "API 监听端口"
msgid "Flush Cache"
msgstr "刷新缓存"
msgid "Flushing Cache will clear any IP addresses or DNS records from MosDNS cache"
msgstr "刷新缓存会清空 MosDNS 所有 IP 地址和 DNS 解析缓存"
msgid "Flushing..."
msgstr "正在刷新..."
msgid "Flushing Success"
msgstr "刷新成功"
msgid "Flushing Failed, Please check if MosDNS is enabled"
msgstr "刷新失败,请检查 MosDNS 是否已启用"
msgid "Match the parsing result with the Cloudflare IP ranges, and when there is a successful match, use the 'Custom IP' as the parsing result (experimental feature)"
msgstr "将解析结果与 Cloudflare IP 范围进行匹配,当匹配成功时,使用 “自选 IP” 作为解析结果(实验性功能)"
msgid "Custom IP"
msgstr "自选 IP"
msgid "Cloudflare IP Ranges"
msgstr "Cloudflare IP 范围"
msgid "Log Level"
msgstr "日志等级"
msgid "DNS Forward"
msgstr "DNS 转发"
msgid "Forward Dnsmasq Domain Name resolution requests to MosDNS"
msgstr "将 Dnsmasq 域名解析请求转发到 MosDNS 服务器"
msgid "Enable DNS ADblock"
msgstr "启用 DNS 广告过滤"
msgid "ADblock Source"
msgstr "广告过滤规则来源"
msgid "When using custom rule sources, please use rule types supported by MosDNS (domain lists)."
msgstr "使用自定义规则来源时,请使用 MosDNS 支持的规则类型(域名列表)"
msgid "Support for local files, such as: file:///var/mosdns/example.txt"
msgstr "支持本地文件例如file:///var/mosdns/example.txt"
msgid "Restart-Service"
msgstr "重启服务"
msgid "Restart the MosDNS process to take effect of new configuration"
msgstr "重启 MosDNS 进程使新配置文件生效"
msgid "Configuration Editor"
msgstr "配置编辑器"
msgid "Geodata Update"
msgstr "更新数据库"
msgid "Update GeoIP & GeoSite dat"
msgstr "更新广告规则、GeoIP & GeoSite 数据库"
msgid "Update Time"
msgstr "更新时间"
msgid "Update Cycle"
msgstr "更新周期"
msgid "Every Day"
msgstr "每天"
msgid "Every Monday"
msgstr "每周一"
msgid "Every Tuesday"
msgstr "每周二"
msgid "Every Wednesday"
msgstr "每周三"
msgid "Every Thursday"
msgstr "每周四"
msgid "Every Friday"
msgstr "每周五"
msgid "Every Saturday"
msgstr "每周六"
msgid "Every Sunday"
msgstr "每周日"
msgid "GitHub Proxy"
msgstr "GitHub 代理"
msgid "Update data files with GitHub Proxy, leave blank to disable proxy downloads."
msgstr "通过 GitHub 代理更新数据文件,留空则禁用代理下载。"
msgid "Database Update"
msgstr "数据库更新"
msgid "Check And Update"
msgstr "检查并更新"
msgid "Enable Auto Database Update"
msgstr "启用自动更新"
msgid "Updating..."
msgstr "正在更新..."
msgid "Update success"
msgstr "更新成功"
msgid "Update failed, Please check the network status"
msgstr "更新失败,请检查网络状态"
msgid "Config File"
msgstr "配置文件"
msgid "Default Config"
msgstr "内置预设"
msgid "Custom Config"
msgstr "自定义"
msgid "Log File"
msgstr "日志文件"
msgid "Remote DNS prefer IPv4"
msgstr "远程 DNS 首选 IPv4"
msgid "IPv4 is preferred for remote DNS resolution of dual-stack addresses, and is not affected when the destination is IPv6 only"
msgstr "远程 DNS 解析双栈地址时首选 IPv4目标仅 IPv6 时不受影响"
msgid "Custom China DNS"
msgstr "自定义国内 DNS"
msgid "Follow WAN interface DNS if not enabled"
msgstr "不启用则使用 WAN 接口 DNS"
msgid "Apple domains optimization"
msgstr "Apple 域名解析优化"
msgid "For Apple domains equipped with Chinese mainland CDN, always responsive to Chinese CDN IP addresses"
msgstr "配备中国大陆 CDN 的 Apple 域名,始终应答中国大陆 CDN 地址"
msgid "China DNS server"
msgstr "国内 DNS 服务器"
msgid "Remote DNS server"
msgstr "远程 DNS 服务器"
msgid "Bootstrap DNS servers"
msgstr "Bootstrap DNS 服务器"
msgid "Bootstrap DNS servers are used to resolve IP addresses of the DoH/DoT resolvers you specify as upstreams"
msgstr "Bootstrap DNS 服务器用于解析您指定为上游的 DoH / DoT 解析器的 IP 地址"
msgid "Tencent Public DNS (119.29.29.29)"
msgstr "腾讯公共 DNS119.29.29.29"
msgid "Tencent Public DNS (119.28.28.28)"
msgstr "腾讯公共 DNS119.28.28.28"
msgid "Aliyun Public DNS (223.5.5.5)"
msgstr "阿里云公共 DNS223.5.5.5"
msgid "Aliyun Public DNS (223.6.6.6)"
msgstr "阿里云公共 DNS223.6.6.6"
msgid "Xinfeng Public DNS (114.114.114.114)"
msgstr "信风公共 DNS114.114.114.114"
msgid "Xinfeng Public DNS (114.114.115.115)"
msgstr "信风公共 DNS114.114.115.115"
msgid "Baidu Public DNS (180.76.76.76)"
msgstr "百度公共 DNS180.76.76.76"
msgid "Tencent Public DNS (DNS over HTTPS)"
msgstr "腾讯公共 DNSDNS over HTTPS"
msgid "Aliyun Public DNS (DNS over QUIC)"
msgstr "阿里云公共 DNSDNS over QUIC"
msgid "Aliyun Public DNS (DNS over HTTPS)"
msgstr "阿里云公共 DNSDNS over HTTPS"
msgid "Aliyun Public DNS (DNS over HTTPS/3)"
msgstr "阿里云公共 DNSDNS over HTTPS/3"
msgid "360 Public DNS (DNS over HTTPS)"
msgstr "360 安全 DNSDNS over HTTPS"
msgid "CloudFlare Public DNS (1.1.1.1)"
msgstr "CloudFlare 公共 DNS1.1.1.1"
msgid "CloudFlare Public DNS (1.0.0.1)"
msgstr "CloudFlare 公共 DNS1.0.0.1"
msgid "Google Public DNS (8.8.8.8)"
msgstr "谷歌公共 DNS8.8.8.8"
msgid "Google Public DNS (8.8.4.4)"
msgstr "谷歌公共 DNS8.8.4.4"
msgid "Quad9 Public DNS (9.9.9.9)"
msgstr "Quad9 公共 DNS9.9.9.9"
msgid "Quad9 Public DNS (149.112.112.112)"
msgstr "Quad9 公共 DNS149.112.112.112"
msgid "Cisco Public DNS (208.67.222.222)"
msgstr "思科公共 DNS208.67.222.222"
msgid "Cisco Public DNS (208.67.220.220)"
msgstr "思科公共 DNS208.67.220.220"
msgid "Concurrent"
msgstr "DNS 服务器并发数(默认 2"
msgid "DNS query request concurrency, The number of upstream DNS servers that are allowed to initiate requests at the same time"
msgstr "DNS 查询请求并发数,允许同时发起请求的上游 DNS 服务器数量"
msgid "Idle Timeout"
msgstr "空闲超时"
msgid "DoH/TCP/DoT Connection Multiplexing idle timeout (default 30 seconds)"
msgstr "DoH/TCP/DoT 连接复用空闲保持时间(默认 30 秒)"
msgid "TCP/DoT Connection Multiplexing"
msgstr "TCP/DoT 连接复用"
msgid "Enable TCP/DoT RFC 7766 new Query Pipelining connection multiplexing mode"
msgstr "启用 TCP/DoT RFC 7766 新型 Query Pipelining 连接复用模式"
msgid "Disable TLS Certificate"
msgstr "禁用 TLS 证书"
msgid "Disable TLS Servers certificate validation, Can be useful if system CA certificate expires or the system time is out of order"
msgstr "禁用 TLS 服务器证书验证,当系统 CA 证书过期或系统时间错乱时,本选项可能会有用"
msgid "Enable EDNS client subnet"
msgstr "启用 EDNS 客户端子网"
msgid "IP Address"
msgstr "IP 地址"
msgid "Please provide the IP address you use when accessing foreign websites. This IP subnet (0/24) will be used as the ECS address for Remote DNS requests"
msgstr "请提供您在访问国外网站时使用的 IP 地址,这个 IP 子网0/24将用作远程 DNS 请求的 ECS 地址"
msgid "This feature is typically used when using a self-built DNS server as an Remote DNS upstream (requires support from the upstream server)"
msgstr "此功能通常在使用自建 DNS 服务器作为 远程 DNS 上游时使用(需要上游服务器的支持)"
msgid "Prevent DNS Leaks"
msgstr "防止 DNS 泄漏"
msgid "Enable this option fallback policy forces forwarding to remote DNS"
msgstr "启用此选项 fallback 策略会强制转发到远程 DNS"
msgid "DNS Cache Size"
msgstr "DNS 缓存大小"
msgid "DNS cache size (in piece). To disable caching, please set to 0."
msgstr "DNS 缓存大小(单位:条),要禁用缓存,请设置为 0"
msgid "Lazy Cache TTL"
msgstr "乐观缓存 TTL"
msgid "Lazy cache survival time (in second). To disable Lazy Cache, please set to 0."
msgstr "乐观缓存生存时间(单位:秒),要禁用乐观缓存,请设置为 0"
msgid "Cache Dump"
msgstr "自动保存缓存"
msgid "Save the cache locally and reload the cache dump on the next startup"
msgstr "保存缓存到本地文件,以供下次启动时重新载入使用"
msgid "Auto Save Cache Interval"
msgstr "自动保存缓存间隔(秒)"
msgid "Minimum TTL"
msgstr "覆盖最小 TTL 值(默认 0"
msgid "Modify the Minimum TTL value (seconds) for DNS answer results, 0 indicating no modification"
msgstr "修改 DNS 应答结果的最小 TTL 值 (秒)0 表示不修改"
msgid "Maximum TTL"
msgstr "覆盖最大 TTL 值(默认 0"
msgid "Modify the Maximum TTL value (seconds) for DNS answer results, 0 indicating no modification"
msgstr "修改 DNS 应答结果的最大 TTL 值0 表示不修改"
msgid "Logs"
msgstr "日志"
msgid "Clear logs"
msgstr "清空日志"
msgid "Rule List"
msgstr "规则列表"
msgid "Rule Settings"
msgstr "自定义规则列表"
msgid "<br>The list of rules only apply to 'Default Config' profiles."
msgstr "<br>规则列表仅适用于 “内置预设” 配置文件"
msgid "White Lists"
msgstr "白名单"
msgid "These domain names allow DNS resolution with the highest priority. Please input the domain names of websites, every line can input only one website domain. For example: hm.baidu.com."
msgstr "加入的域名始终允许使用 “本地 DNS” 进行解析,且优先级最高(每个域名一行,支持域名匹配规则)"
msgid "Block Lists"
msgstr "黑名单"
msgid "These domains are blocked from DNS resolution. Please input the domain names of websites, every line can input only one website domain. For example: baidu.com."
msgstr "加入的域名将屏蔽 DNS 解析(每个域名一行,支持域名匹配规则)"
msgid "Grey Lists"
msgstr "灰名单"
msgid "These domains are always resolved using remote DNS. Please input the domain names of websites, every line can input only one website domain. For example: google.com."
msgstr "加入的域名始终使用 “远程 DNS” 进行解析(每个域名一行,支持域名匹配规则)"
msgid "DDNS Lists"
msgstr "DDNS 域名"
msgid "These domains are always resolved using local DNS. And force TTL 5 seconds, DNS resolution results will not enter the cache. For example: myddns.example.com."
msgstr "加入的域名始终使用 “本地 DNS” 进行解析,并且强制 TTL 5 秒,解析结果不会进入缓存(每个域名一行,支持域名匹配规则)"
msgid "Hosts For example: baidu.com 10.0.0.1"
msgstr "自定义 Hosts 重写baidu.com 10.0.0.1(每个规则一行,支持域名匹配规则)"
msgid "Redirect"
msgstr "重定向"
msgid "The domain name to redirect the request to. Requests domain A, but returns records for domain B. example: a.com b.com"
msgstr "重定向请求的域名。请求域名 A但返回域名 B 的记录baidu.com qq.com每个规则一行"
msgid "Block PTR"
msgstr "PTR 黑名单"
msgid "These domains are blocked from PTR requests"
msgstr "加入的域名将阻止 PTR 请求(每个域名一行,支持域名匹配规则)"
msgid "GeoData Export"
msgstr "GeoData 导出"
msgid "GeoSite Tags"
msgstr "GeoSite 标签"
msgid "Enter the GeoSite.dat category to be exported, Allow add multiple tags"
msgstr "填写需要导出的 GeoSite.dat 类别条目,允许添加多个标签"
msgid "GeoIP Tags"
msgstr "GeoIP 标签"
msgid "Enter the GeoIP.dat category to be exported, Allow add multiple tags"
msgstr "输入需要导出的 GeoIP.dat 类别条目,允许添加多个标签"
msgid "Export directory: /var/mosdns"
msgstr "导出目录:/var/mosdns"

1
luci-app-mosdns/po/zh_Hans Symbolic link
View file

@ -0,0 +1 @@
zh-cn

View file

@ -0,0 +1,30 @@
config mosdns 'config'
option enabled '0'
option listen_port '5335'
option geo_auto_update '0'
option geo_update_week_time '*'
option geo_update_day_time '2'
option redirect '1'
option prefer_ipv4 '1'
option adblock '0'
option configfile '/var/etc/mosdns.json'
option log_level 'info'
option log_file '/var/log/mosdns.log'
option cache_size '8000'
option lazy_cache_ttl '86400'
option dump_file '0'
option concurrent '1'
option idle_timeout '30'
option minimal_ttl '0'
option maximum_ttl '0'
option custom_local_dns '0'
option enable_pipeline '0'
option insecure_skip_verify '0'
option dns_leak '0'
option cloudflare '0'
option listen_port_api '9091'
option bootstrap_dns '119.29.29.29'
list remote_dns 'tls://8.8.8.8'
list remote_dns 'tls://1.1.1.1'

View file

@ -0,0 +1,2 @@
#!/bin/sh
[ "$ACTION" = ifup ] && /etc/init.d/mosdns restart

View file

@ -0,0 +1,705 @@
#!/bin/sh /etc/rc.common
#
# Copyright (C) 2020-2022, IrineSistiana
# Copyright (C) 2023-2024, sbwml <admin@cooluc.com>
#
# This file is part of mosdns.
#
# mosdns is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# mosdns is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
START=51
USE_PROCD=1
PROG=/usr/bin/mosdns
CONF=$(uci -q get mosdns.config.configfile)
CRON_FILE=/etc/crontabs/root
DUMP_FILE=/etc/mosdns/cache.dump
DUMP_FILE_DEFAULT=/usr/share/mosdns/cache.dump
MOSDNS_SCRIPT=/usr/share/mosdns/mosdns.sh
get_config() {
config_get enabled $1 enabled 0
config_get adblock $1 adblock 0
config_get ad_source $1 ad_source ""
config_get cache_size $1 cache_size 8000
config_get lazy_cache_ttl $1 lazy_cache_ttl 86400
config_get dump_file $1 dump_file 0
config_get dump_interval $1 dump_interval 3600
config_get enable_pipeline $1 enable_pipeline 0
config_get geo_auto_update $1 geo_auto_update 0
config_get geo_update_day_time $1 geo_update_day_time 2
config_get geo_update_week_time $1 geo_update_week_time "*"
config_get listen_port $1 listen_port 5335
config_get log_file $1 log_file "/var/log/mosdns.log"
config_get log_level $1 log_level "info"
config_get minimal_ttl $1 minimal_ttl 0
config_get maximum_ttl $1 maximum_ttl 0
config_get redirect $1 redirect 0
config_get prefer_ipv4 $1 prefer_ipv4 0
config_get remote_dns $1 remote_dns "tls://8.8.8.8 tls://1.1.1.1"
config_get custom_local_dns $1 custom_local_dns 0
config_get apple_optimization $1 apple_optimization 0
config_get bootstrap_dns $1 bootstrap_dns "119.29.29.29"
config_get listen_port_api $1 listen_port_api 9091
config_get concurrent $1 concurrent 1
config_get insecure_skip_verify $1 insecure_skip_verify 0
config_get idle_timeout $1 idle_timeout 30
config_get enable_ecs_remote $1 enable_ecs_remote 0
config_get remote_ecs_ip $1 remote_ecs_ip "110.34.181.1"
config_get dns_leak $1 dns_leak 0
config_get cloudflare $1 cloudflare 0
config_get cloudflare_ip $1 cloudflare_ip ""
}
generate_config() {
# jshn shell library
. /usr/share/libubox/jshn.sh
# json data
json_init
# log
json_add_object 'log'
json_add_string "level" "$log_level"
json_add_string "file" "$log_file"
json_close_object
# api
json_add_object 'api'
json_add_string "http" "0.0.0.0:$listen_port_api"
json_close_object
# include
json_add_array "include"
json_close_array
# plugins
json_add_array "plugins"
# plugin: geosite_cn
json_add_object
json_add_string "tag" "geosite_cn"
json_add_string "type" "domain_set"
json_add_object "args"
json_add_array "files"
json_add_string "" "/var/mosdns/geosite_cn.txt"
json_close_array
json_close_object
json_close_object
# plugin: geoip_cn
json_add_object
json_add_string "tag" "geoip_cn"
json_add_string "type" "ip_set"
json_add_object "args"
json_add_array "files"
json_add_string "" "/var/mosdns/geoip_cn.txt"
json_close_array
json_close_object
json_close_object
# plugin: geosite_apple
json_add_object
json_add_string "tag" "geosite_apple"
json_add_string "type" "domain_set"
json_add_object "args"
json_add_array "files"
json_add_string "" "/var/mosdns/geosite_apple.txt"
json_close_array
json_close_object
json_close_object
# plugin: geosite_no_cn
json_add_object
json_add_string "tag" "geosite_no_cn"
json_add_string "type" "domain_set"
json_add_object "args"
json_add_array "files"
json_add_string "" "/var/mosdns/geosite_geolocation-!cn.txt"
json_close_array
json_close_object
json_close_object
# plugin: whitelist
json_add_object
json_add_string "tag" "whitelist"
json_add_string "type" "domain_set"
json_add_object "args"
json_add_array "files"
json_add_string "" "/etc/mosdns/rule/whitelist.txt"
json_close_array
json_close_object
json_close_object
# plugin: blocklist
json_add_object
json_add_string "tag" "blocklist"
json_add_string "type" "domain_set"
json_add_object "args"
json_add_array "files"
json_add_string "" "/etc/mosdns/rule/blocklist.txt"
json_close_array
json_close_object
json_close_object
# plugin: greylist
json_add_object
json_add_string "tag" "greylist"
json_add_string "type" "domain_set"
json_add_object "args"
json_add_array "files"
json_add_string "" "/etc/mosdns/rule/greylist.txt"
json_close_array
json_close_object
json_close_object
# plugin: ddnslist
json_add_object
json_add_string "tag" "ddnslist"
json_add_string "type" "domain_set"
json_add_object "args"
json_add_array "files"
json_add_string "" "/etc/mosdns/rule/ddnslist.txt"
json_close_array
json_close_object
json_close_object
# plugin: hosts
json_add_object
json_add_string "tag" "hosts"
json_add_string "type" "hosts"
json_add_object "args"
json_add_array "files"
json_add_string "" "/etc/mosdns/rule/hosts.txt"
json_close_array
json_close_object
json_close_object
# plugin: redirect
json_add_object
json_add_string "tag" "redirect"
json_add_string "type" "redirect"
json_add_object "args"
json_add_array "files"
json_add_string "" "/etc/mosdns/rule/redirect.txt"
json_close_array
json_close_object
json_close_object
# plugin: adlist
json_add_object
json_add_string "tag" "adlist"
json_add_string "type" "domain_set"
json_add_object "args"
json_add_array "files"
adlist=$($MOSDNS_SCRIPT adlist)
for list in $adlist; do
json_add_string "" "$list"
done
json_close_array
json_close_object
json_close_object
# plugin: local_ptr
json_add_object
json_add_string "tag" "local_ptr"
json_add_string "type" "domain_set"
json_add_object "args"
json_add_array "files"
json_add_string "" "/etc/mosdns/rule/local-ptr.txt"
json_close_array
json_close_object
json_close_object
# plugin: cloudflare_cidr
json_add_object
json_add_string "tag" "cloudflare_cidr"
json_add_string "type" "ip_set"
json_add_object "args"
json_add_array "files"
json_add_string "" "/etc/mosdns/rule/cloudflare-cidr.txt"
json_close_array
json_close_object
json_close_object
# plugin: lazy_cache
json_add_object
json_add_string "tag" "lazy_cache"
json_add_string "type" "cache"
json_add_object "args"
json_add_int "size" "$cache_size"
json_add_int "lazy_cache_ttl" "$lazy_cache_ttl"
[ "$dump_file" -eq 1 ] && {
json_add_string "dump_file" "/etc/mosdns/cache.dump"
json_add_int "dump_interval" "$dump_interval"
}
json_close_object
json_close_object
# plugin: forward_xinfeng_udp
json_add_object
json_add_string "tag" "forward_xinfeng_udp"
json_add_string "type" "forward"
json_add_object "args"
json_add_int "concurrent" 2
json_add_array "upstreams"
json_add_object
json_add_string "addr" "114.114.114.114"
json_close_object
json_add_object
json_add_string "addr" "114.114.115.115"
json_close_object
json_close_array
json_close_object
json_close_object
# plugin: forward_local
json_add_object
json_add_string "tag" "forward_local"
json_add_string "type" "forward"
json_add_object "args"
json_add_int "concurrent" "$concurrent"
json_add_array "upstreams"
local_dns=$($MOSDNS_SCRIPT dns)
for addr in $local_dns; do
enable_http3=0
if echo "$addr" | grep -q "^h3://"; then
enable_http3=1
addr=$(echo $addr | sed 's/h3:\/\//https:\/\//g')
fi
json_add_object
json_add_string "addr" "$addr"
json_add_string "bootstrap" "$bootstrap_dns"
json_add_boolean "enable_pipeline" "$enable_pipeline"
json_add_boolean "insecure_skip_verify" "$insecure_skip_verify"
json_add_int "idle_timeout" "$idle_timeout"
[ "$enable_http3" -eq 1 ] && json_add_boolean "enable_http3" "1"
json_close_object
done
json_close_array
json_close_object
json_close_object
# plugin: forward_remote
json_add_object
json_add_string "tag" "forward_remote"
json_add_string "type" "forward"
json_add_object "args"
json_add_int "concurrent" "$concurrent"
json_add_array "upstreams"
for addr in $remote_dns; do
enable_http3=0
if echo "$addr" | grep -q "^h3://"; then
enable_http3=1
addr=$(echo $addr | sed 's/h3:\/\//https:\/\//g')
fi
json_add_object
json_add_string "addr" "$addr"
json_add_string "bootstrap" "$bootstrap_dns"
json_add_boolean "enable_pipeline" "$enable_pipeline"
json_add_boolean "insecure_skip_verify" "$insecure_skip_verify"
json_add_int "idle_timeout" "$idle_timeout"
[ "$enable_http3" -eq 1 ] && json_add_boolean "enable_http3" "1"
json_close_object
done
json_close_array
json_close_object
json_close_object
# plugin: forward_remote_upstream
json_add_object
json_add_string "tag" "forward_remote_upstream"
json_add_string "type" "sequence"
json_add_array "args"
[ "$prefer_ipv4" -eq 1 ] && {
json_add_object
json_add_string "exec" "prefer_ipv4"
json_close_object
}
[ "$enable_ecs_remote" -eq 1 ] && {
json_add_object
json_add_string "exec" "ecs $remote_ecs_ip"
json_close_object
}
json_add_object
json_add_string "exec" "\$forward_remote"
json_close_object
json_close_array
json_close_object
# plugin: modify_ttl
json_add_object
json_add_string "tag" "modify_ttl"
json_add_string "type" "sequence"
json_add_array "args"
json_add_object
json_add_string "exec" "ttl $minimal_ttl-$maximum_ttl"
json_close_object
json_close_array
json_close_object
# plugin: modify_ddns_ttl
json_add_object
json_add_string "tag" "modify_ddns_ttl"
json_add_string "type" "sequence"
json_add_array "args"
json_add_object
json_add_string "exec" "ttl 5-5"
json_close_object
json_close_array
json_close_object
# plugin: has_resp_sequence
json_add_object
json_add_string "tag" "has_resp_sequence"
json_add_string "type" "sequence"
json_add_array "args"
json_add_object
json_add_string "matches" "qname \$ddnslist"
json_add_string "exec" "\$modify_ddns_ttl"
json_close_object
json_add_object
json_add_string "matches" "!qname \$ddnslist"
json_add_string "exec" "\$modify_ttl"
json_close_object
[ "$cloudflare" -eq 1 ] && {
json_add_object
json_add_string "matches" "resp_ip \$cloudflare_cidr"
json_add_string "exec" "black_hole $cloudflare_ip"
json_close_object
}
json_add_object
json_add_string "matches" "has_resp"
json_add_string "exec" "accept"
json_close_object
json_close_array
json_close_object
# plugin: query_is_non_local_ip
json_add_object
json_add_string "tag" "query_is_non_local_ip"
json_add_string "type" "sequence"
json_add_array "args"
json_add_object
json_add_string "exec" "\$forward_local"
json_close_object
json_add_object
json_add_string "matches" "!resp_ip \$geoip_cn"
json_add_string "exec" "drop_resp"
json_close_object
json_close_array
json_close_object
# plugin: fallback
json_add_object
json_add_string "tag" "fallback"
json_add_string "type" "fallback"
json_add_object "args"
[ "$dns_leak" -eq 1 ] && json_add_string "primary" "forward_remote_upstream" || json_add_string "primary" "query_is_non_local_ip"
json_add_string "secondary" "forward_remote_upstream"
json_add_int "threshold" 500
json_add_boolean "always_standby" 1
json_close_object
json_close_object
# plugin: apple_domain_fallback
json_add_object
json_add_string "tag" "apple_domain_fallback"
json_add_string "type" "fallback"
json_add_object "args"
json_add_string "primary" "query_is_non_local_ip"
json_add_string "secondary" "forward_xinfeng_udp"
json_add_int "threshold" 100
json_add_boolean "always_standby" 1
json_close_object
json_close_object
# plugin: query_is_apple_domain
json_add_object
json_add_string "tag" "query_is_apple_domain"
json_add_string "type" "sequence"
json_add_array "args"
json_add_object
json_add_string "matches" "!qname \$geosite_apple"
json_add_string "exec" "return"
json_close_object
json_add_object
json_add_string "exec" "\$apple_domain_fallback"
json_close_object
json_close_array
json_close_object
# plugin: query_is_ddns_domain
json_add_object
json_add_string "tag" "query_is_ddns_domain"
json_add_string "type" "sequence"
json_add_array "args"
json_add_object
json_add_string "matches" "qname \$ddnslist"
json_add_string "exec" "\$forward_local"
json_close_object
json_close_array
json_close_object
# plugin: query_is_local_domain
json_add_object
json_add_string "tag" "query_is_local_domain"
json_add_string "type" "sequence"
json_add_array "args"
json_add_object
json_add_string "matches" "qname \$geosite_cn"
json_add_string "exec" "\$forward_local"
json_close_object
json_close_array
json_close_object
# plugin: query_is_no_local_domain
json_add_object
json_add_string "tag" "query_is_no_local_domain"
json_add_string "type" "sequence"
json_add_array "args"
json_add_object
json_add_string "matches" "qname \$geosite_no_cn"
json_add_string "exec" "\$forward_remote_upstream"
json_close_object
json_close_array
json_close_object
# plugin: query_is_whitelist_domain
json_add_object
json_add_string "tag" "query_is_whitelist_domain"
json_add_string "type" "sequence"
json_add_array "args"
json_add_object
json_add_string "matches" "qname \$whitelist"
json_add_string "exec" "\$forward_local"
json_close_object
json_close_array
json_close_object
# plugin: query_is_greylist_domain
json_add_object
json_add_string "tag" "query_is_greylist_domain"
json_add_string "type" "sequence"
json_add_array "args"
json_add_object
json_add_string "matches" "qname \$greylist"
json_add_string "exec" "\$forward_remote_upstream"
json_close_object
json_close_array
json_close_object
# plugin: query_is_reject_domain
json_add_object
json_add_string "tag" "query_is_reject_domain"
json_add_string "type" "sequence"
json_add_array "args"
json_add_object
json_add_string "matches" "qname \$blocklist"
json_add_string "exec" "reject 3"
json_close_object
json_add_object
json_add_string "matches" "qname \$adlist"
json_add_string "exec" "reject 3"
json_close_object
json_add_object
json_add_array "matches"
json_add_string "" "qtype 12"
json_add_string "" "qname \$local_ptr"
json_close_array
json_add_string "exec" "reject 3"
json_close_object
json_add_object
json_add_string "matches" "qtype 65"
json_add_string "exec" "reject 3"
json_close_object
json_close_array
json_close_object
# plugin: main_sequence
json_add_object
json_add_string "tag" "main_sequence"
json_add_string "type" "sequence"
json_add_array "args"
json_add_object
json_add_string "exec" "\$hosts"
json_close_object
json_add_object
json_add_string "exec" "jump has_resp_sequence"
json_close_object
json_add_object
json_add_array "matches"
json_add_string "" "!qname \$ddnslist"
json_add_string "" "!qname \$blocklist"
json_add_string "" "!qname \$adlist"
json_add_string "" "!qname \$local_ptr"
json_close_array
json_add_string "exec" "\$lazy_cache"
json_close_object
json_add_object
json_add_string "exec" "\$redirect"
json_close_object
json_add_object
json_add_string "exec" "jump has_resp_sequence"
json_close_object
json_add_object
[ "$apple_optimization" -eq 1 ] && {
json_add_string "exec" "\$query_is_apple_domain"
json_close_object
json_add_object
json_add_string "exec" "jump has_resp_sequence"
json_close_object
json_add_object
}
json_add_string "exec" "\$query_is_ddns_domain"
json_close_object
json_add_object
json_add_string "exec" "jump has_resp_sequence"
json_close_object
json_add_object
json_add_string "exec" "\$query_is_whitelist_domain"
json_close_object
json_add_object
json_add_string "exec" "jump has_resp_sequence"
json_close_object
json_add_object
json_add_string "exec" "\$query_is_reject_domain"
json_close_object
json_add_object
json_add_string "exec" "jump has_resp_sequence"
json_close_object
json_add_object
json_add_string "exec" "\$query_is_greylist_domain"
json_close_object
json_add_object
json_add_string "exec" "jump has_resp_sequence"
json_close_object
json_add_object
json_add_string "exec" "\$query_is_local_domain"
json_close_object
json_add_object
json_add_string "exec" "jump has_resp_sequence"
json_close_object
json_add_object
json_add_string "exec" "\$query_is_no_local_domain"
json_close_object
json_add_object
json_add_string "exec" "jump has_resp_sequence"
json_close_object
json_add_object
json_add_string "exec" "\$fallback"
json_close_object
json_close_array
json_close_object
# plugin: udp_server
json_add_object
json_add_string "tag" "udp_server"
json_add_string "type" "udp_server"
json_add_object "args"
json_add_string "entry" "main_sequence"
json_add_string "listen" ":$listen_port"
json_close_object
json_close_object
# plugin: tcp_server
json_add_object
json_add_string "tag" "tcp_server"
json_add_string "type" "tcp_server"
json_add_object "args"
json_add_string "entry" "main_sequence"
json_add_string "listen" ":$listen_port"
json_close_object
json_close_object
# close plugins array
json_close_array
# print json
json_dump > /var/etc/mosdns.json
# init dump_file
[ "$dump_file" -eq 1 ] && [ ! -f $DUMP_FILE ] && cp -a $DUMP_FILE_DEFAULT $DUMP_FILE
[ "$dump_file" -eq 0 ] && \cp -a $DUMP_FILE_DEFAULT $DUMP_FILE
}
service_triggers() {
procd_add_reload_trigger "mosdns"
}
restore_setting() {
rm -f /etc/mosdns/redirect.lock
sed -i "/list server/d" /etc/config/dhcp
uci set dhcp.@dnsmasq[0].noresolv='0'
uci del dhcp.@dnsmasq[0].cachesize
uci commit dhcp
}
redirect_setting() {
if [ "${CONF}" = "/var/etc/mosdns.json" ]; then
sed -i "/list server/d" /etc/config/dhcp
uci add_list dhcp.@dnsmasq[0].server="127.0.0.1#$listen_port"
uci set dhcp.@dnsmasq[0].rebind_protection='0'
uci set dhcp.@dnsmasq[0].noresolv="1"
uci set dhcp.@dnsmasq[0].cachesize='0'
uci commit dhcp
else
sed -i "/list server/d" /etc/config/dhcp
uci add_list dhcp.@dnsmasq[0].server="127.0.0.1#$(awk -F'[:" ]+' '/^\s+listen:/{for(i=1;i<=NF;i++){if($i~/^[0-9]+$/){print $i;exit}}}' $CONF)"
uci set dhcp.@dnsmasq[0].rebind_protection='0'
uci set dhcp.@dnsmasq[0].noresolv="1"
uci set dhcp.@dnsmasq[0].cachesize='0'
uci commit dhcp
fi
touch /etc/mosdns/redirect.lock
}
reload_dnsmasq() {
/etc/init.d/dnsmasq reload
}
reload_service() {
stop
sleep 1
start
}
setcron() {
sed -i '/mosdns.sh/d' $CRON_FILE 2>/dev/null
[ "$geo_auto_update" -eq 1 ] && echo "0 $geo_update_day_time * * $geo_update_week_time $MOSDNS_SCRIPT geodata" >> $CRON_FILE
crontab $CRON_FILE
}
delcron() {
sed -i '/mosdns.sh/d' $CRON_FILE 2>/dev/null
crontab $CRON_FILE
}
v2dat_dump() {
$MOSDNS_SCRIPT v2dat_dump
}
start_service() {
config_load "mosdns"
config_foreach get_config "mosdns"
[ $enabled -ne 1 ] && return 1
delcron ; setcron
:> $($MOSDNS_SCRIPT logfile)
if [ "${log_level}" = "error" ] || [ "${log_level}" = "warn" ]; then
v2dat_dump > /dev/null 2>&1
else
v2dat_dump >> $($MOSDNS_SCRIPT logfile) 2>&1
fi
[ "${CONF}" = "/var/etc/mosdns.json" ] && generate_config
procd_open_instance mosdns
procd_set_param env QUIC_GO_DISABLE_RECEIVE_BUFFER_WARNING=true
procd_set_param command $PROG start
procd_append_param command -c "$CONF"
procd_append_param command -d "/etc/mosdns"
procd_set_param stdout 1
procd_set_param stderr 1
procd_set_param respawn
procd_close_instance mosdns
[ "$redirect" -ne 1 ] && [ -f "/etc/mosdns/redirect.lock" ] && restore_setting
[ "$redirect" -eq 1 ] && redirect_setting
reload_dnsmasq
# Update Adlist
update_list=0
if [ "$adblock" -eq 1 ]; then
if [ -f "/etc/mosdns/rule/.ad_source" ]; then
for url in $ad_source;
do
if [ "$url" = "geosite.dat" ] || [ $(echo "$url" | grep -c -E "^file://") -eq 1 ]; then
continue
fi
if [ $(grep -c "$url" "/etc/mosdns/rule/.ad_source") -eq 0 ]; then
update_list=1
break
fi
done
else
update_list=1
fi
fi
[ "$update_list" -eq 1 ] && $MOSDNS_SCRIPT adlist_update &> /dev/null &
}
stop_service() {
config_load "mosdns"
config_foreach get_config "mosdns"
[ "$enabled" -eq "0" ] && [ -f "/etc/mosdns/redirect.lock" ] && restore_setting
reload_dnsmasq
delcron
}

View file

@ -0,0 +1,142 @@
log:
level: info
file: "/var/log/mosdns.log"
# API 入口设置
api:
http: "0.0.0.0:9091"
include: []
plugins:
# 国内域名
- tag: geosite_cn
type: domain_set
args:
files:
- "/var/mosdns/geosite_cn.txt"
# 国内 IP
- tag: geoip_cn
type: ip_set
args:
files:
- "/var/mosdns/geoip_cn.txt"
# 国外域名
- tag: geosite_no_cn
type: domain_set
args:
files:
- "/var/mosdns/geosite_geolocation-!cn.txt"
# 缓存
- tag: lazy_cache
type: cache
args:
size: 20000
lazy_cache_ttl: 86400
dump_file: "/etc/mosdns/cache.dump"
dump_interval: 600
# 转发至本地服务器
- tag: forward_local
type: forward
args:
upstreams:
- addr: "https://doh.pub/dns-query"
bootstrap: 180.76.76.76
- addr: 119.29.29.29
# 转发至远程服务器
- tag: forward_remote
type: forward
args:
upstreams:
- addr: tls://8.8.8.8
enable_pipeline: false
# 国内解析
- tag: local_sequence
type: sequence
args:
- exec: $forward_local
# 国外解析
- tag: remote_sequence
type: sequence
args:
- exec: prefer_ipv4
- exec: $forward_remote
# 有响应终止返回
- tag: has_resp_sequence
type: sequence
args:
- matches: has_resp
exec: accept
# fallback 用本地服务器 sequence
# 返回非国内 ip 则 drop_resp
- tag: query_is_local_ip
type: sequence
args:
- exec: $local_sequence
- matches: "!resp_ip $geoip_cn"
exec: drop_resp
# fallback 用远程服务器 sequence
- tag: query_is_remote
type: sequence
args:
- exec: $remote_sequence
# fallback 用远程服务器 sequence
- tag: fallback
type: fallback
args:
primary: query_is_local_ip
secondary: query_is_remote
threshold: 500
always_standby: true
# 查询国内域名
- tag: query_is_local_domain
type: sequence
args:
- matches: qname $geosite_cn
exec: $local_sequence
# 查询国外域名
- tag: query_is_no_local_domain
type: sequence
args:
- matches: qname $geosite_no_cn
exec: $remote_sequence
# 主要的运行逻辑插件
# sequence 插件中调用的插件 tag 必须在 sequence 前定义,
# 否则 sequence 找不到对应插件。
- tag: main_sequence
type: sequence
args:
- exec: $lazy_cache
- exec: $query_is_local_domain
- exec: jump has_resp_sequence
- exec: $query_is_no_local_domain
- exec: jump has_resp_sequence
- exec: $fallback
# 启动 udp 服务器。
- tag: udp_server
type: udp_server
args:
entry: main_sequence
listen: ":5335"
# 启动 tcp 服务器。
- tag: tcp_server
type: tcp_server
args:
entry: main_sequence
listen: ":5335"

View file

@ -0,0 +1,22 @@
173.245.48.0/20
103.21.244.0/22
103.22.200.0/22
103.31.4.0/22
141.101.64.0/18
108.162.192.0/18
190.93.240.0/20
188.114.96.0/20
197.234.240.0/22
198.41.128.0/17
162.158.0.0/15
104.16.0.0/13
104.24.0.0/14
172.64.0.0/13
131.0.72.0/22
2400:cb00::/32
2606:4700::/32
2803:f800::/32
2405:b500::/32
2405:8100::/32
2a06:98c0::/29
2c0f:f248::/32

View file

@ -0,0 +1,87 @@
0.in-addr.arpa
10.in-addr.arpa
127.in-addr.arpa
16.172.in-addr.arpa
17.172.in-addr.arpa
18.172.in-addr.arpa
19.172.in-addr.arpa
20.172.in-addr.arpa
21.172.in-addr.arpa
22.172.in-addr.arpa
23.172.in-addr.arpa
24.172.in-addr.arpa
25.172.in-addr.arpa
26.172.in-addr.arpa
27.172.in-addr.arpa
28.172.in-addr.arpa
29.172.in-addr.arpa
30.172.in-addr.arpa
31.172.in-addr.arpa
64.100.in-addr.arpa
65.100.in-addr.arpa
66.100.in-addr.arpa
67.100.in-addr.arpa
68.100.in-addr.arpa
69.100.in-addr.arpa
70.100.in-addr.arpa
71.100.in-addr.arpa
72.100.in-addr.arpa
73.100.in-addr.arpa
74.100.in-addr.arpa
75.100.in-addr.arpa
76.100.in-addr.arpa
77.100.in-addr.arpa
78.100.in-addr.arpa
79.100.in-addr.arpa
80.100.in-addr.arpa
81.100.in-addr.arpa
82.100.in-addr.arpa
83.100.in-addr.arpa
84.100.in-addr.arpa
85.100.in-addr.arpa
86.100.in-addr.arpa
87.100.in-addr.arpa
88.100.in-addr.arpa
89.100.in-addr.arpa
90.100.in-addr.arpa
91.100.in-addr.arpa
92.100.in-addr.arpa
93.100.in-addr.arpa
94.100.in-addr.arpa
95.100.in-addr.arpa
96.100.in-addr.arpa
97.100.in-addr.arpa
98.100.in-addr.arpa
99.100.in-addr.arpa
100.100.in-addr.arpa
101.100.in-addr.arpa
102.100.in-addr.arpa
103.100.in-addr.arpa
104.100.in-addr.arpa
105.100.in-addr.arpa
106.100.in-addr.arpa
107.100.in-addr.arpa
108.100.in-addr.arpa
109.100.in-addr.arpa
110.100.in-addr.arpa
111.100.in-addr.arpa
112.100.in-addr.arpa
113.100.in-addr.arpa
114.100.in-addr.arpa
115.100.in-addr.arpa
116.100.in-addr.arpa
117.100.in-addr.arpa
118.100.in-addr.arpa
119.100.in-addr.arpa
120.100.in-addr.arpa
121.100.in-addr.arpa
122.100.in-addr.arpa
123.100.in-addr.arpa
124.100.in-addr.arpa
125.100.in-addr.arpa
126.100.in-addr.arpa
127.100.in-addr.arpa
2.0.192.in-addr.arpa
168.192.in-addr.arpa
255.255.255.255.in-addr.arpa
domain:ip6.arpa

View file

@ -0,0 +1,11 @@
domain:bing.com
domain:live.com
domain:msn.com
domain:ntp.org
domain:office.com
domain:qlogo.cn
domain:qq.com
domain:redhat.com
keyword:douyin
keyword:microsoft
keyword:windows

View file

@ -0,0 +1,11 @@
#!/bin/sh
uci -q batch <<-EOF >/dev/null
delete ucitrack.@mosdns[-1]
add ucitrack mosdns
set ucitrack.@mosdns[-1].init=mosdns
commit ucitrack
EOF
rm -rf /tmp/luci-*
exit 0

Binary file not shown.

View file

@ -0,0 +1,192 @@
#!/bin/sh
script_action=${1}
logfile_path() (
configfile=$(uci -q get mosdns.config.configfile)
if [ "$configfile" = "/var/etc/mosdns.json" ]; then
uci -q get mosdns.config.log_file
else
[ ! -f /etc/mosdns/config_custom.yaml ] && exit 1
awk '/^log:/{f=1;next}f==1{if($0~/file:/){print;exit}if($0~/^[^ ]/)exit}' /etc/mosdns/config_custom.yaml | grep -Eo "/[^'\"]+"
fi
)
interface_dns() (
if [ "$(uci -q get mosdns.config.custom_local_dns)" = 1 ]; then
uci -q get mosdns.config.local_dns
else
peerdns=$(uci -q get network.wan.peerdns)
proto=$(uci -q get network.wan.proto)
if [ "$peerdns" = 0 ] || [ "$proto" = "static" ]; then
uci -q get network.wan.dns
else
interface_status=$(ubus call network.interface.wan status)
echo $interface_status | jsonfilter -e "@['dns-server'][0]"
echo $interface_status | jsonfilter -e "@['dns-server'][1]"
fi
[ $? -ne 0 ] && echo "119.29.29.29 223.5.5.5"
fi
)
get_adlist() (
adblock=$(uci -q get mosdns.config.adblock)
if [ "$adblock" = 1 ]; then
mkdir -p /etc/mosdns/rule/adlist
ad_source=$(uci -q get mosdns.config.ad_source)
for url in $ad_source;
do
if [ $(echo $url) = 'geosite.dat' ]; then
echo "/var/mosdns/geosite_category-ads-all.txt"
elif echo "$url" | grep -Eq "^file://" ; then
echo "$url" | sed 's/file:\/\///'
else
echo "/etc/mosdns/rule/adlist/$(basename $url)"
[ ! -f "/etc/mosdns/rule/adlist/$(basename $url)" ] && touch /etc/mosdns/rule/adlist/$(basename $url)
fi
done
else
rm -rf /etc/mosdns/rule/adlist /etc/mosdns/rule/.ad_source
touch /var/mosdns/disable-ads.txt
echo "/var/mosdns/disable-ads.txt"
fi
)
adlist_update() {
[ "$(uci -q get mosdns.config.adblock)" != 1 ] && return 0
lock_file=/var/lock/mosdns_ad_update.lock
ad_source=$(uci -q get mosdns.config.ad_source)
: > /etc/mosdns/rule/.ad_source
if [ -f "$lock_file" ]; then
has_update=0
exit 0
else
: > $lock_file
fi
AD_TMPDIR=$(mktemp -d) || exit 1
has_update=0
for url in $ad_source;
do
if [ "$url" != "geosite.dat" ] && [ $(echo "$url" | grep -c -E "^file://") -eq 0 ]; then
has_update=1
echo "$url" >> /etc/mosdns/rule/.ad_source
filename=$(basename $url)
if echo "$url" | grep -Eq "^https://raw.githubusercontent.com" ; then
[ -n "$(uci -q get mosdns.config.github_proxy)" ] && mirror="$(uci -q get mosdns.config.github_proxy)/"
else
mirror=""
fi
echo -e "\e[1;32mDownloading $mirror$url\e[0m"
curl --connect-timeout 5 -m 90 --ipv4 -kfSLo "$AD_TMPDIR/$filename" "$mirror$url"
fi
done
if [ $? -ne 0 ]; then
echo -e "\e[1;31mRules download failed.\e[0m"
rm -rf "$AD_TMPDIR" "$lock_file"
exit 1
else
[ $has_update -eq 1 ] && {
mkdir -p /etc/mosdns/rule/adlist
rm -rf /etc/mosdns/rule/adlist/*
\cp $AD_TMPDIR/* /etc/mosdns/rule/adlist
}
fi
rm -rf "$AD_TMPDIR" "$lock_file"
}
geodat_update() (
TMPDIR=$(mktemp -d) || exit 1
[ -n "$(uci -q get mosdns.config.github_proxy)" ] && mirror="$(uci -q get mosdns.config.github_proxy)/"
# geoip.dat - cn-private
echo -e "\e[1;32mDownloading "$mirror"https://github.com/Loyalsoldier/geoip/releases/latest/download/geoip-only-cn-private.dat\e[0m"
curl --connect-timeout 5 -m 60 --ipv4 -kfSLo "$TMPDIR/geoip.dat" ""$mirror"https://github.com/Loyalsoldier/geoip/releases/latest/download/geoip-only-cn-private.dat"
[ $? -ne 0 ] && rm -rf "$TMPDIR" && exit 1
# checksum - geoip.dat
echo -e "\e[1;32mDownloading "$mirror"https://github.com/Loyalsoldier/geoip/releases/latest/download/geoip-only-cn-private.dat.sha256sum\e[0m"
curl --connect-timeout 5 -m 10 --ipv4 -kfSLo "$TMPDIR/geoip.dat.sha256sum" ""$mirror"https://github.com/Loyalsoldier/geoip/releases/latest/download/geoip-only-cn-private.dat.sha256sum"
[ $? -ne 0 ] && rm -rf "$TMPDIR" && exit 1
if [ "$(sha256sum "$TMPDIR/geoip.dat" | awk '{print $1}')" != "$(cat "$TMPDIR/geoip.dat.sha256sum" | awk '{print $1}')" ]; then
echo -e "\e[1;31mgeoip.dat checksum error\e[0m"
rm -rf "$TMPDIR"
exit 1
fi
# geosite.dat
echo -e "\e[1;32mDownloading "$mirror"https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat\e[0m"
curl --connect-timeout 5 -m 120 --ipv4 -kfSLo "$TMPDIR/geosite.dat" ""$mirror"https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat"
[ $? -ne 0 ] && rm -rf "$TMPDIR" && exit 1
# checksum - geosite.dat
echo -e "\e[1;32mDownloading "$mirror"https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat.sha256sum\e[0m"
curl --connect-timeout 5 -m 10 --ipv4 -kfSLo "$TMPDIR/geosite.dat.sha256sum" ""$mirror"https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat.sha256sum"
[ $? -ne 0 ] && rm -rf "$TMPDIR" && exit 1
if [ "$(sha256sum "$TMPDIR/geosite.dat" | awk '{print $1}')" != "$(cat "$TMPDIR/geosite.dat.sha256sum" | awk '{print $1}')" ]; then
echo -e "\e[1;31mgeosite.dat checksum error\e[0m"
rm -rf "$TMPDIR"
exit 1
fi
rm -rf "$TMPDIR"/*.sha256sum
\cp -a "$TMPDIR"/* /usr/share/v2ray
rm -rf "$TMPDIR"
)
restart_service() {
/etc/init.d/mosdns restart
}
flush_cache() {
curl -s 127.0.0.1:$(uci -q get mosdns.config.listen_port_api)/plugins/lazy_cache/flush || exit 1
}
v2dat_dump() {
# env
v2dat_dir=/usr/share/v2ray
adblock=$(uci -q get mosdns.config.adblock)
ad_source=$(uci -q get mosdns.config.ad_source)
configfile=$(uci -q get mosdns.config.configfile)
mkdir -p /var/mosdns
rm -f /var/mosdns/geo*.txt
if [ "$configfile" = "/var/etc/mosdns.json" ]; then
# default config
v2dat unpack geoip -o /var/mosdns -f cn $v2dat_dir/geoip.dat
v2dat unpack geosite -o /var/mosdns -f cn -f apple -f 'geolocation-!cn' $v2dat_dir/geosite.dat
[ "$adblock" -eq 1 ] && [ $(echo $ad_source | grep -c geosite.dat) -ge '1' ] && v2dat unpack geosite -o /var/mosdns -f category-ads-all $v2dat_dir/geosite.dat
else
# custom config
v2dat unpack geoip -o /var/mosdns -f cn $v2dat_dir/geoip.dat
v2dat unpack geosite -o /var/mosdns -f cn -f 'geolocation-!cn' $v2dat_dir/geosite.dat
geoip_tags=$(uci -q get mosdns.config.geoip_tags)
geosite_tags=$(uci -q get mosdns.config.geosite_tags)
[ -n "$geoip_tags" ] && v2dat unpack geoip -o /var/mosdns $(echo $geoip_tags | sed -r 's/\S+/-f &/g') $v2dat_dir/geoip.dat
[ -n "$geosite_tags" ] && v2dat unpack geosite -o /var/mosdns $(echo $geosite_tags | sed -r 's/\S+/-f &/g') $v2dat_dir/geosite.dat
fi
}
case $script_action in
"dns")
interface_dns
;;
"adlist")
get_adlist
;;
"geodata")
geodat_update && adlist_update && restart_service
;;
"logfile")
logfile_path
;;
"adlist_update")
adlist_update && [ "$has_update" -eq 1 ] && restart_service
;;
"flush")
flush_cache
;;
"v2dat_dump")
v2dat_dump
;;
"version")
mosdns version
;;
*)
exit 0
;;
esac

View file

@ -0,0 +1,11 @@
{
"luci-app-mosdns": {
"description": "Grant UCI access for luci-app-mosdns",
"read": {
"uci": [ "mosdns" ]
},
"write": {
"uci": [ "mosdns" ]
}
}
}

View file

@ -0,0 +1 @@
!function(n){"object"==typeof exports&&"object"==typeof module?n(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],n):n(CodeMirror)}(function(n){"use strict";function e(e,o,i,t){if(i&&i.call){var l=i;i=null}else l=r(e,i,"rangeFinder");"number"==typeof o&&(o=n.Pos(o,0));var f=r(e,i,"minFoldSize");function d(n){var r=l(e,o);if(!r||r.to.line-r.from.line<f)return null;for(var i=e.findMarksAt(r.from),d=0;d<i.length;++d)if(i[d].__isFold&&"fold"!==t){if(!n)return null;r.cleared=!0,i[d].clear()}return r}var u=d(!0);if(r(e,i,"scanUp"))for(;!u&&o.line>e.firstLine();)o=n.Pos(o.line-1,0),u=d(!1);if(u&&!u.cleared&&"unfold"!==t){var a=function(n,e){var o=r(n,e,"widget");if("string"==typeof o){var i=document.createTextNode(o);(o=document.createElement("span")).appendChild(i),o.className="CodeMirror-foldmarker"}else o&&(o=o.cloneNode(!0));return o}(e,i);n.on(a,"mousedown",function(e){c.clear(),n.e_preventDefault(e)});var c=e.markText(u.from,u.to,{replacedWith:a,clearOnEnter:r(e,i,"clearOnEnter"),__isFold:!0});c.on("clear",function(o,r){n.signal(e,"unfold",e,o,r)}),n.signal(e,"fold",e,u.from,u.to)}}n.newFoldFunction=function(n,o){return function(r,i){e(r,i,{rangeFinder:n,widget:o})}},n.defineExtension("foldCode",function(n,o,r){e(this,n,o,r)}),n.defineExtension("isFolded",function(n){for(var e=this.findMarksAt(n),o=0;o<e.length;++o)if(e[o].__isFold)return!0}),n.commands.toggleFold=function(n){n.foldCode(n.getCursor())},n.commands.fold=function(n){n.foldCode(n.getCursor(),null,"fold")},n.commands.unfold=function(n){n.foldCode(n.getCursor(),null,"unfold")},n.commands.foldAll=function(e){e.operation(function(){for(var o=e.firstLine(),r=e.lastLine();o<=r;o++)e.foldCode(n.Pos(o,0),null,"fold")})},n.commands.unfoldAll=function(e){e.operation(function(){for(var o=e.firstLine(),r=e.lastLine();o<=r;o++)e.foldCode(n.Pos(o,0),null,"unfold")})},n.registerHelper("fold","combine",function(){var n=Array.prototype.slice.call(arguments,0);return function(e,o){for(var r=0;r<n.length;++r){var i=n[r](e,o);if(i)return i}}}),n.registerHelper("fold","auto",function(n,e){for(var o=n.getHelpers(e,"fold"),r=0;r<o.length;r++){var i=o[r](n,e);if(i)return i}});var o={rangeFinder:n.fold.auto,widget:"↔",minFoldSize:0,scanUp:!1,clearOnEnter:!0};function r(n,e,r){if(e&&void 0!==e[r])return e[r];var i=n.options.foldOptions;return i&&void 0!==i[r]?i[r]:o[r]}n.defineOption("foldOptions",null),n.defineExtension("foldOption",function(n,e){return r(this,n,e)})});

View file

@ -0,0 +1 @@
.CodeMirror-foldmarker{color:blue;text-shadow:#b9f 1px 1px 2px,#b9f -1px -1px 2px,#b9f 1px -1px 2px,#b9f -1px 1px 2px;font-family:arial;line-height:.3;cursor:pointer}.CodeMirror-foldgutter{width:.7em}.CodeMirror-foldgutter-open,.CodeMirror-foldgutter-folded{cursor:pointer}.CodeMirror-foldgutter-open:after{content:"\25BE"}.CodeMirror-foldgutter-folded:after{content:"\25B8"}

View file

@ -0,0 +1 @@
!function(t){"object"==typeof exports&&"object"==typeof module?t(require("../../lib/codemirror"),require("./foldcode")):"function"==typeof define&&define.amd?define(["../../lib/codemirror","./foldcode"],t):t(CodeMirror)}(function(t){"use strict";t.defineOption("foldGutter",!1,function(o,e,r){r&&r!=t.Init&&(o.clearGutter(o.state.foldGutter.options.gutter),o.state.foldGutter=null,o.off("gutterClick",a),o.off("changes",d),o.off("viewportChange",u),o.off("fold",l),o.off("unfold",l),o.off("swapDoc",d)),e&&(o.state.foldGutter=new function(t){this.options=t,this.from=this.to=0}(function(t){!0===t&&(t={});null==t.gutter&&(t.gutter="CodeMirror-foldgutter");null==t.indicatorOpen&&(t.indicatorOpen="CodeMirror-foldgutter-open");null==t.indicatorFolded&&(t.indicatorFolded="CodeMirror-foldgutter-folded");return t}(e)),f(o),o.on("gutterClick",a),o.on("changes",d),o.on("viewportChange",u),o.on("fold",l),o.on("unfold",l),o.on("swapDoc",d))});var o=t.Pos;function e(t,e){for(var r=t.findMarks(o(e,0),o(e+1,0)),n=0;n<r.length;++n)if(r[n].__isFold){var i=r[n].find(-1);if(i&&i.line===e)return r[n]}}function r(t){if("string"==typeof t){var o=document.createElement("div");return o.className=t+" CodeMirror-guttermarker-subtle",o}return t.cloneNode(!0)}function n(t,n,f){var a=t.state.foldGutter.options,d=n-1,u=t.foldOption(a,"minFoldSize"),l=t.foldOption(a,"rangeFinder"),c="string"==typeof a.indicatorFolded&&i(a.indicatorFolded),s="string"==typeof a.indicatorOpen&&i(a.indicatorOpen);t.eachLine(n,f,function(n){++d;var i=null,f=n.gutterMarkers;if(f&&(f=f[a.gutter]),e(t,d)){if(c&&f&&c.test(f.className))return;i=r(a.indicatorFolded)}else{var p=o(d,0),m=l&&l(t,p);if(m&&m.to.line-m.from.line>=u){if(s&&f&&s.test(f.className))return;i=r(a.indicatorOpen)}}(i||f)&&t.setGutterMarker(n,a.gutter,i)})}function i(t){return new RegExp("(^|\\s)"+t+"(?:$|\\s)\\s*")}function f(t){var o=t.getViewport(),e=t.state.foldGutter;e&&(t.operation(function(){n(t,o.from,o.to)}),e.from=o.from,e.to=o.to)}function a(t,r,n){var i=t.state.foldGutter;if(i){var f=i.options;if(n==f.gutter){var a=e(t,r);a?a.clear():t.foldCode(o(r,0),f)}}}function d(t){var o=t.state.foldGutter;if(o){var e=o.options;o.from=o.to=0,clearTimeout(o.changeUpdate),o.changeUpdate=setTimeout(function(){f(t)},e.foldOnChangeTimeSpan||600)}}function u(t){var o=t.state.foldGutter;if(o){var e=o.options;clearTimeout(o.changeUpdate),o.changeUpdate=setTimeout(function(){var e=t.getViewport();o.from==o.to||e.from-o.to>20||o.from-e.to>20?f(t):t.operation(function(){e.from<o.from&&(n(t,e.from,o.from),o.from=e.from),e.to>o.to&&(n(t,o.to,e.to),o.to=e.to)})},e.updateViewportTimeSpan||400)}}function l(t,o){var e=t.state.foldGutter;if(e){var r=o.line;r>=e.from&&r<e.to&&n(t,r,r+1)}}});

View file

@ -0,0 +1 @@
!function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}(function(e){"use strict";function n(n,t){var i=n.getLine(t),o=i.search(/\S/);return-1==o||/\bcomment\b/.test(n.getTokenTypeAt(e.Pos(t,o+1)))?-1:e.countColumn(i,null,n.getOption("tabSize"))}e.registerHelper("fold","indent",function(t,i){var o=n(t,i.line);if(!(o<0)){for(var r=null,l=i.line+1,f=t.lastLine();l<=f;++l){var u=n(t,l);if(-1==u);else{if(!(u>o))break;r=l}}return r?{from:e.Pos(i.line,t.getLine(i.line).length),to:e.Pos(r,t.getLine(r).length)}:void 0}})});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
!function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],e):e(CodeMirror)}(function(e){"use strict";e.defineMode("yaml",function(){var e=new RegExp("\\b(("+["true","false","on","off","yes","no"].join(")|(")+"))$","i");return{token:function(i,t){var r=i.peek(),n=t.escaped;if(t.escaped=!1,"#"==r&&(0==i.pos||/\s/.test(i.string.charAt(i.pos-1))))return i.skipToEnd(),"comment";if(i.match(/^('([^']|\\.)*'?|"([^"]|\\.)*"?)/))return"string";if(t.literal&&i.indentation()>t.keyCol)return i.skipToEnd(),"string";if(t.literal&&(t.literal=!1),i.sol()){if(t.keyCol=0,t.pair=!1,t.pairStart=!1,i.match(/---/))return"def";if(i.match(/\.\.\./))return"def";if(i.match(/\s*-\s+/))return"meta"}if(i.match(/^(\{|\}|\[|\])/))return"{"==r?t.inlinePairs++:"}"==r?t.inlinePairs--:"["==r?t.inlineList++:t.inlineList--,"meta";if(t.inlineList>0&&!n&&","==r)return i.next(),"meta";if(t.inlinePairs>0&&!n&&","==r)return t.keyCol=0,t.pair=!1,t.pairStart=!1,i.next(),"meta";if(t.pairStart){if(i.match(/^\s*(\||\>)\s*/))return t.literal=!0,"meta";if(i.match(/^\s*(\&|\*)[a-z0-9\._-]+\b/i))return"variable-2";if(0==t.inlinePairs&&i.match(/^\s*-?[0-9\.\,]+\s?$/))return"number";if(t.inlinePairs>0&&i.match(/^\s*-?[0-9\.\,]+\s?(?=(,|}))/))return"number";if(i.match(e))return"keyword"}return!t.pair&&i.match(/^\s*(?:[,\[\]{}&*!|>'"%@`][^\s'":]|[^,\[\]{}#&*!|>'"%@`])[^#]*?(?=\s*:($|\s))/)?(t.pair=!0,t.keyCol=i.indentation(),"atom"):t.pair&&i.match(/^:\s*/)?(t.pairStart=!0,"meta"):(t.pairStart=!1,t.escaped="\\"==r,i.next(),null)},startState:function(){return{pair:!1,pairStart:!1,keyCol:0,inlinePairs:0,inlineList:0,literal:!1,escaped:!1}},lineComment:"#",fold:"indent"}}),e.defineMIME("text/x-yaml","yaml"),e.defineMIME("text/yaml","yaml")});

View file

@ -0,0 +1 @@
.cm-s-dracula.CodeMirror,.cm-s-dracula .CodeMirror-gutters{background-color:#282a36 !important;color:#f8f8f2 !important;border:0}.cm-s-dracula .CodeMirror-gutters{color:#282a36}.cm-s-dracula .CodeMirror-cursor{border-left:solid thin #f8f8f0}.cm-s-dracula .CodeMirror-linenumber{color:#6d8a88}.cm-s-dracula .CodeMirror-selected{background:rgba(255,255,255,0.10)}.cm-s-dracula .CodeMirror-line::selection,.cm-s-dracula .CodeMirror-line>span::selection,.cm-s-dracula .CodeMirror-line>span>span::selection{background:rgba(255,255,255,0.10)}.cm-s-dracula .CodeMirror-line::-moz-selection,.cm-s-dracula .CodeMirror-line>span::-moz-selection,.cm-s-dracula .CodeMirror-line>span>span::-moz-selection{background:rgba(255,255,255,0.10)}.cm-s-dracula span.cm-comment{color:#6272a4}.cm-s-dracula span.cm-string,.cm-s-dracula span.cm-string-2{color:#f1fa8c}.cm-s-dracula span.cm-number{color:#bd93f9}.cm-s-dracula span.cm-variable{color:#50fa7b}.cm-s-dracula span.cm-variable-2{color:white}.cm-s-dracula span.cm-def{color:#50fa7b}.cm-s-dracula span.cm-operator{color:#ff79c6}.cm-s-dracula span.cm-keyword{color:#ff79c6}.cm-s-dracula span.cm-atom{color:#bd93f9}.cm-s-dracula span.cm-meta{color:#f8f8f2}.cm-s-dracula span.cm-tag{color:#ff79c6}.cm-s-dracula span.cm-attribute{color:#50fa7b}.cm-s-dracula span.cm-qualifier{color:#50fa7b}.cm-s-dracula span.cm-property{color:#66d9ef}.cm-s-dracula span.cm-builtin{color:#50fa7b}.cm-s-dracula span.cm-variable-3,.cm-s-dracula span.cm-type{color:#ffb86c}.cm-s-dracula .CodeMirror-activeline-background{background:rgba(255,255,255,0.1)}.cm-s-dracula .CodeMirror-matchingbracket{text-decoration:underline;color:white !important}

44
mosdns/Makefile Normal file
View file

@ -0,0 +1,44 @@
# SPDX-License-Identifier: GPL-3.0-only
#
# Copyright (C) 2021 ImmortalWrt.org
include $(TOPDIR)/rules.mk
PKG_NAME:=mosdns
PKG_VERSION:=5.3.1
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/IrineSistiana/mosdns/tar.gz/v$(PKG_VERSION)?
PKG_HASH:=7c8c795de794df52fd2b51214826aea9ebde0dcd0da78d8dda9cc5e4ab98cd80
PKG_LICENSE:=GPL-3.0
PKG_LICENSE_FILE:=LICENSE
PKG_MAINTAINER:=Tianling Shen <cnsztl@immortalwrt.org>
PKG_BUILD_DEPENDS:=golang/host
PKG_BUILD_PARALLEL:=1
PKG_USE_MIPS16:=0
PKG_BUILD_FLAGS:=no-mips16
GO_PKG:=github.com/IrineSistiana/mosdns
GO_PKG_LDFLAGS_X:=main.version=v$(PKG_VERSION)
include $(INCLUDE_DIR)/package.mk
include $(TOPDIR)/feeds/packages/lang/golang/golang-package.mk
define Package/mosdns
SECTION:=net
CATEGORY:=Network
SUBMENU:=IP Addresses and Names
TITLE:=A plug-in DNS forwarder/splitter
URL:=https://github.com/IrineSistiana/mosdns
DEPENDS:=$(GO_ARCH_DEPENDS) +ca-bundle
endef
define Package/mosdns/install
$(call GoPackage/Package/Install/Bin,$(1))
endef
$(eval $(call GoBinPackage,mosdns))
$(eval $(call BuildPackage,mosdns))

View file

@ -0,0 +1,51 @@
From 329ba9ca89d25da58d1b51b8107f164beae816bb Mon Sep 17 00:00:00 2001
From: sbwml <admin@cooluc.com>
Date: Tue, 19 Sep 2023 21:15:12 +0800
Subject: [PATCH 1/5] compatible with go1.20
---
go.mod | 6 ++----
go.sum | 4 ++--
2 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/go.mod b/go.mod
index 1839776..1b4cc4b 100644
--- a/go.mod
+++ b/go.mod
@@ -1,8 +1,6 @@
module github.com/IrineSistiana/mosdns/v5
-go 1.21
-
-toolchain go1.21.1
+go 1.20
require (
github.com/IrineSistiana/go-bytes-pool v0.0.0-20230918115058-c72bd9761c57
@@ -45,7 +43,7 @@ require (
github.com/magiconair/properties v1.8.7 // indirect
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
github.com/mdlayher/netlink v1.7.2 // indirect
- github.com/mdlayher/socket v0.5.0 // indirect
+ github.com/mdlayher/socket v0.4.1 // indirect
github.com/onsi/ginkgo/v2 v2.13.0 // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
diff --git a/go.sum b/go.sum
index 41a59b2..ad95d6d 100644
--- a/go.sum
+++ b/go.sum
@@ -173,8 +173,8 @@ github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvls
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k=
github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/g=
github.com/mdlayher/netlink v1.7.2/go.mod h1:xraEF7uJbxLhc5fpHL4cPe221LI2bdttWlU+ZGLfQSw=
-github.com/mdlayher/socket v0.5.0 h1:ilICZmJcQz70vrWVes1MFera4jGiWNocSkykwwoy3XI=
-github.com/mdlayher/socket v0.5.0/go.mod h1:WkcBFfvyG8QENs5+hfQPl1X6Jpd2yeLIYgrGFmJiJxI=
+github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U=
+github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA=
github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE=
github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
--
2.42.0

View file

@ -0,0 +1,24 @@
From 0b86b89629f32e7c8b859239aa1a4814f256053c Mon Sep 17 00:00:00 2001
From: sbwml <admin@cooluc.com>
Date: Thu, 28 Sep 2023 16:42:54 +0800
Subject: [PATCH 3/5] add response for bad request in ServeHTTP handler
---
pkg/server/http_handler.go | 1 +
1 file changed, 1 insertion(+)
diff --git a/pkg/server/http_handler.go b/pkg/server/http_handler.go
index 5a41314..8f33b3f 100644
--- a/pkg/server/http_handler.go
+++ b/pkg/server/http_handler.go
@@ -93,6 +93,7 @@ func (h *HttpHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
if err != nil {
h.warnErr(req, "invalid request", err)
w.WriteHeader(http.StatusBadRequest)
+ w.Write([]byte("Bad Request"))
return
}
--
2.42.0

View file

@ -0,0 +1,56 @@
From e34dca717e78d24a84b98c2b5d371c4253b7e260 Mon Sep 17 00:00:00 2001
From: sbwml <admin@cooluc.com>
Date: Wed, 20 Sep 2023 14:51:19 +0800
Subject: [PATCH 4/5] black_hole: apply Fisher-Yates shuffle algorithm to
randomize IP order
---
plugin/executable/black_hole/black_hole.go | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/plugin/executable/black_hole/black_hole.go b/plugin/executable/black_hole/black_hole.go
index 775253d..f955019 100644
--- a/plugin/executable/black_hole/black_hole.go
+++ b/plugin/executable/black_hole/black_hole.go
@@ -27,6 +27,8 @@ import (
"github.com/miekg/dns"
"net/netip"
"strings"
+ "math/rand"
+ "sync"
)
const PluginType = "black_hole"
@@ -40,6 +42,7 @@ var _ sequence.Executable = (*BlackHole)(nil)
type BlackHole struct {
ipv4 []netip.Addr
ipv6 []netip.Addr
+ shuffleMutex sync.Mutex
}
// QuickSetup format: [ipv4|ipv6] ...
@@ -65,9 +68,21 @@ func NewBlackHole(ips []string) (*BlackHole, error) {
return b, nil
}
+func (b *BlackHole) shuffleIPs() {
+ b.shuffleMutex.Lock()
+ defer b.shuffleMutex.Unlock()
+ rand.Shuffle(len(b.ipv4), func(i, j int) {
+ b.ipv4[i], b.ipv4[j] = b.ipv4[j], b.ipv4[i]
+ })
+ rand.Shuffle(len(b.ipv6), func(i, j int) {
+ b.ipv6[i], b.ipv6[j] = b.ipv6[j], b.ipv6[i]
+ })
+}
+
// Exec implements sequence.Executable. It set a response with given ips if
// query has corresponding qtypes.
func (b *BlackHole) Exec(_ context.Context, qCtx *query_context.Context) error {
+ b.shuffleIPs()
if r := b.Response(qCtx.Q()); r != nil {
qCtx.SetResponse(r)
}
--
2.42.0

View file

@ -0,0 +1,51 @@
From 2dc08749e2de8f19ef869e7f89c9979edbbc71ff Mon Sep 17 00:00:00 2001
From: sbwml <admin@cooluc.com>
Date: Wed, 20 Sep 2023 21:05:18 +0800
Subject: [PATCH 5/5] format logtime
---
mlog/logger.go | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/mlog/logger.go b/mlog/logger.go
index 861f091..1508db0 100644
--- a/mlog/logger.go
+++ b/mlog/logger.go
@@ -21,9 +21,11 @@ package mlog
import (
"fmt"
+ "os"
+ "time"
+
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
- "os"
)
type LogConfig struct {
@@ -64,10 +66,18 @@ func NewLogger(lc LogConfig) (*zap.Logger, error) {
out = stderr
}
- if lc.Production {
- return zap.New(zapcore.NewCore(zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()), out, lvl)), nil
+ encoderConfig := zap.NewDevelopmentEncoderConfig()
+ encoderConfig.EncodeTime = func(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
+ enc.AppendString(t.Format("2006-01-02 15:04:05"))
}
- return zap.New(zapcore.NewCore(zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig()), out, lvl)), nil
+
+ core := zapcore.NewCore(
+ zapcore.NewConsoleEncoder(encoderConfig),
+ out,
+ lvl,
+ )
+
+ return zap.New(core), nil
}
// L is a global logger.
--
2.42.0

46
v2dat/Makefile Normal file
View file

@ -0,0 +1,46 @@
#
# Copyright (C) 2015-2016 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v3.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=v2dat
PKG_SOURCE_DATE:=2022-12-15
PKG_SOURCE_VERSION:=47b8ee51fb528e11e1a83453b7e767a18d20d1f7
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_DATE).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/urlesistiana/v2dat/tar.gz/$(PKG_SOURCE_VERSION)?
PKG_HASH:=dca45a31006aca3dba5f543f6990ca755ffb2bde8e533cc2bbe6bac9ec12f157
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_SOURCE_VERSION)
PKG_LICENSE:=GPL-3.0
PKG_LICENSE_FILE:=LICENSE
PKG_MAINTAINER:=sbwml <admin@cooluc.com>
PKG_BUILD_DEPENDS:=golang/host
PKG_BUILD_PARALLEL:=1
PKG_USE_MIPS16:=0
PKG_BUILD_FLAGS:=no-mips16
GO_PKG:=github.com/urlesistiana/v2dat
include $(INCLUDE_DIR)/package.mk
include $(TOPDIR)/feeds/packages/lang/golang/golang-package.mk
define Package/v2dat
SECTION:=utils
CATEGORY:=Utilities
TITLE:=V2ray geo/ip data unpack tools
URL:=https://github.com/urlesistiana/v2dat
DEPENDS:=$(GO_ARCH_DEPENDS)
endef
define Package/v2dat/install
$(call GoPackage/Package/Install/Bin,$(1))
endef
$(eval $(call GoBinPackage,v2dat))
$(eval $(call BuildPackage,v2dat))

View file

@ -0,0 +1,47 @@
From 7c6a252ab3f7d9aeb743f9fa8d0cc8c7402f984d Mon Sep 17 00:00:00 2001
From: sbwml <admin@cooluc.com>
Date: Wed, 20 Sep 2023 20:52:27 +0800
Subject: [PATCH] format logtime
---
mlog/logger.go | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/mlog/logger.go b/mlog/logger.go
index c8b08a9..b44c88d 100644
--- a/mlog/logger.go
+++ b/mlog/logger.go
@@ -1,17 +1,28 @@
package mlog
-import "go.uber.org/zap"
+import (
+ "time"
+
+ "go.uber.org/zap"
+ "go.uber.org/zap/zapcore"
+)
var logger = mustInitLogger()
func mustInitLogger() *zap.Logger {
- l, err := zap.NewDevelopment(zap.WithCaller(false))
+ config := zap.NewDevelopmentConfig()
+ config.EncoderConfig.EncodeTime = customTimeEncoder
+ l, err := config.Build(zap.WithCaller(false))
if err != nil {
panic("failed to init mlog:" + err.Error())
}
return l
}
+func customTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
+ enc.AppendString(t.Format("2006-01-02 15:04:05"))
+}
+
func L() *zap.Logger {
return logger
}
--
2.34.8