mirror of
https://github.com/caiwx86/small-packages.git
synced 2026-09-10 18:34:09 +08:00
update 2026-06-04 00:28:20
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 ""
|
||||
|
||||
|
||||
@@ -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 "按大小触发日志清理"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 2>/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 2>/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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 = {}
|
||||
|
||||
|
||||
@@ -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 })
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 })
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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("^([^+]+)%+(.+)$")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 || "");
|
||||
|
||||
@@ -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 "گزینههای افزونه ناقص است."
|
||||
|
||||
@@ -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 "Опции плагина указаны не полностью."
|
||||
|
||||
@@ -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 "插件选项不完整。"
|
||||
|
||||
@@ -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 "插件選項不完整。"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
+1
-1
@@ -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+
|
||||
|
||||
@@ -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'
|
||||
|
||||
+23
-1
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user