update 2026-08-25 00:29:42
No files matched your search
|
Before Width: | Height: | Size: 91 KiB |
|
Before Width: | Height: | Size: 319 KiB |
|
Before Width: | Height: | Size: 389 KiB |
|
After Width: | Height: | Size: 640 KiB |
|
After Width: | Height: | Size: 550 KiB |
|
After Width: | Height: | Size: 547 KiB |
|
After Width: | Height: | Size: 659 KiB |
|
After Width: | Height: | Size: 650 KiB |
@@ -25,25 +25,25 @@ o:value("https://wifi.vivo.com.cn/generate_204", "VIVO (CN)")
|
|||||||
o.default = o.keylist[3]
|
o.default = o.keylist[3]
|
||||||
|
|
||||||
if true then
|
if true then
|
||||||
m:appendTemplate("/node_list/node_list")
|
m:appendTemplate("/node_list/node_list")
|
||||||
|
|
||||||
if luci.http.formvalue("cbi.submit") == "1" then
|
if luci.http.formvalue("cbi.submit") == "1" then
|
||||||
local group_order = {}
|
local group_order = {}
|
||||||
group_order = luci.http.formvaluetable("group.order")
|
group_order = luci.http.formvaluetable("group.order")
|
||||||
if group_order then
|
if group_order then
|
||||||
for k, v in pairs(group_order) do
|
for k, v in pairs(group_order) do
|
||||||
if v and v~= "" then
|
if v and v~= "" then
|
||||||
local new_order = {}
|
local new_order = {}
|
||||||
string.gsub(v, "[^" .. " " .. "]+", function(w)
|
string.gsub(v, "[^" .. " " .. "]+", function(w)
|
||||||
new_order[#new_order + 1] = w
|
new_order[#new_order + 1] = w
|
||||||
end)
|
end)
|
||||||
for idx, name in ipairs(new_order) do
|
for idx, name in ipairs(new_order) do
|
||||||
m.uci:reorder(m.config, name, idx - 1)
|
m.uci:reorder(m.config, name, idx - 1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return api.return_map(m)
|
return api.return_map(m)
|
||||||
@@ -117,9 +117,9 @@ end
|
|||||||
o = s:option(DummyValue, "_update", translate("Manual subscription All"))
|
o = s:option(DummyValue, "_update", translate("Manual subscription All"))
|
||||||
o.rawhtml = true
|
o.rawhtml = true
|
||||||
o.cfgvalue = function(self, section)
|
o.cfgvalue = function(self, section)
|
||||||
return string.format([[
|
return string.format([[
|
||||||
<input type="button" class="btn cbi-button cbi-button-apply" onclick="ManualSubscribeAll()" value="%s" />]],
|
<input type="button" class="btn cbi-button cbi-button-apply" onclick="ManualSubscribeAll()" value="%s" />]],
|
||||||
translate("Manual subscription All"))
|
translate("Manual subscription All"))
|
||||||
end
|
end
|
||||||
|
|
||||||
s = m:section(TypedSection, "subscribe_list", "", "<font color='red'>" .. translate("When adding a new subscription, please save and apply before manually subscribing. If you only change the subscription URL, you can subscribe manually, and the system will save it automatically.") .. "</font>")
|
s = m:section(TypedSection, "subscribe_list", "", "<font color='red'>" .. translate("When adding a new subscription, please save and apply before manually subscribing. If you only change the subscription URL, you can subscribe manually, and the system will save it automatically.") .. "</font>")
|
||||||
@@ -215,9 +215,9 @@ end
|
|||||||
o = s:option(DummyValue, "_update", translate("Manual subscription"))
|
o = s:option(DummyValue, "_update", translate("Manual subscription"))
|
||||||
o.rawhtml = true
|
o.rawhtml = true
|
||||||
o.cfgvalue = function(self, section)
|
o.cfgvalue = function(self, section)
|
||||||
return string.format([[
|
return string.format([[
|
||||||
<input type="button" class="btn cbi-button cbi-button-apply" onclick="ManualSubscribe('%s')" value="%s" />]],
|
<input type="button" class="btn cbi-button cbi-button-apply" onclick="ManualSubscribe('%s')" value="%s" />]],
|
||||||
section, translate("Manual subscription"))
|
section, translate("Manual subscription"))
|
||||||
end
|
end
|
||||||
|
|
||||||
m:appendTemplate("/cbi/sortable", {sectiontype = s.sectiontype})
|
m:appendTemplate("/cbi/sortable", {sectiontype = s.sectiontype})
|
||||||
|
|||||||
@@ -161,6 +161,7 @@ local function start()
|
|||||||
end)
|
end)
|
||||||
if firewall_num > 0 then
|
if firewall_num > 0 then
|
||||||
api.uci_save(uci, "firewall", true, true)
|
api.uci_save(uci, "firewall", true, true)
|
||||||
|
cmd("/etc/init.d/firewall reload >/dev/null 2>&1")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -176,6 +177,7 @@ local function stop()
|
|||||||
end)
|
end)
|
||||||
if num > 0 then
|
if num > 0 then
|
||||||
api.uci_save(uci, "firewall", true, true)
|
api.uci_save(uci, "firewall", true, true)
|
||||||
|
cmd("/etc/init.d/firewall reload >/dev/null 2>&1")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
cmd(string.format("rm -rf %s %s", CONFIG_PATH, LOG_APP_FILE))
|
cmd(string.format("rm -rf %s %s", CONFIG_PATH, LOG_APP_FILE))
|
||||||
|
|||||||
@@ -916,12 +916,12 @@ function gen_config(var)
|
|||||||
if xray_settings.fragment == "1" then
|
if xray_settings.fragment == "1" then
|
||||||
local lengths, delays = {}, {}
|
local lengths, delays = {}, {}
|
||||||
api.trim(xray_settings.fragment_lengths):gsub("[^,]+", function(w)
|
api.trim(xray_settings.fragment_lengths):gsub("[^,]+", function(w)
|
||||||
w = w:gsub("%s+", "")
|
w = w:gsub("%s+", "")
|
||||||
if w ~= "" then lengths[#lengths+1] = w end
|
if w ~= "" then lengths[#lengths+1] = w end
|
||||||
end)
|
end)
|
||||||
api.trim(xray_settings.fragment_delays):gsub("[^,]+", function(w)
|
api.trim(xray_settings.fragment_delays):gsub("[^,]+", function(w)
|
||||||
w = w:gsub("%s+", "")
|
w = w:gsub("%s+", "")
|
||||||
if w ~= "" then delays[#delays+1] = w end
|
if w ~= "" then delays[#delays+1] = w end
|
||||||
end)
|
end)
|
||||||
fragment_table = {
|
fragment_table = {
|
||||||
type = "fragment",
|
type = "fragment",
|
||||||
|
|||||||
@@ -534,7 +534,7 @@
|
|||||||
//自定义框
|
//自定义框
|
||||||
function v_customEnter(cbid, labelSpan, hiddenInput, searchInput, panel, listContainer, customInput) {
|
function v_customEnter(cbid, labelSpan, hiddenInput, searchInput, panel, listContainer, customInput) {
|
||||||
let inputValue = customInput.value.trim();
|
let inputValue = customInput.value.trim();
|
||||||
if (!inputValue) {
|
if (!inputValue) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const existingItems = listContainer.querySelectorAll('li[data-key="' + inputValue + '"]');
|
const existingItems = listContainer.querySelectorAll('li[data-key="' + inputValue + '"]');
|
||||||
|
|||||||
@@ -3,42 +3,42 @@ local map = self.map
|
|||||||
local api = map.api
|
local api = map.api
|
||||||
-%>
|
-%>
|
||||||
<style>
|
<style>
|
||||||
.dns-con {
|
.dns-con {
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
}
|
}
|
||||||
.faq-title {
|
.faq-title {
|
||||||
color: var(--primary);
|
color: var(--primary);
|
||||||
font-weight: bolder;
|
font-weight: bolder;
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
.reset-title {
|
.reset-title {
|
||||||
color: var(--primary);
|
color: var(--primary);
|
||||||
font-weight: bolder;
|
font-weight: bolder;
|
||||||
margin-bottom: 0.3rem;
|
margin-bottom: 0.3rem;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-top: 1.2rem;
|
margin-top: 1.2rem;
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
.dns-item {
|
.dns-item {
|
||||||
margin-bottom: 0.8rem;
|
margin-bottom: 0.8rem;
|
||||||
line-height:1.2rem;
|
line-height:1.2rem;
|
||||||
}
|
}
|
||||||
.dns-list {
|
.dns-list {
|
||||||
text-indent:1rem;
|
text-indent:1rem;
|
||||||
line-height: 1.2rem;
|
line-height: 1.2rem;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<div class="dns-con">
|
<div class="dns-con">
|
||||||
<div id="faq_dns">
|
<div id="faq_dns">
|
||||||
<ul>
|
<ul>
|
||||||
<b class="faq-title"><%:DNS related issues:%></b>
|
<b class="faq-title"><%:DNS related issues:%></b>
|
||||||
<li class="dns-item">1. <span><%:Certain browsers such as Chrome have built-in DNS service, which may affect DNS resolution settings. You can go to 'Settings -> Privacy and security -> Use secure DNS' menu to turn it off.%></span></li>
|
<li class="dns-item">1. <span><%:Certain browsers such as Chrome have built-in DNS service, which may affect DNS resolution settings. You can go to 'Settings -> Privacy and security -> Use secure DNS' menu to turn it off.%></span></li>
|
||||||
<li class="dns-item">2. <span><%:If you are unable to access the internet after reboot, please try clearing the cache of your terminal devices (make sure to close all open browser application windows first, this step is especially important):%></span>
|
<li class="dns-item">2. <span><%:If you are unable to access the internet after reboot, please try clearing the cache of your terminal devices (make sure to close all open browser application windows first, this step is especially important):%></span>
|
||||||
<ul><li class="dns-list"> ◦ <span><%:For Windows systems, open Command Prompt and run the command 'ipconfig /flushdns'.%></span></li>
|
<ul><li class="dns-list"> ◦ <span><%:For Windows systems, open Command Prompt and run the command 'ipconfig /flushdns'.%></span></li>
|
||||||
<li class="dns-list"> ◦ <span><%:For Mac systems, open Terminal and run the command 'sudo killall -HUP mDNSResponder'.%></span></li>
|
<li class="dns-list"> ◦ <span><%:For Mac systems, open Terminal and run the command 'sudo killall -HUP mDNSResponder'.%></span></li>
|
||||||
<li class="dns-list"> ◦ <span><%:For mobile devices, you can clear it by reconnecting to the network, such as toggling Airplane Mode and reconnecting to WiFi.%></span></li>
|
<li class="dns-list"> ◦ <span><%:For mobile devices, you can clear it by reconnecting to the network, such as toggling Airplane Mode and reconnecting to WiFi.%></span></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="dns-item">3. <span><%:Please make sure your device's network settings point both the DNS server and default gateway to this router, to ensure DNS queries are properly routed.%></span></li>
|
<li class="dns-item">3. <span><%:Please make sure your device's network settings point both the DNS server and default gateway to this router, to ensure DNS queries are properly routed.%></span></li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -58,7 +58,7 @@ local api = map.api
|
|||||||
}
|
}
|
||||||
|
|
||||||
var dom = document.getElementById("faq_reset");
|
var dom = document.getElementById("faq_reset");
|
||||||
if (dom) {
|
if (dom) {
|
||||||
var li = "";
|
var li = "";
|
||||||
li += "<a href='#' class='reset-title' onclick='hide()'>" + "<%: Hide in main menu:%>"+ "</a>" + "<br />" + "<%: Browser access: %>" + "<a href='#' onclick='hide()'>" + hide_url + "</a>" + "<br />";
|
li += "<a href='#' class='reset-title' onclick='hide()'>" + "<%: Hide in main menu:%>"+ "</a>" + "<br />" + "<%: Browser access: %>" + "<a href='#' onclick='hide()'>" + hide_url + "</a>" + "<br />";
|
||||||
li += "<a href='#' class='reset-title'>" + "<%: Show in main menu:%>"+ "</a>" + "<br />" +"<%: Browser access: %>" + "<a href='#'>" + show_url + "</a>" + "<br />";
|
li += "<a href='#' class='reset-title'>" + "<%: Show in main menu:%>"+ "</a>" + "<br />" +"<%: Browser access: %>" + "<a href='#'>" + show_url + "</a>" + "<br />";
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ table td, .table .td {
|
|||||||
z-index: 99;
|
z-index: 99;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background: white;
|
background: white;
|
||||||
box-shadow: darkgrey 10px 10px 30px 5px;
|
box-shadow: darkgrey 10px 10px 30px 5px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
}
|
}
|
||||||
@@ -55,8 +55,8 @@ table td, .table .td {
|
|||||||
.ping a,
|
.ping a,
|
||||||
.ping_value a,
|
.ping_value a,
|
||||||
.tcping_value a {
|
.tcping_value a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ table th, .table .th {
|
|||||||
|
|
||||||
table td, .table .td {
|
table td, .table .td {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
/* white-space: nowrap; */
|
/* white-space: nowrap; */
|
||||||
word-break: keep-all;
|
word-break: keep-all;
|
||||||
}
|
}
|
||||||
|
|
||||||
.td.cbi-section-actions {
|
.td.cbi-section-actions {
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ local api = map.api
|
|||||||
if (!value) {
|
if (!value) {
|
||||||
alert("<%:Please enter query content!%>");
|
alert("<%:Please enter query content!%>");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lookup_btn.disabled = true;
|
lookup_btn.disabled = true;
|
||||||
extract_btn.disabled = true;
|
extract_btn.disabled = true;
|
||||||
btn.value = '<%:Querying%>';
|
btn.value = '<%:Querying%>';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
if [ -e "/etc/config/ucitrack" ]; then
|
if [ -e "/etc/config/ucitrack" ]; then
|
||||||
uci -q batch <<-EOF
|
uci -q batch <<-EOF
|
||||||
delete ucitrack.@passwall[-1]
|
delete ucitrack.@passwall[-1]
|
||||||
add ucitrack passwall
|
add ucitrack passwall
|
||||||
set ucitrack.@passwall[-1].init=passwall
|
set ucitrack.@passwall[-1].init=passwall
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
if [ -e "/etc/config/ucitrack" ]; then
|
if [ -e "/etc/config/ucitrack" ]; then
|
||||||
uci -q batch <<-EOF
|
uci -q batch <<-EOF
|
||||||
delete ucitrack.@passwall_server[-1]
|
delete ucitrack.@passwall_server[-1]
|
||||||
add ucitrack passwall_server
|
add ucitrack passwall_server
|
||||||
set ucitrack.@passwall_server[-1].init=passwall_server
|
set ucitrack.@passwall_server[-1].init=passwall_server
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ local geo_dir = (api.uci_get_c("@global_rules[0]", "v2ray_location_asset") or "/
|
|||||||
local geosite_path = geo_dir .. "/geosite.dat"
|
local geosite_path = geo_dir .. "/geosite.dat"
|
||||||
local geoip_path = geo_dir .. "/geoip.dat"
|
local geoip_path = geo_dir .. "/geoip.dat"
|
||||||
if fs.access(geosite_path) and fs.access(geoip_path) then
|
if fs.access(geosite_path) and fs.access(geoip_path) then
|
||||||
f = SimpleForm(api.c_config)
|
f = SimpleForm(api.c_config)
|
||||||
f.reset = false
|
f.reset = false
|
||||||
f.submit = false
|
f.submit = false
|
||||||
|
|
||||||
local obj = Template(api.appname .. "/rule/geoview")
|
local obj = Template(api.appname .. "/rule/geoview")
|
||||||
obj.api = api
|
obj.api = api
|
||||||
f:append(obj)
|
f:append(obj)
|
||||||
end
|
end
|
||||||
|
|
||||||
return f
|
return f
|
||||||
@@ -25,25 +25,25 @@ o:value("https://wifi.vivo.com.cn/generate_204", "VIVO (CN)")
|
|||||||
o.default = o.keylist[3]
|
o.default = o.keylist[3]
|
||||||
|
|
||||||
if true then
|
if true then
|
||||||
m:appendTemplate("/node_list/node_list")
|
m:appendTemplate("/node_list/node_list")
|
||||||
|
|
||||||
if luci.http.formvalue("cbi.submit") == "1" then
|
if luci.http.formvalue("cbi.submit") == "1" then
|
||||||
local group_order = {}
|
local group_order = {}
|
||||||
group_order = luci.http.formvaluetable("group.order")
|
group_order = luci.http.formvaluetable("group.order")
|
||||||
if group_order then
|
if group_order then
|
||||||
for k, v in pairs(group_order) do
|
for k, v in pairs(group_order) do
|
||||||
if v and v~= "" then
|
if v and v~= "" then
|
||||||
local new_order = {}
|
local new_order = {}
|
||||||
string.gsub(v, "[^" .. " " .. "]+", function(w)
|
string.gsub(v, "[^" .. " " .. "]+", function(w)
|
||||||
new_order[#new_order + 1] = w
|
new_order[#new_order + 1] = w
|
||||||
end)
|
end)
|
||||||
for idx, name in ipairs(new_order) do
|
for idx, name in ipairs(new_order) do
|
||||||
m.uci:reorder(m.config, name, idx - 1)
|
m.uci:reorder(m.config, name, idx - 1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return api.return_map(m)
|
return api.return_map(m)
|
||||||
@@ -112,8 +112,8 @@ end
|
|||||||
o = s:option(DummyValue, "_update", translate("Manual subscription All"))
|
o = s:option(DummyValue, "_update", translate("Manual subscription All"))
|
||||||
o.rawhtml = true
|
o.rawhtml = true
|
||||||
o.cfgvalue = function(self, section)
|
o.cfgvalue = function(self, section)
|
||||||
return string.format([[
|
return string.format([[
|
||||||
<input type="button" class="btn cbi-button cbi-button-apply" onclick="ManualSubscribeAll()" value="%s" />]],
|
<input type="button" class="btn cbi-button cbi-button-apply" onclick="ManualSubscribeAll()" value="%s" />]],
|
||||||
translate("Manual subscription All"))
|
translate("Manual subscription All"))
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -210,8 +210,8 @@ end
|
|||||||
o = s:option(DummyValue, "_update", translate("Manual subscription"))
|
o = s:option(DummyValue, "_update", translate("Manual subscription"))
|
||||||
o.rawhtml = true
|
o.rawhtml = true
|
||||||
o.cfgvalue = function(self, section)
|
o.cfgvalue = function(self, section)
|
||||||
return string.format([[
|
return string.format([[
|
||||||
<input type="button" class="btn cbi-button cbi-button-apply" onclick="ManualSubscribe('%s')" value="%s" />]],
|
<input type="button" class="btn cbi-button cbi-button-apply" onclick="ManualSubscribe('%s')" value="%s" />]],
|
||||||
section, translate("Manual subscription"))
|
section, translate("Manual subscription"))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,68 +1,68 @@
|
|||||||
if not api.is_finded("sslocal") then
|
if not api.is_finded("sslocal") then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- [[ Shadowsocks Rust ]]
|
-- [[ Shadowsocks Rust ]]
|
||||||
local m, s1 = ...
|
local m, s1 = ...
|
||||||
local type_name = "SS-Rust"
|
local type_name = "SS-Rust"
|
||||||
|
|
||||||
s1.fields["type"]:value(type_name, "Shadowsocks Rust")
|
s1.fields["type"]:value(type_name, "Shadowsocks Rust")
|
||||||
|
|
||||||
if s1.val["type"] ~= type_name then
|
if s1.val["type"] ~= type_name then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local s = NamedSection(m, arg[1], "server")
|
local s = NamedSection(m, arg[1], "server")
|
||||||
s.type_name = type_name
|
s.type_name = type_name
|
||||||
s.option_prefix = "ssrust_"
|
s.option_prefix = "ssrust_"
|
||||||
|
|
||||||
local ssrust_encrypt_method_list = {
|
local ssrust_encrypt_method_list = {
|
||||||
"none", "plain",
|
"none", "plain",
|
||||||
"aes-128-gcm", "aes-256-gcm", "chacha20-ietf-poly1305",
|
"aes-128-gcm", "aes-256-gcm", "chacha20-ietf-poly1305",
|
||||||
"2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha8-poly1305", "2022-blake3-chacha20-poly1305"
|
"2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha8-poly1305", "2022-blake3-chacha20-poly1305"
|
||||||
}
|
}
|
||||||
|
|
||||||
o = s:option(Value, "address", translate("Address (Support Domain Name)"))
|
o = s:option(Value, "address", translate("Address (Support Domain Name)"))
|
||||||
|
|
||||||
o = s:option(Value, "port", translate("Port"))
|
o = s:option(Value, "port", translate("Port"))
|
||||||
o.datatype = "port"
|
o.datatype = "port"
|
||||||
|
|
||||||
o = s:option(Value, "password", translate("Password"))
|
o = s:option(Value, "password", translate("Password"))
|
||||||
o.password = true
|
o.password = true
|
||||||
|
|
||||||
o = s:option(Value, "method", translate("Encrypt Method"))
|
o = s:option(Value, "method", translate("Encrypt Method"))
|
||||||
for a, t in ipairs(ssrust_encrypt_method_list) do o:value(t) end
|
for a, t in ipairs(ssrust_encrypt_method_list) do o:value(t) end
|
||||||
|
|
||||||
o = s:option(Value, "timeout", translate("Connection Timeout"))
|
o = s:option(Value, "timeout", translate("Connection Timeout"))
|
||||||
o.datatype = "uinteger"
|
o.datatype = "uinteger"
|
||||||
o.default = 300
|
o.default = 300
|
||||||
|
|
||||||
o = s:option(Flag, "tcp_fast_open", "TCP " .. translate("Fast Open"), translate("Need node support required"))
|
o = s:option(Flag, "tcp_fast_open", "TCP " .. translate("Fast Open"), translate("Need node support required"))
|
||||||
o.default = 0
|
o.default = 0
|
||||||
|
|
||||||
o = s:option(Flag, "plugin_enabled", translate("plugin"))
|
o = s:option(Flag, "plugin_enabled", translate("plugin"))
|
||||||
o.default = 0
|
o.default = 0
|
||||||
|
|
||||||
o = s:option(Value, "plugin", "SIP003 " .. translate("plugin"), translate("Supports custom SIP003 plugins, Make sure the plugin is installed."))
|
o = s:option(Value, "plugin", "SIP003 " .. translate("plugin"), translate("Supports custom SIP003 plugins, Make sure the plugin is installed."))
|
||||||
o.default = "none"
|
o.default = "none"
|
||||||
o:value("none", translate("none"))
|
o:value("none", translate("none"))
|
||||||
if api.is_finded("xray-plugin") then o:value("xray-plugin") end
|
if api.is_finded("xray-plugin") then o:value("xray-plugin") end
|
||||||
if api.is_finded("v2ray-plugin") then o:value("v2ray-plugin") end
|
if api.is_finded("v2ray-plugin") then o:value("v2ray-plugin") end
|
||||||
if api.is_finded("obfs-local") then o:value("obfs-local") end
|
if api.is_finded("obfs-local") then o:value("obfs-local") end
|
||||||
if api.is_finded("shadow-tls") then o:value("shadow-tls") end
|
if api.is_finded("shadow-tls") then o:value("shadow-tls") end
|
||||||
o:depends({ plugin_enabled = true })
|
o:depends({ plugin_enabled = true })
|
||||||
o.validate = function(self, value, t)
|
o.validate = function(self, value, t)
|
||||||
if value and value ~= "" and value ~= "none" then
|
if value and value ~= "" and value ~= "none" then
|
||||||
if not api.is_finded(value) then
|
if not api.is_finded(value) then
|
||||||
return nil, value .. ": " .. translate("Can't find this file!")
|
return nil, value .. ": " .. translate("Can't find this file!")
|
||||||
else
|
else
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
o = s:option(Value, "plugin_opts", translate("opts"))
|
o = s:option(Value, "plugin_opts", translate("opts"))
|
||||||
o:depends({ plugin_enabled = true })
|
o:depends({ plugin_enabled = true })
|
||||||
|
|
||||||
api.luci_types(s1, s)
|
api.luci_types(s1, s)
|
||||||
@@ -1,66 +1,66 @@
|
|||||||
if not api.is_finded("ssr-local") then
|
if not api.is_finded("ssr-local") then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- [[ ShadowsocksR Libev ]]
|
-- [[ ShadowsocksR Libev ]]
|
||||||
local m, s1 = ...
|
local m, s1 = ...
|
||||||
local type_name = "SSR"
|
local type_name = "SSR"
|
||||||
|
|
||||||
s1.fields["type"]:value(type_name, "ShadowsocksR Libev")
|
s1.fields["type"]:value(type_name, "ShadowsocksR Libev")
|
||||||
|
|
||||||
if s1.val["type"] ~= type_name then
|
if s1.val["type"] ~= type_name then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local s = NamedSection(m, arg[1], "server")
|
local s = NamedSection(m, arg[1], "server")
|
||||||
s.type_name = type_name
|
s.type_name = type_name
|
||||||
s.option_prefix = "ssr_"
|
s.option_prefix = "ssr_"
|
||||||
|
|
||||||
local ssr_encrypt_method_list = {
|
local ssr_encrypt_method_list = {
|
||||||
"none", "table", "rc2-cfb", "rc4", "rc4-md5", "rc4-md5-6", "aes-128-cfb",
|
"none", "table", "rc2-cfb", "rc4", "rc4-md5", "rc4-md5-6", "aes-128-cfb",
|
||||||
"aes-192-cfb", "aes-256-cfb", "aes-128-ctr", "aes-192-ctr", "aes-256-ctr",
|
"aes-192-cfb", "aes-256-cfb", "aes-128-ctr", "aes-192-ctr", "aes-256-ctr",
|
||||||
"bf-cfb", "camellia-128-cfb", "camellia-192-cfb", "camellia-256-cfb",
|
"bf-cfb", "camellia-128-cfb", "camellia-192-cfb", "camellia-256-cfb",
|
||||||
"cast5-cfb", "des-cfb", "idea-cfb", "seed-cfb", "salsa20", "chacha20",
|
"cast5-cfb", "des-cfb", "idea-cfb", "seed-cfb", "salsa20", "chacha20",
|
||||||
"chacha20-ietf"
|
"chacha20-ietf"
|
||||||
}
|
}
|
||||||
|
|
||||||
local ssr_protocol_list = {
|
local ssr_protocol_list = {
|
||||||
"origin", "verify_simple", "verify_deflate", "verify_sha1", "auth_simple",
|
"origin", "verify_simple", "verify_deflate", "verify_sha1", "auth_simple",
|
||||||
"auth_sha1", "auth_sha1_v2", "auth_sha1_v4", "auth_aes128_md5",
|
"auth_sha1", "auth_sha1_v2", "auth_sha1_v4", "auth_aes128_md5",
|
||||||
"auth_aes128_sha1", "auth_chain_a", "auth_chain_b", "auth_chain_c",
|
"auth_aes128_sha1", "auth_chain_a", "auth_chain_b", "auth_chain_c",
|
||||||
"auth_chain_d", "auth_chain_e", "auth_chain_f"
|
"auth_chain_d", "auth_chain_e", "auth_chain_f"
|
||||||
}
|
}
|
||||||
local ssr_obfs_list = {
|
local ssr_obfs_list = {
|
||||||
"plain", "http_simple", "http_post", "random_head", "tls_simple",
|
"plain", "http_simple", "http_post", "random_head", "tls_simple",
|
||||||
"tls1.0_session_auth", "tls1.2_ticket_auth"
|
"tls1.0_session_auth", "tls1.2_ticket_auth"
|
||||||
}
|
}
|
||||||
|
|
||||||
o = s:option(Value, "address", translate("Address (Support Domain Name)"))
|
o = s:option(Value, "address", translate("Address (Support Domain Name)"))
|
||||||
|
|
||||||
o = s:option(Value, "port", translate("Port"))
|
o = s:option(Value, "port", translate("Port"))
|
||||||
o.datatype = "port"
|
o.datatype = "port"
|
||||||
|
|
||||||
o = s:option(Value, "password", translate("Password"))
|
o = s:option(Value, "password", translate("Password"))
|
||||||
o.password = true
|
o.password = true
|
||||||
|
|
||||||
o = s:option(ListValue, "method", translate("Encrypt Method"))
|
o = s:option(ListValue, "method", translate("Encrypt Method"))
|
||||||
for a, t in ipairs(ssr_encrypt_method_list) do o:value(t) end
|
for a, t in ipairs(ssr_encrypt_method_list) do o:value(t) end
|
||||||
|
|
||||||
o = s:option(ListValue, "protocol", translate("Protocol"))
|
o = s:option(ListValue, "protocol", translate("Protocol"))
|
||||||
for a, t in ipairs(ssr_protocol_list) do o:value(t) end
|
for a, t in ipairs(ssr_protocol_list) do o:value(t) end
|
||||||
|
|
||||||
o = s:option(Value, "protocol_param", translate("Protocol_param"))
|
o = s:option(Value, "protocol_param", translate("Protocol_param"))
|
||||||
|
|
||||||
o = s:option(ListValue, "obfs", translate("Obfs"))
|
o = s:option(ListValue, "obfs", translate("Obfs"))
|
||||||
for a, t in ipairs(ssr_obfs_list) do o:value(t) end
|
for a, t in ipairs(ssr_obfs_list) do o:value(t) end
|
||||||
|
|
||||||
o = s:option(Value, "obfs_param", translate("Obfs_param"))
|
o = s:option(Value, "obfs_param", translate("Obfs_param"))
|
||||||
|
|
||||||
o = s:option(Value, "timeout", translate("Connection Timeout"))
|
o = s:option(Value, "timeout", translate("Connection Timeout"))
|
||||||
o.datatype = "uinteger"
|
o.datatype = "uinteger"
|
||||||
o.default = 300
|
o.default = 300
|
||||||
|
|
||||||
o = s:option(Flag, "tcp_fast_open", "TCP " .. translate("Fast Open"), translate("Need node support required"))
|
o = s:option(Flag, "tcp_fast_open", "TCP " .. translate("Fast Open"), translate("Need node support required"))
|
||||||
o.default = 0
|
o.default = 0
|
||||||
|
|
||||||
api.luci_types(s1, s)
|
api.luci_types(s1, s)
|
||||||
@@ -39,7 +39,7 @@ for filename in api.fs.dir(types_dir) do
|
|||||||
table.insert(type_table, filename)
|
table.insert(type_table, filename)
|
||||||
end
|
end
|
||||||
table.sort(type_table, function(a, b)
|
table.sort(type_table, function(a, b)
|
||||||
return a < b
|
return a < b
|
||||||
end)
|
end)
|
||||||
|
|
||||||
for index, value in ipairs(type_table) do
|
for index, value in ipairs(type_table) do
|
||||||
|
|||||||
@@ -1,90 +1,90 @@
|
|||||||
if not api.is_finded("ssserver") then
|
if not api.is_finded("ssserver") then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- [[ Shadowsocks Rust ]]
|
-- [[ Shadowsocks Rust ]]
|
||||||
local m, s1 = ...
|
local m, s1 = ...
|
||||||
local type_name = "SS-Rust"
|
local type_name = "SS-Rust"
|
||||||
|
|
||||||
s1.fields["type"]:value(type_name, translate("Shadowsocks Rust"))
|
s1.fields["type"]:value(type_name, translate("Shadowsocks Rust"))
|
||||||
|
|
||||||
if not s1.val["type"] then
|
if not s1.val["type"] then
|
||||||
s1.val["type"] = type_name
|
s1.val["type"] = type_name
|
||||||
end
|
end
|
||||||
|
|
||||||
if s1.val["type"] and s1.val["type"] ~= type_name then
|
if s1.val["type"] and s1.val["type"] ~= type_name then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local s = NamedSection(m, arg[1], "server")
|
local s = NamedSection(m, arg[1], "server")
|
||||||
s.type_name = type_name
|
s.type_name = type_name
|
||||||
s.option_prefix = "ssrust_"
|
s.option_prefix = "ssrust_"
|
||||||
|
|
||||||
local ssrust_encrypt_method_list = {
|
local ssrust_encrypt_method_list = {
|
||||||
"plain", "none",
|
"plain", "none",
|
||||||
"aes-128-gcm", "aes-256-gcm", "chacha20-ietf-poly1305",
|
"aes-128-gcm", "aes-256-gcm", "chacha20-ietf-poly1305",
|
||||||
"2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha8-poly1305", "2022-blake3-chacha20-poly1305"
|
"2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha8-poly1305", "2022-blake3-chacha20-poly1305"
|
||||||
}
|
}
|
||||||
|
|
||||||
o = s:option(Flag, "custom", translate("Use Custom Config"))
|
o = s:option(Flag, "custom", translate("Use Custom Config"))
|
||||||
|
|
||||||
o = s:option(TextValue, "custom_config", translate("Custom Config") .. " (JSON)")
|
o = s:option(TextValue, "custom_config", translate("Custom Config") .. " (JSON)")
|
||||||
o.rows = 10
|
o.rows = 10
|
||||||
o.wrap = "off"
|
o.wrap = "off"
|
||||||
o:depends({ custom = true })
|
o:depends({ custom = true })
|
||||||
o.datatype = "json"
|
o.datatype = "json"
|
||||||
local o_validate = o.validate
|
local o_validate = o.validate
|
||||||
o.validate = function(self, value)
|
o.validate = function(self, value)
|
||||||
local v = o_validate(self, value)
|
local v = o_validate(self, value)
|
||||||
if v then return v end
|
if v then return v end
|
||||||
return nil, translate("Custom Config") .. " " .. translate("Must be JSON text!")
|
return nil, translate("Custom Config") .. " " .. translate("Must be JSON text!")
|
||||||
end
|
end
|
||||||
o.custom_cfgvalue = function(self, section, value)
|
o.custom_cfgvalue = function(self, section, value)
|
||||||
local config_str = m:get(section, "config_str")
|
local config_str = m:get(section, "config_str")
|
||||||
if config_str then
|
if config_str then
|
||||||
return api.base64Decode(config_str)
|
return api.base64Decode(config_str)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
o.custom_write = function(self, section, value)
|
o.custom_write = function(self, section, value)
|
||||||
m:set(section, "config_str", api.base64Encode(value) or "")
|
m:set(section, "config_str", api.base64Encode(value) or "")
|
||||||
end
|
end
|
||||||
|
|
||||||
o = s:option(Value, "port", translate("Listen Port"))
|
o = s:option(Value, "port", translate("Listen Port"))
|
||||||
o.datatype = "port"
|
o.datatype = "port"
|
||||||
o:depends({ custom = false })
|
o:depends({ custom = false })
|
||||||
|
|
||||||
o = s:option(ListValue, "user", translate("User"))
|
o = s:option(ListValue, "user", translate("User"))
|
||||||
for i, v in ipairs(user_list) do
|
for i, v in ipairs(user_list) do
|
||||||
o:value(v[".name"], v.username)
|
o:value(v[".name"], v.username)
|
||||||
end
|
end
|
||||||
o:depends({ custom = false })
|
o:depends({ custom = false })
|
||||||
|
|
||||||
o = s:option(ListValue, "method", translate("Encrypt Method"))
|
o = s:option(ListValue, "method", translate("Encrypt Method"))
|
||||||
for a, t in ipairs(ssrust_encrypt_method_list) do o:value(t) end
|
for a, t in ipairs(ssrust_encrypt_method_list) do o:value(t) end
|
||||||
o:depends({ custom = false })
|
o:depends({ custom = false })
|
||||||
|
|
||||||
o = s:option(Value, "timeout", translate("Connection Timeout"))
|
o = s:option(Value, "timeout", translate("Connection Timeout"))
|
||||||
o.datatype = "uinteger"
|
o.datatype = "uinteger"
|
||||||
o.default = 300
|
o.default = 300
|
||||||
o:depends({ custom = false })
|
o:depends({ custom = false })
|
||||||
|
|
||||||
o = s:option(Flag, "tcp_fast_open", "TCP " .. translate("Fast Open"))
|
o = s:option(Flag, "tcp_fast_open", "TCP " .. translate("Fast Open"))
|
||||||
o.default = "0"
|
o.default = "0"
|
||||||
o:depends({ custom = false })
|
o:depends({ custom = false })
|
||||||
|
|
||||||
o = s:option(Flag, "firewall_allow", translate("Firewall Allow"))
|
o = s:option(Flag, "firewall_allow", translate("Firewall Allow"))
|
||||||
o.default = "0"
|
o.default = "0"
|
||||||
o:depends({ custom = false })
|
o:depends({ custom = false })
|
||||||
|
|
||||||
o = s:option(Value, "firewall_allow_src", translate("Source zone"))
|
o = s:option(Value, "firewall_allow_src", translate("Source zone"))
|
||||||
o.nocreate = true
|
o.nocreate = true
|
||||||
o.allowany = true
|
o.allowany = true
|
||||||
o.default = "wan"
|
o.default = "wan"
|
||||||
o.template = "cbi/firewall_zonelist"
|
o.template = "cbi/firewall_zonelist"
|
||||||
o:depends({ custom = false, firewall_allow = true })
|
o:depends({ custom = false, firewall_allow = true })
|
||||||
|
|
||||||
o = s:option(Flag, "log", translate("Log"))
|
o = s:option(Flag, "log", translate("Log"))
|
||||||
o.default = "1"
|
o.default = "1"
|
||||||
o.rmempty = false
|
o.rmempty = false
|
||||||
|
|
||||||
api.luci_types(s1, s)
|
api.luci_types(s1, s)
|
||||||
@@ -1,121 +1,121 @@
|
|||||||
if not api.is_finded("ssr-server") then
|
if not api.is_finded("ssr-server") then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- [[ ShadowsocksR ]]
|
-- [[ ShadowsocksR ]]
|
||||||
local m, s1 = ...
|
local m, s1 = ...
|
||||||
local type_name = "SSR"
|
local type_name = "SSR"
|
||||||
|
|
||||||
s1.fields["type"]:value(type_name, translate("ShadowsocksR"))
|
s1.fields["type"]:value(type_name, translate("ShadowsocksR"))
|
||||||
|
|
||||||
if not s1.val["type"] then
|
if not s1.val["type"] then
|
||||||
s1.val["type"] = type_name
|
s1.val["type"] = type_name
|
||||||
end
|
end
|
||||||
|
|
||||||
if s1.val["type"] and s1.val["type"] ~= type_name then
|
if s1.val["type"] and s1.val["type"] ~= type_name then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local s = NamedSection(m, arg[1], "server")
|
local s = NamedSection(m, arg[1], "server")
|
||||||
s.type_name = type_name
|
s.type_name = type_name
|
||||||
s.option_prefix = "ssr_"
|
s.option_prefix = "ssr_"
|
||||||
|
|
||||||
local ssr_encrypt_method_list = {
|
local ssr_encrypt_method_list = {
|
||||||
"none", "table", "rc2-cfb", "rc4", "rc4-md5", "rc4-md5-6", "aes-128-cfb",
|
"none", "table", "rc2-cfb", "rc4", "rc4-md5", "rc4-md5-6", "aes-128-cfb",
|
||||||
"aes-192-cfb", "aes-256-cfb", "aes-128-ctr", "aes-192-ctr", "aes-256-ctr",
|
"aes-192-cfb", "aes-256-cfb", "aes-128-ctr", "aes-192-ctr", "aes-256-ctr",
|
||||||
"bf-cfb", "camellia-128-cfb", "camellia-192-cfb", "camellia-256-cfb",
|
"bf-cfb", "camellia-128-cfb", "camellia-192-cfb", "camellia-256-cfb",
|
||||||
"cast5-cfb", "des-cfb", "idea-cfb", "seed-cfb", "salsa20", "chacha20",
|
"cast5-cfb", "des-cfb", "idea-cfb", "seed-cfb", "salsa20", "chacha20",
|
||||||
"chacha20-ietf"
|
"chacha20-ietf"
|
||||||
}
|
}
|
||||||
|
|
||||||
local ssr_protocol_list = {
|
local ssr_protocol_list = {
|
||||||
"origin", "verify_simple", "verify_deflate", "verify_sha1", "auth_simple",
|
"origin", "verify_simple", "verify_deflate", "verify_sha1", "auth_simple",
|
||||||
"auth_sha1", "auth_sha1_v2", "auth_sha1_v4", "auth_aes128_md5",
|
"auth_sha1", "auth_sha1_v2", "auth_sha1_v4", "auth_aes128_md5",
|
||||||
"auth_aes128_sha1", "auth_chain_a", "auth_chain_b", "auth_chain_c",
|
"auth_aes128_sha1", "auth_chain_a", "auth_chain_b", "auth_chain_c",
|
||||||
"auth_chain_d", "auth_chain_e", "auth_chain_f"
|
"auth_chain_d", "auth_chain_e", "auth_chain_f"
|
||||||
}
|
}
|
||||||
local ssr_obfs_list = {
|
local ssr_obfs_list = {
|
||||||
"plain", "http_simple", "http_post", "random_head", "tls_simple",
|
"plain", "http_simple", "http_post", "random_head", "tls_simple",
|
||||||
"tls1.0_session_auth", "tls1.2_ticket_auth"
|
"tls1.0_session_auth", "tls1.2_ticket_auth"
|
||||||
}
|
}
|
||||||
|
|
||||||
o = s:option(Flag, "custom", translate("Use Custom Config"))
|
o = s:option(Flag, "custom", translate("Use Custom Config"))
|
||||||
|
|
||||||
o = s:option(TextValue, "custom_config", translate("Custom Config") .. " (JSON)")
|
o = s:option(TextValue, "custom_config", translate("Custom Config") .. " (JSON)")
|
||||||
o.rows = 10
|
o.rows = 10
|
||||||
o.wrap = "off"
|
o.wrap = "off"
|
||||||
o:depends({ custom = true })
|
o:depends({ custom = true })
|
||||||
o.datatype = "json"
|
o.datatype = "json"
|
||||||
local o_validate = o.validate
|
local o_validate = o.validate
|
||||||
o.validate = function(self, value)
|
o.validate = function(self, value)
|
||||||
local v = o_validate(self, value)
|
local v = o_validate(self, value)
|
||||||
if v then return v end
|
if v then return v end
|
||||||
return nil, translate("Custom Config") .. " " .. translate("Must be JSON text!")
|
return nil, translate("Custom Config") .. " " .. translate("Must be JSON text!")
|
||||||
end
|
end
|
||||||
o.custom_cfgvalue = function(self, section, value)
|
o.custom_cfgvalue = function(self, section, value)
|
||||||
local config_str = m:get(section, "config_str")
|
local config_str = m:get(section, "config_str")
|
||||||
if config_str then
|
if config_str then
|
||||||
return api.base64Decode(config_str)
|
return api.base64Decode(config_str)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
o.custom_write = function(self, section, value)
|
o.custom_write = function(self, section, value)
|
||||||
m:set(section, "config_str", api.base64Encode(value) or "")
|
m:set(section, "config_str", api.base64Encode(value) or "")
|
||||||
end
|
end
|
||||||
|
|
||||||
o = s:option(Value, "port", translate("Listen Port"))
|
o = s:option(Value, "port", translate("Listen Port"))
|
||||||
o.datatype = "port"
|
o.datatype = "port"
|
||||||
o:depends({ custom = false })
|
o:depends({ custom = false })
|
||||||
|
|
||||||
o = s:option(ListValue, "user", translate("User"))
|
o = s:option(ListValue, "user", translate("User"))
|
||||||
for i, v in ipairs(user_list) do
|
for i, v in ipairs(user_list) do
|
||||||
o:value(v[".name"], v.username)
|
o:value(v[".name"], v.username)
|
||||||
end
|
end
|
||||||
o:depends({ custom = false })
|
o:depends({ custom = false })
|
||||||
|
|
||||||
o = s:option(ListValue, "method", translate("Encrypt Method"))
|
o = s:option(ListValue, "method", translate("Encrypt Method"))
|
||||||
for a, t in ipairs(ssr_encrypt_method_list) do o:value(t) end
|
for a, t in ipairs(ssr_encrypt_method_list) do o:value(t) end
|
||||||
o:depends({ custom = false })
|
o:depends({ custom = false })
|
||||||
|
|
||||||
o = s:option(ListValue, "protocol", translate("Protocol"))
|
o = s:option(ListValue, "protocol", translate("Protocol"))
|
||||||
for a, t in ipairs(ssr_protocol_list) do o:value(t) end
|
for a, t in ipairs(ssr_protocol_list) do o:value(t) end
|
||||||
o:depends({ custom = false })
|
o:depends({ custom = false })
|
||||||
|
|
||||||
o = s:option(Value, "protocol_param", translate("Protocol_param"))
|
o = s:option(Value, "protocol_param", translate("Protocol_param"))
|
||||||
o:depends({ custom = false })
|
o:depends({ custom = false })
|
||||||
|
|
||||||
o = s:option(ListValue, "obfs", translate("Obfs"))
|
o = s:option(ListValue, "obfs", translate("Obfs"))
|
||||||
for a, t in ipairs(ssr_obfs_list) do o:value(t) end
|
for a, t in ipairs(ssr_obfs_list) do o:value(t) end
|
||||||
o:depends({ custom = false })
|
o:depends({ custom = false })
|
||||||
|
|
||||||
o = s:option(Value, "obfs_param", translate("Obfs_param"))
|
o = s:option(Value, "obfs_param", translate("Obfs_param"))
|
||||||
o:depends({ custom = false })
|
o:depends({ custom = false })
|
||||||
|
|
||||||
o = s:option(Value, "timeout", translate("Connection Timeout"))
|
o = s:option(Value, "timeout", translate("Connection Timeout"))
|
||||||
o.datatype = "uinteger"
|
o.datatype = "uinteger"
|
||||||
o.default = 300
|
o.default = 300
|
||||||
o:depends({ custom = false })
|
o:depends({ custom = false })
|
||||||
|
|
||||||
o = s:option(Flag, "tcp_fast_open", "TCP " .. translate("Fast Open"))
|
o = s:option(Flag, "tcp_fast_open", "TCP " .. translate("Fast Open"))
|
||||||
o.default = "0"
|
o.default = "0"
|
||||||
o:depends({ custom = false })
|
o:depends({ custom = false })
|
||||||
|
|
||||||
o = s:option(Flag, "udp_forward", translate("UDP Forward"))
|
o = s:option(Flag, "udp_forward", translate("UDP Forward"))
|
||||||
o.default = "1"
|
o.default = "1"
|
||||||
o.rmempty = false
|
o.rmempty = false
|
||||||
|
|
||||||
o = s:option(Flag, "firewall_allow", translate("Firewall Allow"))
|
o = s:option(Flag, "firewall_allow", translate("Firewall Allow"))
|
||||||
o.default = "0"
|
o.default = "0"
|
||||||
o:depends({ custom = false })
|
o:depends({ custom = false })
|
||||||
|
|
||||||
o = s:option(Value, "firewall_allow_src", translate("Source zone"))
|
o = s:option(Value, "firewall_allow_src", translate("Source zone"))
|
||||||
o.nocreate = true
|
o.nocreate = true
|
||||||
o.allowany = true
|
o.allowany = true
|
||||||
o.default = "wan"
|
o.default = "wan"
|
||||||
o.template = "cbi/firewall_zonelist"
|
o.template = "cbi/firewall_zonelist"
|
||||||
o:depends({ custom = false, firewall_allow = true })
|
o:depends({ custom = false, firewall_allow = true })
|
||||||
|
|
||||||
o = s:option(Flag, "log", translate("Log"))
|
o = s:option(Flag, "log", translate("Log"))
|
||||||
o.default = "1"
|
o.default = "1"
|
||||||
o.rmempty = false
|
o.rmempty = false
|
||||||
|
|
||||||
api.luci_types(s1, s)
|
api.luci_types(s1, s)
|
||||||
@@ -464,14 +464,14 @@ datatypes.json = is_json
|
|||||||
|
|
||||||
function is_timehhmm(str)
|
function is_timehhmm(str)
|
||||||
local hour, minute = string.match(str, "^(%d?%d):(%d%d)$")
|
local hour, minute = string.match(str, "^(%d?%d):(%d%d)$")
|
||||||
if hour and minute then
|
if hour and minute then
|
||||||
hour = tonumber(hour)
|
hour = tonumber(hour)
|
||||||
minute = tonumber(minute)
|
minute = tonumber(minute)
|
||||||
if hour >= 0 and hour <= 23 and minute >= 0 and minute <= 59 then
|
if hour >= 0 and hour <= 23 and minute >= 0 and minute <= 59 then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
datatypes.timehhmm = is_timehhmm
|
datatypes.timehhmm = is_timehhmm
|
||||||
|
|
||||||
|
|||||||
@@ -922,12 +922,12 @@ function gen_config(var)
|
|||||||
if xray_settings.fragment == "1" then
|
if xray_settings.fragment == "1" then
|
||||||
local lengths, delays = {}, {}
|
local lengths, delays = {}, {}
|
||||||
api.trim(xray_settings.fragment_lengths):gsub("[^,]+", function(w)
|
api.trim(xray_settings.fragment_lengths):gsub("[^,]+", function(w)
|
||||||
w = w:gsub("%s+", "")
|
w = w:gsub("%s+", "")
|
||||||
if w ~= "" then lengths[#lengths+1] = w end
|
if w ~= "" then lengths[#lengths+1] = w end
|
||||||
end)
|
end)
|
||||||
api.trim(xray_settings.fragment_delays):gsub("[^,]+", function(w)
|
api.trim(xray_settings.fragment_delays):gsub("[^,]+", function(w)
|
||||||
w = w:gsub("%s+", "")
|
w = w:gsub("%s+", "")
|
||||||
if w ~= "" then delays[#delays+1] = w end
|
if w ~= "" then delays[#delays+1] = w end
|
||||||
end)
|
end)
|
||||||
fragment_table = {
|
fragment_table = {
|
||||||
type = "fragment",
|
type = "fragment",
|
||||||
|
|||||||
@@ -534,7 +534,7 @@
|
|||||||
//自定义框
|
//自定义框
|
||||||
function v_customEnter(cbid, labelSpan, hiddenInput, searchInput, panel, listContainer, customInput) {
|
function v_customEnter(cbid, labelSpan, hiddenInput, searchInput, panel, listContainer, customInput) {
|
||||||
let inputValue = customInput.value.trim();
|
let inputValue = customInput.value.trim();
|
||||||
if (!inputValue) {
|
if (!inputValue) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const existingItems = listContainer.querySelectorAll('li[data-key="' + inputValue + '"]');
|
const existingItems = listContainer.querySelectorAll('li[data-key="' + inputValue + '"]');
|
||||||
|
|||||||
@@ -3,28 +3,28 @@ local map = self.map
|
|||||||
local api = map.api
|
local api = map.api
|
||||||
-%>
|
-%>
|
||||||
<style>
|
<style>
|
||||||
.dns-con {
|
.dns-con {
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
}
|
}
|
||||||
.faq-title {
|
.faq-title {
|
||||||
color: var(--primary);
|
color: var(--primary);
|
||||||
font-weight: bolder;
|
font-weight: bolder;
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
.reset-title {
|
.reset-title {
|
||||||
color: var(--primary);
|
color: var(--primary);
|
||||||
font-weight: bolder;
|
font-weight: bolder;
|
||||||
margin-bottom: 0.3rem;
|
margin-bottom: 0.3rem;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-top: 1.2rem;
|
margin-top: 1.2rem;
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
.dns-item {
|
.dns-item {
|
||||||
margin-bottom: 0.8rem;
|
margin-bottom: 0.8rem;
|
||||||
line-height:1.2rem;
|
line-height:1.2rem;
|
||||||
}
|
}
|
||||||
.dns-list {
|
.dns-list {
|
||||||
text-indent:1rem;
|
text-indent:1rem;
|
||||||
line-height: 1.2rem;
|
line-height: 1.2rem;
|
||||||
}
|
}
|
||||||
@@ -32,13 +32,13 @@ local api = map.api
|
|||||||
<div class="dns-con">
|
<div class="dns-con">
|
||||||
<div id="faq_dns">
|
<div id="faq_dns">
|
||||||
<ul>
|
<ul>
|
||||||
<b class="faq-title"><%:DNS related issues:%></b>
|
<b class="faq-title"><%:DNS related issues:%></b>
|
||||||
<li class="dns-item">1. <span><%:Certain browsers such as Chrome have built-in DNS service, which may affect DNS resolution settings. You can go to 'Settings -> Privacy and security -> Use secure DNS' menu to turn it off.%></span></li>
|
<li class="dns-item">1. <span><%:Certain browsers such as Chrome have built-in DNS service, which may affect DNS resolution settings. You can go to 'Settings -> Privacy and security -> Use secure DNS' menu to turn it off.%></span></li>
|
||||||
<li class="dns-item">2. <span><%:If you are unable to access the internet after reboot, please try clearing the cache of your terminal devices (make sure to close all open browser application windows first, this step is especially important):%></span>
|
<li class="dns-item">2. <span><%:If you are unable to access the internet after reboot, please try clearing the cache of your terminal devices (make sure to close all open browser application windows first, this step is especially important):%></span>
|
||||||
<ul><li class="dns-list"> ◦ <span><%:For Windows systems, open Command Prompt and run the command 'ipconfig /flushdns'.%></span></li>
|
<ul><li class="dns-list"> ◦ <span><%:For Windows systems, open Command Prompt and run the command 'ipconfig /flushdns'.%></span></li>
|
||||||
<li class="dns-list"> ◦ <span><%:For Mac systems, open Terminal and run the command 'sudo killall -HUP mDNSResponder'.%></span></li>
|
<li class="dns-list"> ◦ <span><%:For Mac systems, open Terminal and run the command 'sudo killall -HUP mDNSResponder'.%></span></li>
|
||||||
<li class="dns-list"> ◦ <span><%:For mobile devices, you can clear it by reconnecting to the network, such as toggling Airplane Mode and reconnecting to WiFi.%></span></li>
|
<li class="dns-list"> ◦ <span><%:For mobile devices, you can clear it by reconnecting to the network, such as toggling Airplane Mode and reconnecting to WiFi.%></span></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="dns-item">3. <span><%:Please make sure your device's network settings point both the DNS server and default gateway to this router, to ensure DNS queries are properly routed.%></span></li>
|
<li class="dns-item">3. <span><%:Please make sure your device's network settings point both the DNS server and default gateway to this router, to ensure DNS queries are properly routed.%></span></li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -58,7 +58,7 @@ local api = map.api
|
|||||||
}
|
}
|
||||||
|
|
||||||
var dom = document.getElementById("faq_reset");
|
var dom = document.getElementById("faq_reset");
|
||||||
if (dom) {
|
if (dom) {
|
||||||
var li = "";
|
var li = "";
|
||||||
li += "<a href='#' class='reset-title' onclick='hide()'>" + "<%: Hide in main menu:%>"+ "</a>" + "<br />" + "<%: Browser access: %>" + "<a href='#' onclick='hide()'>" + hide_url + "</a>" + "<br />";
|
li += "<a href='#' class='reset-title' onclick='hide()'>" + "<%: Hide in main menu:%>"+ "</a>" + "<br />" + "<%: Browser access: %>" + "<a href='#' onclick='hide()'>" + hide_url + "</a>" + "<br />";
|
||||||
li += "<a href='#' class='reset-title'>" + "<%: Show in main menu:%>"+ "</a>" + "<br />" +"<%: Browser access: %>" + "<a href='#'>" + show_url + "</a>" + "<br />";
|
li += "<a href='#' class='reset-title'>" + "<%: Show in main menu:%>"+ "</a>" + "<br />" +"<%: Browser access: %>" + "<a href='#'>" + show_url + "</a>" + "<br />";
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ table th, .table .th {
|
|||||||
|
|
||||||
table td, .table .td {
|
table td, .table .td {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
/* white-space: nowrap; */
|
/* white-space: nowrap; */
|
||||||
word-break: keep-all;
|
word-break: keep-all;
|
||||||
}
|
}
|
||||||
|
|
||||||
#set_node_div {
|
#set_node_div {
|
||||||
@@ -41,7 +41,7 @@ table td, .table .td {
|
|||||||
z-index: 99;
|
z-index: 99;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background: white;
|
background: white;
|
||||||
box-shadow: darkgrey 10px 10px 30px 5px;
|
box-shadow: darkgrey 10px 10px 30px 5px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
}
|
}
|
||||||
@@ -53,8 +53,8 @@ table td, .table .td {
|
|||||||
.ping a,
|
.ping a,
|
||||||
.ping_value a,
|
.ping_value a,
|
||||||
.tcping_value a {
|
.tcping_value a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ local api = self.api
|
|||||||
if (!value) {
|
if (!value) {
|
||||||
alert("<%:Please enter query content!%>");
|
alert("<%:Please enter query content!%>");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lookup_btn.disabled = true;
|
lookup_btn.disabled = true;
|
||||||
extract_btn.disabled = true;
|
extract_btn.disabled = true;
|
||||||
btn.value = '<%:Querying%>';
|
btn.value = '<%:Querying%>';
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ table th, .table .th {
|
|||||||
|
|
||||||
table td, .table .td {
|
table td, .table .td {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
/* white-space: nowrap; */
|
/* white-space: nowrap; */
|
||||||
word-break: keep-all;
|
word-break: keep-all;
|
||||||
}
|
}
|
||||||
|
|
||||||
.td.cbi-section-actions {
|
.td.cbi-section-actions {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
if [ -e "/etc/config/ucitrack" ]; then
|
if [ -e "/etc/config/ucitrack" ]; then
|
||||||
uci -q batch <<-EOF
|
uci -q batch <<-EOF
|
||||||
delete ucitrack.@passwall2[-1]
|
delete ucitrack.@passwall2[-1]
|
||||||
add ucitrack passwall2
|
add ucitrack passwall2
|
||||||
set ucitrack.@passwall2[-1].init=passwall2
|
set ucitrack.@passwall2[-1].init=passwall2
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
if [ -e "/etc/config/ucitrack" ]; then
|
if [ -e "/etc/config/ucitrack" ]; then
|
||||||
uci -q batch <<-EOF
|
uci -q batch <<-EOF
|
||||||
delete ucitrack.@passwall2_server[-1]
|
delete ucitrack.@passwall2_server[-1]
|
||||||
add ucitrack passwall2_server
|
add ucitrack passwall2_server
|
||||||
set ucitrack.@passwall2_server[-1].init=passwall2_server
|
set ucitrack.@passwall2_server[-1].init=passwall2_server
|
||||||
|
|||||||
@@ -1,371 +1,371 @@
|
|||||||
local api = require "luci.passwall2.api"
|
local api = require "luci.passwall2.api"
|
||||||
local c_config = api.c_config
|
local c_config = api.c_config
|
||||||
local sys = api.sys
|
local sys = api.sys
|
||||||
local jsonc = api.jsonc
|
local jsonc = api.jsonc
|
||||||
local fs = api.fs
|
local fs = api.fs
|
||||||
local datatypes = api.datatypes
|
local datatypes = api.datatypes
|
||||||
local TMP = {}
|
local TMP = {}
|
||||||
|
|
||||||
local function tinsert(table_name, val)
|
local function tinsert(table_name, val)
|
||||||
if table_name and type(table_name) == "table" then
|
if table_name and type(table_name) == "table" then
|
||||||
if not TMP[table_name] then
|
if not TMP[table_name] then
|
||||||
TMP[table_name] = {}
|
TMP[table_name] = {}
|
||||||
end
|
end
|
||||||
if TMP[table_name][val] then
|
if TMP[table_name][val] then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
table.insert(table_name, val)
|
table.insert(table_name, val)
|
||||||
TMP[table_name][val] = true
|
TMP[table_name][val] = true
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
local function backup_servers()
|
local function backup_servers()
|
||||||
local DNSMASQ_DNS = api.uci_get("dhcp", "@dnsmasq[0]", "server")
|
local DNSMASQ_DNS = api.uci_get("dhcp", "@dnsmasq[0]", "server")
|
||||||
if DNSMASQ_DNS and #DNSMASQ_DNS > 0 then
|
if DNSMASQ_DNS and #DNSMASQ_DNS > 0 then
|
||||||
api.uci_set_c("@global[0]", "dnsmasq_servers", DNSMASQ_DNS)
|
api.uci_set_c("@global[0]", "dnsmasq_servers", DNSMASQ_DNS)
|
||||||
api.uci_save_c(true)
|
api.uci_save_c(true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function restore_servers()
|
local function restore_servers()
|
||||||
local dns_table = {}
|
local dns_table = {}
|
||||||
local DNSMASQ_DNS = api.uci_get("dhcp", "@dnsmasq[0]", "server")
|
local DNSMASQ_DNS = api.uci_get("dhcp", "@dnsmasq[0]", "server")
|
||||||
if DNSMASQ_DNS and #DNSMASQ_DNS > 0 then
|
if DNSMASQ_DNS and #DNSMASQ_DNS > 0 then
|
||||||
for k, v in ipairs(DNSMASQ_DNS) do
|
for k, v in ipairs(DNSMASQ_DNS) do
|
||||||
tinsert(dns_table, v)
|
tinsert(dns_table, v)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local OLD_SERVER = api.uci_get_c("@global[0]", "dnsmasq_servers")
|
local OLD_SERVER = api.uci_get_c("@global[0]", "dnsmasq_servers")
|
||||||
if OLD_SERVER and #OLD_SERVER > 0 then
|
if OLD_SERVER and #OLD_SERVER > 0 then
|
||||||
for k, v in ipairs(OLD_SERVER) do
|
for k, v in ipairs(OLD_SERVER) do
|
||||||
tinsert(dns_table, v)
|
tinsert(dns_table, v)
|
||||||
end
|
end
|
||||||
api.uci_del_c("@global[0]", "dnsmasq_servers")
|
api.uci_del_c("@global[0]", "dnsmasq_servers")
|
||||||
api.uci_save_c(true)
|
api.uci_save_c(true)
|
||||||
end
|
end
|
||||||
if dns_table and #dns_table > 0 then
|
if dns_table and #dns_table > 0 then
|
||||||
api.uci_set("dhcp", "@dnsmasq[0]", "server", dns_table)
|
api.uci_set("dhcp", "@dnsmasq[0]", "server", dns_table)
|
||||||
api.uci_save(nil, "dhcp", true)
|
api.uci_save(nil, "dhcp", true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function stretch()
|
function stretch()
|
||||||
local dnsmasq_server = api.uci_get("dhcp", "@dnsmasq[0]", "server")
|
local dnsmasq_server = api.uci_get("dhcp", "@dnsmasq[0]", "server")
|
||||||
local dnsmasq_noresolv = api.uci_get("dhcp", "@dnsmasq[0]", "noresolv")
|
local dnsmasq_noresolv = api.uci_get("dhcp", "@dnsmasq[0]", "noresolv")
|
||||||
local _flag
|
local _flag
|
||||||
if dnsmasq_server and #dnsmasq_server > 0 then
|
if dnsmasq_server and #dnsmasq_server > 0 then
|
||||||
for k, v in ipairs(dnsmasq_server) do
|
for k, v in ipairs(dnsmasq_server) do
|
||||||
if not v:find("/") then
|
if not v:find("/") then
|
||||||
_flag = true
|
_flag = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if not _flag and dnsmasq_noresolv == "1" then
|
if not _flag and dnsmasq_noresolv == "1" then
|
||||||
api.uci_del("dhcp", "@dnsmasq[0]", "noresolv")
|
api.uci_del("dhcp", "@dnsmasq[0]", "noresolv")
|
||||||
local RESOLVFILE = "/tmp/resolv.conf.d/resolv.conf.auto"
|
local RESOLVFILE = "/tmp/resolv.conf.d/resolv.conf.auto"
|
||||||
local file = io.open(RESOLVFILE, "r")
|
local file = io.open(RESOLVFILE, "r")
|
||||||
if not file then
|
if not file then
|
||||||
RESOLVFILE = "/tmp/resolv.conf.auto"
|
RESOLVFILE = "/tmp/resolv.conf.auto"
|
||||||
else
|
else
|
||||||
local size = file:seek("end")
|
local size = file:seek("end")
|
||||||
file:close()
|
file:close()
|
||||||
if size == 0 then
|
if size == 0 then
|
||||||
RESOLVFILE = "/tmp/resolv.conf.auto"
|
RESOLVFILE = "/tmp/resolv.conf.auto"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
api.uci_set("dhcp", "@dnsmasq[0]", "resolvfile", RESOLVFILE)
|
api.uci_set("dhcp", "@dnsmasq[0]", "resolvfile", RESOLVFILE)
|
||||||
api.uci_save(nil, "dhcp", true)
|
api.uci_save(nil, "dhcp", true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function restart(var)
|
function restart(var)
|
||||||
local LOG = var["LOG"]
|
local LOG = var["LOG"]
|
||||||
sys.call("/etc/init.d/dnsmasq restart >/dev/null 2>&1")
|
sys.call("/etc/init.d/dnsmasq restart >/dev/null 2>&1")
|
||||||
if LOG == "1" then
|
if LOG == "1" then
|
||||||
api.log(0, api.i18n.translate("Restart dnsmasq service."))
|
api.log(0, api.i18n.translate("Restart dnsmasq service."))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function logic_restart(var)
|
function logic_restart(var)
|
||||||
local LOG = var["LOG"]
|
local LOG = var["LOG"]
|
||||||
local DEFAULT_DNS = api.get_cache_var("DEFAULT_DNS")
|
local DEFAULT_DNS = api.get_cache_var("DEFAULT_DNS")
|
||||||
if DEFAULT_DNS then
|
if DEFAULT_DNS then
|
||||||
backup_servers()
|
backup_servers()
|
||||||
--sys.call("sed -i '/list server/d' /etc/config/dhcp >/dev/null 2>&1")
|
--sys.call("sed -i '/list server/d' /etc/config/dhcp >/dev/null 2>&1")
|
||||||
local dns_table = {}
|
local dns_table = {}
|
||||||
local dnsmasq_server = api.uci_get("dhcp", "@dnsmasq[0]", "server")
|
local dnsmasq_server = api.uci_get("dhcp", "@dnsmasq[0]", "server")
|
||||||
if dnsmasq_server and #dnsmasq_server > 0 then
|
if dnsmasq_server and #dnsmasq_server > 0 then
|
||||||
for k, v in ipairs(dnsmasq_server) do
|
for k, v in ipairs(dnsmasq_server) do
|
||||||
if v:find("/") then
|
if v:find("/") then
|
||||||
tinsert(dns_table, v)
|
tinsert(dns_table, v)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
api.uci_set("dhcp", "@dnsmasq[0]", "server", dns_table)
|
api.uci_set("dhcp", "@dnsmasq[0]", "server", dns_table)
|
||||||
api.uci_save(nil, "dhcp", true)
|
api.uci_save(nil, "dhcp", true)
|
||||||
end
|
end
|
||||||
sys.call("/etc/init.d/dnsmasq restart >/dev/null 2>&1")
|
sys.call("/etc/init.d/dnsmasq restart >/dev/null 2>&1")
|
||||||
restore_servers()
|
restore_servers()
|
||||||
else
|
else
|
||||||
sys.call("/etc/init.d/dnsmasq restart >/dev/null 2>&1")
|
sys.call("/etc/init.d/dnsmasq restart >/dev/null 2>&1")
|
||||||
end
|
end
|
||||||
if LOG == "1" then
|
if LOG == "1" then
|
||||||
api.log(0, api.i18n.translate("Restart dnsmasq service."))
|
api.log(0, api.i18n.translate("Restart dnsmasq service."))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function copy_instance(var)
|
function copy_instance(var)
|
||||||
local LISTEN_PORT = var["LISTEN_PORT"]
|
local LISTEN_PORT = var["LISTEN_PORT"]
|
||||||
local TMP_DNSMASQ_PATH = var["TMP_DNSMASQ_PATH"]
|
local TMP_DNSMASQ_PATH = var["TMP_DNSMASQ_PATH"]
|
||||||
local conf_lines = {}
|
local conf_lines = {}
|
||||||
local DEFAULT_DNSMASQ_CFGID = sys.exec("echo -n $(uci -q show dhcp.@dnsmasq[0] | awk 'NR==1 {split($0, conf, /[.=]/); print conf[2]}')")
|
local DEFAULT_DNSMASQ_CFGID = sys.exec("echo -n $(uci -q show dhcp.@dnsmasq[0] | awk 'NR==1 {split($0, conf, /[.=]/); print conf[2]}')")
|
||||||
for line in io.lines("/tmp/etc/dnsmasq.conf." .. DEFAULT_DNSMASQ_CFGID) do
|
for line in io.lines("/tmp/etc/dnsmasq.conf." .. DEFAULT_DNSMASQ_CFGID) do
|
||||||
local filter
|
local filter
|
||||||
if line:find("passwall2") then filter = true end
|
if line:find("passwall2") then filter = true end
|
||||||
if line:find("ubus") then filter = true end
|
if line:find("ubus") then filter = true end
|
||||||
if line:find("dhcp") then filter = true end
|
if line:find("dhcp") then filter = true end
|
||||||
if line:find("server=") == 1 then filter = true end
|
if line:find("server=") == 1 then filter = true end
|
||||||
if line:find("port=") == 1 then filter = true end
|
if line:find("port=") == 1 then filter = true end
|
||||||
if line:find("conf%-dir=") == 1 then
|
if line:find("conf%-dir=") == 1 then
|
||||||
filter = true
|
filter = true
|
||||||
if TMP_DNSMASQ_PATH then
|
if TMP_DNSMASQ_PATH then
|
||||||
local tmp_path = line:sub(1 + #"conf-dir=")
|
local tmp_path = line:sub(1 + #"conf-dir=")
|
||||||
sys.call(string.format("cp -r %s/* %s/ 2>/dev/null", tmp_path, TMP_DNSMASQ_PATH))
|
sys.call(string.format("cp -r %s/* %s/ 2>/dev/null", tmp_path, TMP_DNSMASQ_PATH))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if line:find("address=") == 1 or (line:find("server=") == 1 and line:find("/")) then filter = nil end
|
if line:find("address=") == 1 or (line:find("server=") == 1 and line:find("/")) then filter = nil end
|
||||||
if not filter then
|
if not filter then
|
||||||
tinsert(conf_lines, line)
|
tinsert(conf_lines, line)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
tinsert(conf_lines, "port=" .. LISTEN_PORT)
|
tinsert(conf_lines, "port=" .. LISTEN_PORT)
|
||||||
if TMP_DNSMASQ_PATH then
|
if TMP_DNSMASQ_PATH then
|
||||||
sys.call("rm -rf " .. TMP_DNSMASQ_PATH .. "/*passwall2*")
|
sys.call("rm -rf " .. TMP_DNSMASQ_PATH .. "/*passwall2*")
|
||||||
end
|
end
|
||||||
if var["return"] == "1" then
|
if var["return"] == "1" then
|
||||||
return conf_lines
|
return conf_lines
|
||||||
end
|
end
|
||||||
if #conf_lines > 0 then
|
if #conf_lines > 0 then
|
||||||
local DNSMASQ_CONF = var["DNSMASQ_CONF"]
|
local DNSMASQ_CONF = var["DNSMASQ_CONF"]
|
||||||
local conf_out = io.open(DNSMASQ_CONF, "a")
|
local conf_out = io.open(DNSMASQ_CONF, "a")
|
||||||
conf_out:write(table.concat(conf_lines, "\n"))
|
conf_out:write(table.concat(conf_lines, "\n"))
|
||||||
conf_out:write("\n")
|
conf_out:write("\n")
|
||||||
conf_out:close()
|
conf_out:close()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function add_rule(var)
|
function add_rule(var)
|
||||||
local FLAG = var["FLAG"]
|
local FLAG = var["FLAG"]
|
||||||
local TMP_DNSMASQ_PATH = var["TMP_DNSMASQ_PATH"]
|
local TMP_DNSMASQ_PATH = var["TMP_DNSMASQ_PATH"]
|
||||||
local DNSMASQ_CONF_FILE = var["DNSMASQ_CONF_FILE"]
|
local DNSMASQ_CONF_FILE = var["DNSMASQ_CONF_FILE"]
|
||||||
local LISTEN_PORT = var["LISTEN_PORT"]
|
local LISTEN_PORT = var["LISTEN_PORT"]
|
||||||
local DEFAULT_DNS = var["DEFAULT_DNS"]
|
local DEFAULT_DNS = var["DEFAULT_DNS"]
|
||||||
local LOCAL_DNS = var["LOCAL_DNS"]
|
local LOCAL_DNS = var["LOCAL_DNS"]
|
||||||
local TUN_DNS = var["TUN_DNS"]
|
local TUN_DNS = var["TUN_DNS"]
|
||||||
local NFTFLAG = var["NFTFLAG"]
|
local NFTFLAG = var["NFTFLAG"]
|
||||||
local CACHE_PATH = api.CACHE_PATH
|
local CACHE_PATH = api.CACHE_PATH
|
||||||
local CACHE_FLAG = "dnsmasq_" .. FLAG
|
local CACHE_FLAG = "dnsmasq_" .. FLAG
|
||||||
local CACHE_DNS_PATH = CACHE_PATH .. "/" .. CACHE_FLAG
|
local CACHE_DNS_PATH = CACHE_PATH .. "/" .. CACHE_FLAG
|
||||||
local CACHE_TEXT_FILE = CACHE_DNS_PATH .. ".txt"
|
local CACHE_TEXT_FILE = CACHE_DNS_PATH .. ".txt"
|
||||||
|
|
||||||
local list1 = {}
|
local list1 = {}
|
||||||
|
|
||||||
local function check_dns(domain, dns)
|
local function check_dns(domain, dns)
|
||||||
if domain == "" or domain:find("#") then
|
if domain == "" or domain:find("#") then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
if not dns then
|
if not dns then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
for k,v in ipairs(list1[domain].dns) do
|
for k,v in ipairs(list1[domain].dns) do
|
||||||
if dns == v then
|
if dns == v then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
local function check_ipset(domain, ipset)
|
local function check_ipset(domain, ipset)
|
||||||
if domain == "" or domain:find("#") then
|
if domain == "" or domain:find("#") then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
if not ipset then
|
if not ipset then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
for k,v in ipairs(list1[domain].ipsets) do
|
for k,v in ipairs(list1[domain].ipsets) do
|
||||||
if ipset == v then
|
if ipset == v then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
local function set_domain_dns(domain, dns)
|
local function set_domain_dns(domain, dns)
|
||||||
if domain == "" or domain:find("#") then
|
if domain == "" or domain:find("#") then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if not dns then
|
if not dns then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if not list1[domain] then
|
if not list1[domain] then
|
||||||
list1[domain] = {
|
list1[domain] = {
|
||||||
dns = {},
|
dns = {},
|
||||||
ipsets = {}
|
ipsets = {}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
for line in string.gmatch(dns, '[^' .. "," .. ']+') do
|
for line in string.gmatch(dns, '[^' .. "," .. ']+') do
|
||||||
if not check_dns(domain, line) then
|
if not check_dns(domain, line) then
|
||||||
table.insert(list1[domain].dns, line)
|
table.insert(list1[domain].dns, line)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function set_domain_ipset(domain, ipset)
|
local function set_domain_ipset(domain, ipset)
|
||||||
if domain == "" or domain:find("#") then
|
if domain == "" or domain:find("#") then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if not ipset then
|
if not ipset then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if not list1[domain] then
|
if not list1[domain] then
|
||||||
list1[domain] = {
|
list1[domain] = {
|
||||||
dns = {},
|
dns = {},
|
||||||
ipsets = {}
|
ipsets = {}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
for line in string.gmatch(ipset, '[^' .. "," .. ']+') do
|
for line in string.gmatch(ipset, '[^' .. "," .. ']+') do
|
||||||
if not check_ipset(domain, line) then
|
if not check_ipset(domain, line) then
|
||||||
table.insert(list1[domain].ipsets, line)
|
table.insert(list1[domain].ipsets, line)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local cache_text = ""
|
local cache_text = ""
|
||||||
local nodes_address_md5 = sys.exec("echo -n $(uci show %s | grep '\\.address') | md5sum" % c_config)
|
local nodes_address_md5 = sys.exec("echo -n $(uci show %s | grep '\\.address') | md5sum" % c_config)
|
||||||
local new_text = TMP_DNSMASQ_PATH .. DNSMASQ_CONF_FILE .. DEFAULT_DNS .. LOCAL_DNS .. TUN_DNS .. nodes_address_md5 .. NFTFLAG
|
local new_text = TMP_DNSMASQ_PATH .. DNSMASQ_CONF_FILE .. DEFAULT_DNS .. LOCAL_DNS .. TUN_DNS .. nodes_address_md5 .. NFTFLAG
|
||||||
if fs.access(CACHE_TEXT_FILE) then
|
if fs.access(CACHE_TEXT_FILE) then
|
||||||
for line in io.lines(CACHE_TEXT_FILE) do
|
for line in io.lines(CACHE_TEXT_FILE) do
|
||||||
cache_text = line
|
cache_text = line
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if cache_text ~= new_text then
|
if cache_text ~= new_text then
|
||||||
api.remove(CACHE_DNS_PATH .. "*")
|
api.remove(CACHE_DNS_PATH .. "*")
|
||||||
end
|
end
|
||||||
|
|
||||||
local dnsmasq_default_dns = TUN_DNS
|
local dnsmasq_default_dns = TUN_DNS
|
||||||
|
|
||||||
local setflag_4= (NFTFLAG == "1") and "4#inet#passwall2#" or ""
|
local setflag_4= (NFTFLAG == "1") and "4#inet#passwall2#" or ""
|
||||||
local setflag_6= (NFTFLAG == "1") and "6#inet#passwall2#" or ""
|
local setflag_6= (NFTFLAG == "1") and "6#inet#passwall2#" or ""
|
||||||
|
|
||||||
if not fs.access(CACHE_DNS_PATH) then
|
if not fs.access(CACHE_DNS_PATH) then
|
||||||
fs.mkdir(CACHE_DNS_PATH)
|
fs.mkdir(CACHE_DNS_PATH)
|
||||||
|
|
||||||
local fwd_dns
|
local fwd_dns
|
||||||
|
|
||||||
-- Always use domestic DNS to resolve node domain names
|
-- Always use domestic DNS to resolve node domain names
|
||||||
if true then
|
if true then
|
||||||
fwd_dns = LOCAL_DNS
|
fwd_dns = LOCAL_DNS
|
||||||
api.uci_foreach_c("nodes", function(t)
|
api.uci_foreach_c("nodes", function(t)
|
||||||
local function process_address(address)
|
local function process_address(address)
|
||||||
address = (address or ""):lower()
|
address = (address or ""):lower()
|
||||||
if address == "engage.cloudflareclient.com" then return end
|
if address == "engage.cloudflareclient.com" then return end
|
||||||
if datatypes.hostname(address) then
|
if datatypes.hostname(address) then
|
||||||
set_domain_dns(address, fwd_dns)
|
set_domain_dns(address, fwd_dns)
|
||||||
set_domain_ipset(address, setflag_4 .. "psw2_vps," .. setflag_6 .. "psw2_vps6")
|
set_domain_ipset(address, setflag_4 .. "psw2_vps," .. setflag_6 .. "psw2_vps6")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
process_address(t.address)
|
process_address(t.address)
|
||||||
process_address(t.download_address)
|
process_address(t.download_address)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
if list1 and next(list1) then
|
if list1 and next(list1) then
|
||||||
local server_out = io.open(CACHE_DNS_PATH .. "/001-server.conf", "a")
|
local server_out = io.open(CACHE_DNS_PATH .. "/001-server.conf", "a")
|
||||||
local ipset_out = io.open(CACHE_DNS_PATH .. "/ipset.conf", "a")
|
local ipset_out = io.open(CACHE_DNS_PATH .. "/ipset.conf", "a")
|
||||||
local set_name = "ipset"
|
local set_name = "ipset"
|
||||||
if NFTFLAG == "1" then
|
if NFTFLAG == "1" then
|
||||||
set_name = "nftset"
|
set_name = "nftset"
|
||||||
end
|
end
|
||||||
for key, value in pairs(list1) do
|
for key, value in pairs(list1) do
|
||||||
if value.dns and #value.dns > 0 then
|
if value.dns and #value.dns > 0 then
|
||||||
for i, dns in ipairs(value.dns) do
|
for i, dns in ipairs(value.dns) do
|
||||||
server_out:write(string.format("server=/.%s/%s", key, dns) .. "\n")
|
server_out:write(string.format("server=/.%s/%s", key, dns) .. "\n")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if value.ipsets and #value.ipsets > 0 then
|
if value.ipsets and #value.ipsets > 0 then
|
||||||
local ipsets_str = ""
|
local ipsets_str = ""
|
||||||
for i, ipset in ipairs(value.ipsets) do
|
for i, ipset in ipairs(value.ipsets) do
|
||||||
ipsets_str = ipsets_str .. ipset .. ","
|
ipsets_str = ipsets_str .. ipset .. ","
|
||||||
end
|
end
|
||||||
ipsets_str = ipsets_str:sub(1, #ipsets_str - 1)
|
ipsets_str = ipsets_str:sub(1, #ipsets_str - 1)
|
||||||
ipset_out:write(string.format("%s=/.%s/%s", set_name, key, ipsets_str) .. "\n")
|
ipset_out:write(string.format("%s=/.%s/%s", set_name, key, ipsets_str) .. "\n")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
server_out:close()
|
server_out:close()
|
||||||
ipset_out:close()
|
ipset_out:close()
|
||||||
end
|
end
|
||||||
|
|
||||||
local f_out = io.open(CACHE_TEXT_FILE, "a")
|
local f_out = io.open(CACHE_TEXT_FILE, "a")
|
||||||
f_out:write(new_text)
|
f_out:write(new_text)
|
||||||
f_out:close()
|
f_out:close()
|
||||||
end
|
end
|
||||||
|
|
||||||
api.remove(TMP_DNSMASQ_PATH)
|
api.remove(TMP_DNSMASQ_PATH)
|
||||||
fs.symlink(CACHE_DNS_PATH, TMP_DNSMASQ_PATH)
|
fs.symlink(CACHE_DNS_PATH, TMP_DNSMASQ_PATH)
|
||||||
|
|
||||||
if DNSMASQ_CONF_FILE ~= "nil" then
|
if DNSMASQ_CONF_FILE ~= "nil" then
|
||||||
local conf_lines = {}
|
local conf_lines = {}
|
||||||
if LISTEN_PORT then
|
if LISTEN_PORT then
|
||||||
--Copy dnsmasq instance
|
--Copy dnsmasq instance
|
||||||
conf_lines = copy_instance({
|
conf_lines = copy_instance({
|
||||||
["LISTEN_PORT"] = LISTEN_PORT,
|
["LISTEN_PORT"] = LISTEN_PORT,
|
||||||
["TMP_DNSMASQ_PATH"] = TMP_DNSMASQ_PATH,
|
["TMP_DNSMASQ_PATH"] = TMP_DNSMASQ_PATH,
|
||||||
["return"] = "1"
|
["return"] = "1"
|
||||||
})
|
})
|
||||||
--dhcp.leases to hostsMore actions
|
--dhcp.leases to hostsMore actions
|
||||||
local hosts = api.CACHE_PATH .. "/dhcp-hosts"
|
local hosts = api.CACHE_PATH .. "/dhcp-hosts"
|
||||||
sys.call("touch " .. hosts)
|
sys.call("touch " .. hosts)
|
||||||
tinsert(conf_lines, "addn-hosts=" .. hosts)
|
tinsert(conf_lines, "addn-hosts=" .. hosts)
|
||||||
else
|
else
|
||||||
--Modify the default dnsmasq service
|
--Modify the default dnsmasq service
|
||||||
end
|
end
|
||||||
tinsert(conf_lines, string.format("conf-dir=%s", TMP_DNSMASQ_PATH))
|
tinsert(conf_lines, string.format("conf-dir=%s", TMP_DNSMASQ_PATH))
|
||||||
if dnsmasq_default_dns then
|
if dnsmasq_default_dns then
|
||||||
for s in string.gmatch(dnsmasq_default_dns, '[^' .. "," .. ']+') do
|
for s in string.gmatch(dnsmasq_default_dns, '[^' .. "," .. ']+') do
|
||||||
tinsert(conf_lines, string.format("server=%s", s))
|
tinsert(conf_lines, string.format("server=%s", s))
|
||||||
end
|
end
|
||||||
tinsert(conf_lines, "all-servers")
|
tinsert(conf_lines, "all-servers")
|
||||||
tinsert(conf_lines, "no-poll")
|
tinsert(conf_lines, "no-poll")
|
||||||
tinsert(conf_lines, "no-resolv")
|
tinsert(conf_lines, "no-resolv")
|
||||||
|
|
||||||
if FLAG == "default" then
|
if FLAG == "default" then
|
||||||
api.set_cache_var("DEFAULT_DNS", DEFAULT_DNS)
|
api.set_cache_var("DEFAULT_DNS", DEFAULT_DNS)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if #conf_lines > 0 then
|
if #conf_lines > 0 then
|
||||||
local conf_out = io.open(DNSMASQ_CONF_FILE, "a")
|
local conf_out = io.open(DNSMASQ_CONF_FILE, "a")
|
||||||
conf_out:write(table.concat(conf_lines, "\n"))
|
conf_out:write(table.concat(conf_lines, "\n"))
|
||||||
conf_out:write("\n")
|
conf_out:write("\n")
|
||||||
conf_out:close()
|
conf_out:close()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
_G.stretch = stretch
|
_G.stretch = stretch
|
||||||
_G.restart = restart
|
_G.restart = restart
|
||||||
_G.logic_restart = logic_restart
|
_G.logic_restart = logic_restart
|
||||||
_G.copy_instance = copy_instance
|
_G.copy_instance = copy_instance
|
||||||
_G.add_rule = add_rule
|
_G.add_rule = add_rule
|
||||||
|
|
||||||
if arg[1] then
|
if arg[1] then
|
||||||
local func =_G[arg[1]]
|
local func =_G[arg[1]]
|
||||||
if func then
|
if func then
|
||||||
local var = nil
|
local var = nil
|
||||||
if arg[2] then
|
if arg[2] then
|
||||||
var = jsonc.parse(arg[2])
|
var = jsonc.parse(arg[2])
|
||||||
end
|
end
|
||||||
func(var)
|
func(var)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
if #arg > 0 then
|
if #arg > 0 then
|
||||||
local api = require "luci.passwall2.api"
|
local api = require "luci.passwall2.api"
|
||||||
local str = arg[1]
|
local str = arg[1]
|
||||||
table.remove(arg, 1)
|
table.remove(arg, 1)
|
||||||
print(api.i18n.translatef(str, unpack(arg)))
|
print(api.i18n.translatef(str, unpack(arg)))
|
||||||
end
|
end
|
||||||
@@ -891,7 +891,7 @@ add_firewall_rule() {
|
|||||||
|
|
||||||
del_firewall_rule() {
|
del_firewall_rule() {
|
||||||
for nft in "dstnat" "srcnat" "nat_output" "mangle_prerouting" "mangle_output"; do
|
for nft in "dstnat" "srcnat" "nat_output" "mangle_prerouting" "mangle_output"; do
|
||||||
local handles=$(nft -a list chain $NFTABLE_NAME ${nft} 2>/dev/null | grep -E "PSW2_" | awk -F '# handle ' '{print$2}')
|
local handles=$(nft -a list chain $NFTABLE_NAME ${nft} 2>/dev/null | grep -E "PSW2_" | awk -F '# handle ' '{print$2}')
|
||||||
for handle in $handles; do
|
for handle in $handles; do
|
||||||
nft delete rule $NFTABLE_NAME ${nft} handle ${handle} 2>/dev/null
|
nft delete rule $NFTABLE_NAME ${nft} handle ${handle} 2>/dev/null
|
||||||
done
|
done
|
||||||
|
|||||||