luci: adjust and optimize sing-box shunt DNS order

This commit is contained in:
xiaorouji 2023-09-20 15:36:09 +08:00 committed by sbwml
parent 6167b6a10f
commit 27850f78fe

View File

@ -692,9 +692,7 @@ function gen_config(var)
local dns_socks_port = var["-dns_socks_port"] local dns_socks_port = var["-dns_socks_port"]
local tags = var["-tags"] local tags = var["-tags"]
local dns_direct_domains = {} local dns_domain_rules = {}
local dns_remote_domains = {}
local dns_block_domains = {}
local dns = nil local dns = nil
local inbounds = {} local inbounds = {}
local outbounds = {} local outbounds = {}
@ -717,7 +715,7 @@ function gen_config(var)
local experimental = nil local experimental = nil
local dns_outTag = nil local default_outTag = nil
if node_id then if node_id then
local node = uci:get_all(appname, node_id) local node = uci:get_all(appname, node_id)
@ -1000,40 +998,37 @@ function gen_config(var)
end end
if e.domain_list then if e.domain_list then
local domain = {} local domain_table = {
local domain_suffix = {} outboundTag = outboundTag,
local domain_keyword = {} domain = {},
local domain_regex = {} domain_suffix = {},
local geosite = {} domain_keyword = {},
domain_regex = {},
geosite = {},
}
string.gsub(e.domain_list, '[^' .. "\r\n" .. ']+', function(w) string.gsub(e.domain_list, '[^' .. "\r\n" .. ']+', function(w)
if w:find("geosite:") == 1 then if w:find("geosite:") == 1 then
table.insert(geosite, w:sub(1 + #"geosite:")) table.insert(domain_table.geosite, w:sub(1 + #"geosite:"))
elseif w:find("regexp:") == 1 then elseif w:find("regexp:") == 1 then
table.insert(domain_regex, w:sub(1 + #"regexp:")) table.insert(domain_table.domain_regex, w:sub(1 + #"regexp:"))
elseif w:find("full:") == 1 then elseif w:find("full:") == 1 then
table.insert(domain, w:sub(1 + #"full:")) table.insert(domain_table.domain, w:sub(1 + #"full:"))
elseif w:find("domain:") == 1 then elseif w:find("domain:") == 1 then
table.insert(domain_keyword, w:sub(1 + #"domain:")) table.insert(domain_table.domain, w:sub(1 + #"domain:"))
table.insert(domain_table.domain_suffix, "." .. w:sub(1 + #"domain:"))
else else
table.insert(domain, w) table.insert(domain_table.domain_keyword, w)
end
if outboundTag == "direct" then
table.insert(dns_direct_domains, w)
elseif outboundTag == "block" then
table.insert(dns_block_domains, w)
else
if outboundTag ~= "nil" then
table.insert(dns_remote_domains, w)
end
end end
end) end)
rule.domain = #domain_table.domain > 0 and domain_table.domain or nil
rule.domain_suffix = #domain_table.domain_suffix > 0 and domain_table.domain_suffix or nil
rule.domain_keyword = #domain_table.domain_keyword > 0 and domain_table.domain_keyword or nil
rule.domain_regex = #domain_table.domain_regex > 0 and domain_table.domain_regex or nil
rule.geosite = #domain_table.geosite > 0 and domain_table.geosite or nil
rule.domain = #domain > 0 and domain or nil if outboundTag and outboundTag ~= "nil" then
rule.domain_suffix = #domain_suffix > 0 and domain_suffix or nil table.insert(dns_domain_rules, domain_table)
rule.domain_keyword = #domain_keyword > 0 and domain_keyword or nil end
rule.domain_regex = #domain_regex > 0 and domain_regex or nil
rule.geosite = #geosite > 0 and geosite or nil
end end
if e.ip_list then if e.ip_list then
@ -1057,7 +1052,7 @@ function gen_config(var)
if default_outboundTag then if default_outboundTag then
route.final = default_outboundTag route.final = default_outboundTag
dns_outTag = default_outboundTag default_outTag = default_outboundTag
end end
for index, value in ipairs(rules) do for index, value in ipairs(rules) do
@ -1079,7 +1074,7 @@ function gen_config(var)
outbound = gen_outbound(flag, node) outbound = gen_outbound(flag, node)
end end
if outbound then if outbound then
dns_outTag = outbound.tag default_outTag = outbound.tag
table.insert(outbounds, outbound) table.insert(outbounds, outbound)
end end
@ -1098,46 +1093,21 @@ function gen_config(var)
fakeip = nil, fakeip = nil,
} }
table.insert(dns.servers, {
tag = "block",
address = "rcode://success",
})
if dns_socks_address and dns_socks_port then if dns_socks_address and dns_socks_port then
dns_outTag = "dns_socks_out" default_outTag = "dns_socks_out"
table.insert(outbounds, 1, { table.insert(outbounds, 1, {
type = "socks", type = "socks",
tag = dns_outTag, tag = default_outTag,
server = dns_socks_address, server = dns_socks_address,
server_port = tonumber(dns_socks_port) server_port = tonumber(dns_socks_port)
}) })
end end
local dns_tag = "remote"
local domain = {}
local domain_suffix = {}
local domain_keyword = {}
local domain_regex = {}
local geosite = {}
for index, value in ipairs(dns_remote_domains) do
if value:find("geosite:") == 1 then
table.insert(geosite, value:sub(1 + #"geosite:"))
elseif value:find("regexp:") == 1 then
table.insert(domain_regex, value:sub(1 + #"regexp:"))
elseif value:find("full:") == 1 then
table.insert(domain, value:sub(1 + #"full:"))
elseif value:find("domain:") == 1 then
table.insert(domain_keyword, value:sub(1 + #"domain:"))
else
table.insert(domain, value)
end
end
local remote_rule = {
server = dns_tag,
domain = #domain > 0 and domain or nil,
domain_suffix = #domain_suffix > 0 and domain_suffix or nil,
domain_keyword = #domain_keyword > 0 and domain_keyword or nil,
domain_regex = #domain_regex > 0 and domain_regex or nil,
geosite = #geosite > 0 and geosite or nil,
disable_cache = true,
}
local remote_strategy = "prefer_ipv6" local remote_strategy = "prefer_ipv6"
if remote_dns_query_strategy == "UseIPv4" then if remote_dns_query_strategy == "UseIPv4" then
remote_strategy = "ipv4_only" remote_strategy = "ipv4_only"
@ -1145,32 +1115,32 @@ function gen_config(var)
remote_strategy = "ipv6_only" remote_strategy = "ipv6_only"
end end
local server = { local remote_server = {
tag = dns_tag, tag = "remote",
address_strategy = "prefer_ipv4", address_strategy = "prefer_ipv4",
strategy = remote_strategy, strategy = remote_strategy,
address_resolver = "direct", address_resolver = "direct",
detour = dns_outTag, detour = default_outTag,
} }
if remote_dns_udp_server then if remote_dns_udp_server then
local server_port = tonumber(remote_dns_port) or 53 local server_port = tonumber(remote_dns_port) or 53
server.address = "udp://" .. remote_dns_udp_server .. ":" .. server_port remote_server.address = "udp://" .. remote_dns_udp_server .. ":" .. server_port
end end
if remote_dns_tcp_server then if remote_dns_tcp_server then
server.address = remote_dns_tcp_server remote_server.address = remote_dns_tcp_server
end end
if remote_dns_doh_url and remote_dns_doh_host then if remote_dns_doh_url and remote_dns_doh_host then
server.address = remote_dns_doh_url remote_server.address = remote_dns_doh_url
end end
if server.address then if remote_server.address then
table.insert(dns.servers, server) table.insert(dns.servers, remote_server)
end end
local fakedns_tag = dns_tag .. "_fakeip" local fakedns_tag = "remote_fakeip"
if remote_dns_fake then if remote_dns_fake then
dns.fakeip = { dns.fakeip = {
enabled = true, enabled = true,
@ -1194,56 +1164,18 @@ function gen_config(var)
} }
end end
end end
if remote_rule.domain or remote_rule.domain_suffix or remote_rule.domain_keyword or remote_rule.domain_regex or remote_rule.geosite then
local rule = api.clone(remote_rule)
rule.server = dns_tag
if remote_dns_fake then
rule.query_type = {
"A", "AAAA"
}
rule.server = fakedns_tag
end
table.insert(dns.rules, rule)
end
if direct_dns_udp_server then if direct_dns_udp_server then
local domain = {}
local nodes_domain_text = sys.exec('uci show passwall | grep ".address=" | cut -d "\'" -f 2 | grep "[a-zA-Z]$" | sort -u') local nodes_domain_text = sys.exec('uci show passwall | grep ".address=" | cut -d "\'" -f 2 | grep "[a-zA-Z]$" | sort -u')
string.gsub(nodes_domain_text, '[^' .. "\r\n" .. ']+', function(w) string.gsub(nodes_domain_text, '[^' .. "\r\n" .. ']+', function(w)
table.insert(dns_direct_domains, "full:" .. w) table.insert(domain, w)
end) end)
if #domain > 0 then
local dns_tag = "direct" table.insert(dns_domain_rules, {
outboundTag = "direct",
local domain = {} domain = domain
local domain_suffix = {} })
local domain_keyword = {}
local domain_regex = {}
local geosite = {}
for index, value in ipairs(dns_direct_domains) do
if value:find("geosite:") == 1 then
table.insert(geosite, value:sub(1 + #"geosite:"))
elseif value:find("regexp:") == 1 then
table.insert(domain_regex, value:sub(1 + #"regexp:"))
elseif value:find("full:") == 1 then
table.insert(domain, value:sub(1 + #"full:"))
elseif value:find("domain:") == 1 then
table.insert(domain_keyword, value:sub(1 + #"domain:"))
else
table.insert(domain, value)
end
end
local direct_rule = {
server = dns_tag,
domain = #domain > 0 and domain or nil,
domain_suffix = #domain_suffix > 0 and domain_suffix or nil,
domain_keyword = #domain_keyword > 0 and domain_keyword or nil,
domain_regex = #domain_regex > 0 and domain_regex or nil,
geosite = #geosite > 0 and geosite or nil,
disable_cache = false,
}
if direct_rule.domain or direct_rule.domain_suffix or direct_rule.domain_keyword or direct_rule.domain_regex or direct_rule.geosite then
table.insert(dns.rules, direct_rule)
end end
local direct_strategy = "prefer_ipv6" local direct_strategy = "prefer_ipv6"
@ -1256,7 +1188,7 @@ function gen_config(var)
local port = tonumber(direct_dns_port) or 53 local port = tonumber(direct_dns_port) or 53
table.insert(dns.servers, { table.insert(dns.servers, {
tag = dns_tag, tag = "direct",
address = "udp://" .. direct_dns_udp_server .. ":" .. port, address = "udp://" .. direct_dns_udp_server .. ":" .. port,
address_strategy = "prefer_ipv6", address_strategy = "prefer_ipv6",
strategy = direct_strategy, strategy = direct_strategy,
@ -1264,43 +1196,6 @@ function gen_config(var)
}) })
end end
table.insert(dns.servers, {
tag = "block",
address = "rcode://success",
})
local block_domain = {}
local block_domain_suffix = {}
local block_domain_keyword = {}
local block_domain_regex = {}
local block_geosite = {}
for index, value in ipairs(dns_block_domains) do
if value:find("geosite:") == 1 then
table.insert(block_geosite, value:sub(1 + #"geosite:"))
elseif value:find("regexp:") == 1 then
table.insert(block_domain_regex, value:sub(1 + #"regexp:"))
elseif value:find("full:") == 1 then
table.insert(block_domain, value:sub(1 + #"full:"))
elseif value:find("domain:") == 1 then
table.insert(block_domain_keyword, value:sub(1 + #"domain:"))
else
table.insert(block_domain, value)
end
end
local block_rule = {
server = "block",
domain = #block_domain > 0 and block_domain or nil,
domain_suffix = #block_domain_suffix > 0 and block_domain_suffix or nil,
domain_keyword = #block_domain_keyword > 0 and block_domain_keyword or nil,
domain_regex = #block_domain_regex > 0 and block_domain_regex or nil,
geosite = #block_geosite > 0 and block_geosite or nil,
disable_cache = true,
}
if block_rule.domain or block_rule.domain_suffix or block_rule.domain_keyword or block_rule.domain_regex or block_rule.geosite then
table.insert(dns.rules, block_rule)
end
local default_dns_flag = "remote" local default_dns_flag = "remote"
if dns_socks_address and dns_socks_port then if dns_socks_address and dns_socks_port then
else else
@ -1323,6 +1218,43 @@ function gen_config(var)
end end
end end
dns.final = default_dns_flag dns.final = default_dns_flag
--按分流顺序DNS
if dns_domain_rules and #dns_domain_rules > 0 then
for index, value in ipairs(dns_domain_rules) do
if value.outboundTag and (value.domain or value.domain_suffix or value.domain_keyword or value.domain_regex or value.geosite) then
local dns_rule = {
server = value.outboundTag,
domain = (value.domain and #value.domain > 0) and value.domain or nil,
domain_suffix = (value.domain_suffix and #value.domain_suffix > 0) and value.domain_suffix or nil,
domain_keyword = (value.domain_keyword and #value.domain_keyword > 0) and value.domain_keyword or nil,
domain_regex = (value.domain_regex and #value.domain_regex > 0) and value.domain_regex or nil,
geosite = (value.geosite and #value.geosite > 0) and value.geosite or nil,
disable_cache = false,
}
if value.outboundTag ~= "block" and value.outboundTag ~= "direct" then
dns_rule.server = "remote"
if value.outboundTag ~= "default" and remote_server.address then
local remote_dns_server = api.clone(remote_server)
remote_dns_server.tag = value.outboundTag
remote_dns_server.detour = value.outboundTag
table.insert(dns.servers, remote_dns_server)
dns_rule.server = remote_dns_server.tag
end
if remote_dns_fake then
local fakedns_dns_rule = api.clone(dns_rule)
fakedns_dns_rule.query_type = {
"A", "AAAA"
}
fakedns_dns_rule.server = fakedns_tag
fakedns_dns_rule.disable_cache = true
table.insert(dns.rules, fakedns_dns_rule)
end
end
table.insert(dns.rules, dns_rule)
end
end
end
table.insert(inbounds, { table.insert(inbounds, {
type = "direct", type = "direct",