client-config.lua 45 KB

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