client-config.lua 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394
  1. -- Copyright (C) 2017 yushi studio <[email protected]> github.com/ywb94
  2. -- Licensed to the public under the GNU General Public License v3.
  3. require "nixio.fs"
  4. require "luci.sys"
  5. require "luci.http"
  6. require "luci.jsonc"
  7. require "luci.model.uci"
  8. local uci = require "luci.model.uci".cursor()
  9. local m, s, o
  10. local sid = arg[1]
  11. local uuid = luci.sys.exec("cat /proc/sys/kernel/random/uuid")
  12. -- 确保正确判断程序是否存在
  13. local function is_finded(e)
  14. return luci.sys.exec(string.format('type -t -p "%s" 2>/dev/null', e)) ~= ""
  15. end
  16. local function is_installed(e)
  17. return luci.model.ipkg.installed(e)
  18. end
  19. local function showMsg_Redirect(redirectUrl, delay)
  20. local redirectUrl = redirectUrl or ""
  21. local delay = delay or 3000
  22. luci.http.write([[
  23. <script type="text/javascript">
  24. document.addEventListener('DOMContentLoaded', function() {
  25. setTimeout(function() {
  26. if ("]] .. redirectUrl .. [[" !== "") {
  27. window.location.href = "]] .. redirectUrl .. [[";
  28. }
  29. }, ]] .. delay .. [[);
  30. });
  31. </script>
  32. ]])
  33. end
  34. local has_ss_rust = is_finded("sslocal") or is_finded("ssserver")
  35. local has_ss_libev = is_finded("ss-redir") or is_finded("ss-local")
  36. -- 读取当前存储的 ss_type
  37. local ss_type = uci:get_first("shadowsocksr", "server_subscribe", "ss_type")
  38. local server_table = {}
  39. local encrypt_methods = {
  40. -- ssr
  41. "none",
  42. "table",
  43. "rc4",
  44. "rc4-md5-6",
  45. "rc4-md5",
  46. "aes-128-cfb",
  47. "aes-192-cfb",
  48. "aes-256-cfb",
  49. "aes-128-ctr",
  50. "aes-192-ctr",
  51. "aes-256-ctr",
  52. "bf-cfb",
  53. "camellia-128-cfb",
  54. "camellia-192-cfb",
  55. "camellia-256-cfb",
  56. "cast5-cfb",
  57. "des-cfb",
  58. "idea-cfb",
  59. "rc2-cfb",
  60. "seed-cfb",
  61. "salsa20",
  62. "chacha20",
  63. "chacha20-ietf"
  64. }
  65. local encrypt_methods_ss = {
  66. -- plain
  67. "none",
  68. "plain",
  69. -- aead
  70. "aes-128-gcm",
  71. "aes-192-gcm",
  72. "aes-256-gcm",
  73. "chacha20-ietf-poly1305",
  74. "xchacha20-ietf-poly1305",
  75. -- aead 2022
  76. "2022-blake3-aes-128-gcm",
  77. "2022-blake3-aes-256-gcm",
  78. "2022-blake3-chacha20-poly1305"
  79. --[[ stream
  80. "none",
  81. "plain",
  82. "table",
  83. "rc4",
  84. "rc4-md5",
  85. "aes-128-cfb",
  86. "aes-192-cfb",
  87. "aes-256-cfb",
  88. "aes-128-ctr",
  89. "aes-192-ctr",
  90. "aes-256-ctr",
  91. "bf-cfb",
  92. "camellia-128-cfb",
  93. "camellia-192-cfb",
  94. "camellia-256-cfb",
  95. "salsa20",
  96. "chacha20",
  97. "chacha20-ietf" ]]--
  98. }
  99. local protocol = {
  100. -- ssr
  101. "origin",
  102. "verify_deflate",
  103. "auth_sha1_v4",
  104. "auth_aes128_sha1",
  105. "auth_aes128_md5",
  106. "auth_chain_a",
  107. "auth_chain_b",
  108. "auth_chain_c",
  109. "auth_chain_d",
  110. "auth_chain_e",
  111. "auth_chain_f"
  112. }
  113. local obfs = {
  114. -- ssr
  115. "plain",
  116. "http_simple",
  117. "http_post",
  118. "random_head",
  119. "tls1.2_ticket_auth"
  120. }
  121. local securitys = {
  122. -- vmess
  123. "auto",
  124. "none",
  125. "zero",
  126. "aes-128-gcm",
  127. "chacha20-poly1305"
  128. }
  129. local tls_flows = {
  130. -- tls
  131. "xtls-rprx-vision",
  132. "xtls-rprx-vision-udp443",
  133. "none"
  134. }
  135. m = Map("shadowsocksr", translate("Edit ShadowSocksR Server"))
  136. m.redirect = luci.dispatcher.build_url("admin/services/shadowsocksr/servers")
  137. if m.uci:get("shadowsocksr", sid) ~= "servers" then
  138. luci.http.redirect(m.redirect)
  139. return
  140. end
  141. -- 保存&应用成功后跳转到节点列表
  142. m.apply_on_parse = true
  143. m.on_after_apply = function(self)
  144. showMsg_Redirect(self.redirect, 4500)
  145. end
  146. -- [[ Servers Setting ]]--
  147. s = m:section(NamedSection, sid, "servers")
  148. s.anonymous = true
  149. s.addremove = false
  150. o = s:option(DummyValue, "ssr_url", "SS/SSR/V2RAY/TROJAN/HYSTERIA2 URL")
  151. o.rawhtml = true
  152. o.template = "shadowsocksr/ssrurl"
  153. o.value = sid
  154. o = s:option(ListValue, "type", translate("Server Node Type"))
  155. if is_finded("xray") or is_finded("v2ray") then
  156. o:value("v2ray", translate("V2Ray/XRay"))
  157. end
  158. if is_finded("ssr-redir") then
  159. o:value("ssr", translate("ShadowsocksR"))
  160. end
  161. if has_ss_rust or has_ss_libev then
  162. o:value("ss", translate("ShadowSocks"))
  163. end
  164. if is_finded("trojan") then
  165. o:value("trojan", translate("Trojan"))
  166. end
  167. if is_finded("naive") then
  168. o:value("naiveproxy", translate("NaiveProxy"))
  169. end
  170. if is_finded("hysteria") then
  171. o:value("hysteria2", translate("Hysteria2"))
  172. end
  173. if is_finded("tuic-client") then
  174. o:value("tuic", translate("TUIC"))
  175. end
  176. if is_finded("shadow-tls") and is_finded("sslocal") then
  177. o:value("shadowtls", translate("Shadow-TLS"))
  178. end
  179. if is_finded("ipt2socks") then
  180. o:value("socks5", translate("Socks5"))
  181. end
  182. if is_finded("redsocks2") then
  183. o:value("tun", translate("Network Tunnel"))
  184. end
  185. o.description = translate("Using incorrect encryption mothod may causes service fail to start")
  186. o = s:option(Value, "alias", translate("Alias(optional)"))
  187. o = s:option(ListValue, "iface", translate("Network interface to use"))
  188. for _, e in ipairs(luci.sys.net.devices()) do
  189. if e ~= "lo" then
  190. o:value(e)
  191. end
  192. end
  193. o:depends("type", "tun")
  194. o.description = translate("Redirect traffic to this network interface")
  195. -- 新增一个选择框,用于选择 Shadowsocks 版本
  196. o = s:option(ListValue, "has_ss_type", string.format("<b><span style='color:red;'>%s</span></b>", translate("ShadowSocks Node Use Version")))
  197. o.description = translate("Selection ShadowSocks Node Use Version.")
  198. -- 设置默认 Shadowsocks 版本
  199. -- 动态添加选项
  200. if has_ss_rust then
  201. o:value("ss-rust", translate("ShadowSocks-rust Version"))
  202. end
  203. if has_ss_libev then
  204. o:value("ss-libev", translate("ShadowSocks-libev Version"))
  205. end
  206. -- 设置默认值
  207. if ss_type == "ss-rust" then
  208. o.default = "ss-rust"
  209. elseif ss_type == "ss-libev" then
  210. o.default = "ss-libev"
  211. end
  212. o:depends("type", "ss")
  213. o.write = function(self, section, value)
  214. -- 更新 Shadowsocks 节点的 has_ss_type
  215. uci:foreach("shadowsocksr", "servers", function(s)
  216. local node_type = uci:get("shadowsocksr", s[".name"], "type") -- 获取节点类型
  217. if node_type == "ss" then -- 仅修改 Shadowsocks 节点
  218. local old_value = uci:get("shadowsocksr", s[".name"], "has_ss_type")
  219. if old_value ~= value then
  220. uci:set("shadowsocksr", s[".name"], "has_ss_type", value)
  221. end
  222. end
  223. end)
  224. -- 更新 server_subscribe 的 ss_type
  225. local old_value = uci:get("shadowsocksr", "server_subscribe", "ss_type")
  226. if old_value ~= value then
  227. uci:set("shadowsocksr", "@server_subscribe[0]", "ss_type", value)
  228. end
  229. -- 更新当前 section 的 has_ss_type
  230. Value.write(self, section, value)
  231. end
  232. o = s:option(ListValue, "v2ray_protocol", translate("V2Ray/XRay protocol"))
  233. o:value("vless", translate("VLESS"))
  234. o:value("vmess", translate("VMess"))
  235. o:value("trojan", translate("Trojan"))
  236. o:value("shadowsocks", translate("ShadowSocks"))
  237. if is_finded("xray") then
  238. o:value("wireguard", translate("WireGuard"))
  239. end
  240. o:value("socks", translate("Socks"))
  241. o:value("http", translate("HTTP"))
  242. o:depends("type", "v2ray")
  243. o = s:option(Value, "server", translate("Server Address"))
  244. o.datatype = "host"
  245. o.rmempty = false
  246. o:depends("type", "ssr")
  247. o:depends("type", "ss")
  248. o:depends("type", "v2ray")
  249. o:depends("type", "trojan")
  250. o:depends("type", "naiveproxy")
  251. o:depends("type", "hysteria2")
  252. o:depends("type", "tuic")
  253. o:depends("type", "shadowtls")
  254. o:depends("type", "socks5")
  255. o = s:option(Value, "server_port", translate("Server Port"))
  256. o.datatype = "port"
  257. o.rmempty = true
  258. o:depends("type", "ssr")
  259. o:depends("type", "ss")
  260. o:depends("type", "v2ray")
  261. o:depends("type", "trojan")
  262. o:depends("type", "naiveproxy")
  263. o:depends("type", "hysteria2")
  264. o:depends("type", "tuic")
  265. o:depends("type", "shadowtls")
  266. o:depends("type", "socks5")
  267. o = s:option(Flag, "auth_enable", translate("Enable Authentication"))
  268. o.rmempty = false
  269. o.default = "0"
  270. o:depends("type", "socks5")
  271. o:depends({type = "v2ray", v2ray_protocol = "http"})
  272. o:depends({type = "v2ray", v2ray_protocol = "socks"})
  273. o = s:option(Value, "username", translate("Username"))
  274. o.rmempty = true
  275. o:depends("type", "naiveproxy")
  276. o:depends({type = "socks5", auth_enable = true})
  277. o:depends({type = "v2ray", v2ray_protocol = "http", auth_enable = true})
  278. o:depends({type = "v2ray", v2ray_protocol = "socks", auth_enable = true})
  279. o = s:option(Value, "password", translate("Password"))
  280. o.password = true
  281. o.rmempty = true
  282. o:depends("type", "ssr")
  283. o:depends("type", "ss")
  284. o:depends("type", "trojan")
  285. o:depends("type", "naiveproxy")
  286. o:depends("type", "shadowtls")
  287. o:depends({type = "socks5", auth_enable = true})
  288. o:depends({type = "v2ray", v2ray_protocol = "http", auth_enable = true})
  289. o:depends({type = "v2ray", v2ray_protocol = "socks", socks_ver = "5", auth_enable = true})
  290. o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"})
  291. o:depends({type = "v2ray", v2ray_protocol = "trojan"})
  292. o = s:option(ListValue, "encrypt_method", translate("Encrypt Method"))
  293. for _, v in ipairs(encrypt_methods) do
  294. o:value(v)
  295. end
  296. o.rmempty = true
  297. o:depends("type", "ssr")
  298. o = s:option(ListValue, "encrypt_method_ss", translate("Encrypt Method"))
  299. for _, v in ipairs(encrypt_methods_ss) do
  300. if v == "none" then
  301. o.default = "none"
  302. o:value("none", translate("none"))
  303. else
  304. o:value(v, translate(v))
  305. end
  306. end
  307. o.rmempty = true
  308. o:depends("type", "ss")
  309. o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"})
  310. o = s:option(Flag, "uot", translate("UDP over TCP"))
  311. o.description = translate("Enable the SUoT protocol, requires server support.")
  312. o.rmempty = true
  313. o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"})
  314. o.default = "0"
  315. o = s:option(Flag, "ivCheck", translate("Bloom Filter"))
  316. o.rmempty = true
  317. o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"})
  318. o.default = "1"
  319. -- [[ Enable Shadowsocks Plugin ]]--
  320. o = s:option(Flag, "enable_plugin", translate("Enable Plugin"))
  321. o.rmempty = true
  322. o:depends("type", "ss")
  323. o.default = "0"
  324. -- Shadowsocks Plugin
  325. o = s:option(ListValue, "plugin", translate("Obfs"))
  326. o:value("none", translate("None"))
  327. if is_finded("obfs-local") then
  328. o:value("obfs-local", translate("obfs-local"))
  329. end
  330. if is_finded("v2ray-plugin") then
  331. o:value("v2ray-plugin", translate("v2ray-plugin"))
  332. end
  333. if is_finded("xray-plugin") then
  334. o:value("xray-plugin", translate("xray-plugin"))
  335. end
  336. if is_finded("shadow-tls") then
  337. o:value("shadow-tls", translate("shadow-tls"))
  338. end
  339. o:value("custom", translate("Custom"))
  340. o.rmempty = true
  341. o:depends({enable_plugin = true})
  342. o = s:option(Value, "custom_plugin", translate("Custom Plugin Path"))
  343. o.placeholder = "/path/to/custom-plugin"
  344. o:depends({plugin = "custom"})
  345. o = s:option(Value, "plugin_opts", translate("Plugin Opts"))
  346. o.rmempty = true
  347. o:depends({enable_plugin = true})
  348. o = s:option(ListValue, "protocol", translate("Protocol"))
  349. for _, v in ipairs(protocol) do
  350. o:value(v)
  351. end
  352. o.rmempty = true
  353. o:depends("type", "ssr")
  354. o = s:option(Value, "protocol_param", translate("Protocol param (optional)"))
  355. o:depends("type", "ssr")
  356. o = s:option(ListValue, "obfs", translate("Obfs"))
  357. for _, v in ipairs(obfs) do
  358. o:value(v)
  359. end
  360. o.rmempty = true
  361. o:depends("type", "ssr")
  362. o = s:option(Value, "obfs_param", translate("Obfs param (optional)"))
  363. o:depends("type", "ssr")
  364. -- [[ Hysteria2 ]]--
  365. o = s:option(Value, "hy2_auth", translate("Users Authentication"))
  366. o:depends("type", "hysteria2")
  367. o.password = true
  368. o.rmempty = false
  369. o = s:option(Flag, "flag_port_hopping", translate("Enable Port Hopping"))
  370. o:depends("type", "hysteria2")
  371. o.rmempty = true
  372. o.default = "0"
  373. o = s:option(Value, "port_range", translate("Port hopping range"))
  374. o.description = translate("Format as 10000:20000 or 10000-20000 Multiple groups are separated by commas (,).")
  375. o:depends({type = "hysteria2", flag_port_hopping = true})
  376. --o.datatype = "portrange"
  377. o.rmempty = true
  378. o = s:option(Flag, "flag_transport", translate("Enable Transport Protocol Settings"))
  379. o:depends("type", "hysteria2")
  380. o.rmempty = true
  381. o.default = "0"
  382. o = s:option(ListValue, "transport_protocol", translate("Transport Protocol"))
  383. o:depends({type = "hysteria2", flag_transport = true})
  384. o:value("udp", translate("UDP"))
  385. o.default = "udp"
  386. o.rmempty = true
  387. o = s:option(Value, "hopinterval", translate("Port Hopping Interval(Unit:Second)"))
  388. o:depends({type = "hysteria2", flag_transport = true, flag_port_hopping = true})
  389. o.datatype = "uinteger"
  390. o.rmempty = true
  391. o.default = "30"
  392. o = s:option(Flag, "flag_obfs", translate("Enable Obfuscation"))
  393. o:depends("type", "hysteria2")
  394. o.rmempty = true
  395. o.default = "0"
  396. o = s:option(Flag, "lazy_mode", translate("Enable Lazy Mode"))
  397. o:depends("type", "hysteria2")
  398. o.rmempty = true
  399. o.default = "0"
  400. o = s:option(Value, "obfs_type", translate("Obfuscation Type"))
  401. o:depends({type = "hysteria2", flag_obfs = "1"})
  402. o.rmempty = true
  403. o.placeholder = "salamander"
  404. o = s:option(Value, "salamander", translate("Obfuscation Password"))
  405. o:depends({type = "hysteria2", flag_obfs = "1"})
  406. o.password = true
  407. o.rmempty = true
  408. o.placeholder = "cry_me_a_r1ver"
  409. o = s:option(Flag, "flag_quicparam", translate("Hysterir QUIC parameters"))
  410. o:depends("type", "hysteria2")
  411. o.rmempty = true
  412. o.default = "0"
  413. o = s:option(Flag, "disablepathmtudiscovery", translate("Disable QUIC path MTU discovery"))
  414. o:depends({type = "hysteria2",flag_quicparam = "1"})
  415. o.rmempty = true
  416. o.default = false
  417. --[[Hysteria2 QUIC parameters setting]]
  418. o = s:option(Value, "initstreamreceivewindow", translate("QUIC initStreamReceiveWindow"))
  419. o:depends({type = "hysteria2", flag_quicparam = "1"})
  420. o.datatype = "uinteger"
  421. o.rmempty = true
  422. o.default = "8388608"
  423. o = s:option(Value, "maxstreamseceivewindow", translate("QUIC maxStreamReceiveWindow"))
  424. o:depends({type = "hysteria2", flag_quicparam = "1"})
  425. o.datatype = "uinteger"
  426. o.rmempty = true
  427. o.default = "8388608"
  428. o = s:option(Value, "initconnreceivewindow", translate("QUIC initConnReceiveWindow"))
  429. o:depends({type = "hysteria2", flag_quicparam = "1"})
  430. o.datatype = "uinteger"
  431. o.rmempty = true
  432. o.default = "20971520"
  433. o = s:option(Value, "maxconnreceivewindow", translate("QUIC maxConnReceiveWindow"))
  434. o:depends({type = "hysteria2", flag_quicparam = "1"})
  435. o.datatype = "uinteger"
  436. o.rmempty = true
  437. o.default = "20971520"
  438. o = s:option(Value, "maxidletimeout", translate("QUIC maxIdleTimeout(Unit:second)"))
  439. o:depends({type = "hysteria2", flag_quicparam = "1"})
  440. o.rmempty = true
  441. o.datatype = "uinteger"
  442. o.default = "30"
  443. o = s:option(Value, "keepaliveperiod", translate("The keep-alive period.(Unit:second)"))
  444. o.description = translate("Default value 0 indicatesno heartbeat.")
  445. o:depends({type = "hysteria2", flag_quicparam = "1"})
  446. o:depends({type = "v2ray", v2ray_protocol = "wireguard"})
  447. o.rmempty = true
  448. o.datatype = "uinteger"
  449. o.default = "10"
  450. --[[ Shadow-TLS Options ]]
  451. o = s:option(ListValue, "shadowtls_protocol", translate("shadowTLS protocol Version"))
  452. o:depends("type", "shadowtls")
  453. o:value("v3", translate("Enable V3 protocol."))
  454. o:value("v2", translate("Enable V2 protocol."))
  455. o.default = "v3"
  456. o.rmempty = true
  457. o = s:option(Flag, "strict", translate("TLS 1.3 Strict mode"))
  458. o:depends("type", "shadowtls")
  459. o.default = "1"
  460. o.rmempty = false
  461. o = s:option(Flag, "fastopen", translate("TCP Fast Open"), translate("Enabling TCP Fast Open Requires Server Support."))
  462. o:depends("type", "shadowtls")
  463. o.default = "0"
  464. o.rmempty = false
  465. o = s:option(Flag, "disable_nodelay", translate("Disable TCP No_delay"))
  466. o:depends("type", "shadowtls")
  467. o.default = "0"
  468. o.rmempty = true
  469. o = s:option(Value, "shadowtls_sni", translate("shadow-TLS SNI"))
  470. o:depends("type", "shadowtls")
  471. o.datatype = "host"
  472. o.rmempty = true
  473. o.default = ""
  474. --[[ add a ListValue for Choose chain type,sslocal or vmess ]]
  475. o = s:option(ListValue, "chain_type", translate("Shadow-TLS ChainPoxy type"))
  476. o:depends("type", "shadowtls")
  477. if is_finded("sslocal") then
  478. o:value("sslocal", translate("ShadowSocks-rust Version"))
  479. end
  480. if is_finded("xray") or is_finded("v2ray") then
  481. o:value("vmess", translate("Vmess Protocol"))
  482. end
  483. o.default = "sslocal"
  484. o.rmempty = false
  485. o = s:option(Value, "sslocal_password",translate("Shadowsocks password"))
  486. o:depends({type = "shadowtls", chain_type = "sslocal"})
  487. o.rmempty = true
  488. o = s:option(ListValue, "sslocal_method", translate("Encrypt Method"))
  489. o:depends({type = "shadowtls", chain_type = "sslocal"})
  490. for _, v in ipairs(encrypt_methods_ss) do
  491. o:value(v)
  492. end
  493. o = s:option(Value, "vmess_uuid", translate("Vmess UUID"))
  494. o:depends({type = "shadowtls", chain_type = "vmess"})
  495. o.rmempty = false
  496. o.default = uuid
  497. o = s:option(ListValue, "vmess_method", translate("Encrypt Method"))
  498. o:depends({type = "shadowtls", chain_type = "vmess"})
  499. for _, v in ipairs(securitys) do
  500. o:value(v, v:lower())
  501. end
  502. o.rmempty = true
  503. o.default="auto"
  504. -- [[ TUIC ]]
  505. -- TuicNameId
  506. o = s:option(Value, "tuic_uuid", translate("TUIC User UUID"))
  507. o.password = true
  508. o.rmempty = true
  509. o.default = uuid
  510. o:depends("type", "tuic")
  511. --Tuic IP
  512. o = s:option(Value, "tuic_ip", translate("TUIC Server IP Address"))
  513. o.rmempty = true
  514. o.datatype = "ip4addr"
  515. o.default = ""
  516. o:depends("type", "tuic")
  517. -- Tuic Password
  518. o = s:option(Value, "tuic_passwd", translate("TUIC User Password"))
  519. o.password = true
  520. o.rmempty = true
  521. o.default = ""
  522. o:depends("type", "tuic")
  523. o = s:option(ListValue, "udp_relay_mode", translate("UDP relay mode"))
  524. o:depends("type", "tuic")
  525. o:value("native", translate("native UDP characteristics"))
  526. o:value("quic", translate("lossless UDP relay using QUIC streams"))
  527. o.default = "native"
  528. o.rmempty = true
  529. o = s:option(ListValue, "congestion_control", translate("Congestion control algorithm"))
  530. o:depends("type", "tuic")
  531. o:value("bbr", translate("BBR"))
  532. o:value("cubic", translate("CUBIC"))
  533. o:value("new_reno", translate("New Reno"))
  534. o.default = "cubic"
  535. o.rmempty = true
  536. o = s:option(Value, "heartbeat", translate("Heartbeat interval(second)"))
  537. o:depends("type", "tuic")
  538. o.datatype = "uinteger"
  539. o.default = "3"
  540. o.rmempty = true
  541. o = s:option(Value, "timeout", translate("Timeout for establishing a connection to server(second)"))
  542. o:depends("type", "tuic")
  543. o.datatype = "uinteger"
  544. o.default = "8"
  545. o.rmempty = true
  546. o = s:option(Value, "gc_interval", translate("Garbage collection interval(second)"))
  547. o:depends("type", "tuic")
  548. o.datatype = "uinteger"
  549. o.default = "3"
  550. o.rmempty = true
  551. o = s:option(Value, "gc_lifetime", translate("Garbage collection lifetime(second)"))
  552. o:depends("type", "tuic")
  553. o.datatype = "uinteger"
  554. o.default = "15"
  555. o.rmempty = true
  556. o = s:option(Value, "send_window", translate("TUIC send window"))
  557. o:depends("type", "tuic")
  558. o.datatype = "uinteger"
  559. o.default = 20971520
  560. o.rmempty = true
  561. o = s:option(Value, "receive_window", translate("TUIC receive window"))
  562. o:depends("type", "tuic")
  563. o.datatype = "uinteger"
  564. o.default = 10485760
  565. o.rmempty = true
  566. o = s:option(Flag, "disable_sni", translate("Disable SNI"))
  567. o:depends("type", "tuic")
  568. o.default = "0"
  569. o.rmempty = true
  570. o = s:option(Flag, "zero_rtt_handshake", translate("Enable 0-RTT QUIC handshake"))
  571. o:depends("type", "tuic")
  572. o.default = "0"
  573. o.rmempty = true
  574. -- Tuic settings for the local inbound socks5 server
  575. o = s:option(Flag, "tuic_dual_stack", translate("Dual-stack Listening Socket"))
  576. o.description = translate("If this option is not set, the socket behavior is platform dependent.")
  577. o:depends("type", "tuic")
  578. o.default = "0"
  579. o.rmempty = true
  580. o = s:option(Value, "tuic_max_package_size", translate("Maximum packet size the socks5 server can receive from external"))
  581. o:depends("type", "tuic")
  582. o.datatype = "uinteger"
  583. o.default = 1500
  584. o.rmempty = true
  585. -- AlterId
  586. o = s:option(Value, "alter_id", translate("AlterId"))
  587. o.datatype = "port"
  588. o.default = 16
  589. o.rmempty = true
  590. o:depends({type = "v2ray", v2ray_protocol = "vmess"})
  591. -- VmessId
  592. o = s:option(Value, "vmess_id", translate("Vmess/VLESS ID (UUID)"))
  593. o.password = true
  594. o.rmempty = true
  595. o.default = uuid
  596. o:depends({type = "v2ray", v2ray_protocol = "vmess"})
  597. o:depends({type = "v2ray", v2ray_protocol = "vless"})
  598. -- VLESS Encryption
  599. o = s:option(Value, "vless_encryption", translate("VLESS Encryption"))
  600. o.rmempty = true
  601. o.default = "none"
  602. o:depends({type = "v2ray", v2ray_protocol = "vless"})
  603. -- 加密方式
  604. o = s:option(ListValue, "security", translate("Encrypt Method"))
  605. for _, v in ipairs(securitys) do
  606. o:value(v, v:upper())
  607. end
  608. o.rmempty = true
  609. o:depends({type = "v2ray", v2ray_protocol = "vmess"})
  610. -- SOCKS Version
  611. o = s:option(ListValue, "socks_ver", translate("Socks Version"))
  612. o:value("4", "Socks4")
  613. o:value("4a", "Socks4A")
  614. o:value("5", "Socks5")
  615. o.rmempty = true
  616. o.default = "5"
  617. o:depends({type = "v2ray", v2ray_protocol = "socks"})
  618. -- 传输协议
  619. o = s:option(ListValue, "transport", translate("Transport"))
  620. o:value("raw", "RAW (TCP)")
  621. o:value("kcp", "mKCP")
  622. o:value("ws", "WebSocket")
  623. o:value("httpupgrade", "HTTPUpgrade")
  624. o:value("xhttp", "XHTTP (SplitHTTP)")
  625. o:value("h2", "HTTP/2")
  626. o:value("quic", "QUIC")
  627. o:value("grpc", "gRPC")
  628. o.rmempty = true
  629. o:depends({type = "v2ray", v2ray_protocol = "vless"})
  630. o:depends({type = "v2ray", v2ray_protocol = "vmess"})
  631. o:depends({type = "v2ray", v2ray_protocol = "trojan"})
  632. o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"})
  633. o:depends({type = "v2ray", v2ray_protocol = "socks"})
  634. o:depends({type = "v2ray", v2ray_protocol = "http"})
  635. -- [[ RAW部分 ]]--
  636. -- TCP伪装
  637. o = s:option(ListValue, "tcp_guise", translate("Camouflage Type"))
  638. o:depends("transport", "raw")
  639. o:value("none", translate("None"))
  640. o:value("http", "HTTP")
  641. o.rmempty = true
  642. -- HTTP域名
  643. o = s:option(Value, "http_host", translate("HTTP Host"))
  644. o:depends("tcp_guise", "http")
  645. o.rmempty = true
  646. -- HTTP路径
  647. o = s:option(Value, "http_path", translate("HTTP Path"))
  648. o:depends("tcp_guise", "http")
  649. o.rmempty = true
  650. -- [[ WS部分 ]]--
  651. -- WS域名
  652. o = s:option(Value, "ws_host", translate("WebSocket Host"))
  653. o:depends({transport = "ws", tls = false})
  654. o.datatype = "hostname"
  655. o.rmempty = true
  656. -- WS路径
  657. o = s:option(Value, "ws_path", translate("WebSocket Path"))
  658. o:depends("transport", "ws")
  659. o.rmempty = true
  660. if is_finded("v2ray") then
  661. -- WS前置数据
  662. o = s:option(Value, "ws_ed", translate("Max Early Data"))
  663. o:depends("ws_ed_enable", true)
  664. o.datatype = "uinteger"
  665. o:value("2048")
  666. o.rmempty = true
  667. -- WS前置数据标头
  668. o = s:option(Value, "ws_ed_header", translate("Early Data Header Name"))
  669. o:depends("ws_ed_enable", true)
  670. o:value("Sec-WebSocket-Protocol")
  671. o.rmempty = true
  672. end
  673. -- [[ httpupgrade部分 ]]--
  674. -- httpupgrade域名
  675. o = s:option(Value, "httpupgrade_host", translate("Httpupgrade Host"))
  676. o:depends({transport = "httpupgrade", tls = false})
  677. o.rmempty = true
  678. -- httpupgrade路径
  679. o = s:option(Value, "httpupgrade_path", translate("Httpupgrade Path"))
  680. o:depends("transport", "httpupgrade")
  681. o.rmempty = true
  682. -- [[ XHTTP部分 ]]--
  683. -- XHTTP 模式
  684. o = s:option(ListValue, "xhttp_mode", translate("XHTTP Mode"))
  685. o:depends("transport", "xhttp")
  686. o.default = "auto"
  687. o:value("auto")
  688. o:value("packet-up")
  689. o:value("stream-up")
  690. o:value("stream-one")
  691. -- XHTTP 主机
  692. o = s:option(Value, "xhttp_host", translate("XHTTP Host"))
  693. o.datatype = "hostname"
  694. o:depends("transport", "xhttp")
  695. o.rmempty = true
  696. -- XHTTP 路径
  697. o = s:option(Value, "xhttp_path", translate("XHTTP Path"))
  698. o.placeholder = "/"
  699. o:depends("transport", "xhttp")
  700. o.rmempty = true
  701. -- XHTTP 附加项
  702. o = s:option(Flag, "enable_xhttp_extra", translate("XHTTP Extra"))
  703. o.description = translate("Enable this option to configure XHTTP Extra (JSON format).")
  704. o.rmempty = true
  705. o.default = "0"
  706. o:depends("transport", "xhttp")
  707. o = s:option(TextValue, "xhttp_extra", " ")
  708. o.description = translate(
  709. "<font><b>" .. translate("Configure XHTTP Extra Settings (JSON format), see:") .. "</b></font>" ..
  710. " <a href='https://xtls.github.io/config/transports/splithttp.html#extra' target='_blank'>" ..
  711. "<font style='color:green'><b>" .. translate("Click to the page") .. "</b></font></a>")
  712. o:depends("enable_xhttp_extra", true)
  713. o.rmempty = true
  714. o.rows = 10
  715. o.wrap = "off"
  716. o.custom_write = function(self, section, value)
  717. m:set(section, "xhttp_extra", value)
  718. local success, data = pcall(luci.jsonc.parse, value)
  719. if success and data then
  720. local address = (data.extra and data.extra.downloadSettings and data.extra.downloadSettings.address)
  721. or (data.downloadSettings and data.downloadSettings.address)
  722. if address and address ~= "" then
  723. m:set(section, "download_address", address)
  724. else
  725. m:del(section, "download_address")
  726. end
  727. else
  728. m:del(section, "download_address")
  729. end
  730. end
  731. o.validate = function(self, value)
  732. value = value:gsub("\r\n", "\n"):gsub("^[ \t]*\n", ""):gsub("\n[ \t]*$", ""):gsub("\n[ \t]*\n", "\n")
  733. if value:sub(-1) == "\n" then
  734. value = value:sub(1, -2)
  735. end
  736. local success, data = pcall(luci.jsonc.parse, value)
  737. if not success or not data then
  738. return nil, translate("Invalid JSON format")
  739. end
  740. return value
  741. end
  742. -- XHTTP ALPN
  743. o = s:option(ListValue, "xhttp_alpn", translate("XHTTP ALPN"))
  744. o.default = ""
  745. o:value("", translate("Default"))
  746. o:value("h3")
  747. o:value("h2")
  748. o:value("h3,h2")
  749. o:value("http/1.1")
  750. o:value("h2,http/1.1")
  751. o:value("h3,h2,http/1.1")
  752. o:depends({transport = "xhttp", tls = true})
  753. -- [[ H2部分 ]]--
  754. -- H2域名
  755. o = s:option(Value, "h2_host", translate("HTTP/2 Host"))
  756. o:depends("transport", "h2")
  757. o.rmempty = true
  758. -- H2路径
  759. o = s:option(Value, "h2_path", translate("HTTP/2 Path"))
  760. o:depends("transport", "h2")
  761. o.rmempty = true
  762. -- gRPC
  763. o = s:option(Value, "serviceName", translate("gRPC Service Name"))
  764. o:depends("transport", "grpc")
  765. o.rmempty = true
  766. if is_finded("xray") then
  767. -- gPRC模式
  768. o = s:option(ListValue, "grpc_mode", translate("gRPC Mode"))
  769. o:depends("transport", "grpc")
  770. o:value("gun", translate("Gun"))
  771. o:value("multi", translate("Multi"))
  772. o.rmempty = true
  773. end
  774. if is_finded("xray") then
  775. -- gRPC初始窗口
  776. o = s:option(Value, "initial_windows_size", translate("Initial Windows Size"))
  777. o.datatype = "uinteger"
  778. o:depends("transport", "grpc")
  779. o.default = 0
  780. o.rmempty = true
  781. -- H2/gRPC健康检查
  782. o = s:option(Flag, "health_check", translate("H2/gRPC Health Check"))
  783. o:depends("transport", "h2")
  784. o:depends("transport", "grpc")
  785. o.rmempty = true
  786. o = s:option(Value, "read_idle_timeout", translate("H2 Read Idle Timeout"))
  787. o.datatype = "uinteger"
  788. o:depends({health_check = true, transport = "h2"})
  789. o.default = 60
  790. o.rmempty = true
  791. o = s:option(Value, "idle_timeout", translate("gRPC Idle Timeout"))
  792. o.datatype = "uinteger"
  793. o:depends({health_check = true, transport = "grpc"})
  794. o.default = 60
  795. o.rmempty = true
  796. o = s:option(Value, "health_check_timeout", translate("Health Check Timeout"))
  797. o.datatype = "uinteger"
  798. o:depends("health_check", 1)
  799. o.default = 20
  800. o.rmempty = true
  801. o = s:option(Flag, "permit_without_stream", translate("Permit Without Stream"))
  802. o:depends({health_check = true, transport = "grpc"})
  803. o.rmempty = true
  804. end
  805. -- [[ QUIC部分 ]]--
  806. o = s:option(ListValue, "quic_security", translate("QUIC Security"))
  807. o:depends("transport", "quic")
  808. o:value("none", translate("None"))
  809. o:value("aes-128-gcm", translate("aes-128-gcm"))
  810. o:value("chacha20-poly1305", translate("chacha20-poly1305"))
  811. o.rmempty = true
  812. o = s:option(Value, "quic_key", translate("QUIC Key"))
  813. o:depends("transport", "quic")
  814. o.rmempty = true
  815. o = s:option(ListValue, "quic_guise", translate("Header"))
  816. o:depends("transport", "quic")
  817. o.rmempty = true
  818. o:value("none", translate("None"))
  819. o:value("srtp", translate("VideoCall (SRTP)"))
  820. o:value("utp", translate("BitTorrent (uTP)"))
  821. o:value("wechat-video", translate("WechatVideo"))
  822. o:value("dtls", translate("DTLS 1.2"))
  823. o:value("wireguard", translate("WireGuard"))
  824. -- [[ mKCP部分 ]]--
  825. o = s:option(ListValue, "kcp_guise", translate("Camouflage Type"))
  826. o:depends("transport", "kcp")
  827. o:value("none", translate("None"))
  828. o:value("srtp", translate("VideoCall (SRTP)"))
  829. o:value("utp", translate("BitTorrent (uTP)"))
  830. o:value("wechat-video", translate("WechatVideo"))
  831. o:value("dtls", translate("DTLS 1.2"))
  832. o:value("wireguard", translate("WireGuard"))
  833. o.rmempty = true
  834. o = s:option(Value, "mtu", translate("MTU"))
  835. o.datatype = "uinteger"
  836. o:depends("transport", "kcp")
  837. o:depends({type = "v2ray", v2ray_protocol = "wireguard"})
  838. -- o.default = 1350
  839. o.rmempty = true
  840. o = s:option(Value, "tti", translate("TTI"))
  841. o.datatype = "uinteger"
  842. o:depends("transport", "kcp")
  843. o.default = 50
  844. o.rmempty = true
  845. o = s:option(Value, "uplink_capacity", translate("Uplink Capacity(Default:Mbps)"))
  846. o.datatype = "uinteger"
  847. o:depends("transport", "kcp")
  848. o:depends("type", "hysteria2")
  849. o.placeholder = 5
  850. o.rmempty = true
  851. o = s:option(Value, "downlink_capacity", translate("Downlink Capacity(Default:Mbps)"))
  852. o.datatype = "uinteger"
  853. o:depends("transport", "kcp")
  854. o:depends("type", "hysteria2")
  855. o.placeholder = 20
  856. o.rmempty = true
  857. o = s:option(Value, "read_buffer_size", translate("Read Buffer Size"))
  858. o.datatype = "uinteger"
  859. o:depends("transport", "kcp")
  860. o.default = 2
  861. o.rmempty = true
  862. o = s:option(Value, "write_buffer_size", translate("Write Buffer Size"))
  863. o.datatype = "uinteger"
  864. o:depends("transport", "kcp")
  865. o.default = 2
  866. o.rmempty = true
  867. o = s:option(Value, "seed", translate("Obfuscate password (optional)"))
  868. o:depends("transport", "kcp")
  869. o.rmempty = true
  870. o = s:option(Flag, "congestion", translate("Congestion"))
  871. o:depends("transport", "kcp")
  872. o.rmempty = true
  873. -- [[ WireGuard 部分 ]]--
  874. o = s:option(Flag, "kernelmode", translate("Enabled Kernel virtual NIC TUN(optional)"))
  875. o.description = translate("Virtual NIC TUN of Linux kernel can be used only when system supports and have root permission. If used, IPv6 routing table 1023 is occupied.")
  876. o:depends({type = "v2ray", v2ray_protocol = "wireguard"})
  877. o.default = "0"
  878. o.rmempty = true
  879. o = s:option(DynamicList, "local_addresses", translate("Local addresses"))
  880. o.datatype = "cidr"
  881. o:depends({type = "v2ray", v2ray_protocol = "wireguard"})
  882. o.rmempty = true
  883. o = s:option(DynamicList, "reserved", translate("Reserved bytes(optional)"))
  884. o.description = translate("Wireguard reserved bytes.")
  885. o:depends({type = "v2ray", v2ray_protocol = "wireguard"})
  886. o.rmempty = true
  887. o = s:option(Value, "private_key", translate("Private key"))
  888. o:depends({type = "v2ray", v2ray_protocol = "wireguard"})
  889. o.password = true
  890. o.rmempty = true
  891. o = s:option(Value, "peer_pubkey", translate("Peer public key"))
  892. o:depends({type = "v2ray", v2ray_protocol = "wireguard"})
  893. o.rmempty = true
  894. o = s:option(Value, "preshared_key", translate("Pre-shared key"))
  895. o:depends({type = "v2ray", v2ray_protocol = "wireguard"})
  896. o.password = true
  897. o.rmempty = true
  898. o = s:option(DynamicList, "allowedips", translate("allowedIPs(optional)"))
  899. o.description = translate("Wireguard allows only traffic from specific source IP.")
  900. o.datatype = "cidr"
  901. o:depends({type = "v2ray", v2ray_protocol = "wireguard"})
  902. o.default = "0.0.0.0/0"
  903. o.rmempty = true
  904. -- [[ TLS ]]--
  905. o = s:option(Flag, "tls", translate("TLS"))
  906. o.rmempty = true
  907. o.default = "0"
  908. o:depends({type = "v2ray", v2ray_protocol = "vless", reality = false})
  909. o:depends({type = "v2ray", v2ray_protocol = "vmess", reality = false})
  910. o:depends({type = "v2ray", v2ray_protocol = "trojan", reality = false})
  911. o:depends({type = "v2ray", v2ray_protocol = "shadowsocks", reality = false})
  912. o:depends({type = "v2ray", v2ray_protocol = "socks", socks_ver = "5", reality = false})
  913. o:depends({type = "v2ray", v2ray_protocol = "http", reality = false})
  914. o:depends("type", "trojan")
  915. o:depends("type", "hysteria2")
  916. -- [[ TLS部分 ]] --
  917. o = s:option(Flag, "tls_sessionTicket", translate("Session Ticket"))
  918. o:depends({type = "trojan", tls = true})
  919. o.default = "0"
  920. if is_finded("xray") then
  921. -- [[ REALITY ]]
  922. o = s:option(Flag, "reality", translate("REALITY"))
  923. o.rmempty = true
  924. o.default = "0"
  925. o:depends({type = "v2ray", v2ray_protocol = "vless", tls = false})
  926. o = s:option(Value, "reality_publickey", translate("Public key"))
  927. o.rmempty = true
  928. o:depends({type = "v2ray", v2ray_protocol = "vless", reality = true})
  929. o = s:option(Value, "reality_shortid", translate("Short ID"))
  930. o.rmempty = true
  931. o:depends({type = "v2ray", v2ray_protocol = "vless", reality = true})
  932. o = s:option(Value, "reality_spiderx", translate("spiderX"))
  933. o.rmempty = true
  934. o:depends({type = "v2ray", v2ray_protocol = "vless", reality = true})
  935. -- [[ XTLS ]]--
  936. o = s:option(ListValue, "tls_flow", translate("Flow"))
  937. for _, v in ipairs(tls_flows) do
  938. if v == "none" then
  939. o.default = "none"
  940. o:value("none", translate("none"))
  941. else
  942. o:value(v, translate(v))
  943. end
  944. end
  945. o.rmempty = true
  946. o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "raw", tls = true})
  947. o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "raw", reality = true})
  948. o = s:option(ListValue, "xhttp_tls_flow", translate("Flow"))
  949. for _, v in ipairs(tls_flows) do
  950. if v == "none" then
  951. o.default = "none"
  952. o:value("none", translate("none"))
  953. else
  954. o:value("xtls-rprx-vision", translate("xtls-rprx-vision"))
  955. end
  956. end
  957. o.rmempty = true
  958. o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "xhttp", tls = true})
  959. o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "xhttp", reality = true})
  960. -- [[ uTLS ]]--
  961. o = s:option(ListValue, "fingerprint", translate("Finger Print"))
  962. o.default = ""
  963. o:value("chrome", translate("chrome"))
  964. o:value("firefox", translate("firefox"))
  965. o:value("safari", translate("safari"))
  966. o:value("ios", translate("ios"))
  967. o:value("android", translate("android"))
  968. o:value("edge", translate("edge"))
  969. o:value("360", translate("360"))
  970. o:value("qq", translate("qq"))
  971. o:value("random", translate("random"))
  972. o:value("randomized", translate("randomized"))
  973. o:value("", translate("disable"))
  974. o:depends({type = "v2ray", tls = true})
  975. o:depends({type = "v2ray", reality = true})
  976. o = s:option(Flag, "enable_ech", translate("Enable ECH(optional)"))
  977. o.rmempty = true
  978. o.default = "0"
  979. o:depends({type = "v2ray", tls = true})
  980. o = s:option(TextValue, "ech_config", translate("ECH Config"))
  981. o.description = translate(
  982. "<font><b>" .. translate("If it is not empty, it indicates that the Client has enabled Encrypted Client, see:") .. "</b></font>" ..
  983. " <a href='https://xtls.github.io/config/transport.html#tlsobject' target='_blank'>" ..
  984. "<font style='color:green'><b>" .. translate("Click to the page") .. "</b></font></a>")
  985. o:depends("enable_ech", true)
  986. o.default = ""
  987. o.rows = 5
  988. o.wrap = "soft"
  989. o.validate = function(self, value)
  990. -- 清理空行和多余换行
  991. return (value:gsub("[\r\n]", "")):gsub("^%s*(.-)%s*$", "%1")
  992. end
  993. o = s:option(ListValue, "ech_ForceQuery", translate("ECH Query Policy"))
  994. o.description = translate("Controls the policy used when performing DNS queries for ECH configuration.")
  995. o.default = "none"
  996. o:value("none")
  997. o:value("half")
  998. o:value("full")
  999. o:depends("enable_ech", true)
  1000. o = s:option(Flag, "enable_mldsa65verify", translate("Enable ML-DSA-65(optional)"))
  1001. o.rmempty = true
  1002. o.default = "0"
  1003. o:depends({type = "v2ray", reality = true})
  1004. o = s:option(TextValue, "reality_mldsa65verify", translate("ML-DSA-65 Public key"))
  1005. o.description = translate(
  1006. "<font><b>" .. translate("The client has not configured mldsa65Verify, but it will not perform the \"additional verification\" step and can still connect normally, see:") .. "</b></font>" ..
  1007. " <a href='https://github.com/XTLS/Xray-core/pull/4915' target='_blank'>" ..
  1008. "<font style='color:green'><b>" .. translate("Click to the page") .. "</b></font></a>")
  1009. o:depends("enable_mldsa65verify", true)
  1010. o.default = ""
  1011. o.rows = 5
  1012. o.wrap = "soft"
  1013. o.validate = function(self, value)
  1014. -- 清理空行和多余换行
  1015. return (value:gsub("[\r\n]", "")):gsub("^%s*(.-)%s*$", "%1")
  1016. end
  1017. end
  1018. o = s:option(Value, "tls_host", translate("TLS Host"))
  1019. o.datatype = "hostname"
  1020. o:depends("tls", true)
  1021. o:depends("xtls", true)
  1022. o:depends("reality", true)
  1023. o.rmempty = true
  1024. o = s:option(ListValue, "tls_alpn", translate("TLS ALPN"))
  1025. o.default = ""
  1026. o:value("", translate("Default"))
  1027. o:value("h3")
  1028. o:value("spdy/3.1")
  1029. o:value("h3,spdy/3.1")
  1030. o:depends("type", "tuic")
  1031. -- [[ allowInsecure ]]--
  1032. o = s:option(Flag, "insecure", translate("allowInsecure"))
  1033. o.rmempty = false
  1034. o:depends("tls", true)
  1035. o:depends("type", "hysteria2")
  1036. o.description = translate("If true, allowss insecure connection at TLS client, e.g., TLS server uses unverifiable certificates.")
  1037. -- [[ Hysteria2 TLS pinSHA256 ]] --
  1038. o = s:option(Value, "pinsha256", translate("Certificate fingerprint"))
  1039. o:depends({type = "hysteria2", insecure = true })
  1040. o.rmempty = true
  1041. -- [[ Mux.Cool ]] --
  1042. o = s:option(Flag, "mux", translate("Mux"), translate("Enable Mux.Cool"))
  1043. o.rmempty = false
  1044. o.default = false
  1045. o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "raw"})
  1046. o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "ws"})
  1047. o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "kcp"})
  1048. o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "httpupgrade"})
  1049. o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "splithttp"})
  1050. o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "h2"})
  1051. o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "quic"})
  1052. o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "grpc"})
  1053. o:depends({type = "v2ray", v2ray_protocol = "vmess"})
  1054. o:depends({type = "v2ray", v2ray_protocol = "trojan"})
  1055. o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"})
  1056. o:depends({type = "v2ray", v2ray_protocol = "socks"})
  1057. o:depends({type = "v2ray", v2ray_protocol = "http"})
  1058. -- [[ XUDP Mux ]] --
  1059. o = s:option(Flag, "xmux", translate("Xudp Mux"), translate("Enable Xudp Mux"))
  1060. o.rmempty = false
  1061. o.default = false
  1062. o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "xhttp"})
  1063. -- [[ TCP 最大并发连接数 ]]--
  1064. o = s:option(Value, "concurrency", translate("concurrency"))
  1065. o.description = translate(
  1066. "<ul>"
  1067. .. "<li>" .. translate("Default: disable. When entering a negative number, such as -1, The Mux module will not be used to carry TCP traffic.") .. "</li>"
  1068. .. "<li>" .. translate("Min value is 1, Max value is 128. When omitted or set to 0, it equals 8.") .. "</li>"
  1069. .. "</ul>")
  1070. o.rmempty = true
  1071. o.default = "-1"
  1072. o:value("-1", translate("disable"))
  1073. o:value("8", translate("8"))
  1074. o:depends("mux", true)
  1075. -- [[ UDP 最大并发连接数 ]]--
  1076. o = s:option(Value, "xudpConcurrency", translate("xudpConcurrency"))
  1077. o.description = translate(
  1078. "<ul>"
  1079. .. "<li>" .. translate("Default:16. When entering a negative number, such as -1, The Mux module will not be used to carry UDP traffic, Use original UDP transmission method of proxy protocol.") .. "</li>"
  1080. .. "<li>" .. translate("Min value is 1, Max value is 1024. When omitted or set to 0, Will same path as TCP traffic.") .. "</li>"
  1081. .. "</ul>")
  1082. o.rmempty = true
  1083. o.default = "16"
  1084. o:value("-1", translate("disable"))
  1085. o:value("16", translate("16"))
  1086. o:depends("mux", true)
  1087. o:depends("xmux", true)
  1088. -- [[ 对被代理的 UDP/443 流量处理方式 ]]--
  1089. o = s:option(ListValue, "xudpProxyUDP443", translate("xudpProxyUDP443"))
  1090. o.description = translate(
  1091. "<ul>"
  1092. .. "<li>" .. translate("Default reject rejects traffic.") .. "</li>"
  1093. .. "<li>" .. translate("allow: Allows use Mux connection.") .. "</li>"
  1094. .. "<li>" .. translate("skip: Not use Mux module to carry UDP 443 traffic, Use original UDP transmission method of proxy protocol.") .. "</li>"
  1095. .. "</ul>")
  1096. o.rmempty = true
  1097. o.default = "reject"
  1098. o:value("reject", translate("reject"))
  1099. o:value("allow", translate("allow"))
  1100. o:value("skip", translate("skip"))
  1101. o:depends("mux", true)
  1102. -- [[ XHTTP TCP Fast Open ]]--
  1103. o = s:option(Flag, "tcpfastopen", translate("TCP Fast Open"), translate("Enabling TCP Fast Open Requires Server Support."))
  1104. o.rmempty = true
  1105. o.default = "0"
  1106. o:depends({type = "v2ray", v2ray_protocol = "vless", transport = "xhttp"})
  1107. -- [[ MPTCP ]]--
  1108. o = s:option(Flag, "mptcp", translate("MPTCP"), translate("Enable Multipath TCP, need to be enabled in both server and client configuration."))
  1109. o.rmempty = true
  1110. o.default = "0"
  1111. o:depends({type = "v2ray", v2ray_protocol = "vless"})
  1112. o:depends({type = "v2ray", v2ray_protocol = "vmess"})
  1113. o:depends({type = "v2ray", v2ray_protocol = "trojan"})
  1114. o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"})
  1115. o:depends({type = "v2ray", v2ray_protocol = "socks"})
  1116. o:depends({type = "v2ray", v2ray_protocol = "http"})
  1117. -- [[ custom_tcpcongestion 连接服务器节点的 TCP 拥塞控制算法 ]]--
  1118. o = s:option(ListValue, "custom_tcpcongestion", translate("custom_tcpcongestion"))
  1119. o.rmempty = true
  1120. o.default = ""
  1121. o:value("", translate("comment_tcpcongestion_disable"))
  1122. o:value("bbr", translate("BBR"))
  1123. o:value("cubic", translate("CUBIC"))
  1124. o:value("reno", translate("Reno"))
  1125. o:depends({type = "v2ray", v2ray_protocol = "vless"})
  1126. o:depends({type = "v2ray", v2ray_protocol = "vmess"})
  1127. o:depends({type = "v2ray", v2ray_protocol = "trojan"})
  1128. o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"})
  1129. o:depends({type = "v2ray", v2ray_protocol = "socks"})
  1130. o:depends({type = "v2ray", v2ray_protocol = "http"})
  1131. -- [[ Cert ]]--
  1132. o = s:option(Flag, "certificate", translate("Self-signed Certificate"))
  1133. o.rmempty = true
  1134. o.default = "0"
  1135. o:depends("type", "tuic")
  1136. o:depends({type = "hysteria2", insecure = false})
  1137. o:depends({type = "trojan", tls = true, insecure = false})
  1138. o:depends({type = "v2ray", v2ray_protocol = "vmess", tls = true, insecure = false})
  1139. o:depends({type = "v2ray", v2ray_protocol = "vless", tls = true, insecure = false})
  1140. o.description = translate("If you have a self-signed certificate,please check the box")
  1141. o = s:option(DummyValue, "upload", translate("Upload"))
  1142. o.template = "shadowsocksr/certupload"
  1143. o:depends("certificate", 1)
  1144. cert_dir = "/etc/ssl/private/"
  1145. local path
  1146. luci.http.setfilehandler(function(meta, chunk, eof)
  1147. if not fd then
  1148. if (not meta) or (not meta.name) or (not meta.file) then
  1149. return
  1150. end
  1151. fd = nixio.open(cert_dir .. meta.file, "w")
  1152. if not fd then
  1153. path = translate("Create upload file error.")
  1154. return
  1155. end
  1156. end
  1157. if chunk and fd then
  1158. fd:write(chunk)
  1159. end
  1160. if eof and fd then
  1161. fd:close()
  1162. fd = nil
  1163. path = '/etc/ssl/private/' .. meta.file .. ''
  1164. end
  1165. end)
  1166. if luci.http.formvalue("upload") then
  1167. local f = luci.http.formvalue("ulfile")
  1168. if #f <= 0 then
  1169. path = translate("No specify upload file.")
  1170. end
  1171. end
  1172. o = s:option(Value, "certpath", translate("Current Certificate Path"))
  1173. o:depends("certificate", 1)
  1174. o:value("/etc/ssl/private/ca.crt")
  1175. o.description = translate("Please confirm the current certificate path")
  1176. o.default = "/etc/ssl/private/ca.crt"
  1177. o = s:option(Flag, "fast_open", translate("TCP Fast Open"), translate("Enabling TCP Fast Open Requires Server Support."))
  1178. o.rmempty = true
  1179. o.default = "0"
  1180. o:depends("type", "ssr")
  1181. o:depends("type", "ss")
  1182. o:depends("type", "trojan")
  1183. o:depends("type", "hysteria2")
  1184. o = s:option(Flag, "switch_enable", translate("Enable Auto Switch"))
  1185. o.rmempty = false
  1186. o.default = "1"
  1187. o = s:option(Value, "local_port", translate("Local Port"))
  1188. o.datatype = "port"
  1189. o.default = 1234
  1190. o.rmempty = false
  1191. if is_finded("kcptun-client") then
  1192. o = s:option(Flag, "kcp_enable", translate("KcpTun Enable"))
  1193. o.rmempty = true
  1194. o.default = "0"
  1195. o:depends("type", "ssr")
  1196. o:depends("type", "ss")
  1197. o = s:option(Value, "kcp_port", translate("KcpTun Port"))
  1198. o.datatype = "portrange"
  1199. o.default = 4000
  1200. o:depends("type", "ssr")
  1201. o:depends("type", "ss")
  1202. o = s:option(Value, "kcp_password", translate("KcpTun Password"))
  1203. o.password = true
  1204. o:depends("type", "ssr")
  1205. o:depends("type", "ss")
  1206. o = s:option(Value, "kcp_param", translate("KcpTun Param"))
  1207. o.default = "--nocomp"
  1208. o:depends("type", "ssr")
  1209. o:depends("type", "ss")
  1210. end
  1211. return m