"
37 | source.cast = "string"
38 | source.cfgvalue = function(self, section)
39 | local value
40 | if self.tag_error[section] then
41 | value = self:formvalue(section)
42 | else
43 | value = self.map:get(section, self.option)
44 | if type(value) == "string" then
45 | local value2 = {}
46 | string.gsub(value, '[^' .. " " .. ']+', function(w) table.insert(value2, w) end)
47 | value = value2
48 | end
49 | end
50 | return value
51 | end
52 | source.validate = function(self, value, t)
53 | local err = {}
54 | for _, v in ipairs(value) do
55 | local flag = false
56 | if datatypes.ip4addr(v) then
57 | flag = true
58 | end
59 |
60 | if flag == false and v:find("geoip:") and v:find("geoip:") == 1 then
61 | flag = true
62 | end
63 |
64 | if flag == false then
65 | err[#err + 1] = v
66 | end
67 | end
68 |
69 | if #err > 0 then
70 | self:add_error(t, "invalid", translate("Not true format, please re-enter!"))
71 | for _, v in ipairs(err) do
72 | self:add_error(t, "invalid", v)
73 | end
74 | end
75 |
76 | return value
77 | end
78 |
79 | local dynamicList_write = function(self, section, value)
80 | local t = {}
81 | local t2 = {}
82 | if type(value) == "table" then
83 | local x
84 | for _, x in ipairs(value) do
85 | if x and #x > 0 then
86 | if not t2[x] then
87 | t2[x] = x
88 | t[#t+1] = x
89 | end
90 | end
91 | end
92 | else
93 | t = { value }
94 | end
95 | t = table.concat(t, " ")
96 | return DynamicList.write(self, section, t)
97 | end
98 |
99 | source.write = dynamicList_write
100 |
101 | sourcePort = s:option(Value, "sourcePort", translate("Source port"))
102 |
103 | port = s:option(Value, "port", translate("port"))
104 |
105 | domain_list = s:option(TextValue, "domain_list", translate("Domain"))
106 | domain_list.rows = 10
107 | domain_list.wrap = "off"
108 | domain_list.validate = function(self, value)
109 | local hosts= {}
110 | value = value:gsub("^%s+", ""):gsub("%s+$","\n"):gsub("\r\n","\n"):gsub("[ \t]*\n[ \t]*", "\n")
111 | string.gsub(value, "[^\r\n]+", function(w) table.insert(hosts, w) end)
112 | for index, host in ipairs(hosts) do
113 | local flag = 1
114 | local tmp_host = host
115 | if not host:find("#") and host:find("%s") then
116 | elseif host:find("regexp:") and host:find("regexp:") == 1 then
117 | flag = 0
118 | elseif host:find("domain:.") and host:find("domain:.") == 1 then
119 | tmp_host = host:gsub("domain:", "")
120 | elseif host:find("full:.") and host:find("full:.") == 1 then
121 | tmp_host = host:gsub("full:", "")
122 | elseif host:find("geosite:") and host:find("geosite:") == 1 then
123 | flag = 0
124 | elseif host:find("ext:") and host:find("ext:") == 1 then
125 | flag = 0
126 | elseif host:find("#") and host:find("#") == 1 then
127 | flag = 0
128 | end
129 | if flag == 1 then
130 | if not datatypes.hostname(tmp_host) then
131 | return nil, tmp_host .. " " .. translate("Not valid domain name, please re-enter!")
132 | end
133 | end
134 | end
135 | return value
136 | end
137 | domain_list.description = "
" .. translate("Plaintext: If this string matches any part of the targeting domain, this rule takes effet. Example: rule 'sina.com' matches targeting domain 'sina.com', 'sina.com.cn' and 'www.sina.com', but not 'sina.cn'.")
138 | .. "
" .. translate("Regular expression: Begining with 'regexp:', the rest is a regular expression. When the regexp matches targeting domain, this rule takes effect. Example: rule 'regexp:\\.goo.*\\.com$' matches 'www.google.com' and 'fonts.googleapis.com', but not 'google.com'.")
139 | .. "
" .. translate("Subdomain (recommended): Begining with 'domain:' and the rest is a domain. When the targeting domain is exactly the value, or is a subdomain of the value, this rule takes effect. Example: rule 'domain:v2ray.com' matches 'www.v2ray.com', 'v2ray.com', but not 'xv2ray.com'.")
140 | .. "
" .. translate("Full domain: Begining with 'full:' and the rest is a domain. When the targeting domain is exactly the value, the rule takes effect. Example: rule 'domain:v2ray.com' matches 'v2ray.com', but not 'www.v2ray.com'.")
141 | .. "
" .. translate("Pre-defined domain list: Begining with 'geosite:' and the rest is a name, such as geosite:google or geosite:cn.")
142 | .. "
" .. translate("Annotation: Begining with #")
143 | .. "
"
144 | ip_list = s:option(TextValue, "ip_list", "IP")
145 | ip_list.rows = 10
146 | ip_list.wrap = "off"
147 | ip_list.validate = function(self, value)
148 | local ipmasks= {}
149 | value = value:gsub("^%s+", ""):gsub("%s+$","\n"):gsub("\r\n","\n"):gsub("[ \t]*\n[ \t]*", "\n")
150 | string.gsub(value, "[^\r\n]+", function(w) table.insert(ipmasks, w) end)
151 | for index, ipmask in ipairs(ipmasks) do
152 | if ipmask:find("geoip:") and ipmask:find("geoip:") == 1 and not ipmask:find("%s") then
153 | elseif ipmask:find("ext:") and ipmask:find("ext:") == 1 and not ipmask:find("%s") then
154 | elseif ipmask:find("#") and ipmask:find("#") == 1 then
155 | else
156 | if not (datatypes.ipmask4(ipmask) or datatypes.ipmask6(ipmask)) then
157 | return nil, ipmask .. " " .. translate("Not valid IP format, please re-enter!")
158 | end
159 | end
160 | end
161 | return value
162 | end
163 | ip_list.description = "
" .. translate("IP: such as '127.0.0.1'.")
164 | .. "
" .. translate("CIDR: such as '127.0.0.0/8'.")
165 | .. "
" .. translate("GeoIP: such as 'geoip:cn'. It begins with geoip: (lower case) and followed by two letter of country code.")
166 | .. "
" .. translate("Annotation: Begining with #")
167 | .. "
"
168 |
169 | return m
170 |
--------------------------------------------------------------------------------
/luci-app-passwall2/luasrc/model/cbi/passwall2/client/socks_config.lua:
--------------------------------------------------------------------------------
1 | local api = require "luci.passwall2.api"
2 | local appname = api.appname
3 |
4 | m = Map(appname)
5 | api.set_apply_on_parse(m)
6 |
7 | if not arg[1] or not m:get(arg[1]) then
8 | luci.http.redirect(api.url())
9 | end
10 |
11 | local has_singbox = api.finded_com("sing-box")
12 | local has_xray = api.finded_com("xray")
13 |
14 | local nodes_table = {}
15 | for k, e in ipairs(api.get_valid_nodes()) do
16 | nodes_table[#nodes_table + 1] = e
17 | end
18 |
19 | s = m:section(NamedSection, arg[1], translate("Socks Config"), translate("Socks Config"))
20 | s.addremove = false
21 | s.dynamic = false
22 |
23 | ---- Enable
24 | o = s:option(Flag, "enabled", translate("Enable"))
25 | o.default = 1
26 | o.rmempty = false
27 |
28 | local auto_switch_tip
29 | local current_node = api.get_cache_var("socks_" .. arg[1])
30 | if current_node then
31 | local n = m:get(current_node)
32 | if n then
33 | if tonumber(m:get(arg[1], "enable_autoswitch") or 0) == 1 then
34 | if n then
35 | local remarks = api.get_node_remarks(n)
36 | local url = api.url("node_config", n[".name"])
37 | auto_switch_tip = translatef("Current node: %s", string.format('%s', url, remarks)) .. " "
38 | end
39 | end
40 | end
41 | end
42 |
43 | socks_node = s:option(ListValue, "node", translate("Node"))
44 | if auto_switch_tip then
45 | socks_node.description = auto_switch_tip
46 | end
47 |
48 | o = s:option(Flag, "bind_local", translate("Bind Local"), translate("When selected, it can only be accessed localhost."))
49 | o.default = "0"
50 |
51 | local n = 1
52 | m.uci:foreach(appname, "socks", function(s)
53 | if s[".name"] == section then
54 | return false
55 | end
56 | n = n + 1
57 | end)
58 |
59 | o = s:option(Value, "port", "Socks " .. translate("Listen Port"))
60 | o.default = n + 1080
61 | o.datatype = "port"
62 | o.rmempty = false
63 |
64 | if has_singbox or has_xray then
65 | o = s:option(Value, "http_port", "HTTP " .. translate("Listen Port") .. " " .. translate("0 is not use"))
66 | o.default = 0
67 | o.datatype = "port"
68 | end
69 |
70 | o = s:option(Flag, "log", translate("Enable") .. " " .. translate("Log"))
71 | o.default = 1
72 | o.rmempty = false
73 |
74 | o = s:option(Flag, "enable_autoswitch", translate("Auto Switch"))
75 | o.default = 0
76 | o.rmempty = false
77 |
78 | o = s:option(Value, "autoswitch_testing_time", translate("How often to test"), translate("Units:seconds"))
79 | o.datatype = "min(10)"
80 | o.default = 30
81 | o:depends("enable_autoswitch", true)
82 |
83 | o = s:option(Value, "autoswitch_connect_timeout", translate("Timeout seconds"), translate("Units:seconds"))
84 | o.datatype = "min(1)"
85 | o.default = 3
86 | o:depends("enable_autoswitch", true)
87 |
88 | o = s:option(Value, "autoswitch_retry_num", translate("Timeout retry num"))
89 | o.datatype = "min(1)"
90 | o.default = 1
91 | o:depends("enable_autoswitch", true)
92 |
93 | autoswitch_backup_node = s:option(DynamicList, "autoswitch_backup_node", translate("List of backup nodes"))
94 | autoswitch_backup_node:depends("enable_autoswitch", true)
95 | function o.write(self, section, value)
96 | local t = {}
97 | local t2 = {}
98 | if type(value) == "table" then
99 | local x
100 | for _, x in ipairs(value) do
101 | if x and #x > 0 then
102 | if not t2[x] then
103 | t2[x] = x
104 | t[#t+1] = x
105 | end
106 | end
107 | end
108 | else
109 | t = { value }
110 | end
111 | return DynamicList.write(self, section, t)
112 | end
113 |
114 | o = s:option(Flag, "autoswitch_restore_switch", translate("Restore Switch"), translate("When detects main node is available, switch back to the main node."))
115 | o:depends("enable_autoswitch", true)
116 |
117 | o = s:option(Value, "autoswitch_probe_url", translate("Probe URL"), translate("The URL used to detect the connection status."))
118 | o.default = "https://www.google.com/generate_204"
119 | o:depends("enable_autoswitch", true)
120 |
121 | for k, v in pairs(nodes_table) do
122 | autoswitch_backup_node:value(v.id, v["remark"])
123 | socks_node:value(v.id, v["remark"])
124 | end
125 |
126 | o = s:option(DummyValue, "btn", " ")
127 | o.template = appname .. "/socks_auto_switch/btn"
128 | o:depends("enable_autoswitch", true)
129 |
130 | return m
131 |
--------------------------------------------------------------------------------
/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/hysteria2.lua:
--------------------------------------------------------------------------------
1 | local m, s = ...
2 |
3 | local api = require "luci.passwall2.api"
4 |
5 | if not api.finded_com("hysteria") then
6 | return
7 | end
8 |
9 | local type_name = "Hysteria2"
10 |
11 | local option_prefix = "hysteria2_"
12 |
13 | local function _n(name)
14 | return option_prefix .. name
15 | end
16 |
17 | -- [[ Hysteria2 ]]
18 |
19 | s.fields["type"]:value(type_name, "Hysteria2")
20 |
21 | o = s:option(ListValue, _n("protocol"), translate("Protocol"))
22 | o:value("udp", "UDP")
23 |
24 | o = s:option(Value, _n("address"), translate("Address (Support Domain Name)"))
25 |
26 | o = s:option(Value, _n("port"), translate("Port"))
27 | o.datatype = "port"
28 |
29 | o = s:option(Value, _n("hop"), translate("Port hopping range"))
30 | o.description = translate("Format as 1000:2000 or 1000-2000 Multiple groups are separated by commas (,).")
31 | o.rewrite_option = o.option
32 |
33 | o = s:option(Value, _n("obfs"), translate("Obfs Password"))
34 | o.rewrite_option = o.option
35 |
36 | o = s:option(Value, _n("auth_password"), translate("Auth Password"))
37 | o.password = true
38 | o.rewrite_option = o.option
39 |
40 | o = s:option(Flag, _n("fast_open"), translate("Fast Open"))
41 | o.default = "0"
42 |
43 | o = s:option(Value, _n("tls_serverName"), translate("Domain"))
44 |
45 | o = s:option(Flag, _n("tls_allowInsecure"), translate("allowInsecure"), translate("Whether unsafe connections are allowed. When checked, Certificate validation will be skipped."))
46 | o.default = "0"
47 |
48 | o = s:option(Value, _n("tls_pinSHA256"), translate("PinSHA256"),translate("Certificate fingerprint"))
49 | o.rewrite_option = o.option
50 |
51 | o = s:option(Value, _n("up_mbps"), translate("Max upload Mbps"))
52 | o.rewrite_option = o.option
53 |
54 | o = s:option(Value, _n("down_mbps"), translate("Max download Mbps"))
55 | o.rewrite_option = o.option
56 |
57 | o = s:option(Value, _n("hop_interval"), translate("Hop Interval"), translate("Example:") .. "30s (≥5s)")
58 | o.rewrite_option = o.option
59 |
60 | o = s:option(Value, _n("recv_window"), translate("QUIC stream receive window"))
61 | o.rewrite_option = o.option
62 |
63 | o = s:option(Value, _n("recv_window_conn"), translate("QUIC connection receive window"))
64 | o.rewrite_option = o.option
65 |
66 | o = s:option(Value, _n("idle_timeout"), translate("Idle Timeout"), translate("Example:") .. "30s (4s-120s)")
67 | o.rewrite_option = o.option
68 |
69 | o = s:option(Flag, _n("disable_mtu_discovery"), translate("Disable MTU detection"))
70 | o.default = "0"
71 | o.rewrite_option = o.option
72 |
73 | o = s:option(Flag, _n("lazy_start"), translate("Lazy Start"))
74 | o.default = "0"
75 | o.rewrite_option = o.option
76 |
77 | api.luci_types(arg[1], m, s, type_name, option_prefix)
78 |
--------------------------------------------------------------------------------
/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/naive.lua:
--------------------------------------------------------------------------------
1 | local m, s = ...
2 |
3 | local api = require "luci.passwall2.api"
4 |
5 | if not api.is_finded("naive") then
6 | return
7 | end
8 |
9 | local type_name = "Naiveproxy"
10 |
11 | local option_prefix = "naive_"
12 |
13 | local function _n(name)
14 | return option_prefix .. name
15 | end
16 |
17 | -- [[ Naive ]]
18 |
19 | s.fields["type"]:value(type_name, translate("NaiveProxy"))
20 |
21 | o = s:option(ListValue, _n("protocol"), translate("Protocol"))
22 | o:value("https", translate("HTTPS"))
23 | o:value("quic", translate("QUIC"))
24 |
25 | o = s:option(Value, _n("address"), translate("Address (Support Domain Name)"))
26 |
27 | o = s:option(Value, _n("port"), translate("Port"))
28 | o.datatype = "port"
29 |
30 | o = s:option(Value, _n("username"), translate("Username"))
31 |
32 | o = s:option(Value, _n("password"), translate("Password"))
33 | o.password = true
34 |
35 | api.luci_types(arg[1], m, s, type_name, option_prefix)
36 |
--------------------------------------------------------------------------------
/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ss-rust.lua:
--------------------------------------------------------------------------------
1 | local m, s = ...
2 |
3 | local api = require "luci.passwall2.api"
4 |
5 | if not api.is_finded("sslocal") then
6 | return
7 | end
8 |
9 | local type_name = "SS-Rust"
10 |
11 | local option_prefix = "ssrust_"
12 |
13 | local function _n(name)
14 | return option_prefix .. name
15 | end
16 |
17 | local ssrust_encrypt_method_list = {
18 | "plain", "none",
19 | "aes-128-gcm", "aes-256-gcm", "chacha20-ietf-poly1305",
20 | "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha8-poly1305", "2022-blake3-chacha20-poly1305"
21 | }
22 |
23 | -- [[ Shadowsocks Rust ]]
24 |
25 | s.fields["type"]:value(type_name, translate("Shadowsocks Rust"))
26 |
27 | o = s:option(Value, _n("address"), translate("Address (Support Domain Name)"))
28 |
29 | o = s:option(Value, _n("port"), translate("Port"))
30 | o.datatype = "port"
31 |
32 | o = s:option(Value, _n("password"), translate("Password"))
33 | o.password = true
34 |
35 | o = s:option(Value, _n("method"), translate("Encrypt Method"))
36 | for a, t in ipairs(ssrust_encrypt_method_list) do o:value(t) end
37 |
38 | o = s:option(Value, _n("timeout"), translate("Connection Timeout"))
39 | o.datatype = "uinteger"
40 | o.default = 300
41 |
42 | o = s:option(ListValue, _n("tcp_fast_open"), "TCP " .. translate("Fast Open"), translate("Need node support required"))
43 | o:value("false")
44 | o:value("true")
45 |
46 | o = s:option(ListValue, _n("plugin"), translate("plugin"))
47 | o:value("none", translate("none"))
48 | if api.is_finded("xray-plugin") then o:value("xray-plugin") end
49 | if api.is_finded("v2ray-plugin") then o:value("v2ray-plugin") end
50 | if api.is_finded("obfs-local") then o:value("obfs-local") end
51 |
52 | o = s:option(Value, _n("plugin_opts"), translate("opts"))
53 | o:depends({ [_n("plugin")] = "xray-plugin"})
54 | o:depends({ [_n("plugin")] = "v2ray-plugin"})
55 | o:depends({ [_n("plugin")] = "obfs-local"})
56 |
57 | api.luci_types(arg[1], m, s, type_name, option_prefix)
58 |
--------------------------------------------------------------------------------
/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ss.lua:
--------------------------------------------------------------------------------
1 | local m, s = ...
2 |
3 | local api = require "luci.passwall2.api"
4 |
5 | if not api.is_finded("ss-local") then
6 | return
7 | end
8 |
9 | local type_name = "SS"
10 |
11 | local option_prefix = "ss_"
12 |
13 | local function _n(name)
14 | return option_prefix .. name
15 | end
16 |
17 | local ss_encrypt_method_list = {
18 | "rc4-md5", "aes-128-cfb", "aes-192-cfb", "aes-256-cfb", "aes-128-ctr",
19 | "aes-192-ctr", "aes-256-ctr", "bf-cfb", "salsa20", "chacha20", "chacha20-ietf",
20 | "aes-128-gcm", "aes-192-gcm", "aes-256-gcm", "chacha20-ietf-poly1305",
21 | "xchacha20-ietf-poly1305"
22 | }
23 |
24 | -- [[ Shadowsocks Libev ]]
25 |
26 | s.fields["type"]:value(type_name, translate("Shadowsocks Libev"))
27 |
28 | o = s:option(Value, _n("address"), translate("Address (Support Domain Name)"))
29 |
30 | o = s:option(Value, _n("port"), translate("Port"))
31 | o.datatype = "port"
32 |
33 | o = s:option(Value, _n("password"), translate("Password"))
34 | o.password = true
35 |
36 | o = s:option(Value, _n("method"), translate("Encrypt Method"))
37 | for a, t in ipairs(ss_encrypt_method_list) do o:value(t) end
38 |
39 | o = s:option(Value, _n("timeout"), translate("Connection Timeout"))
40 | o.datatype = "uinteger"
41 | o.default = 300
42 |
43 | o = s:option(ListValue, _n("tcp_fast_open"), "TCP " .. translate("Fast Open"), translate("Need node support required"))
44 | o:value("false")
45 | o:value("true")
46 |
47 | o = s:option(ListValue, _n("plugin"), translate("plugin"))
48 | o:value("none", translate("none"))
49 | if api.is_finded("xray-plugin") then o:value("xray-plugin") end
50 | if api.is_finded("v2ray-plugin") then o:value("v2ray-plugin") end
51 | if api.is_finded("obfs-local") then o:value("obfs-local") end
52 |
53 | o = s:option(Value, _n("plugin_opts"), translate("opts"))
54 | o:depends({ [_n("plugin")] = "xray-plugin"})
55 | o:depends({ [_n("plugin")] = "v2ray-plugin"})
56 | o:depends({ [_n("plugin")] = "obfs-local"})
57 |
58 | api.luci_types(arg[1], m, s, type_name, option_prefix)
59 |
--------------------------------------------------------------------------------
/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ssr.lua:
--------------------------------------------------------------------------------
1 | local m, s = ...
2 |
3 | local api = require "luci.passwall2.api"
4 |
5 | if not api.is_finded("ssr-local") then
6 | return
7 | end
8 |
9 | local type_name = "SSR"
10 |
11 | local option_prefix = "ssr_"
12 |
13 | local function _n(name)
14 | return option_prefix .. name
15 | end
16 |
17 | local ssr_encrypt_method_list = {
18 | "none", "table", "rc2-cfb", "rc4", "rc4-md5", "rc4-md5-6", "aes-128-cfb",
19 | "aes-192-cfb", "aes-256-cfb", "aes-128-ctr", "aes-192-ctr", "aes-256-ctr",
20 | "bf-cfb", "camellia-128-cfb", "camellia-192-cfb", "camellia-256-cfb",
21 | "cast5-cfb", "des-cfb", "idea-cfb", "seed-cfb", "salsa20", "chacha20",
22 | "chacha20-ietf"
23 | }
24 |
25 | local ssr_protocol_list = {
26 | "origin", "verify_simple", "verify_deflate", "verify_sha1", "auth_simple",
27 | "auth_sha1", "auth_sha1_v2", "auth_sha1_v4", "auth_aes128_md5",
28 | "auth_aes128_sha1", "auth_chain_a", "auth_chain_b", "auth_chain_c",
29 | "auth_chain_d", "auth_chain_e", "auth_chain_f"
30 | }
31 | local ssr_obfs_list = {
32 | "plain", "http_simple", "http_post", "random_head", "tls_simple",
33 | "tls1.0_session_auth", "tls1.2_ticket_auth"
34 | }
35 |
36 | -- [[ ShadowsocksR Libev ]]
37 |
38 | s.fields["type"]:value(type_name, translate("ShadowsocksR Libev"))
39 |
40 | o = s:option(Value, _n("address"), translate("Address (Support Domain Name)"))
41 |
42 | o = s:option(Value, _n("port"), translate("Port"))
43 | o.datatype = "port"
44 |
45 | o = s:option(Value, _n("password"), translate("Password"))
46 | o.password = true
47 |
48 | o = s:option(ListValue, _n("method"), translate("Encrypt Method"))
49 | for a, t in ipairs(ssr_encrypt_method_list) do o:value(t) end
50 |
51 | o = s:option(ListValue, _n("protocol"), translate("Protocol"))
52 | for a, t in ipairs(ssr_protocol_list) do o:value(t) end
53 |
54 | o = s:option(Value, _n("protocol_param"), translate("Protocol_param"))
55 |
56 | o = s:option(ListValue, _n("obfs"), translate("Obfs"))
57 | for a, t in ipairs(ssr_obfs_list) do o:value(t) end
58 |
59 | o = s:option(Value, _n("obfs_param"), translate("Obfs_param"))
60 |
61 | o = s:option(Value, _n("timeout"), translate("Connection Timeout"))
62 | o.datatype = "uinteger"
63 | o.default = 300
64 |
65 | o = s:option(ListValue, _n("tcp_fast_open"), "TCP " .. translate("Fast Open"), translate("Need node support required"))
66 | o:value("false")
67 | o:value("true")
68 |
69 | api.luci_types(arg[1], m, s, type_name, option_prefix)
70 |
--------------------------------------------------------------------------------
/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/tuic.lua:
--------------------------------------------------------------------------------
1 | local m, s = ...
2 |
3 | local api = require "luci.passwall2.api"
4 |
5 | if not api.is_finded("tuic-client") then
6 | return
7 | end
8 |
9 | local type_name = "TUIC"
10 |
11 | local option_prefix = "tuic_"
12 |
13 | local function _n(name)
14 | return option_prefix .. name
15 | end
16 |
17 | -- [[ TUIC ]]
18 |
19 | s.fields["type"]:value(type_name, translate("TUIC"))
20 |
21 | o = s:option(Value, _n("address"), translate("Address (Support Domain Name)"))
22 |
23 | o = s:option(Value, _n("port"), translate("Port"))
24 | o.datatype = "port"
25 |
26 | o = s:option(Value, _n("uuid"), translate("ID"))
27 | o.password = true
28 |
29 | -- Tuic Password for remote server connect
30 | o = s:option(Value, _n("password"), translate("TUIC User Password For Connect Remote Server"))
31 | o.password = true
32 | o.rmempty = true
33 | o.default = ""
34 | o.rewrite_option = o.option
35 |
36 | --[[
37 | -- Tuic username for local socks connect
38 | o = s:option(Value, _n("socks_username"), translate("TUIC UserName For Local Socks"))
39 | o.rmempty = true
40 | o.default = ""
41 | o.rewrite_option = o.option
42 |
43 | -- Tuic Password for local socks connect
44 | o = s:option(Value, _n("socks_password"), translate("TUIC Password For Local Socks"))
45 | o.password = true
46 | o.rmempty = true
47 | o.default = ""
48 | o.rewrite_option = o.option
49 | --]]
50 |
51 | o = s:option(Value, _n("ip"), translate("Set the TUIC proxy server ip address"))
52 | o.datatype = "ipaddr"
53 | o.rmempty = true
54 | o.rewrite_option = o.option
55 |
56 | o = s:option(ListValue, _n("udp_relay_mode"), translate("UDP relay mode"))
57 | o:value("native", translate("native"))
58 | o:value("quic", translate("QUIC"))
59 | o.default = "native"
60 | o.rmempty = true
61 | o.rewrite_option = o.option
62 |
63 | o = s:option(ListValue, _n("congestion_control"), translate("Congestion control algorithm"))
64 | o:value("bbr", translate("BBR"))
65 | o:value("cubic", translate("CUBIC"))
66 | o:value("new_reno", translate("New Reno"))
67 | o.default = "cubic"
68 | o.rmempty = true
69 | o.rewrite_option = o.option
70 |
71 | o = s:option(Value, _n("heartbeat"), translate("Heartbeat interval(second)"))
72 | o.datatype = "uinteger"
73 | o.default = "3"
74 | o.rmempty = true
75 | o.rewrite_option = o.option
76 |
77 | o = s:option(Value, _n("timeout"), translate("Timeout for establishing a connection to server(second)"))
78 | o.datatype = "uinteger"
79 | o.default = "8"
80 | o.rmempty = true
81 | o.rewrite_option = o.option
82 |
83 | o = s:option(Value, _n("gc_interval"), translate("Garbage collection interval(second)"))
84 | o.datatype = "uinteger"
85 | o.default = "3"
86 | o.rmempty = true
87 | o.rewrite_option = o.option
88 |
89 | o = s:option(Value, _n("gc_lifetime"), translate("Garbage collection lifetime(second)"))
90 | o.datatype = "uinteger"
91 | o.default = "15"
92 | o.rmempty = true
93 | o.rewrite_option = o.option
94 |
95 | o = s:option(Value, _n("send_window"), translate("TUIC send window"))
96 | o.datatype = "uinteger"
97 | o.default = 20971520
98 | o.rmempty = true
99 | o.rewrite_option = o.option
100 |
101 | o = s:option(Value, _n("receive_window"), translate("TUIC receive window"))
102 | o.datatype = "uinteger"
103 | o.default = 10485760
104 | o.rmempty = true
105 | o.rewrite_option = o.option
106 |
107 | o = s:option(Value, _n("max_package_size"), translate("TUIC Maximum packet size the socks5 server can receive from external, in bytes"))
108 | o.datatype = "uinteger"
109 | o.default = 1500
110 | o.rmempty = true
111 | o.rewrite_option = o.option
112 |
113 | --Tuic settings for the local inbound socks5 server
114 | o = s:option(Flag, _n("dual_stack"), translate("Set if the listening socket should be dual-stack"))
115 | o.default = 0
116 | o.rmempty = true
117 | o.rewrite_option = o.option
118 |
119 | o = s:option(Flag, _n("disable_sni"), translate("Disable SNI"))
120 | o.default = 0
121 | o.rmempty = true
122 | o.rewrite_option = o.option
123 |
124 | o = s:option(Flag, _n("zero_rtt_handshake"), translate("Enable 0-RTT QUIC handshake"))
125 | o.default = 0
126 | o.rmempty = true
127 | o.rewrite_option = o.option
128 |
129 | o = s:option(DynamicList, _n("tls_alpn"), translate("TLS ALPN"))
130 | o.rmempty = true
131 | o.rewrite_option = o.option
132 |
133 | api.luci_types(arg[1], m, s, type_name, option_prefix)
134 |
--------------------------------------------------------------------------------
/luci-app-passwall2/luasrc/model/cbi/passwall2/server/index.lua:
--------------------------------------------------------------------------------
1 | local api = require "luci.passwall2.api"
2 |
3 | m = Map("passwall2_server", translate("Server-Side"))
4 | api.set_apply_on_parse(m)
5 |
6 | t = m:section(NamedSection, "global", "global")
7 | t.anonymous = true
8 | t.addremove = false
9 |
10 | e = t:option(Flag, "enable", translate("Enable"))
11 | e.rmempty = false
12 |
13 | t = m:section(TypedSection, "user", translate("Users Manager"))
14 | t.anonymous = true
15 | t.addremove = true
16 | t.sortable = true
17 | t.template = "cbi/tblsection"
18 | t.extedit = api.url("server_user", "%s")
19 | function t.create(e, t)
20 | local uuid = api.gen_uuid()
21 | t = uuid
22 | TypedSection.create(e, t)
23 | luci.http.redirect(e.extedit:format(t))
24 | end
25 | function t.remove(e, t)
26 | e.map.proceed = true
27 | e.map:del(t)
28 | luci.http.redirect(api.url("server"))
29 | end
30 |
31 | e = t:option(Flag, "enable", translate("Enable"))
32 | e.width = "5%"
33 | e.rmempty = false
34 |
35 | e = t:option(DummyValue, "status", translate("Status"))
36 | e.rawhtml = true
37 | e.cfgvalue = function(t, n)
38 | return string.format('%s', translate("Collecting data..."))
39 | end
40 |
41 | e = t:option(DummyValue, "remarks", translate("Remarks"))
42 | e.width = "15%"
43 |
44 | e = t:option(DummyValue, "type", translate("Type"))
45 | e.width = "20%"
46 | e.rawhtml = true
47 | e.cfgvalue = function(t, n)
48 | local str = ""
49 | local type = m:get(n, "type") or ""
50 | if type == "sing-box" or type == "Xray" then
51 | local protocol = m:get(n, "protocol") or ""
52 | if protocol == "vmess" then
53 | protocol = "VMess"
54 | elseif protocol == "vless" then
55 | protocol = "VLESS"
56 | elseif protocol == "shadowsocks" then
57 | protocol = "SS"
58 | elseif protocol == "shadowsocksr" then
59 | protocol = "SSR"
60 | elseif protocol == "wireguard" then
61 | protocol = "WG"
62 | elseif protocol == "hysteria" then
63 | protocol = "HY"
64 | elseif protocol == "hysteria2" then
65 | protocol = "HY2"
66 | elseif protocol == "anytls" then
67 | protocol = "AnyTLS"
68 | else
69 | protocol = protocol:gsub("^%l",string.upper)
70 | local custom = m:get(n, "custom") or "0"
71 | if custom == "1" then
72 | protocol = translate("Custom Config")
73 | end
74 | end
75 | if type == "sing-box" then type = "Sing-Box" end
76 | type = type .. " " .. protocol
77 | end
78 | str = str .. translate(type)
79 | return str
80 | end
81 |
82 | e = t:option(DummyValue, "port", translate("Port"))
83 |
84 | e = t:option(Flag, "log", translate("Log"))
85 | e.default = "1"
86 | e.rmempty = false
87 |
88 | m:append(Template("passwall2/server/log"))
89 |
90 | m:append(Template("passwall2/server/users_list_status"))
91 | return m
92 |
93 |
--------------------------------------------------------------------------------
/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/hysteria2.lua:
--------------------------------------------------------------------------------
1 | local m, s = ...
2 |
3 | local api = require "luci.passwall2.api"
4 |
5 | if not api.finded_com("hysteria") then
6 | return
7 | end
8 |
9 | local type_name = "Hysteria2"
10 |
11 | local option_prefix = "hysteria2_"
12 |
13 | local function _n(name)
14 | return option_prefix .. name
15 | end
16 |
17 | -- [[ Hysteria2 ]]
18 |
19 | s.fields["type"]:value(type_name, "Hysteria2")
20 |
21 | o = s:option(Flag, _n("custom"), translate("Use Custom Config"))
22 |
23 | o = s:option(Value, _n("port"), translate("Listen Port"))
24 | o.datatype = "port"
25 | o:depends({ [_n("custom")] = false })
26 |
27 | o = s:option(Value, _n("obfs"), translate("Obfs Password"))
28 | o.rewrite_option = o.option
29 | o:depends({ [_n("custom")] = false })
30 |
31 | o = s:option(Value, _n("auth_password"), translate("Auth Password"))
32 | o.password = true
33 | o.rewrite_option = o.option
34 | o:depends({ [_n("custom")] = false })
35 |
36 | o = s:option(Flag, _n("udp"), translate("UDP"))
37 | o.default = "1"
38 | o.rewrite_option = o.option
39 | o:depends({ [_n("custom")] = false })
40 |
41 | o = s:option(Value, _n("up_mbps"), translate("Max upload Mbps"))
42 | o.rewrite_option = o.option
43 | o:depends({ [_n("custom")] = false })
44 |
45 | o = s:option(Value, _n("down_mbps"), translate("Max download Mbps"))
46 | o.rewrite_option = o.option
47 | o:depends({ [_n("custom")] = false })
48 |
49 | o = s:option(Flag, _n("ignoreClientBandwidth"), translate("ignoreClientBandwidth"))
50 | o.default = "0"
51 | o.rewrite_option = o.option
52 | o:depends({ [_n("custom")] = false })
53 |
54 | o = s:option(FileUpload, _n("tls_certificateFile"), translate("Public key absolute path"), translate("as:") .. "/etc/ssl/fullchain.pem")
55 | o.default = m:get(s.section, "tls_certificateFile") or "/etc/config/ssl/" .. arg[1] .. ".pem"
56 | if o and o:formvalue(arg[1]) then o.default = o:formvalue(arg[1]) end
57 | o.validate = function(self, value, t)
58 | if value and value ~= "" then
59 | if not nixio.fs.access(value) then
60 | return nil, translate("Can't find this file!")
61 | else
62 | return value
63 | end
64 | end
65 | return nil
66 | end
67 | o:depends({ [_n("custom")] = false })
68 |
69 | o = s:option(FileUpload, _n("tls_keyFile"), translate("Private key absolute path"), translate("as:") .. "/etc/ssl/private.key")
70 | o.default = m:get(s.section, "tls_keyFile") or "/etc/config/ssl/" .. arg[1] .. ".key"
71 | if o and o:formvalue(arg[1]) then o.default = o:formvalue(arg[1]) end
72 | o.validate = function(self, value, t)
73 | if value and value ~= "" then
74 | if not nixio.fs.access(value) then
75 | return nil, translate("Can't find this file!")
76 | else
77 | return value
78 | end
79 | end
80 | return nil
81 | end
82 | o:depends({ [_n("custom")] = false })
83 |
84 | o = s:option(TextValue, _n("custom_config"), translate("Custom Config"))
85 | o.rows = 10
86 | o.wrap = "off"
87 | o:depends({ [_n("custom")] = true })
88 | o.validate = function(self, value, t)
89 | if value and api.jsonc.parse(value) then
90 | return value
91 | else
92 | return nil, translate("Must be JSON text!")
93 | end
94 | end
95 | o.custom_cfgvalue = function(self, section, value)
96 | local config_str = m:get(section, "config_str")
97 | if config_str then
98 | return api.base64Decode(config_str)
99 | end
100 | end
101 | o.custom_write = function(self, section, value)
102 | m:set(section, "config_str", api.base64Encode(value))
103 | end
104 |
105 | o = s:option(Flag, _n("log"), translate("Log"))
106 | o.default = "1"
107 | o.rmempty = false
108 |
109 | api.luci_types(arg[1], m, s, type_name, option_prefix)
110 |
--------------------------------------------------------------------------------
/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/ss-rust.lua:
--------------------------------------------------------------------------------
1 | local m, s = ...
2 |
3 | local api = require "luci.passwall2.api"
4 |
5 | if not api.is_finded("ssserver") then
6 | return
7 | end
8 |
9 | local type_name = "SS-Rust"
10 |
11 | local option_prefix = "ssrust_"
12 |
13 | local function _n(name)
14 | return option_prefix .. name
15 | end
16 |
17 | local ssrust_encrypt_method_list = {
18 | "plain", "none",
19 | "aes-128-gcm", "aes-256-gcm", "chacha20-ietf-poly1305",
20 | "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha8-poly1305", "2022-blake3-chacha20-poly1305"
21 | }
22 |
23 | -- [[ Shadowsocks Rust ]]
24 |
25 | s.fields["type"]:value(type_name, translate("Shadowsocks Rust"))
26 |
27 | o = s:option(Flag, _n("custom"), translate("Use Custom Config"))
28 |
29 | o = s:option(Value, _n("port"), translate("Listen Port"))
30 | o.datatype = "port"
31 | o:depends({ [_n("custom")] = false })
32 |
33 | o = s:option(Value, _n("password"), translate("Password"))
34 | o.password = true
35 | o:depends({ [_n("custom")] = false })
36 |
37 | o = s:option(ListValue, _n("method"), translate("Encrypt Method"))
38 | for a, t in ipairs(ssrust_encrypt_method_list) do o:value(t) end
39 | o:depends({ [_n("custom")] = false })
40 |
41 | o = s:option(Value, _n("timeout"), translate("Connection Timeout"))
42 | o.datatype = "uinteger"
43 | o.default = 300
44 | o:depends({ [_n("custom")] = false })
45 |
46 | o = s:option(Flag, _n("tcp_fast_open"), "TCP " .. translate("Fast Open"))
47 | o.default = "0"
48 | o:depends({ [_n("custom")] = false })
49 |
50 | o = s:option(TextValue, _n("custom_config"), translate("Custom Config"))
51 | o.rows = 10
52 | o.wrap = "off"
53 | o:depends({ [_n("custom")] = true })
54 | o.validate = function(self, value, t)
55 | if value and api.jsonc.parse(value) then
56 | return value
57 | else
58 | return nil, translate("Must be JSON text!")
59 | end
60 | end
61 | o.custom_cfgvalue = function(self, section, value)
62 | local config_str = m:get(section, "config_str")
63 | if config_str then
64 | return api.base64Decode(config_str)
65 | end
66 | end
67 | o.custom_write = function(self, section, value)
68 | m:set(section, "config_str", api.base64Encode(value))
69 | end
70 |
71 | o = s:option(Flag, _n("log"), translate("Log"))
72 | o.default = "1"
73 | o.rmempty = false
74 |
75 | api.luci_types(arg[1], m, s, type_name, option_prefix)
76 |
--------------------------------------------------------------------------------
/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/ss.lua:
--------------------------------------------------------------------------------
1 | local m, s = ...
2 |
3 | local api = require "luci.passwall2.api"
4 |
5 | if not api.is_finded("ss-server") then
6 | return
7 | end
8 |
9 | local type_name = "SS"
10 |
11 | local option_prefix = "ss_"
12 |
13 | local function _n(name)
14 | return option_prefix .. name
15 | end
16 |
17 | local ss_encrypt_method_list = {
18 | "rc4-md5", "aes-128-cfb", "aes-192-cfb", "aes-256-cfb", "aes-128-ctr",
19 | "aes-192-ctr", "aes-256-ctr", "bf-cfb", "camellia-128-cfb",
20 | "camellia-192-cfb", "camellia-256-cfb", "salsa20", "chacha20",
21 | "chacha20-ietf", -- aead
22 | "aes-128-gcm", "aes-192-gcm", "aes-256-gcm", "chacha20-ietf-poly1305",
23 | "xchacha20-ietf-poly1305"
24 | }
25 |
26 | -- [[ Shadowsocks ]]
27 |
28 | s.fields["type"]:value(type_name, translate("Shadowsocks"))
29 |
30 | o = s:option(Flag, _n("custom"), translate("Use Custom Config"))
31 |
32 | o = s:option(Value, _n("port"), translate("Listen Port"))
33 | o.datatype = "port"
34 | o:depends({ [_n("custom")] = false })
35 |
36 | o = s:option(Value, _n("password"), translate("Password"))
37 | o.password = true
38 | o:depends({ [_n("custom")] = false })
39 |
40 | o = s:option(ListValue, _n("method"), translate("Encrypt Method"))
41 | for a, t in ipairs(ss_encrypt_method_list) do o:value(t) end
42 | o:depends({ [_n("custom")] = false })
43 |
44 | o = s:option(Value, _n("timeout"), translate("Connection Timeout"))
45 | o.datatype = "uinteger"
46 | o.default = 300
47 | o:depends({ [_n("custom")] = false })
48 |
49 | o = s:option(Flag, _n("tcp_fast_open"), "TCP " .. translate("Fast Open"))
50 | o.default = "0"
51 | o:depends({ [_n("custom")] = false })
52 |
53 | o = s:option(TextValue, _n("custom_config"), translate("Custom Config"))
54 | o.rows = 10
55 | o.wrap = "off"
56 | o:depends({ [_n("custom")] = true })
57 | o.validate = function(self, value, t)
58 | if value and api.jsonc.parse(value) then
59 | return value
60 | else
61 | return nil, translate("Must be JSON text!")
62 | end
63 | end
64 | o.custom_cfgvalue = function(self, section, value)
65 | local config_str = m:get(section, "config_str")
66 | if config_str then
67 | return api.base64Decode(config_str)
68 | end
69 | end
70 | o.custom_write = function(self, section, value)
71 | m:set(section, "config_str", api.base64Encode(value))
72 | end
73 |
74 | o = s:option(Flag, _n("log"), translate("Log"))
75 | o.default = "1"
76 | o.rmempty = false
77 |
78 | api.luci_types(arg[1], m, s, type_name, option_prefix)
79 |
--------------------------------------------------------------------------------
/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/ssr.lua:
--------------------------------------------------------------------------------
1 | local m, s = ...
2 |
3 | local api = require "luci.passwall2.api"
4 |
5 | if not api.is_finded("ssr-server") then
6 | return
7 | end
8 |
9 | local type_name = "SSR"
10 |
11 | local option_prefix = "ssr_"
12 |
13 | local function _n(name)
14 | return option_prefix .. name
15 | end
16 |
17 | local ssr_encrypt_method_list = {
18 | "none", "table", "rc2-cfb", "rc4", "rc4-md5", "rc4-md5-6", "aes-128-cfb",
19 | "aes-192-cfb", "aes-256-cfb", "aes-128-ctr", "aes-192-ctr", "aes-256-ctr",
20 | "bf-cfb", "camellia-128-cfb", "camellia-192-cfb", "camellia-256-cfb",
21 | "cast5-cfb", "des-cfb", "idea-cfb", "seed-cfb", "salsa20", "chacha20",
22 | "chacha20-ietf"
23 | }
24 |
25 | local ssr_protocol_list = {
26 | "origin", "verify_simple", "verify_deflate", "verify_sha1", "auth_simple",
27 | "auth_sha1", "auth_sha1_v2", "auth_sha1_v4", "auth_aes128_md5",
28 | "auth_aes128_sha1", "auth_chain_a", "auth_chain_b", "auth_chain_c",
29 | "auth_chain_d", "auth_chain_e", "auth_chain_f"
30 | }
31 | local ssr_obfs_list = {
32 | "plain", "http_simple", "http_post", "random_head", "tls_simple",
33 | "tls1.0_session_auth", "tls1.2_ticket_auth"
34 | }
35 |
36 | -- [[ ShadowsocksR ]]
37 |
38 | s.fields["type"]:value(type_name, translate("ShadowsocksR"))
39 |
40 | o = s:option(Flag, _n("custom"), translate("Use Custom Config"))
41 |
42 | o = s:option(Value, _n("port"), translate("Listen Port"))
43 | o.datatype = "port"
44 | o:depends({ [_n("custom")] = false })
45 |
46 | o = s:option(Value, _n("password"), translate("Password"))
47 | o.password = true
48 | o:depends({ [_n("custom")] = false })
49 |
50 | o = s:option(ListValue, _n("method"), translate("Encrypt Method"))
51 | for a, t in ipairs(ssr_encrypt_method_list) do o:value(t) end
52 | o:depends({ [_n("custom")] = false })
53 |
54 | o = s:option(ListValue, _n("protocol"), translate("Protocol"))
55 | for a, t in ipairs(ssr_protocol_list) do o:value(t) end
56 | o:depends({ [_n("custom")] = false })
57 |
58 | o = s:option(Value, _n("protocol_param"), translate("Protocol_param"))
59 | o:depends({ [_n("custom")] = false })
60 |
61 | o = s:option(ListValue, _n("obfs"), translate("Obfs"))
62 | for a, t in ipairs(ssr_obfs_list) do o:value(t) end
63 | o:depends({ [_n("custom")] = false })
64 |
65 | o = s:option(Value, _n("obfs_param"), translate("Obfs_param"))
66 | o:depends({ [_n("custom")] = false })
67 |
68 | o = s:option(Value, _n("timeout"), translate("Connection Timeout"))
69 | o.datatype = "uinteger"
70 | o.default = 300
71 | o:depends({ [_n("custom")] = false })
72 |
73 | o = s:option(Flag, _n("tcp_fast_open"), "TCP " .. translate("Fast Open"))
74 | o.default = "0"
75 | o:depends({ [_n("custom")] = false })
76 |
77 | o = s:option(TextValue, _n("custom_config"), translate("Custom Config"))
78 | o.rows = 10
79 | o.wrap = "off"
80 | o:depends({ [_n("custom")] = true })
81 | o.validate = function(self, value, t)
82 | if value and api.jsonc.parse(value) then
83 | return value
84 | else
85 | return nil, translate("Must be JSON text!")
86 | end
87 | end
88 | o.custom_cfgvalue = function(self, section, value)
89 | local config_str = m:get(section, "config_str")
90 | if config_str then
91 | return api.base64Decode(config_str)
92 | end
93 | end
94 | o.custom_write = function(self, section, value)
95 | m:set(section, "config_str", api.base64Encode(value))
96 | end
97 |
98 | o = s:option(Flag, _n("udp_forward"), translate("UDP Forward"))
99 | o.default = "1"
100 | o.rmempty = false
101 |
102 | o = s:option(Flag, _n("log"), translate("Log"))
103 | o.default = "1"
104 | o.rmempty = false
105 |
106 | api.luci_types(arg[1], m, s, type_name, option_prefix)
107 |
--------------------------------------------------------------------------------
/luci-app-passwall2/luasrc/model/cbi/passwall2/server/user.lua:
--------------------------------------------------------------------------------
1 | local api = require "luci.passwall2.api"
2 | local fs = require "nixio.fs"
3 | local types_dir = "/usr/lib/lua/luci/model/cbi/passwall2/server/type/"
4 |
5 | m = Map("passwall2_server", translate("Server Config"))
6 | m.redirect = api.url("server")
7 | api.set_apply_on_parse(m)
8 |
9 | s = m:section(NamedSection, arg[1], "user", "")
10 | s.addremove = false
11 | s.dynamic = false
12 |
13 | o = s:option(Flag, "enable", translate("Enable"))
14 | o.default = "1"
15 | o.rmempty = false
16 |
17 | o = s:option(Value, "remarks", translate("Remarks"))
18 | o.default = translate("Remarks")
19 | o.rmempty = false
20 |
21 | o = s:option(ListValue, "type", translate("Type"))
22 |
23 | local type_table = {}
24 | for filename in fs.dir(types_dir) do
25 | table.insert(type_table, filename)
26 | end
27 | table.sort(type_table)
28 |
29 | for index, value in ipairs(type_table) do
30 | local p_func = loadfile(types_dir .. value)
31 | setfenv(p_func, getfenv(1))(m, s)
32 | end
33 |
34 | return m
35 |
--------------------------------------------------------------------------------
/luci-app-passwall2/luasrc/passwall2/com.lua:
--------------------------------------------------------------------------------
1 | local _M = {}
2 |
3 | local function gh_release_url(self)
4 | return "https://api.github.com/repos/" .. self.repo .. "/releases/latest"
5 | end
6 |
7 | local function gh_pre_release_url(self)
8 | return "https://api.github.com/repos/" .. self.repo .. "/releases?per_page=1"
9 | end
10 |
11 | _M.hysteria = {
12 | name = "Hysteria",
13 | repo = "HyNetwork/hysteria",
14 | get_url = gh_release_url,
15 | cmd_version = "version | awk '/^Version:/ {print $2}'",
16 | remote_version_str_replace = "app/",
17 | zipped = false,
18 | default_path = "/usr/bin/hysteria",
19 | match_fmt_str = "linux%%-%s$",
20 | file_tree = {
21 | armv6 = "arm",
22 | armv7 = "arm"
23 | }
24 | }
25 |
26 | _M["sing-box"] = {
27 | name = "Sing-Box",
28 | repo = "SagerNet/sing-box",
29 | get_url = gh_release_url,
30 | cmd_version = "version | awk '{print $3}' | sed -n 1P",
31 | zipped = true,
32 | zipped_suffix = "tar.gz",
33 | default_path = "/usr/bin/sing-box",
34 | match_fmt_str = "linux%%-%s",
35 | file_tree = {
36 | x86_64 = "amd64",
37 | mips64el = "mips64le"
38 | }
39 | }
40 |
41 | _M.xray = {
42 | name = "Xray",
43 | repo = "XTLS/Xray-core",
44 | get_url = gh_pre_release_url,
45 | cmd_version = "version | awk '{print $2}' | sed -n 1P",
46 | zipped = true,
47 | default_path = "/usr/bin/xray",
48 | match_fmt_str = "linux%%-%s",
49 | file_tree = {
50 | x86_64 = "64",
51 | x86 = "32",
52 | mips = "mips32",
53 | mipsel = "mips32le",
54 | mips64el = "mips64le"
55 | }
56 | }
57 |
58 | return _M
59 |
--------------------------------------------------------------------------------
/luci-app-passwall2/luasrc/passwall2/server_app.lua:
--------------------------------------------------------------------------------
1 | #!/usr/bin/lua
2 |
3 | local action = arg[1]
4 | local api = require "luci.passwall2.api"
5 | local sys = api.sys
6 | local uci = api.uci
7 | local jsonc = api.jsonc
8 |
9 | local CONFIG = "passwall2_server"
10 | local CONFIG_PATH = "/tmp/etc/" .. CONFIG
11 | local NFT_INCLUDE_FILE = CONFIG_PATH .. "/" .. CONFIG .. ".nft"
12 | local LOG_APP_FILE = "/tmp/log/" .. CONFIG .. ".log"
13 | local TMP_BIN_PATH = CONFIG_PATH .. "/bin"
14 | local require_dir = "luci.passwall2."
15 |
16 | local ipt_bin = sys.exec("echo -n $(/usr/share/passwall2/iptables.sh get_ipt_bin)")
17 | local ip6t_bin = sys.exec("echo -n $(/usr/share/passwall2/iptables.sh get_ip6t_bin)")
18 |
19 | local nft_flag = api.is_finded("fw4") and "1" or "0"
20 |
21 | local function log(...)
22 | local f, err = io.open(LOG_APP_FILE, "a")
23 | if f and err == nil then
24 | local str = os.date("%Y-%m-%d %H:%M:%S: ") .. table.concat({...}, " ")
25 | f:write(str .. "\n")
26 | f:close()
27 | end
28 | end
29 |
30 | local function cmd(cmd)
31 | sys.call(cmd)
32 | end
33 |
34 | local function ipt(arg)
35 | if ipt_bin and #ipt_bin > 0 then
36 | cmd(ipt_bin .. " -w " .. arg)
37 | end
38 | end
39 |
40 | local function ip6t(arg)
41 | if ip6t_bin and #ip6t_bin > 0 then
42 | cmd(ip6t_bin .. " -w " .. arg)
43 | end
44 | end
45 |
46 | local function ln_run(s, d, command, output)
47 | if not output then
48 | output = "/dev/null"
49 | end
50 | d = TMP_BIN_PATH .. "/" .. d
51 | cmd(string.format('[ ! -f "%s" ] && ln -s %s %s 2>/dev/null', d, s, d))
52 | return string.format("%s >%s 2>&1 &", d .. " " ..command, output)
53 | end
54 |
55 | local function gen_include()
56 | cmd(string.format("echo '#!/bin/sh' > /tmp/etc/%s.include", CONFIG))
57 | local function extract_rules(n, a)
58 | local _ipt = ipt_bin
59 | if n == "6" then
60 | _ipt = ip6t_bin
61 | end
62 | local result = "*" .. a
63 | result = result .. "\n" .. sys.exec(_ipt .. '-save -t ' .. a .. ' | grep "PSW2-SERVER" | sed -e "s/^-A \\(INPUT\\)/-I \\1 1/"')
64 | result = result .. "COMMIT"
65 | return result
66 | end
67 | local f, err = io.open("/tmp/etc/" .. CONFIG .. ".include", "a")
68 | if f and err == nil then
69 | if nft_flag == "0" then
70 | f:write(ipt_bin .. '-save -c | grep -v "PSW2-SERVER" | ' .. ipt_bin .. '-restore -c' .. "\n")
71 | f:write(ipt_bin .. '-restore -n <<-EOT' .. "\n")
72 | f:write(extract_rules("4", "filter") .. "\n")
73 | f:write("EOT" .. "\n")
74 | f:write(ip6t_bin .. '-save -c | grep -v "PSW2-SERVER" | ' .. ip6t_bin .. '-restore -c' .. "\n")
75 | f:write(ip6t_bin .. '-restore -n <<-EOT' .. "\n")
76 | f:write(extract_rules("6", "filter") .. "\n")
77 | f:write("EOT" .. "\n")
78 | f:close()
79 | else
80 | f:write("nft -f " .. NFT_INCLUDE_FILE .. "\n")
81 | f:close()
82 | end
83 | end
84 | end
85 |
86 | local function start()
87 | local enabled = tonumber(uci:get(CONFIG, "@global[0]", "enable") or 0)
88 | if enabled == nil or enabled == 0 then
89 | return
90 | end
91 | cmd(string.format("mkdir -p %s %s", CONFIG_PATH, TMP_BIN_PATH))
92 | cmd(string.format("touch %s", LOG_APP_FILE))
93 | if nft_flag == "0" then
94 | ipt("-N PSW2-SERVER")
95 | ipt("-I INPUT -j PSW2-SERVER")
96 | ip6t("-N PSW2-SERVER")
97 | ip6t("-I INPUT -j PSW2-SERVER")
98 | else
99 | nft_file, err = io.open(NFT_INCLUDE_FILE, "w")
100 | nft_file:write('#!/usr/sbin/nft -f\n')
101 | nft_file:write('add chain inet fw4 PSW2-SERVER\n')
102 | nft_file:write('flush chain inet fw4 PSW2-SERVER\n')
103 | nft_file:write('insert rule inet fw4 input position 0 jump PSW2-SERVER comment "PSW2-SERVER"\n')
104 | end
105 | uci:foreach(CONFIG, "user", function(user)
106 | local id = user[".name"]
107 | local enable = user.enable
108 | if enable and tonumber(enable) == 1 then
109 | local enable_log = user.log
110 | local log_path = nil
111 | if enable_log and enable_log == "1" then
112 | log_path = CONFIG_PATH .. "/" .. id .. ".log"
113 | else
114 | log_path = nil
115 | end
116 | local remarks = user.remarks
117 | local port = tonumber(user.port)
118 | local bin
119 | local config = {}
120 | local config_file = CONFIG_PATH .. "/" .. id .. ".json"
121 | local udp_forward = 1
122 | local type = user.type or ""
123 | if type == "SS" or type == "SSR" then
124 | if user.custom == "1" and user.config_str then
125 | config = jsonc.parse(api.base64Decode(user.config_str))
126 | else
127 | config = require(require_dir .. "util_shadowsocks").gen_config_server(user)
128 | end
129 | local udp_param = ""
130 | udp_forward = tonumber(user.udp_forward) or 1
131 | if udp_forward == 1 then
132 | udp_param = "-u"
133 | end
134 | type = type:lower()
135 | bin = ln_run("/usr/bin/" .. type .. "-server", type .. "-server", "-c " .. config_file .. " " .. udp_param, log_path)
136 | elseif type == "SS-Rust" then
137 | if user.custom == "1" and user.config_str then
138 | config = jsonc.parse(api.base64Decode(user.config_str))
139 | else
140 | config = require(require_dir .. "util_shadowsocks").gen_config_server(user)
141 | end
142 | bin = ln_run("/usr/bin/ssserver", "ssserver", "-c " .. config_file, log_path)
143 | elseif type == "Xray" then
144 | if user.custom == "1" and user.config_str then
145 | config = jsonc.parse(api.base64Decode(user.config_str))
146 | if log_path then
147 | if not config.log then
148 | config.log = {}
149 | end
150 | config.log.loglevel = user.loglevel
151 | end
152 | else
153 | config = require(require_dir .. "util_xray").gen_config_server(user)
154 | end
155 | bin = ln_run(api.get_app_path("xray"), "xray", "run -c " .. config_file, log_path)
156 | elseif type == "sing-box" then
157 | if user.custom == "1" and user.config_str then
158 | config = jsonc.parse(api.base64Decode(user.config_str))
159 | if log_path then
160 | if not config.log then
161 | config.log = {}
162 | end
163 | config.log.timestamp = true
164 | config.log.disabled = false
165 | config.log.level = user.loglevel
166 | config.log.output = log_path
167 | end
168 | else
169 | config = require(require_dir .. "util_sing-box").gen_config_server(user)
170 | end
171 | bin = ln_run(api.get_app_path("sing-box"), "sing-box", "run -c " .. config_file, log_path)
172 | elseif type == "Hysteria2" then
173 | if user.custom == "1" and user.config_str then
174 | config = jsonc.parse(api.base64Decode(user.config_str))
175 | else
176 | config = require(require_dir .. "util_hysteria2").gen_config_server(user)
177 | end
178 | bin = ln_run(api.get_app_path("hysteria"), "hysteria", "-c " .. config_file .. " server", log_path)
179 | end
180 |
181 | if next(config) then
182 | local f, err = io.open(config_file, "w")
183 | if f and err == nil then
184 | f:write(jsonc.stringify(config, 1))
185 | f:close()
186 | end
187 | log(string.format("%s 生成配置文件并运行 - %s", remarks, config_file))
188 | end
189 |
190 | if bin then
191 | cmd(bin)
192 | end
193 |
194 | local bind_local = user.bind_local or 0
195 | if bind_local and tonumber(bind_local) ~= 1 and port then
196 | if nft_flag == "0" then
197 | ipt(string.format('-A PSW2-SERVER -p tcp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks))
198 | ip6t(string.format('-A PSW2-SERVER -p tcp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks))
199 | if udp_forward == 1 then
200 | ipt(string.format('-A PSW2-SERVER -p udp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks))
201 | ip6t(string.format('-A PSW2-SERVER -p udp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks))
202 | end
203 | else
204 | nft_file:write(string.format('add rule inet fw4 PSW2-SERVER meta l4proto tcp tcp dport {%s} counter accept comment "%s"\n', port, remarks))
205 | if udp_forward == 1 then
206 | nft_file:write(string.format('add rule inet fw4 PSW2-SERVER meta l4proto udp udp dport {%s} counter accept comment "%s"\n', port, remarks))
207 | end
208 | end
209 | end
210 | end
211 | end)
212 | if nft_flag == "1" then
213 | nft_file:write("add rule inet fw4 PSW2-SERVER return\n")
214 | nft_file:close()
215 | cmd("nft -f " .. NFT_INCLUDE_FILE)
216 | end
217 | gen_include()
218 | end
219 |
220 | local function stop()
221 | cmd(string.format("/bin/busybox top -bn1 | grep -v 'grep' | grep '%s/' | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1", CONFIG_PATH))
222 | if nft_flag == "0" then
223 | ipt("-D INPUT -j PSW2-SERVER 2>/dev/null")
224 | ipt("-F PSW2-SERVER 2>/dev/null")
225 | ipt("-X PSW2-SERVER 2>/dev/null")
226 | ip6t("-D INPUT -j PSW2-SERVER 2>/dev/null")
227 | ip6t("-F PSW2-SERVER 2>/dev/null")
228 | ip6t("-X PSW2-SERVER 2>/dev/null")
229 | else
230 | local nft_cmd = "handles=$(nft -a list chain inet fw4 input | grep -E \"PSW2-SERVER\" | awk -F '# handle ' '{print$2}')\n for handle in $handles; do\n nft delete rule inet fw4 input handle ${handle} 2>/dev/null\n done"
231 | cmd(nft_cmd)
232 | cmd("nft flush chain inet fw4 PSW2-SERVER 2>/dev/null")
233 | cmd("nft delete chain inet fw4 PSW2-SERVER 2>/dev/null")
234 | end
235 | cmd(string.format("rm -rf %s %s /tmp/etc/%s.include", CONFIG_PATH, LOG_APP_FILE, CONFIG))
236 | end
237 |
238 | if action then
239 | if action == "start" then
240 | start()
241 | elseif action == "stop" then
242 | stop()
243 | end
244 | end
245 |
--------------------------------------------------------------------------------
/luci-app-passwall2/luasrc/passwall2/util_hysteria2.lua:
--------------------------------------------------------------------------------
1 | module("luci.passwall2.util_hysteria2", package.seeall)
2 | local api = require "luci.passwall2.api"
3 | local uci = api.uci
4 | local jsonc = api.jsonc
5 |
6 | function gen_config_server(node)
7 | local config = {
8 | listen = ":" .. node.port,
9 | tls = {
10 | cert = node.tls_certificateFile,
11 | key = node.tls_keyFile,
12 | },
13 | obfs = (node.hysteria2_obfs) and {
14 | type = "salamander",
15 | salamander = {
16 | password = node.hysteria2_obfs
17 | }
18 | } or nil,
19 | auth = {
20 | type = "password",
21 | password = node.hysteria2_auth_password
22 | },
23 | bandwidth = (node.hysteria2_up_mbps or node.hysteria2_down_mbps) and {
24 | up = node.hysteria2_up_mbps and node.hysteria2_up_mbps .. " mbps" or nil,
25 | down = node.hysteria2_down_mbps and node.hysteria2_down_mbps .. " mbps" or nil
26 | } or nil,
27 | ignoreClientBandwidth = (node.hysteria2_ignoreClientBandwidth == "1") and true or false,
28 | disableUDP = (node.hysteria2_udp == "0") and true or false,
29 | }
30 | return config
31 | end
32 |
33 | function gen_config(var)
34 | local node_id = var["-node"]
35 | if not node_id then
36 | print("-node 不能为空")
37 | return
38 | end
39 | local node = uci:get_all("passwall2", node_id)
40 | local local_socks_address = var["-local_socks_address"] or "0.0.0.0"
41 | local local_socks_port = var["-local_socks_port"]
42 | local local_socks_username = var["-local_socks_username"]
43 | local local_socks_password = var["-local_socks_password"]
44 | local local_http_address = var["-local_http_address"] or "0.0.0.0"
45 | local local_http_port = var["-local_http_port"]
46 | local local_http_username = var["-local_http_username"]
47 | local local_http_password = var["-local_http_password"]
48 | local server_host = var["-server_host"] or node.address
49 | local server_port = var["-server_port"] or node.port
50 |
51 | if api.is_ipv6(server_host) then
52 | server_host = api.get_ipv6_full(server_host)
53 | end
54 | local server = server_host .. ":" .. server_port
55 |
56 | if (node.hysteria2_hop) then
57 | server = server .. "," .. string.gsub(node.hysteria2_hop, ":", "-")
58 | end
59 |
60 | local config = {
61 | server = server,
62 | transport = {
63 | type = node.protocol or "udp",
64 | udp = {
65 | hopInterval = (function()
66 | local HopIntervalStr = tostring(node.hysteria2_hop_interval or "30s")
67 | local HopInterval = tonumber(HopIntervalStr:match("^%d+"))
68 | if HopInterval and HopInterval >= 5 then
69 | return tostring(HopInterval) .. "s"
70 | end
71 | return "30s"
72 | end)(),
73 | }
74 | },
75 | obfs = (node.hysteria2_obfs) and {
76 | type = "salamander",
77 | salamander = {
78 | password = node.hysteria2_obfs
79 | }
80 | } or nil,
81 | auth = node.hysteria2_auth_password,
82 | tls = {
83 | sni = node.tls_serverName,
84 | insecure = (node.tls_allowInsecure == "1") and true or false,
85 | pinSHA256 = (node.hysteria2_tls_pinSHA256) and node.hysteria2_tls_pinSHA256 or nil,
86 | },
87 | quic = {
88 | initStreamReceiveWindow = (node.hysteria2_recv_window) and tonumber(node.hysteria2_recv_window) or nil,
89 | initConnReceiveWindow = (node.hysteria2_recv_window_conn) and tonumber(node.hysteria2_recv_window_conn) or nil,
90 | maxIdleTimeout = (function()
91 | local timeoutStr = tostring(node.hysteria2_idle_timeout or "")
92 | local timeout = tonumber(timeoutStr:match("^%d+"))
93 | if timeout and timeout >= 4 and timeout <= 120 then
94 | return tostring(timeout) .. "s"
95 | end
96 | return nil
97 | end)(),
98 | disablePathMTUDiscovery = (node.hysteria2_disable_mtu_discovery) and true or false,
99 | },
100 | bandwidth = (node.hysteria2_up_mbps or node.hysteria2_down_mbps) and {
101 | up = node.hysteria2_up_mbps and node.hysteria2_up_mbps .. " mbps" or nil,
102 | down = node.hysteria2_down_mbps and node.hysteria2_down_mbps .. " mbps" or nil
103 | } or nil,
104 | fast_open = (node.fast_open == "1") and true or false,
105 | lazy = (node.hysteria2_lazy_start == "1") and true or false,
106 | socks5 = (local_socks_address and local_socks_port) and {
107 | listen = local_socks_address .. ":" .. local_socks_port,
108 | username = (local_socks_username and local_socks_password) and local_socks_username or nil,
109 | password = (local_socks_username and local_socks_password) and local_socks_password or nil,
110 | disableUDP = false,
111 | } or nil,
112 | http = (local_http_address and local_http_port) and {
113 | listen = local_http_address .. ":" .. local_http_port,
114 | username = (local_http_username and local_http_password) and local_http_username or nil,
115 | password = (local_http_username and local_http_password) and local_http_password or nil,
116 | } or nil
117 | }
118 |
119 | return jsonc.stringify(config, 1)
120 | end
121 |
122 | _G.gen_config = gen_config
123 |
124 | if arg[1] then
125 | local func =_G[arg[1]]
126 | if func then
127 | print(func(api.get_function_args(arg)))
128 | end
129 | end
130 |
--------------------------------------------------------------------------------
/luci-app-passwall2/luasrc/passwall2/util_naiveproxy.lua:
--------------------------------------------------------------------------------
1 | module("luci.passwall2.util_navieproxy", package.seeall)
2 | local api = require "luci.passwall2.api"
3 | local uci = api.uci
4 | local jsonc = api.jsonc
5 |
6 | function gen_config(var)
7 | local node_id = var["-node"]
8 | if not node_id then
9 | print("-node 不能为空")
10 | return
11 | end
12 | local node = uci:get_all("passwall2", node_id)
13 | local run_type = var["-run_type"]
14 | local local_addr = var["-local_addr"]
15 | local local_port = var["-local_port"]
16 | local server_host = var["-server_host"] or node.address
17 | local server_port = var["-server_port"] or node.port
18 |
19 | if api.is_ipv6(server_host) then
20 | server_host = api.get_ipv6_full(server_host)
21 | end
22 | local server = server_host .. ":" .. server_port
23 |
24 | local config = {
25 | listen = run_type .. "://" .. local_addr .. ":" .. local_port,
26 | proxy = node.protocol .. "://" .. node.username .. ":" .. node.password .. "@" .. server
27 | }
28 |
29 | return jsonc.stringify(config, 1)
30 | end
31 |
32 | _G.gen_config = gen_config
33 |
34 | if arg[1] then
35 | local func =_G[arg[1]]
36 | if func then
37 | print(func(api.get_function_args(arg)))
38 | end
39 | end
40 |
--------------------------------------------------------------------------------
/luci-app-passwall2/luasrc/passwall2/util_shadowsocks.lua:
--------------------------------------------------------------------------------
1 | module("luci.passwall2.util_shadowsocks", package.seeall)
2 | local api = require "luci.passwall2.api"
3 | local uci = api.uci
4 | local jsonc = api.jsonc
5 |
6 | function gen_config_server(node)
7 | local config = {}
8 | config.server_port = tonumber(node.port)
9 | config.password = node.password
10 | config.timeout = tonumber(node.timeout)
11 | config.fast_open = (node.tcp_fast_open and node.tcp_fast_open == "1") and true or false
12 | config.method = node.method
13 |
14 | if node.type == "SS-Rust" then
15 | config.server = "::"
16 | config.mode = "tcp_and_udp"
17 | else
18 | config.server = {"[::0]", "0.0.0.0"}
19 | end
20 |
21 | if node.type == "SSR" then
22 | config.protocol = node.protocol
23 | config.protocol_param = node.protocol_param
24 | config.obfs = node.obfs
25 | config.obfs_param = node.obfs_param
26 | end
27 |
28 | return config
29 | end
30 |
31 |
32 | function gen_config(var)
33 | local node_id = var["-node"]
34 | if not node_id then
35 | print("-node 不能为空")
36 | return
37 | end
38 | local node = uci:get_all("passwall2", node_id)
39 | local server_host = var["-server_host"] or node.address
40 | local server_port = var["-server_port"] or node.port
41 | local local_addr = var["-local_addr"]
42 | local local_port = var["-local_port"]
43 | local mode = var["-mode"]
44 | local local_socks_address = var["-local_socks_address"] or "0.0.0.0"
45 | local local_socks_port = var["-local_socks_port"]
46 | local local_socks_username = var["-local_socks_username"]
47 | local local_socks_password = var["-local_socks_password"]
48 | local local_http_address = var["-local_http_address"] or "0.0.0.0"
49 | local local_http_port = var["-local_http_port"]
50 | local local_http_username = var["-local_http_username"]
51 | local local_http_password = var["-local_http_password"]
52 |
53 | if api.is_ipv6(server_host) then
54 | server_host = api.get_ipv6_only(server_host)
55 | end
56 | local server = server_host
57 |
58 | local config = {
59 | server = server,
60 | server_port = tonumber(server_port),
61 | local_address = local_addr,
62 | local_port = tonumber(local_port),
63 | password = node.password,
64 | method = node.method,
65 | timeout = tonumber(node.timeout),
66 | fast_open = (node.tcp_fast_open and node.tcp_fast_open == "true") and true or false,
67 | reuse_port = true
68 | }
69 |
70 | if node.type == "SS" then
71 | if node.plugin and node.plugin ~= "none" then
72 | config.plugin = node.plugin
73 | config.plugin_opts = node.plugin_opts or nil
74 | end
75 | config.mode = mode
76 | elseif node.type == "SSR" then
77 | config.protocol = node.protocol
78 | config.protocol_param = node.protocol_param
79 | config.obfs = node.obfs
80 | config.obfs_param = node.obfs_param
81 | elseif node.type == "SS-Rust" then
82 | config = {
83 | servers = {
84 | {
85 | address = server,
86 | port = tonumber(server_port),
87 | method = node.method,
88 | password = node.password,
89 | timeout = tonumber(node.timeout),
90 | plugin = (node.plugin and node.plugin ~= "none") and node.plugin or nil,
91 | plugin_opts = (node.plugin and node.plugin ~= "none") and node.plugin_opts or nil
92 | }
93 | },
94 | locals = {},
95 | fast_open = (node.tcp_fast_open and node.tcp_fast_open == "true") and true or false
96 | }
97 | if local_socks_address and local_socks_port then
98 | table.insert(config.locals, {
99 | local_address = local_socks_address,
100 | local_port = tonumber(local_socks_port),
101 | mode = "tcp_and_udp"
102 | })
103 | end
104 | if local_http_address and local_http_port then
105 | table.insert(config.locals, {
106 | protocol = "http",
107 | local_address = local_http_address,
108 | local_port = tonumber(local_http_port)
109 | })
110 | end
111 | end
112 |
113 | return jsonc.stringify(config, 1)
114 | end
115 |
116 | _G.gen_config = gen_config
117 |
118 | if arg[1] then
119 | local func =_G[arg[1]]
120 | if func then
121 | print(func(api.get_function_args(arg)))
122 | end
123 | end
124 |
--------------------------------------------------------------------------------
/luci-app-passwall2/luasrc/passwall2/util_tuic.lua:
--------------------------------------------------------------------------------
1 | module("luci.passwall2.util_tuic", package.seeall)
2 | local api = require "luci.passwall2.api"
3 | local uci = api.uci
4 | local json = api.jsonc
5 |
6 | function gen_config(var)
7 | local node_id = var["-node"]
8 | if not node_id then
9 | print("-node 不能为空")
10 | return
11 | end
12 | local node = uci:get_all("passwall2", node_id)
13 | local local_addr = var["-local_addr"]
14 | local local_port = var["-local_port"]
15 | local server_host = var["-server_host"] or node.address
16 | local server_port = var["-server_port"] or node.port
17 | local loglevel = var["-loglevel"] or "warn"
18 |
19 | local tuic= {
20 | relay = {
21 | server = server_host .. ":" .. server_port,
22 | ip = node.tuic_ip,
23 | uuid = node.uuid,
24 | password = node.tuic_password,
25 | -- certificates = node.tuic_certificate and { node.tuic_certpath } or nil,
26 | udp_relay_mode = node.tuic_udp_relay_mode,
27 | congestion_control = node.tuic_congestion_control,
28 | heartbeat = node.tuic_heartbeat .. "s",
29 | timeout = node.tuic_timeout .. "s",
30 | gc_interval = node.tuic_gc_interval .. "s",
31 | gc_lifetime = node.tuic_gc_lifetime .. "s",
32 | alpn = node.tuic_tls_alpn,
33 | disable_sni = (node.tuic_disable_sni == "1"),
34 | zero_rtt_handshake = (node.tuic_zero_rtt_handshake == "1"),
35 | send_window = tonumber(node.tuic_send_window),
36 | receive_window = tonumber(node.tuic_receive_window)
37 | },
38 | ["local"] = {
39 | server = "[::]:" .. local_port,
40 | username = node.tuic_socks_username,
41 | password = node.tuic_socks_password,
42 | dual_stack = (node.tuic_dual_stack == "1") and true or false,
43 | max_packet_size = tonumber(node.tuic_max_package_size)
44 | },
45 | log_level = loglevel
46 | }
47 | return json.stringify(tuic, 1)
48 | end
49 |
50 | _G.gen_config = gen_config
51 |
52 | if arg[1] then
53 | local func =_G[arg[1]]
54 | if func then
55 | print(func(api.get_function_args(arg)))
56 | end
57 | end
58 |
--------------------------------------------------------------------------------
/luci-app-passwall2/luasrc/view/passwall2/app_update/app_version.htm:
--------------------------------------------------------------------------------
1 | <%
2 | local api = require "luci.passwall2.api"
3 | local com = require "luci.passwall2.com"
4 | local version = {}
5 | -%>
6 |
7 |
179 |
180 |
1. <%: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.%>
36 |
2. <%: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):%>
37 |
◦ <%:For Windows systems, open Command Prompt and run the command 'ipconfig /flushdns'.%>
38 |
◦ <%:For Mac systems, open Terminal and run the command 'sudo killall -HUP mDNSResponder'.%>
39 |
◦ <%:For mobile devices, you can clear it by reconnecting to the network, such as toggling Airplane Mode and reconnecting to WiFi.%>
40 |
41 |
42 |
3. <%: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.%>