diff --git a/luci-app-momo/Makefile b/luci-app-momo/Makefile index 5b60a71f..6f233481 100644 --- a/luci-app-momo/Makefile +++ b/luci-app-momo/Makefile @@ -1,6 +1,6 @@ include $(TOPDIR)/rules.mk -PKG_VERSION:=1.2.0 +PKG_VERSION:=1.2.1 LUCI_TITLE:=LuCI Support for momo LUCI_DEPENDS:=+luci-base +momo diff --git a/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js b/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js index 27840a3c..acc7aa32 100644 --- a/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js +++ b/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js @@ -134,6 +134,12 @@ return view.extend({ s.tab('rlimit', _('RLIMIT Config')); + o = s.taboption('rlimit', form.Value, 'rlimit_nproc_soft', _('Number of Processes Soft Limit')); + o.datatype = 'uinteger'; + + o = s.taboption('rlimit', form.Value, 'rlimit_nproc_hard', _('Number of Processes Hard Limit')); + o.datatype = 'uinteger'; + o = s.taboption('rlimit', form.Value, 'rlimit_address_space_soft', _('Address Space Size Soft Limit')); o.datatype = 'uinteger'; o.placeholder = _('Unlimited'); @@ -164,6 +170,16 @@ return view.extend({ o = s.taboption('rlimit', form.Value, 'rlimit_nofile_hard', _('Number of Open Files Hard Limit')); o.datatype = 'uinteger'; + s.tab('environment_variable', _('Environment Variable Config')); + + o = s.taboption('environment_variable', form.Value, 'env_go_max_procs', 'GOMAXPROCS'); + o.datatype = 'uinteger'; + o.placeholder = _('Unlimited'); + + o = s.taboption('environment_variable', form.Value, 'env_go_mem_limit', 'GOMEMLIMIT'); + o.datatype = 'uinteger'; + o.placeholder = _('Unlimited'); + return m.render(); } }); diff --git a/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js b/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js index 0bd81cf1..fa0b6e5d 100644 --- a/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js +++ b/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js @@ -28,6 +28,9 @@ return view.extend({ s.tab('log_config', _('Log Config')); + o = s.taboption('log_config', form.Flag, 'clear_at_stop', _('Clear At Stop')); + o.rmempty = false; + o = s.taboption('log_config', form.Flag, 'scheduled_clear', _('Scheduled Clear')); o.rmempty = false; diff --git a/luci-app-momo/po/templates/momo.pot b/luci-app-momo/po/templates/momo.pot index e84f1adc..3062b187 100644 --- a/luci-app-momo/po/templates/momo.pot +++ b/luci-app-momo/po/templates/momo.pot @@ -14,11 +14,11 @@ msgstr "" msgid "Access Control" msgstr "" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:141 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:147 msgid "Address Space Size Hard Limit" msgstr "" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:137 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:143 msgid "Address Space Size Soft Limit" msgstr "" @@ -32,7 +32,7 @@ msgstr "" msgid "App Config" msgstr "" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:53 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:56 msgid "App Log" msgstr "" @@ -92,8 +92,12 @@ msgstr "" msgid "Choose Profile" msgstr "" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:57 -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:90 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:31 +msgid "Clear At Stop" +msgstr "" + +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:60 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:93 msgid "Clear Log" msgstr "" @@ -102,7 +106,7 @@ msgstr "" msgid "Commonly Used Port" msgstr "" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:86 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:89 msgid "Core Log" msgstr "" @@ -151,7 +155,7 @@ msgstr "" msgid "DNS Strategy" msgstr "" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:119 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:122 msgid "Debug Log" msgstr "" @@ -206,6 +210,10 @@ msgstr "" msgid "Enable" msgstr "" +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:173 +msgid "Environment Variable Config" +msgstr "" + #: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/profile.js:50 msgid "Expire At" msgstr "" @@ -231,7 +239,7 @@ msgstr "" msgid "General Config" msgstr "" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:123 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:126 msgid "Generate & Download" msgstr "" @@ -243,11 +251,11 @@ msgstr "" msgid "Group" msgstr "" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:149 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:155 msgid "Heap Size Hard Limit" msgstr "" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:145 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:151 msgid "Heap Size Soft Limit" msgstr "" @@ -358,14 +366,22 @@ msgstr "" msgid "Not Running" msgstr "" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:164 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:170 msgid "Number of Open Files Hard Limit" msgstr "" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:161 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:167 msgid "Number of Open Files Soft Limit" msgstr "" +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:140 +msgid "Number of Processes Hard Limit" +msgstr "" + +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:137 +msgid "Number of Processes Soft Limit" +msgstr "" + #: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:89 msgid "Open Dashboard" msgstr "" @@ -438,19 +454,19 @@ msgstr "" msgid "Running" msgstr "" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:31 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:34 msgid "Scheduled Clear" msgstr "" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:34 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:37 msgid "Scheduled Clear Cron" msgstr "" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:39 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:42 msgid "Scheduled Clear Size Limit" msgstr "" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:45 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:48 msgid "Scheduled Clear Size Limit Unit" msgstr "" @@ -462,16 +478,16 @@ msgstr "" msgid "Scheduled Restart Cron" msgstr "" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:80 -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:113 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:83 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:116 msgid "Scroll To Bottom" msgstr "" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:157 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:163 msgid "Stack Size Hard Limit" msgstr "" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:153 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:159 msgid "Stack Size Soft Limit" msgstr "" @@ -554,12 +570,14 @@ msgstr "" msgid "UI Path" msgstr "" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:139 -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:143 -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:147 -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:151 -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:155 -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:159 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:145 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:149 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:153 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:157 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:161 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:165 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:177 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:181 msgid "Unlimited" msgstr "" diff --git a/luci-app-momo/po/zh_Hans/momo.po b/luci-app-momo/po/zh_Hans/momo.po index 8e834d95..803d3c5a 100644 --- a/luci-app-momo/po/zh_Hans/momo.po +++ b/luci-app-momo/po/zh_Hans/momo.po @@ -21,11 +21,11 @@ msgstr "API 密码" msgid "Access Control" msgstr "访问控制" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:141 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:147 msgid "Address Space Size Hard Limit" msgstr "地址空间大小硬限制" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:137 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:143 msgid "Address Space Size Soft Limit" msgstr "地址空间大小软限制" @@ -39,7 +39,7 @@ msgstr "全部端口" msgid "App Config" msgstr "插件配置" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:53 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:56 msgid "App Log" msgstr "插件日志" @@ -99,8 +99,12 @@ msgstr "选择文件" msgid "Choose Profile" msgstr "选择配置文件" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:57 -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:90 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:31 +msgid "Clear At Stop" +msgstr "停止时清空" + +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:60 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:93 msgid "Clear Log" msgstr "清空日志" @@ -109,7 +113,7 @@ msgstr "清空日志" msgid "Commonly Used Port" msgstr "常用端口" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:86 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:89 msgid "Core Log" msgstr "核心日志" @@ -158,7 +162,7 @@ msgstr "DNS 反向映射" msgid "DNS Strategy" msgstr "DNS 策略" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:119 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:122 msgid "Debug Log" msgstr "调试日志" @@ -213,6 +217,10 @@ msgstr "编辑器" msgid "Enable" msgstr "启用" +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:173 +msgid "Environment Variable Config" +msgstr "环境变量配置" + #: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/profile.js:50 msgid "Expire At" msgstr "到期时间" @@ -238,7 +246,7 @@ msgstr "文件:" msgid "General Config" msgstr "全局配置" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:123 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:126 msgid "Generate & Download" msgstr "生成并下载" @@ -250,11 +258,11 @@ msgstr "授予访问 momo 程序的权限" msgid "Group" msgstr "用户组" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:149 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:155 msgid "Heap Size Hard Limit" msgstr "堆大小硬限制" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:145 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:151 msgid "Heap Size Soft Limit" msgstr "堆大小软限制" @@ -365,14 +373,22 @@ msgstr "NTP 服务端口" msgid "Not Running" msgstr "未在运行" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:164 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:170 msgid "Number of Open Files Hard Limit" msgstr "打开文件数量硬限制" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:161 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:167 msgid "Number of Open Files Soft Limit" msgstr "打开文件数量软限制" +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:140 +msgid "Number of Processes Hard Limit" +msgstr "进程数硬限制" + +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:137 +msgid "Number of Processes Soft Limit" +msgstr "进程数软限制" + #: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:89 msgid "Open Dashboard" msgstr "打开面板" @@ -445,19 +461,19 @@ msgstr "路由器代理" msgid "Running" msgstr "运行中" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:31 -msgid "Scheduled Clear" -msgstr "定时清除"" - #: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:34 +msgid "Scheduled Clear" +msgstr "定时清空" + +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:37 msgid "Scheduled Clear Cron" msgstr "Cron 表达式" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:39 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:42 msgid "Scheduled Clear Size Limit" msgstr "日志大小上限" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:45 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:48 msgid "Scheduled Clear Size Limit Unit" msgstr "日志大小上限单位" @@ -469,16 +485,16 @@ msgstr "定时重启" msgid "Scheduled Restart Cron" msgstr "Cron 表达式" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:80 -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:113 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:83 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/log.js:116 msgid "Scroll To Bottom" msgstr "滚动到底部" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:157 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:163 msgid "Stack Size Hard Limit" msgstr "栈大小硬限制" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:153 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:159 msgid "Stack Size Soft Limit" msgstr "栈大小软限制" @@ -561,12 +577,14 @@ msgstr "UI 下载地址" msgid "UI Path" msgstr "UI 路径" -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:139 -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:143 -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:147 -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:151 -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:155 -#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:159 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:145 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:149 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:153 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:157 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:161 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:165 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:177 +#: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:181 msgid "Unlimited" msgstr "无限制" @@ -626,35 +644,3 @@ msgstr "用户代理(UA)" #: applications/luci-app-momo/htdocs/luci-static/resources/view/momo/app.js:128 msgid "procd Config" msgstr "procd 配置" - -#~ msgid "Cron Expression" -#~ msgstr "Cron 表达式" - -#~ msgid "Check log size at the configured cron schedule before cleaning up." -#~ msgstr "按设定的 Cron 周期检查日志大小,满足条件后再清理。" - -#~ msgid "" -#~ "Clear app, core and debug logs when their total size reaches this " -#~ "threshold." -#~ msgstr "当插件日志、核心日志和调试日志总大小达到该阈值时自动清理。" - -#~ msgid "Log Cleanup" -#~ msgstr "日志清理" - -#~ msgid "Log Cleanup Cron Expression" -#~ msgstr "日志清理 Cron 表达式" - -#~ msgid "Log Cleanup Size Threshold (MB)" -#~ msgstr "日志清理大小阈值(MB)" - -#~ msgid "Log Size Check Cron Expression" -#~ msgstr "日志大小检查 Cron 表达式" - -#~ msgid "Run unconditional log cleanup at the configured cron schedule." -#~ msgstr "按设定的 Cron 时间无条件执行日志清理。" - -#~ msgid "Scheduled Log Cleanup" -#~ msgstr "定时日志清理" - -#~ msgid "Size-based Log Cleanup" -#~ msgstr "按大小触发日志清理" diff --git a/luci-app-passwall/luasrc/controller/passwall.lua b/luci-app-passwall/luasrc/controller/passwall.lua index 8dc85445..ebd69699 100644 --- a/luci-app-passwall/luasrc/controller/passwall.lua +++ b/luci-app-passwall/luasrc/controller/passwall.lua @@ -1067,10 +1067,12 @@ function fetch_certsha256() local id = http.formvalue("id") or "" local address = (id ~= "") and uci:get(appname, id, "address") or "" local port = (id ~= "") and uci:get(appname, id, "port") or 0 - if id == "" or address == "" or not api.datatypes.hostname(address) or port == 0 then + local sni = (id ~= "") and uci:get(appname, id, "tls_serverName") or "" + sni = (sni ~= "") and sni or address + if address == "" or port == 0 then http_write_json_error() return end - local data = api.fetch_cert_sha256(address, port, 5) + local data = api.fetch_cert_sha256(address, port, sni, 5) http_write_json(data ~= "" and { code = 1, data = data } or { code = 0 }) end diff --git a/luci-app-passwall/luasrc/passwall/api.lua b/luci-app-passwall/luasrc/passwall/api.lua index 10886cf0..44bf97cb 100644 --- a/luci-app-passwall/luasrc/passwall/api.lua +++ b/luci-app-passwall/luasrc/passwall/api.lua @@ -1570,31 +1570,23 @@ function cleanEmptyTables(t) return next(t) and t or nil end -function fetch_cert_sha256(host, port, timeout) - if not host or not datatypes.hostname(host) then return "" end +function fetch_cert_sha256(host, port, sni, timeout) + if not host then return "" end port = tonumber(port) or 443 + sni = sni or host timeout = tonumber(timeout) or 5 - local xray = finded_com("xray") - local cmd - if xray then - cmd = string.format( - "timeout %d %q tls ping %s:%d 2>/dev/null " .. - "| awk 'tolower($0) ~ /without sni/ {f=1} tolower($0) ~ /with sni/ {f=0} " .. - "f && tolower($0) ~ /cert.*leaf.*sha256/ {sub(/.*:/,\"\"); gsub(/[[:space:]]/,\"\"); print; exit}'", - timeout, xray, host, port - ) - else - cmd = string.format( - "timeout %d openssl s_client -connect %s:%d -servername %s -showcerts /dev/null " .. - "| awk 'BEGIN{c=0}/BEGIN CERT/{c++} c==1{print} /END CERT/{if(c==1)exit}' " .. - "| openssl x509 -outform der 2>/dev/null " .. - "| sha256sum 2>/dev/null", - timeout, host, port, host - ) - end + local cmd = string.format( + "timeout %d openssl s_client -connect %s:%d -servername %s -showcerts /dev/null " .. + "| awk 'BEGIN{c=0}/BEGIN CERT/{c++} c==1{print} /END CERT/{if(c==1)exit}' " .. + "| openssl x509 -outform der 2>/dev/null " .. + "| sha256sum 2>/dev/null", + timeout, host, port, sni + ) local out = trim(sys.exec(cmd)) local fp = out:match("^([0-9a-fA-F]+)") - if not fp then return "" end + if not fp or fp:lower():match("^e3b0c44298fc1c149afbf4c8996fb924") then + return "" + end return fp:upper() end diff --git a/luci-app-passwall/luasrc/passwall/util_sing-box.lua b/luci-app-passwall/luasrc/passwall/util_sing-box.lua index 325f80b8..f9662125 100644 --- a/luci-app-passwall/luasrc/passwall/util_sing-box.lua +++ b/luci-app-passwall/luasrc/passwall/util_sing-box.lua @@ -1666,7 +1666,8 @@ function gen_config(var) invert = e.invert == "1" and true or nil } string.gsub(e.domain_list, '[^' .. "\r\n" .. ']+', function(w) - if w:find("#") == 1 then return end + w = api.trim(w) + if w == "" or w:find("#") == 1 then return end if w:find("geosite:") == 1 then local _geosite = w:sub(1 + #"geosite:") --适配srs local t = geo_rule_set("geosite", _geosite) @@ -1703,7 +1704,7 @@ function gen_config(var) domain_table.fakedns = true end - if outboundTag then + if outboundTag and (rule.domain or rule.domain_suffix or rule.domain_keyword or rule.domain_regex or rule.rule_set) then table.insert(dns_domain_rules, api.clone(domain_table)) end end @@ -1712,7 +1713,8 @@ function gen_config(var) local ip_cidr = {} local is_private = false string.gsub(e.ip_list, '[^' .. "\r\n" .. ']+', function(w) - if w:find("#") == 1 then return end + w = api.trim(w) + if w == "" or w:find("#") == 1 then return end if w:find("geoip:") == 1 then local _geoip = w:sub(1 + #"geoip:") --适配srs if _geoip == "private" then diff --git a/luci-app-passwall/luasrc/passwall/util_xray.lua b/luci-app-passwall/luasrc/passwall/util_xray.lua index 671985b1..6d5d6447 100644 --- a/luci-app-passwall/luasrc/passwall/util_xray.lua +++ b/luci-app-passwall/luasrc/passwall/util_xray.lua @@ -498,9 +498,9 @@ function gen_config_server(node) if node.protocol == "vmess" or node.protocol == "vless" then if node.uuid then - local clients = {} + local users = {} for i = 1, #node.uuid do - clients[i] = { + users[i] = { id = node.uuid[i], flow = (node.protocol == "vless" and (node.tls == "1" or (node.decryption and node.decryption ~= "" and node.decryption ~= "none")) @@ -508,7 +508,7 @@ function gen_config_server(node) } end settings = { - clients = clients, + users = users, decryption = (node.protocol == "vless") and ((node.decryption and node.decryption ~= "") and node.decryption or "none") or nil } end @@ -516,7 +516,7 @@ function gen_config_server(node) settings = { udp = ("1" == node.udp_forward) and true or false, auth = ("1" == node.auth) and "password" or "noauth", - accounts = ("1" == node.auth) and { + users = ("1" == node.auth) and { { user = node.username, pass = node.password @@ -526,7 +526,7 @@ function gen_config_server(node) elseif node.protocol == "http" then settings = { allowTransparent = false, - accounts = ("1" == node.auth) and { + users = ("1" == node.auth) and { { user = node.username, pass = node.password @@ -544,20 +544,20 @@ function gen_config_server(node) } elseif node.protocol == "trojan" then if node.uuid then - local clients = {} + local users = {} for i = 1, #node.uuid do - clients[i] = { + users[i] = { password = node.uuid[i], } end settings = { - clients = clients + users = users } end elseif node.protocol == "hysteria2" then settings = { version = 2, - clients = node.hysteria2_auth_password and { + users = node.hysteria2_auth_password and { { auth = node.hysteria2_auth_password } } } @@ -946,7 +946,7 @@ function gen_config(var) end if local_socks_username and local_socks_password and local_socks_username ~= "" and local_socks_password ~= "" then inbound.settings.auth = "password" - inbound.settings.accounts = { + inbound.settings.users = { { user = local_socks_username, pass = local_socks_password @@ -963,7 +963,7 @@ function gen_config(var) settings = {allowTransparent = false} } if local_http_username and local_http_password and local_http_username ~= "" and local_http_password ~= "" then - inbound.settings.accounts = { + inbound.settings.users = { { user = local_http_username, pass = local_http_password @@ -1422,7 +1422,8 @@ function gen_config(var) } domains = {} string.gsub(e.domain_list, '[^' .. "\r\n" .. ']+', function(w) - if w:find("#") == 1 then return end + w = api.trim(w) + if w == "" or w:find("#") == 1 then return end if w:find("rule-set:", 1, true) == 1 or w:find("rs:") == 1 then return end table.insert(domains, w) table.insert(domain_table.domain, w) @@ -1430,16 +1431,17 @@ function gen_config(var) if inner_fakedns == "1" and node[e[".name"] .. "_fakedns"] == "1" and #domains > 0 then domain_table.fakedns = true end - if outbound_tag then + if #domains == 0 then domains = nil end + if outbound_tag and domains then table.insert(dns_domain_rules, api.clone(domain_table)) end - if #domains == 0 then domains = nil end end local ip = nil if e.ip_list then ip = {} string.gsub(e.ip_list, '[^' .. "\r\n" .. ']+', function(w) - if w:find("#") == 1 then return end + w = api.trim(w) + if w == "" or w:find("#") == 1 then return end if w:find("rule-set:", 1, true) == 1 or w:find("rs:") == 1 then return end table.insert(ip, w) end) @@ -2036,7 +2038,7 @@ function gen_proto_config(var) } if local_socks_username and local_socks_password and local_socks_username ~= "" and local_socks_password ~= "" then inbound.settings.auth = "password" - inbound.settings.accounts = { + inbound.settings.users = { { user = local_socks_username, pass = local_socks_password @@ -2056,7 +2058,7 @@ function gen_proto_config(var) } } if local_http_username and local_http_password and local_http_username ~= "" and local_http_password ~= "" then - inbound.settings.accounts = { + inbound.settings.users = { { user = local_http_username, pass = local_http_password diff --git a/luci-app-passwall2/Makefile b/luci-app-passwall2/Makefile index 3d8aa3cf..7d04e36a 100644 --- a/luci-app-passwall2/Makefile +++ b/luci-app-passwall2/Makefile @@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-passwall2 -PKG_VERSION:=26.5.19 +PKG_VERSION:=26.6.3 PKG_RELEASE:=1 PKG_PO_VERSION:=$(PKG_VERSION) diff --git a/luci-app-passwall2/luasrc/controller/passwall2.lua b/luci-app-passwall2/luasrc/controller/passwall2.lua index c3520cfc..c6cd1a9e 100644 --- a/luci-app-passwall2/luasrc/controller/passwall2.lua +++ b/luci-app-passwall2/luasrc/controller/passwall2.lua @@ -22,7 +22,6 @@ function index() local appname = api.appname -- global definitions not available local uci = api.uci -- in function index() entry({"admin", "services", appname}).dependent = true - entry({"admin", "services", appname, "reset_config"}, call("reset_config")).leaf = true entry({"admin", "services", appname, "show"}, call("show_menu")).leaf = true entry({"admin", "services", appname, "hide"}, call("hide_menu")).leaf = true local e @@ -109,6 +108,7 @@ function index() --[[Backup]] entry({"admin", "services", appname, "create_backup"}, call("create_backup")).leaf = true entry({"admin", "services", appname, "restore_backup"}, call("restore_backup")).leaf = true + entry({"admin", "services", appname, "reset_config"}, call("reset_config")).leaf = true --[[geoview]] entry({"admin", "services", appname, "geo_view"}, call("geo_view")).leaf = true @@ -130,6 +130,8 @@ local function http_write_json_error(data) end function reset_config() + uci:revert(appname) + luci.sys.call("echo '' > /tmp/log/passwall2.log") luci.sys.call('/etc/init.d/passwall2 stop') luci.sys.call('[ -f "/usr/share/passwall2/0_default_config" ] && cp -f /usr/share/passwall2/0_default_config /etc/config/passwall2') http.redirect(api.url()) @@ -745,6 +747,7 @@ function restore_backup() fp:write(decoded) fp:close() if chunk_index + 1 == total_chunks then + uci:revert(appname) api.sys.call("echo '' > /tmp/log/passwall2.log") api.log(0, string.format(" * PassWall2 %s", i18n.translate("Configuration file uploaded successfully…"))) local temp_dir = '/tmp/passwall2_bak' diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/global.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/global.lua index 103af778..e77b1aa1 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/global.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/global.lua @@ -72,7 +72,7 @@ end m:append(Template(appname .. "/global/status")) -global_cfgid = m:get("@global[0]")[".name"] +global_cfgid = (m:get("@global[0]") or {})[".name"] or "" s = m:section(TypedSection, "global") s.anonymous = true diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/hysteria2.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/hysteria2.lua index f5c66225..8cf95aed 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/hysteria2.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/hysteria2.lua @@ -59,11 +59,13 @@ o.rewrite_option = o.option o = s:option(ListValue, _n("obfs_type"), translate("Obfs Type")) o:value("", translate("Disable")) o:value("salamander") +o:value("gecko") o.rewrite_option = o.option o = s:option(Value, _n("obfs_password"), translate("Obfs Password")) o.rewrite_option = o.option o:depends({ [_n("obfs_type")] = "salamander" }) +o:depends({ [_n("obfs_type")] = "gecko" }) o = s:option(Flag, _n("fast_open"), translate("Fast Open")) o.default = "0" diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ray.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ray.lua index f1264f1f..22c48b1d 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ray.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/ray.lua @@ -339,13 +339,28 @@ o:depends({ [_n("protocol")] = "vless" }) ---- [[hysteria2]] o = s:option(Value, _n("hysteria2_hop"), translate("Port hopping range")) o.description = translate("Format as 1000:2000 or 1000-2000 Multiple groups are separated by commas (,).") -o:depends({ [_n("protocol")] = "hysteria2" }) +o:depends({ [_n("protocol")] = "hysteria2", [_n("hysteria2_realms")] = false }) o = s:option(Value, _n("hysteria2_hop_interval"), translate("Hop Interval(second)"), translate("Supports a fixed value or a random range (e.g., 30, 5-30), minimum 5.")) o.datatype = "or(uinteger,portrange)" o.placeholder = "30" o.default = "30" -o:depends({ [_n("protocol")] = "hysteria2" }) +o:depends({ [_n("protocol")] = "hysteria2", [_n("hysteria2_realms")] = false }) + +o = s:option(Flag, _n("hysteria2_realms"), translate("Realms")) +o.default = "0" +if api.compare_versions(xray_version, ">", "26.5.9") then + o:depends({ [_n("protocol")] = "hysteria2"}) +else + o:depends({ [_n("protocol")] = "__hide"}) +end + +o = s:option(Value, _n("hysteria2_realm_url"), translate("Realm URL"), translate("Example:") .. "realm://public@realm.hy2.io/your-realm-name") +o:depends({ [_n("hysteria2_realms")] = "1" }) + +o = s:option(DynamicList, _n("hysteria2_realm_stun"), translate("Realm STUN")) +o.default = { "stun.sip.us:3478", "stun.nextcloud.com:3478", "global.stun.twilio.com:3478" } +o:depends({ [_n("hysteria2_realms")] = "1" }) o = s:option(Value, _n("hysteria2_auth_password"), translate("Auth Password")) o.password = true @@ -354,10 +369,12 @@ o:depends({ [_n("protocol")] = "hysteria2"}) o = s:option(ListValue, _n("hysteria2_obfs_type"), translate("Obfs Type")) o:value("", translate("Disable")) o:value("salamander") +o:value("gecko") o:depends({ [_n("protocol")] = "hysteria2" }) o = s:option(Value, _n("hysteria2_obfs_password"), translate("Obfs Password")) o:depends({ [_n("hysteria2_obfs_type")] = "salamander" }) +o:depends({ [_n("hysteria2_obfs_type")] = "gecko" }) o = s:option(Value, _n("hysteria2_up_mbps"), translate("Max upload Mbps")) o:depends({ [_n("protocol")] = "hysteria2" }) @@ -431,11 +448,26 @@ if api.compare_versions(xray_version, ">=", "26.1.31") then o:depends({ [_n("protocol")] = "hysteria2" }) end -o = s:option(Flag, _n("ech"), translate("ECH")) +o = s:option(Flag, _n("tls_certificate"), translate("TLS Certificate (PEM)")) o.default = "0" o:depends({ [_n("tls")] = true, [_n("reality")] = false }) o:depends({ [_n("protocol")] = "hysteria2" }) +o = s:option(TextValue, _n("tls_certificate_pem"), " ", translate("Full certificate (chain), PEM format.")) +o.default = "" +o.rows = 5 +o.wrap = "off" +o:depends({ [_n("tls_certificate")] = true }) +o.validate = function(self, value) + value = api.trim(value):gsub("\r\n", "\n"):gsub("[ \t]*\n[ \t]*", "\n"):gsub("\n+", "\n") + return value +end + +o = s:option(Flag, _n("ech"), translate("ECH")) +o.default = "0" +o:depends({ [_n("tls")] = true, [_n("reality")] = false }) +o:depends({ [_n("protocol")] = "hysteria2", [_n("hysteria2_realms")] = false }) + o = s:option(TextValue, _n("ech_config"), translate("ECH Config")) o.default = "" o.rows = 5 @@ -706,7 +738,7 @@ o:depends({ [_n("protocol")] = "vless" }) o:depends({ [_n("protocol")] = "trojan" }) o:depends({ [_n("protocol")] = "shadowsocks" }) o:depends({ [_n("protocol")] = "wireguard" }) -o:depends({ [_n("protocol")] = "hysteria2" }) +o:depends({ [_n("protocol")] = "hysteria2", [_n("hysteria2_realms")] = false }) o = s:option(TextValue, _n("finalmask"), " ") o:depends({ [_n("use_finalmask")] = true }) @@ -775,10 +807,14 @@ local protocols = s.fields[_n("protocol")].keylist if #protocols > 0 then for i, v in ipairs(protocols) do if not v:find("^_") then - s.fields[_n("address")]:depends({ [_n("protocol")] = v }) - s.fields[_n("port")]:depends({ [_n("protocol")] = v }) - s.fields[_n("domain_resolver")]:depends({ [_n("protocol")] = v }) - s.fields[_n("domain_strategy")]:depends({ [_n("protocol")] = v }) + local depends_condition = { [_n("protocol")] = v } + if v == "hysteria2" then + depends_condition[_n("hysteria2_realms")] = false + end + s.fields[_n("address")]:depends(depends_condition) + s.fields[_n("port")]:depends(depends_condition) + s.fields[_n("domain_resolver")]:depends(depends_condition) + s.fields[_n("domain_strategy")]:depends(depends_condition) if v ~= "hysteria2" then s.fields[_n("tcp_fast_open")]:depends({ [_n("protocol")] = v }) @@ -801,7 +837,7 @@ if not load_shunt_options then o:value("2", translate("Landing Node")) o1 = s:option(ListValue, _n("preproxy_node"), translate("Preproxy Node"), translate("Only support a layer of proxy.")) - o1:depends({ [_n("chain_proxy")] = "1" }) + o1:depends({ [_n("chain_proxy")] = "1", [_n("hysteria2_realms")] = false }) o1.template = appname .. "/cbi/nodes_listvalue" o1.group = {} @@ -813,7 +849,7 @@ if not load_shunt_options then end o2 = s:option(ListValue, _n("to_node"), translate("Landing Node"), translate("Only support a layer of proxy.")) - o2:depends({ [_n("chain_proxy")] = "2" }) + o2:depends({ [_n("chain_proxy")] = "2", [_n("hysteria2_realms")] = false }) o2.template = appname .. "/cbi/nodes_listvalue" o2.group = {} diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/sing-box.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/sing-box.lua index a3c591ca..55d75677 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/sing-box.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/sing-box.lua @@ -423,10 +423,12 @@ if singbox_tags:find("with_quic") then o = s:option(ListValue, _n("hysteria2_obfs_type"), translate("Obfs Type")) o:value("", translate("Disable")) o:value("salamander") + o:value("gecko") o:depends({ [_n("protocol")] = "hysteria2" }) o = s:option(Value, _n("hysteria2_obfs_password"), translate("Obfs Password")) o:depends({ [_n("hysteria2_obfs_type")] = "salamander" }) + o:depends({ [_n("hysteria2_obfs_type")] = "gecko" }) o = s:option(Value, _n("hysteria2_up_mbps"), translate("Max upload Mbps")) o:depends({ [_n("protocol")] = "hysteria2" }) @@ -531,6 +533,24 @@ o:depends({ [_n("protocol")] = "hysteria"}) o:depends({ [_n("protocol")] = "tuic" }) o:depends({ [_n("protocol")] = "hysteria2" }) +o = s:option(Flag, _n("tls_certificate"), translate("TLS Certificate (PEM)")) +o.default = "0" +o:depends({ [_n("tls")] = true, [_n("reality")] = false }) +o:depends({ [_n("protocol")] = "hysteria"}) +o:depends({ [_n("protocol")] = "tuic" }) +o:depends({ [_n("protocol")] = "hysteria2" }) +o:depends({ [_n("protocol")] = "naive" }) + +o = s:option(TextValue, _n("tls_certificate_pem"), " ", translate("Full certificate (chain), PEM format.")) +o.default = "" +o.rows = 5 +o.wrap = "off" +o:depends({ [_n("tls_certificate")] = true }) +o.validate = function(self, value) + value = api.trim(value):gsub("\r\n", "\n"):gsub("[ \t]*\n[ \t]*", "\n"):gsub("\n+", "\n") + return value +end + o = s:option(Flag, _n("ech"), translate("ECH")) o.default = "0" o:depends({ [_n("tls")] = true, [_n("flow")] = "", [_n("reality")] = false }) diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/hysteria2.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/hysteria2.lua index 89742db8..cc9a733a 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/hysteria2.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/hysteria2.lua @@ -48,12 +48,14 @@ o:depends({ [_n("custom")] = false }) o = s:option(ListValue, _n("obfs_type"), translate("Obfs Type")) o:value("", translate("Disable")) o:value("salamander") +o:value("gecko") o.rewrite_option = o.option o:depends({ [_n("custom")] = false }) o = s:option(Value, _n("obfs_password"), translate("Obfs Password")) o.rewrite_option = o.option o:depends({ [_n("obfs_type")] = "salamander" }) +o:depends({ [_n("obfs_type")] = "gecko" }) o = s:option(Flag, _n("udp"), translate("UDP")) o.default = "1" diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/ray.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/ray.lua index ff99b15b..14a48bc5 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/ray.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/ray.lua @@ -127,6 +127,17 @@ o:value("xtls-rprx-vision") o:depends({ [_n("protocol")] = "vless" }) ---- [[ hysteria2 ]] +o = s:option(Flag, _n("hysteria2_realms"), translate("Realms")) +o.default = "0" +o:depends({ [_n("protocol")] = "hysteria2"}) + +o = s:option(Value, _n("hysteria2_realm_url"), translate("Realm URL"), translate("Example:") .. "realm://public@realm.hy2.io/your-realm-name") +o:depends({ [_n("hysteria2_realms")] = "1" }) + +o = s:option(DynamicList, _n("hysteria2_realm_stun"), translate("Realm STUN")) +o.default = { "stun.sip.us:3478", "stun.nextcloud.com:3478", "global.stun.twilio.com:3478" } +o:depends({ [_n("hysteria2_realms")] = "1" }) + o = s:option(Value, _n("hysteria2_auth_password"), translate("Auth Password")) o.password = true o:depends({ [_n("protocol")] = "hysteria2"}) @@ -134,10 +145,12 @@ o:depends({ [_n("protocol")] = "hysteria2"}) o = s:option(ListValue, _n("hysteria2_obfs_type"), translate("Obfs Type")) o:value("", translate("Disable")) o:value("salamander") +o:value("gecko") o:depends({ [_n("protocol")] = "hysteria2" }) o = s:option(Value, _n("hysteria2_obfs_password"), translate("Obfs Password")) o:depends({ [_n("hysteria2_obfs_type")] = "salamander" }) +o:depends({ [_n("hysteria2_obfs_type")] = "gecko" }) o = s:option(Flag, _n("hysteria2_ignore_client_bandwidth"), translate("Client BBR Flow Control")) o.default = 0 @@ -210,7 +223,8 @@ function o.write(self, section, value) end o = s:option(ListValue, _n("alpn"), translate("alpn")) -o.default = "h2,http/1.1" +o.default = "default" +o:value("default", translate("Default")) o:value("h3") o:value("h2") o:value("h3,h2") @@ -378,7 +392,7 @@ o:depends({ [_n("custom")] = false, [_n("protocol")] = "vless" }) o:depends({ [_n("custom")] = false, [_n("protocol")] = "trojan" }) o:depends({ [_n("custom")] = false, [_n("protocol")] = "shadowsocks" }) o:depends({ [_n("custom")] = false, [_n("protocol")] = "wireguard" }) -o:depends({ [_n("custom")] = false, [_n("protocol")] = "hysteria2" }) +o:depends({ [_n("custom")] = false, [_n("protocol")] = "hysteria2", [_n("hysteria2_realms")] = false }) o = s:option(TextValue, _n("finalmask"), "FinalMask JSON") o:depends({ [_n("use_finalmask")] = true }) diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/sing-box.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/sing-box.lua index dd3cb2f4..f367a01c 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/sing-box.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/server/type/sing-box.lua @@ -175,10 +175,12 @@ if singbox_tags:find("with_quic") then o = s:option(ListValue, _n("hysteria2_obfs_type"), translate("Obfs Type")) o:value("", translate("Disable")) o:value("salamander") + o:value("gecko") o:depends({ [_n("protocol")] = "hysteria2" }) o = s:option(Value, _n("hysteria2_obfs_password"), translate("Obfs Password")) o:depends({ [_n("hysteria2_obfs_type")] = "salamander" }) + o:depends({ [_n("hysteria2_obfs_type")] = "gecko" }) o = s:option(Flag, _n("hysteria2_ignore_client_bandwidth"), translate("Client BBR Flow Control"), translate("Commands the client to use the BBR flow control algorithm")) o.default = 0 diff --git a/luci-app-passwall2/luasrc/passwall2/api.lua b/luci-app-passwall2/luasrc/passwall2/api.lua index e2510f51..5ee4cb7b 100644 --- a/luci-app-passwall2/luasrc/passwall2/api.lua +++ b/luci-app-passwall2/luasrc/passwall2/api.lua @@ -154,12 +154,14 @@ function base64Encode(text) end function UrlEncode(szText) + if type(szText) ~= "string" then return "" end return szText:gsub("([^%w%-_%.%~])", function(c) return string.format("%%%02X", string.byte(c)) end) end function UrlDecode(szText) + if type(szText) ~= "string" then return "" end return szText and szText:gsub("%+", " "):gsub("%%(%x%x)", function(h) return string.char(tonumber(h, 16)) end) or nil diff --git a/luci-app-passwall2/luasrc/passwall2/util_hysteria2.lua b/luci-app-passwall2/luasrc/passwall2/util_hysteria2.lua index 7075dd11..43b586e2 100644 --- a/luci-app-passwall2/luasrc/passwall2/util_hysteria2.lua +++ b/luci-app-passwall2/luasrc/passwall2/util_hysteria2.lua @@ -20,8 +20,8 @@ function gen_config_server(node) key = node.tls_keyFile, }, obfs = (node.hysteria2_obfs_type and node.hysteria2_obfs_password) and { - type = "salamander", - salamander = { + type = node.hysteria2_obfs_type, + [node.hysteria2_obfs_type] = { password = node.hysteria2_obfs_password } } or nil, @@ -101,8 +101,8 @@ function gen_config(var) end)() or nil }, obfs = (node.hysteria2_obfs_type and node.hysteria2_obfs_password) and { - type = "salamander", - salamander = { + type = node.hysteria2_obfs_type, + [node.hysteria2_obfs_type] = { password = node.hysteria2_obfs_password } } or nil, diff --git a/luci-app-passwall2/luasrc/passwall2/util_sing-box.lua b/luci-app-passwall2/luasrc/passwall2/util_sing-box.lua index 8080b147..c7c98007 100644 --- a/luci-app-passwall2/luasrc/passwall2/util_sing-box.lua +++ b/luci-app-passwall2/luasrc/passwall2/util_sing-box.lua @@ -255,6 +255,7 @@ function gen_outbound(flag, node, tag, proxy_table) --max_version = "1.3", fragment = fragment, record_fragment = record_fragment, + certificate = (node.tls_certificate == "1" and node.tls_certificate_pem ~= "") and split(node.tls_certificate_pem, "\n") or nil, ech = (node.ech == "1") and (function() local function get_ech_domain(s) --兼容xray "域名+DNS" 格式ech local domain, dns = s:match("^([^+]+)%+(.+)$") diff --git a/luci-app-passwall2/luasrc/passwall2/util_xray.lua b/luci-app-passwall2/luasrc/passwall2/util_xray.lua index 3ba5db0e..3c0f708b 100644 --- a/luci-app-passwall2/luasrc/passwall2/util_xray.lua +++ b/luci-app-passwall2/luasrc/passwall2/util_xray.lua @@ -73,8 +73,8 @@ function gen_outbound(flag, node, tag, proxy_table) local run_socks_instance = true if proxy_table ~= nil and type(proxy_table) == "table" then proxy_tag = proxy_table.tag or nil - fragment = proxy_table.fragment or nil - noise = proxy_table.noise or nil + fragment = (proxy_table.fragment and not node.hysteria2_realms) and true or nil + noise = (proxy_table.noise and not node.hysteria2_realms) and true or nil run_socks_instance = proxy_table.run_socks_instance end @@ -189,7 +189,11 @@ function gen_outbound(flag, node, tag, proxy_table) if not node.tls_CertByName then return "" end return node.tls_CertByName end)(), - echConfigList = (node.ech == "1") and node.ech_config or nil + echConfigList = (node.ech == "1") and node.ech_config or nil, + certificates = (node.tls_certificate == "1" and node.tls_certificate_pem ~= "") and { + certificate = api.split(node.tls_certificate_pem, "\n"), + usage = "verify" + } or nil } or nil, realitySettings = (node.stream_security == "reality") and { serverName = node.tls_serverName, @@ -298,14 +302,36 @@ function gen_outbound(flag, node, tag, proxy_table) udp[#udp+1] = c finalmask.udp = udp elseif TP == "hysteria" then + local udp = {} if node.hysteria2_obfs_type and node.hysteria2_obfs_type ~= "" then - finalmask.udp = {{ - type = node.hysteria2_obfs_type, + local o = { + type = "salamander", settings = node.hysteria2_obfs_password and { - password = node.hysteria2_obfs_password + password = node.hysteria2_obfs_password, + packetSize = node.hysteria2_obfs_type == "gecko" and "512-1200" or nil } or nil - }} + } + udp[#udp+1] = o end + if node.hysteria2_realms then + local realm = api.parse_realm_uri(node.hysteria2_realm_url) + local url, stun + if realm then + if realm.token and realm.server_url and realm.realm_id then + url = "realm://" .. realm.token .. "@" .. realm.server_url .. "/" .. realm.realm_id + end + stun = realm.stun_servers or node.hysteria2_realm_stun + end + local r = { + type = "realm", + settings = { + url = url, + stunServers = stun + } + } + udp[#udp+1] = r + end + finalmask.udp = udp local up = tonumber(node.hysteria2_up_mbps) or 0 local down = tonumber(node.hysteria2_down_mbps) or 0 finalmask.quicParams = { @@ -415,6 +441,13 @@ function gen_outbound(flag, node, tag, proxy_table) if node.protocol == "wireguard" then result.settings.kernelMode = false + if node.finalmask and node.finalmask ~= "" then + local ok, fm = pcall(jsonc.parse, api.base64Decode(node.finalmask)) + if ok and type(fm) == "table" then + result.streamSettings = result.streamSettings or {} + result.streamSettings.finalmask = fm + end + end end local alpn = {} @@ -487,9 +520,9 @@ function gen_config_server(node) if node.protocol == "vmess" or node.protocol == "vless" then if node.uuid then - local clients = {} + local users = {} for i = 1, #node.uuid do - clients[i] = { + users[i] = { id = node.uuid[i], flow = (node.protocol == "vless" and (node.tls == "1" or (node.decryption and node.decryption ~= "" and node.decryption ~= "none")) @@ -497,7 +530,7 @@ function gen_config_server(node) } end settings = { - clients = clients, + users = users, decryption = (node.protocol == "vless") and ((node.decryption and node.decryption ~= "") and node.decryption or "none") or nil } end @@ -505,7 +538,7 @@ function gen_config_server(node) settings = { udp = ("1" == node.udp_forward) and true or false, auth = ("1" == node.auth) and "password" or "noauth", - accounts = ("1" == node.auth) and { + users = ("1" == node.auth) and { { user = node.username, pass = node.password @@ -515,7 +548,7 @@ function gen_config_server(node) elseif node.protocol == "http" then settings = { allowTransparent = false, - accounts = ("1" == node.auth) and { + users = ("1" == node.auth) and { { user = node.username, pass = node.password @@ -533,20 +566,20 @@ function gen_config_server(node) } elseif node.protocol == "trojan" then if node.uuid then - local clients = {} + local users = {} for i = 1, #node.uuid do - clients[i] = { - password = node.uuid[i] + users[i] = { + password = node.uuid[i], } end settings = { - clients = clients + users = users } end elseif node.protocol == "hysteria2" then settings = { version = 2, - clients = node.hysteria2_auth_password and { + users = node.hysteria2_auth_password and { { auth = node.hysteria2_auth_password } } } @@ -724,14 +757,36 @@ function gen_config_server(node) udp[#udp+1] = c finalmask.udp = udp elseif node.transport == "hysteria" then + local udp = {} if node.hysteria2_obfs_type and node.hysteria2_obfs_type ~= "" then - finalmask.udp = {{ - type = node.hysteria2_obfs_type, + local o = { + type = "salamander", settings = node.hysteria2_obfs_password and { - password = node.hysteria2_obfs_password + password = node.hysteria2_obfs_password, + packetSize = node.hysteria2_obfs_type == "gecko" and "512-1200" or nil } or nil - }} + } + udp[#udp+1] = o end + if node.hysteria2_realms then + local realm = api.parse_realm_uri(node.hysteria2_realm_url) + local url, stun + if realm then + if realm.token and realm.server_url and realm.realm_id then + url = "realm://" .. realm.token .. "@" .. realm.server_url .. "/" .. realm.realm_id + end + stun = realm.stun_servers or node.hysteria2_realm_stun + end + local r = { + type = "realm", + settings = { + url = url, + stunServers = stun + } + } + udp[#udp+1] = r + end + finalmask.udp = udp local ignore = tonumber(node.hysteria2_ignore_client_bandwidth) == 1 local up = (not ignore) and tonumber(node.hysteria2_up_mbps) or 0 local down = (not ignore) and tonumber(node.hysteria2_down_mbps) or 0 @@ -761,7 +816,7 @@ function gen_config_server(node) } local alpn = {} - if node.alpn then + if node.alpn and node.alpn ~= "default" then string.gsub(node.alpn, '[^' .. "," .. ']+', function(w) table.insert(alpn, w) end) @@ -907,7 +962,7 @@ function gen_config(var) end if local_socks_username and local_socks_password and local_socks_username ~= "" and local_socks_password ~= "" then inbound.settings.auth = "password" - inbound.settings.accounts = { + inbound.settings.users = { { user = local_socks_username, pass = local_socks_password @@ -925,7 +980,7 @@ function gen_config(var) settings = {allowTransparent = false} } if local_http_username and local_http_password and local_http_username ~= "" and local_http_password ~= "" then - inbound.settings.accounts = { + inbound.settings.users = { { user = local_http_username, pass = local_http_password @@ -2047,7 +2102,7 @@ function gen_proto_config(var) } if local_socks_username and local_socks_password and local_socks_username ~= "" and local_socks_password ~= "" then inbound.settings.auth = "password" - inbound.settings.accounts = { + inbound.settings.users = { { user = local_socks_username, pass = local_socks_password @@ -2067,7 +2122,7 @@ function gen_proto_config(var) } } if local_http_username and local_http_password and local_http_username ~= "" and local_http_password ~= "" then - inbound.settings.accounts = { + inbound.settings.users = { { user = local_http_username, pass = local_http_password diff --git a/luci-app-passwall2/luasrc/view/passwall2/global/backup.htm b/luci-app-passwall2/luasrc/view/passwall2/global/backup.htm index aec626b8..c155754e 100644 --- a/luci-app-passwall2/luasrc/view/passwall2/global/backup.htm +++ b/luci-app-passwall2/luasrc/view/passwall2/global/backup.htm @@ -150,12 +150,9 @@ local api = require "luci.passwall2.api" if (confirm("<%: Do you want to restore the client to default settings?%>")) { setTimeout(function () { if (confirm("<%: Are you sure you want to restore the client to default settings?%>")) { - var xhr1 = new XMLHttpRequest(); - xhr1.open("GET",'<%= api.url("clear_log") %>', false); - xhr1.send(); - var xhr2 = new XMLHttpRequest(); - xhr2.open("GET",'<%= api.url("reset_config") %>', false); - xhr2.send(); + const xhr = new XMLHttpRequest(); + xhr.open("GET",'<%= api.url("reset_config") %>', false); + xhr.send(); window.location.href = '<%= api.url("log") %>' } }, 1000); diff --git a/luci-app-passwall2/luasrc/view/passwall2/node_config/link_share_man.htm b/luci-app-passwall2/luasrc/view/passwall2/node_config/link_share_man.htm index 7b7ed9a6..28128380 100644 --- a/luci-app-passwall2/luasrc/view/passwall2/node_config/link_share_man.htm +++ b/luci-app-passwall2/luasrc/view/passwall2/node_config/link_share_man.htm @@ -600,7 +600,7 @@ local current_node = map:get(section) v_password = opt.get("hysteria2_auth_password"); var dom_obfs = opt.get("hysteria2_obfs_password"); if (dom_obfs && dom_obfs.value != "") { - params += "&obfs=" + "salamander"; + params += opt.query("obfs", "hysteria2_obfs_type"); params += opt.query("obfs-password", "hysteria2_obfs_password"); } params += opt.query("mport", "hysteria2_hop"); @@ -1598,7 +1598,7 @@ local current_node = map:get(section) opt.set(dom_prefix + 'protocol', "hysteria2"); opt.set(dom_prefix + 'hysteria2_auth_password', decodeURIComponent(password)); if (queryParam["obfs-password"] || queryParam["obfs_password"]) { - opt.set(dom_prefix + 'hysteria2_obfs_type', "salamander"); + opt.set(dom_prefix + 'hysteria2_obfs_type', queryParam.obfs || "salamander"); opt.set(dom_prefix + 'hysteria2_obfs_password', queryParam["obfs-password"] || queryParam["obfs_password"]); } opt.set(dom_prefix + 'hysteria2_hop', queryParam.mport || ""); @@ -1609,7 +1609,7 @@ local current_node = map:get(section) dom_prefix = "hysteria2_" opt.set(dom_prefix + 'auth_password', decodeURIComponent(password)); if (queryParam["obfs-password"] || queryParam["obfs_password"]) { - opt.set(dom_prefix + 'obfs_type', "salamander"); + opt.set(dom_prefix + 'obfs_type', queryParam.obfs || "salamander"); opt.set(dom_prefix + 'obfs_password', queryParam["obfs-password"] || queryParam["obfs_password"]); } opt.set(dom_prefix + 'hop', queryParam.mport || ""); diff --git a/luci-app-passwall2/po/fa/passwall2.po b/luci-app-passwall2/po/fa/passwall2.po index dfb60669..e2cf45c5 100644 --- a/luci-app-passwall2/po/fa/passwall2.po +++ b/luci-app-passwall2/po/fa/passwall2.po @@ -1656,6 +1656,12 @@ msgstr "نام گواهی TLS (CertName)" msgid "TLS is used to verify the leaf certificate name." msgstr "TLS برای تأیید نام گواهی برگ (Leaf Certificate) استفاده می‌شود." +msgid "TLS Certificate (PEM)" +msgstr "گواهی TLS (PEM)" + +msgid "Full certificate (chain), PEM format." +msgstr "گواهی کامل (زنجیره‌ای)، فرمت PEM." + msgid "ECH Config" msgstr "پیکربندی ECH" @@ -2281,8 +2287,8 @@ msgstr "نادیده گرفتن گره %s به دلیل ناسازگاری با msgid "Skip node: %s. Because Sing-Box does not support the %s protocol's %s transmission method, Xray needs to be used instead." msgstr "صرف‌نظر از گره: %s. زیرا Sing-Box از روش انتقال %s پروتکل %s پشتیبانی نمی‌کند، باید به جای آن از Xray استفاده شود." -msgid "Xray unsupport %s plugin." -msgstr "Xray از افزونه %s پشتیبانی نمی‌کند." +msgid "%s unsupport SS %s plugin." +msgstr "%s از افزونه %s پشتیبانی نمی‌کند." msgid "Plugin options Incomplete." msgstr "گزینه‌های افزونه ناقص است." diff --git a/luci-app-passwall2/po/ru/passwall2.po b/luci-app-passwall2/po/ru/passwall2.po index cb5b8969..be21069c 100644 --- a/luci-app-passwall2/po/ru/passwall2.po +++ b/luci-app-passwall2/po/ru/passwall2.po @@ -1657,6 +1657,12 @@ msgstr "Имя TLS-сертификата (CertName)" msgid "TLS is used to verify the leaf certificate name." msgstr "Используется TLS для проверки имени конечного сертификата." +msgid "TLS Certificate (PEM)" +msgstr "Сертификат TLS (PEM)" + +msgid "Full certificate (chain), PEM format." +msgstr "Полный сертификат (цепочка), формат PEM." + msgid "ECH Config" msgstr "Конфигурация ECH" @@ -2279,8 +2285,8 @@ msgstr "Пропуск сервера %s: несовместимость с яд msgid "Skip node: %s. Because Sing-Box does not support the %s protocol's %s transmission method, Xray needs to be used instead." msgstr "Пропуск сервера: %s. Sing-Box не поддерживает метод передачи %s протокола %s, необходимо использовать Xray." -msgid "Xray unsupport %s plugin." -msgstr "Xray не поддерживает плагин %s." +msgid "%s unsupport SS %s plugin." +msgstr "%s не поддерживает плагин %s." msgid "Plugin options Incomplete." msgstr "Опции плагина указаны не полностью." diff --git a/luci-app-passwall2/po/zh-cn/passwall2.po b/luci-app-passwall2/po/zh-cn/passwall2.po index 1010101b..026e4e91 100644 --- a/luci-app-passwall2/po/zh-cn/passwall2.po +++ b/luci-app-passwall2/po/zh-cn/passwall2.po @@ -1648,6 +1648,12 @@ msgstr "TLS 证书名称(CertName)" msgid "TLS is used to verify the leaf certificate name." msgstr "TLS 用于验证 leaf 证书的 name。" +msgid "TLS Certificate (PEM)" +msgstr "TLS 证书(PEM)" + +msgid "Full certificate (chain), PEM format." +msgstr "完整证书(链),PEM 格式。" + msgid "ECH Config" msgstr "ECH 配置" @@ -2267,8 +2273,8 @@ msgstr "跳过 %s 节点,因未适配到 %s 核心程序,或未正确设置 msgid "Skip node: %s. Because Sing-Box does not support the %s protocol's %s transmission method, Xray needs to be used instead." msgstr "跳过节点:%s,因 Sing-Box 不支持 %s 协议的 %s 传输方式,需更换 Xray。" -msgid "Xray unsupport %s plugin." -msgstr "Xray 不支持 %s 插件。" +msgid "%s unsupport SS %s plugin." +msgstr "%s 不支持 %s 插件。" msgid "Plugin options Incomplete." msgstr "插件选项不完整。" diff --git a/luci-app-passwall2/po/zh-tw/passwall2.po b/luci-app-passwall2/po/zh-tw/passwall2.po index efea133a..cf6d3089 100644 --- a/luci-app-passwall2/po/zh-tw/passwall2.po +++ b/luci-app-passwall2/po/zh-tw/passwall2.po @@ -1648,6 +1648,12 @@ msgstr "TLS 憑證名稱(CertName)" msgid "TLS is used to verify the leaf certificate name." msgstr "TLS 用於驗證 leaf 憑證的 name。" +msgid "TLS Certificate (PEM)" +msgstr "TLS 憑證(PEM)" + +msgid "Full certificate (chain), PEM format." +msgstr "完整憑證(鏈),PEM 格式。" + msgid "ECH Config" msgstr "ECH 配置" @@ -2273,8 +2279,8 @@ msgstr "跳過 %s 節點,因未適配到 %s 核心程序,或未正確設置 msgid "Skip node: %s. Because Sing-Box does not support the %s protocol's %s transmission method, Xray needs to be used instead." msgstr "跳過節點:%s,因 Sing-Box 不支持 %s 協議的 %s 傳輸方式,需更換 Xray。" -msgid "Xray unsupport %s plugin." -msgstr "Xray 不支持 %s 插件。" +msgid "%s unsupport SS %s plugin." +msgstr "%s 不支持 %s 插件。" msgid "Plugin options Incomplete." msgstr "插件選項不完整。" diff --git a/luci-app-passwall2/root/usr/share/passwall2/app.sh b/luci-app-passwall2/root/usr/share/passwall2/app.sh index b65a3217..4a159e82 100755 --- a/luci-app-passwall2/root/usr/share/passwall2/app.sh +++ b/luci-app-passwall2/root/usr/share/passwall2/app.sh @@ -1012,9 +1012,10 @@ acl_app() { [ -n "$items" ] && { local index=0 local item - local redir_port dns_port dnsmasq_port + local redir_port dns_port dnsmasq_port socks_port local ipt_tmp msg msg2 redir_port=11200 + socks_port=11600 dns_port=11300 dnsmasq_port=${GLOBAL_DNSMASQ_PORT:-11400} for item in $items; do @@ -1098,12 +1099,13 @@ acl_app() { set_cache_var "ACL_${sid}_default" "1" else redir_port=$(get_new_port $(expr $redir_port + 1)) + socks_port=$(get_new_port $(expr $socks_port + 1)) local type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z') if [ -n "${type}" ]; then config_file=$TMP_ACL_PATH/${node}_TCP_UDP_DNS_${redir_port}.json dns_port=$(get_new_port $(expr $dns_port + 1)) - local acl_socks_port=$(get_new_port $(expr $redir_port + $index)) + local acl_socks_port=$socks_port local run_func [ -n "${XRAY_BIN}" ] && run_func="run_xray" [ -n "${SINGBOX_BIN}" ] && run_func="run_singbox" diff --git a/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua b/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua index 35104922..f8c8f01e 100755 --- a/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua +++ b/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua @@ -528,36 +528,50 @@ local function parseClashNode(node, add_mode, group, sub_cfg) elseif node.plugin == "v2ray-plugin" then result.plugin = "v2ray-plugin" end - if node["plugin-opts"] then - if node.plugin == "obfs" then - local plugin_opts = "" - local opts_mode = node["plugin-opts"].mode - if opts_mode then - plugin_opts = plugin_opts .. "obfs=" .. opts_mode .. ";" + if result.plugin then + result.plugin_enabled = "1" + if result.type == 'Xray' then + if result.plugin ~= "obfs-local" then + result.plugin_enabled = nil + result.error_msg = i18n.translatef("%s unsupport SS %s plugin.", "Xray", result.plugin) end - local opts_host = node["plugin-opts"].host - if opts_host then - plugin_opts = plugin_opts .. "obfs-host=" .. opts_host + elseif result.type == 'sing-box' then + if result.plugin ~= "obfs-local" and result.plugin ~= "v2ray-plugin" then + result.plugin_enabled = nil + result.error_msg = i18n.translatef("%s unsupport SS %s plugin.", "Sing-Box", result.plugin) end - result.plugin_opts = plugin_opts - elseif node.plugin == "v2ray-plugin" then - local plugin_opts = "" - local opts_mode = node["plugin-opts"].mode - local opts_tls = node["plugin-opts"].tls - if opts_tls then - plugin_opts = plugin_opts .. "tls;" + end + if node["plugin-opts"] and result.plugin_enabled == "1" then + if node.plugin == "obfs" then + local plugin_opts = "" + local opts_mode = node["plugin-opts"].mode + if opts_mode then + plugin_opts = plugin_opts .. "obfs=" .. opts_mode .. ";" + end + local opts_host = node["plugin-opts"].host + if opts_host then + plugin_opts = plugin_opts .. "obfs-host=" .. opts_host + end + result.plugin_opts = plugin_opts + elseif node.plugin == "v2ray-plugin" then + local plugin_opts = "" + local opts_mode = node["plugin-opts"].mode + local opts_tls = node["plugin-opts"].tls + if opts_tls then + plugin_opts = plugin_opts .. "tls;" + end + local opts_skip_cert_verify = node["plugin-opts"]["skip-cert-verify"] + local opts_host = node["plugin-opts"].host + if opts_host then + plugin_opts = plugin_opts .. "host=" .. opts_host .. ";" + end + local opts_path = node["plugin-opts"].path + local opts_mux = node["plugin-opts"].mux + if node["plugin-opts"].headers then + --todo + end + result.plugin_opts = plugin_opts end - local opts_skip_cert_verify = node["plugin-opts"]["skip-cert-verify"] - local opts_host = node["plugin-opts"].host - if opts_host then - plugin_opts = plugin_opts .. "host=" .. opts_host .. ";" - end - local opts_path = node["plugin-opts"].path - local opts_mux = node["plugin-opts"].mux - if node["plugin-opts"].headers then - --todo - end - result.plugin_opts = plugin_opts end end elseif node.type == 'ssr' then @@ -961,6 +975,11 @@ local function processData(szType, content, add_mode, group, sub_cfg) result.tls = "0" end + if info.ech and info.ech ~= "" then + result.ech = "1" + result.ech_config = info.ech + end + result.tcp_fast_open = info.tfo info.fm = (info.fm and info.fm ~= "") and UrlDecode(info.fm) or nil @@ -1090,7 +1109,7 @@ local function processData(szType, content, add_mode, group, sub_cfg) if result.type == 'Xray' then -- The obfs-local plugin converts data to a format supported by xray. if result.plugin ~= "obfs-local" then - result.error_msg = i18n.translatef("Xray unsupport %s plugin.", result.plugin) + result.error_msg = i18n.translatef("%s unsupport SS %s plugin.", "Xray", result.plugin) else local obfs = result.plugin_opts:match("obfs=([^;]+)") or "" local obfs_host = result.plugin_opts:match("obfs%-host=([^;]+)") or "" @@ -1110,6 +1129,12 @@ local function processData(szType, content, add_mode, group, sub_cfg) result.plugin = nil result.plugin_opts = nil end + elseif result.type == 'sing-box' then + if result.plugin ~= "obfs-local" and result.plugin ~= "v2ray-plugin" then + result.error_msg = i18n.translatef("%s unsupport SS %s plugin.", "Sing-Box", result.plugin) + else + result.plugin_enabled = "1" + end else result.plugin_enabled = "1" end @@ -1223,7 +1248,7 @@ local function processData(szType, content, add_mode, group, sub_cfg) local insecure = params.allowinsecure or params.allowInsecure or params.insecure result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0") result.uot = params.udp - elseif (params.type ~= "tcp" and params.type ~= "raw") and (params.headerType and params.headerType ~= "none") then + else result.error_msg = i18n.translatef("Please replace Xray or Sing-Box to support more transmission methods in Shadowsocks.") end end @@ -1684,7 +1709,7 @@ local function processData(szType, content, add_mode, group, sub_cfg) result.hysteria2_down_mbps = params.downmbps or sub_hy_down_mbps result.hysteria2_hop = params.mport if params["obfs-password"] or params["obfs_password"] then - result.hysteria2_obfs_type = "salamander" + result.hysteria2_obfs_type = params.obfs or "salamander" result.hysteria2_obfs_password = params["obfs-password"] or params["obfs_password"] end @@ -1818,6 +1843,10 @@ local function processData(szType, content, add_mode, group, sub_cfg) result.reality_publicKey = params.pbk or nil result.reality_shortId = params.sid or nil end + if params.ech and params.ech ~= "" then + result.ech = "1" + result.ech_config = params.ech + end end result.port = port local insecure = params.allowinsecure or params.insecure diff --git a/momo/Makefile b/momo/Makefile index 23aef7c5..cbb49b88 100644 --- a/momo/Makefile +++ b/momo/Makefile @@ -1,7 +1,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=momo -PKG_VERSION:=2026.04.09 +PKG_VERSION:=2026.06.03 PKG_RELEASE:=1 PKG_LICENSE:=GPL-3.0+ diff --git a/momo/files/momo.conf b/momo/files/momo.conf index a709d49b..fd86b011 100644 --- a/momo/files/momo.conf +++ b/momo/files/momo.conf @@ -121,6 +121,7 @@ config routing 'routing' option 'dummy_device' 'momo-dummy' config log 'log' + option 'clear_at_stop' '1' option 'scheduled_clear' '1' option 'scheduled_clear_cron' '*/5 * * * *' option 'scheduled_clear_size_limit' '1' diff --git a/momo/files/momo.init b/momo/files/momo.init index a8ea4de7..d94244e6 100644 --- a/momo/files/momo.init +++ b/momo/files/momo.init @@ -67,7 +67,9 @@ start_service() { local fast_reload config_get_bool fast_reload "procd" "fast_reload" 0 ### rlimit - local rlimit_address_space_soft rlimit_address_space_hard rlimit_data_soft rlimit_data_hard rlimit_stack_soft rlimit_stack_hard rlimit_nofile_soft rlimit_nofile_hard + local rlimit_nproc_soft rlimit_nproc_hard rlimit_address_space_soft rlimit_address_space_hard rlimit_data_soft rlimit_data_hard rlimit_stack_soft rlimit_stack_hard rlimit_nofile_soft rlimit_nofile_hard + config_get rlimit_nproc_soft "procd" "rlimit_nproc_soft" "$(ulimit -Su)" + config_get rlimit_nproc_hard "procd" "rlimit_nproc_hard" "$(ulimit -Hu)" config_get rlimit_address_space_soft "procd" "rlimit_address_space_soft" config_get rlimit_address_space_hard "procd" "rlimit_address_space_hard" config_get rlimit_data_soft "procd" "rlimit_data_soft" @@ -76,6 +78,10 @@ start_service() { config_get rlimit_stack_hard "procd" "rlimit_stack_hard" config_get rlimit_nofile_soft "procd" "rlimit_nofile_soft" "$(ulimit -Sn)" config_get rlimit_nofile_hard "procd" "rlimit_nofile_hard" "$(ulimit -Hn)" + ### environment variable + local env_go_max_procs env_go_mem_limit + config_get env_go_max_procs "procd" "env_go_max_procs" + config_get env_go_mem_limit "procd" "env_go_mem_limit" ## core config local redirect_inbound_tag tproxy_inbound_tag tun_inbound_tag dns_inbound_tag fake_ip_dns_server_tag config_get redirect_inbound_tag "core" "redirect_inbound_tag" @@ -133,6 +139,8 @@ start_service() { log "Mixin" "Mixin config." ucode -S "$MIXIN_UC" fi + # format profile + $PROG -c "$RUN_PROFILE_PATH" format -w # check profile if [ "$core_only" = 0 ] && [ "$proxy_enabled" = 1 ]; then log "Profile" "Checking..." @@ -197,11 +205,16 @@ start_service() { fi procd_set_param pidfile "$PID_FILE_PATH" procd_set_param respawn + + procd_append_param limits nproc="${rlimit_nproc_soft} ${rlimit_nproc_hard}" procd_append_param limits as="${rlimit_address_space_soft:-unlimited} ${rlimit_address_space_hard:-unlimited}" procd_append_param limits data="${rlimit_data_soft:-unlimited} ${rlimit_data_hard:-unlimited}" procd_append_param limits stack="${rlimit_stack_soft:-unlimited} ${rlimit_stack_hard:-unlimited}" procd_append_param limits nofile="${rlimit_nofile_soft} ${rlimit_nofile_hard}" + procd_append_param env GOMAXPROCS="$env_go_max_procs" + procd_append_param env GOMEMLIMIT="$env_go_mem_limit" + procd_close_instance # cron local reload_cron; reload_cron=0 @@ -379,11 +392,20 @@ cleanup() { # load config config_load momo # get config + ## log config + local log_clear_at_stop + config_get_bool log_clear_at_stop "log" "clear_at_stop" 0 ## routing config local tproxy_route_table tun_route_table dummy_device config_get tproxy_route_table "routing" "tproxy_route_table" "80" config_get tun_route_table "routing" "tun_route_table" "81" config_get dummy_device "routing" "dummy_device" "momo-dummy" + # clear logs if needed + if [ "$log_clear_at_stop" = 1 ]; then + echo -n > "$APP_LOG_PATH" + echo -n > "$CORE_LOG_PATH" + log "Log" "Logs are cleared due to clear at stop is enabled." + fi # delete routing policy ip -4 rule del table "$tproxy_route_table" > /dev/null 2>&1 ip -4 rule del table "$tun_route_table" > /dev/null 2>&1 diff --git a/momo/files/uci-defaults/migrate.sh b/momo/files/uci-defaults/migrate.sh index 9dab7d1c..11cb9414 100644 --- a/momo/files/uci-defaults/migrate.sh +++ b/momo/files/uci-defaults/migrate.sh @@ -51,6 +51,9 @@ section_mixin=$(uci -q get momo.mixin); [ -z "$section_mixin" ] && { uci set momo.mixin.external_control_ui_download_url='https://github.com/Zephyruso/zashboard/releases/latest/download/dist-cdn-fonts.zip' } +# since v1.2.1 +config_clear_at_stop=$(uci -q get momo.log.clear_at_stop); [ -z "$config_clear_at_stop" ] && uci set momo.log.clear_at_stop=1 + # commit uci commit momo diff --git a/momo/files/ucode/hijack.ut b/momo/files/ucode/hijack.ut index 9baa1a73..31ddaa0e 100644 --- a/momo/files/ucode/hijack.ut +++ b/momo/files/ucode/hijack.ut @@ -248,6 +248,7 @@ table inet momo { } {% if (router_proxy): %} + {% if (length(dns_hijack_nfproto) > 0): %} chain router_dns_hijack { {% for (let access_control in router_access_control): %} {% if (length(access_control['user']) == 0 && length(access_control['group']) == 0 && length(access_control['cgroup']) == 0): %} @@ -267,6 +268,7 @@ table inet momo { {% endif %} {% endfor %} } + {% endif %} {% if (tcp_mode == 'redirect'): %} chain router_redirect { @@ -360,6 +362,7 @@ table inet momo { {% endif %} {% if (lan_proxy): %} + {% if (length(dns_hijack_nfproto) > 0): %} chain lan_dns_hijack { {% for (let access_control in lan_access_control): %} {% if (length(access_control['ip']) == 0 && length(access_control['ip6']) == 0 && length(access_control['mac']) == 0): %} @@ -381,6 +384,7 @@ table inet momo { {% endif %} {% endfor %} } + {% endif %} {% if (tcp_mode == 'redirect'): %} chain lan_redirect { diff --git a/v2ray-geodata/Makefile b/v2ray-geodata/Makefile index 5418aaff..bce078fd 100644 --- a/v2ray-geodata/Makefile +++ b/v2ray-geodata/Makefile @@ -21,13 +21,13 @@ define Download/geoip HASH:=e9002979e0df72bce1c8751ff70725386594c551db684b7a232935b8b2bb8aa2 endef -GEOSITE_VER:=20260602145358 +GEOSITE_VER:=20260603121550 GEOSITE_FILE:=dlc.dat.$(GEOSITE_VER) define Download/geosite URL:=https://github.com/v2fly/domain-list-community/releases/download/$(GEOSITE_VER)/ URL_FILE:=dlc.dat FILE:=$(GEOSITE_FILE) - HASH:=92d535187e8a2eee0a3cfb3ed22e481884c4fb93a7ab903e30b26ca405fa530b + HASH:=fab7cce3d3009121a88939d616f0366d3067741dce21424b627426cbd17f1e62 endef GEOSITE_IRAN_VER:=202606010205