client-config.lua 40 KB

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