mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-07-27 02:11:19 +08:00
🌴 Sync 2026-07-14 04:31:14
This commit is contained in:
parent
f398c537dc
commit
0f3b9d2516
@ -6,9 +6,9 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=dae
|
||||
PKG_VERSION:=2026.07.08
|
||||
PKG_RELEASE:=15
|
||||
PKG_RELEASE:=16
|
||||
|
||||
PKG_SOURCE:=dae-src-2026.07.08-ca25ef2aa396.tar.gz
|
||||
PKG_SOURCE:=dae-src-2026.07.08-6a60ae809f8b.tar.gz
|
||||
PKG_SOURCE_URL:=https://github.com/kenzok8/openwrt-daede/releases/download/dae-src
|
||||
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
|
||||
PKG_HASH:=skip
|
||||
|
||||
@ -6,9 +6,9 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=daed
|
||||
PKG_VERSION:=2026.07.08
|
||||
PKG_RELEASE:=21
|
||||
PKG_RELEASE:=22
|
||||
|
||||
PKG_SOURCE:=daed-src-2026.07.08-71b818ad193b.tar.gz
|
||||
PKG_SOURCE:=daed-src-2026.07.08-e83da9ff800e.tar.gz
|
||||
PKG_SOURCE_URL:=https://github.com/kenzok8/openwrt-daede/releases/download/daed-src
|
||||
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
|
||||
PKG_HASH:=skip
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=hysteria
|
||||
PKG_VERSION:=2.9.3
|
||||
PKG_RELEASE:=11
|
||||
PKG_VERSION:=2.10.0
|
||||
PKG_RELEASE:=12
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/apernet/hysteria/tar.gz/app/v$(PKG_VERSION)?
|
||||
|
||||
@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=internet-detector
|
||||
PKG_VERSION:=1.7.3
|
||||
PKG_RELEASE:=3
|
||||
PKG_RELEASE:=4
|
||||
PKG_MAINTAINER:=gSpot <https://github.com/gSpotx2f/luci-app-internet-detector>
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
@ -64,4 +64,15 @@ define Package/$(PKG_NAME)/install
|
||||
$(INSTALL_DATA) ./files/usr/lib/lua/internet-detector/modules/mod_regular_script.lua $(1)/usr/lib/lua/internet-detector/modules/mod_regular_script.lua
|
||||
endef
|
||||
|
||||
define Package/$(PKG_NAME)/postinst
|
||||
#!/bin/sh
|
||||
|
||||
ID_CONF="/etc/internet-detector"
|
||||
SYSUP_CONF="/etc/sysupgrade.conf"
|
||||
|
||||
grep -e "^$${ID_CONF}" "$$SYSUP_CONF" > /dev/null || echo "$$ID_CONF" >> "$$SYSUP_CONF"
|
||||
|
||||
exit 0
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,$(PKG_NAME)))
|
||||
|
||||
@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-daede
|
||||
PKG_VERSION:=1.14.7
|
||||
PKG_RELEASE:=31
|
||||
PKG_RELEASE:=32
|
||||
PKG_MAINTAINER:=kenzok8
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
|
||||
|
||||
|
||||
@ -52,19 +52,26 @@ fi
|
||||
(
|
||||
flock 9
|
||||
apk update 2>&1
|
||||
# pin exact latest version + --force-broken-world so unrelated broken
|
||||
# packages can't block this upgrade (cf. clashoo component_update)
|
||||
ver=$(apk list "$PKG" 2>/dev/null | awk -v p="$PKG" '$1 ~ "^" p "-[0-9]" { v=$1; sub("^" p "-", "", v); print v }' | sort -V | tail -1)
|
||||
if [ -n "$ver" ]; then
|
||||
echo "--- apk add $PKG=$ver ---"
|
||||
apk add "$PKG=$ver" --force-broken-world 2>&1
|
||||
constraint="$PKG=$ver"
|
||||
else
|
||||
echo "--- apk add $PKG ---"
|
||||
apk add "$PKG" --force-broken-world 2>&1
|
||||
constraint="$PKG"
|
||||
fi
|
||||
|
||||
echo "--- apk add -s $constraint ---"
|
||||
if apk add -s "$constraint" 2>&1; then
|
||||
echo "--- apk add $constraint ---"
|
||||
apk add "$constraint" 2>&1
|
||||
else
|
||||
echo "result: apk cannot resolve $constraint; no packages were changed"
|
||||
exit 1
|
||||
fi
|
||||
) 9>/tmp/luci-app-daede.apk.lock
|
||||
# apk's exit code is unreliable (broken-world noise); judge by state instead
|
||||
if ! apk list --installed 2>/dev/null | grep -q "^${PKG}-"; then
|
||||
rc=$?
|
||||
if [ "$rc" != 0 ]; then
|
||||
:
|
||||
elif ! apk list --installed 2>/dev/null | grep -q "^${PKG}-"; then
|
||||
echo "result: $PKG is not installed"
|
||||
rc=1
|
||||
elif apk list -u 2>/dev/null | grep -q "^${PKG}-"; then
|
||||
|
||||
@ -164,7 +164,7 @@ const inbound_type = [
|
||||
['anytls', _('AnyTLS') + ' - ' + _('TCP')],
|
||||
['tuic', _('TUIC') + ' - ' + _('UDP')],
|
||||
['hysteria2', _('Hysteria2') + ' - ' + _('UDP')],
|
||||
['hysteria2-realm', _('Hysteria2 Realm') + ' - ' + _('TCP/UDP')],
|
||||
['hysteria2-realm', _('Hysteria2 Realm Server') + ' - ' + _('TCP/UDP')],
|
||||
['trusttunnel', _('TrustTunnel') + ' - ' + _('TCP/UDP')],
|
||||
['tunnel', _('Tunnel') + ' - ' + _('TCP/UDP')]
|
||||
];
|
||||
@ -198,12 +198,12 @@ const outbound_type = [
|
||||
['vless', _('VLESS') + ' - ' + _('TCP')],
|
||||
['trojan', _('Trojan') + ' - ' + _('TCP')],
|
||||
['anytls', _('AnyTLS') + ' - ' + _('TCP')],
|
||||
['tuic', _('TUIC') + ' - ' + _('UDP')],
|
||||
//['hysteria', _('Hysteria') + ' - ' + _('UDP')],
|
||||
['hysteria2', _('Hysteria2') + ' - ' + _('UDP')],
|
||||
['tuic', _('TUIC') + ' - ' + _('UDP')],
|
||||
['masque', _('Masque') + ' - ' + _('UDP')], // https://blog.cloudflare.com/post-quantum-warp/
|
||||
['trusttunnel', _('TrustTunnel') + ' - ' + _('TCP/UDP')],
|
||||
['wireguard', _('WireGuard') + ' - ' + _('UDP')],
|
||||
['masque', _('Masque') + ' - ' + _('UDP')], // https://blog.cloudflare.com/post-quantum-warp/
|
||||
['ssh', _('SSH') + ' - ' + _('TCP')]
|
||||
];
|
||||
|
||||
|
||||
@ -171,86 +171,6 @@ function renderListeners(s, uciconfig, isClient) {
|
||||
o.depends({type: /^(tuic)$/, uuid: /.+/});
|
||||
o.modalonly = true;
|
||||
|
||||
/* Hysteria2 fields */
|
||||
o = s.taboption('field_general', form.Value, 'hysteria_up_mbps', _('Max upload speed'),
|
||||
_('In Mbps.'));
|
||||
o.datatype = 'uinteger';
|
||||
o.depends('type', 'hysteria2');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_general', form.Value, 'hysteria_down_mbps', _('Max download speed'),
|
||||
_('In Mbps.'));
|
||||
o.datatype = 'uinteger';
|
||||
o.depends('type', 'hysteria2');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_general', form.Flag, 'hysteria_ignore_client_bandwidth', _('Ignore client bandwidth'),
|
||||
_('Tell the client to use the BBR flow control algorithm instead of Hysteria CC.'));
|
||||
o.default = o.disabled;
|
||||
o.depends({type: 'hysteria2', hysteria_up_mbps: '', hysteria_down_mbps: ''});
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_general', form.ListValue, 'hysteria_obfs_type', _('Obfuscate type'));
|
||||
o.value('', _('Disable'));
|
||||
o.value('salamander', _('Salamander'));
|
||||
o.value('gecko', _('Gecko'));
|
||||
o.depends('type', 'hysteria2');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_general', hm.GenValue, 'hysteria_obfs_password', _('Obfuscate password'),
|
||||
_('Enabling obfuscation will make the server incompatible with standard QUIC connections, losing the ability to masquerade with HTTP/3.'));
|
||||
o.password = true;
|
||||
o.rmempty = false;
|
||||
o.depends('type', 'hysteria');
|
||||
o.depends({type: 'hysteria2', hysteria_obfs_type: /.+/});
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_general', form.Value, 'hysteria_obfs_min_packet_size', _('Obfuscate minimum packet size'));
|
||||
o.placeholder = '512'
|
||||
o.depends('hysteria_obfs_type', 'gecko');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_general', form.Value, 'hysteria_obfs_max_packet_size', _('Obfuscate maximum packet size'));
|
||||
o.placeholder = '1200'
|
||||
o.depends('hysteria_obfs_type', 'gecko');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_general', form.Value, 'hysteria_masquerade', _('Masquerade'),
|
||||
_('HTTP3 server behavior when authentication fails.<br/>A 404 page will be returned if empty.'));
|
||||
o.placeholder = 'file:///var/www or http://127.0.0.1:8080'
|
||||
o.depends('type', 'hysteria2');
|
||||
o.modalonly = true;
|
||||
|
||||
/* Hysteria2 Realmserver fields */
|
||||
o = s.taboption('field_general', form.Value, 'hysteria2_realmserver_token', _('Pre-shared key'));
|
||||
o.placeholder = 'public';
|
||||
o.rmempty = false;
|
||||
o.depends('type', 'hysteria2-realm');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_general', form.Value, 'hysteria2_realmserver_max_realms', _('Max realms'));
|
||||
o.datatype = 'uinteger';
|
||||
o.placeholder = '65536';
|
||||
o.depends('type', 'hysteria2-realm');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_general', form.Value, 'hysteria2_realmserver_max_realms_per_ip', _('Max realms per client IP'));
|
||||
o.datatype = 'uinteger';
|
||||
o.placeholder = '4';
|
||||
o.depends('type', 'hysteria2-realm');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_general', form.Value, 'hysteria2_realmserver_trusted_proxy_header', _('Trusted proxy header'),
|
||||
_('Header to read real client IP from (e.g. X-Forwarded-For)'));
|
||||
o.depends('type', 'hysteria2-realm');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_general', form.Value, 'hysteria2_realmserver_realm_name_pattern', _('Realm name pattern'));
|
||||
o.default = '^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$';
|
||||
o.rmempty = false;
|
||||
o.depends('type', 'hysteria2-realm');
|
||||
o.modalonly = true;
|
||||
|
||||
/* Shadowsocks fields */
|
||||
o = s.taboption('field_general', form.ListValue, 'shadowsocks_chipher', _('Chipher'));
|
||||
o.default = hm.shadowsocks_cipher_methods[1][0];
|
||||
@ -470,31 +390,26 @@ function renderListeners(s, uciconfig, isClient) {
|
||||
o.depends('type', 'snell');
|
||||
o.modalonly = true;
|
||||
|
||||
/* Tuic fields */
|
||||
o = s.taboption('field_general', hm.GenValue, 'uuid', _('UUID'));
|
||||
/* VMess / VLESS fields */
|
||||
o = s.taboption('field_general', hm.GenValue, 'vmess_uuid', _('UUID'));
|
||||
o.rmempty = false;
|
||||
o.validate = hm.validateUUID;
|
||||
o.depends('type', 'tuic');
|
||||
o.depends({type: /^(vmess|vless)$/});
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_general', form.Value, 'tuic_max_udp_relay_packet_size', _('Max UDP relay packet size'));
|
||||
o = s.taboption('field_general', form.ListValue, 'vless_flow', _('Flow'));
|
||||
o.default = hm.vless_flow[0][0];
|
||||
hm.vless_flow.forEach((res) => {
|
||||
o.value.apply(o, res);
|
||||
})
|
||||
o.depends('type', 'vless');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_general', form.Value, 'vmess_alterid', _('Alter ID'),
|
||||
_('Legacy protocol support (VMess MD5 Authentication) is provided for compatibility purposes only, use of alterId > 1 is not recommended.'));
|
||||
o.datatype = 'uinteger';
|
||||
o.default = '1500';
|
||||
o.depends('type', 'tuic');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_general', form.Value, 'tuic_max_idle_time', _('Idle timeout'),
|
||||
_('In seconds.'));
|
||||
o.default = '15000';
|
||||
o.validate = hm.validateTimeDuration;
|
||||
o.depends('type', 'tuic');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_general', form.Value, 'tuic_authentication_timeout', _('Auth timeout'),
|
||||
_('In seconds.'));
|
||||
o.default = '1000';
|
||||
o.validate = hm.validateTimeDuration;
|
||||
o.depends('type', 'tuic');
|
||||
o.placeholder = '0';
|
||||
o.depends('type', 'vmess');
|
||||
o.modalonly = true;
|
||||
|
||||
/* Trojan fields */
|
||||
@ -525,26 +440,111 @@ function renderListeners(s, uciconfig, isClient) {
|
||||
o.depends('type', 'anytls');
|
||||
o.modalonly = true;
|
||||
|
||||
/* VMess / VLESS fields */
|
||||
o = s.taboption('field_general', hm.GenValue, 'vmess_uuid', _('UUID'));
|
||||
/* Tuic fields */
|
||||
o = s.taboption('field_general', hm.GenValue, 'uuid', _('UUID'));
|
||||
o.rmempty = false;
|
||||
o.validate = hm.validateUUID;
|
||||
o.depends({type: /^(vmess|vless)$/});
|
||||
o.depends('type', 'tuic');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_general', form.ListValue, 'vless_flow', _('Flow'));
|
||||
o.default = hm.vless_flow[0][0];
|
||||
hm.vless_flow.forEach((res) => {
|
||||
o.value.apply(o, res);
|
||||
})
|
||||
o.depends('type', 'vless');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_general', form.Value, 'vmess_alterid', _('Alter ID'),
|
||||
_('Legacy protocol support (VMess MD5 Authentication) is provided for compatibility purposes only, use of alterId > 1 is not recommended.'));
|
||||
o = s.taboption('field_general', form.Value, 'tuic_max_udp_relay_packet_size', _('Max UDP relay packet size'));
|
||||
o.datatype = 'uinteger';
|
||||
o.placeholder = '0';
|
||||
o.depends('type', 'vmess');
|
||||
o.default = '1500';
|
||||
o.depends('type', 'tuic');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_general', form.Value, 'tuic_max_idle_time', _('Idle timeout'),
|
||||
_('In seconds.'));
|
||||
o.default = '15000';
|
||||
o.validate = hm.validateTimeDuration;
|
||||
o.depends('type', 'tuic');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_general', form.Value, 'tuic_authentication_timeout', _('Auth timeout'),
|
||||
_('In seconds.'));
|
||||
o.default = '1000';
|
||||
o.validate = hm.validateTimeDuration;
|
||||
o.depends('type', 'tuic');
|
||||
o.modalonly = true;
|
||||
|
||||
/* Hysteria2 fields */
|
||||
o = s.taboption('field_general', form.Value, 'hysteria_up_mbps', _('Max upload speed'),
|
||||
_('In Mbps.'));
|
||||
o.datatype = 'uinteger';
|
||||
o.depends('type', 'hysteria2');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_general', form.Value, 'hysteria_down_mbps', _('Max download speed'),
|
||||
_('In Mbps.'));
|
||||
o.datatype = 'uinteger';
|
||||
o.depends('type', 'hysteria2');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_general', form.Flag, 'hysteria_ignore_client_bandwidth', _('Ignore client bandwidth'),
|
||||
_('Tell the client to use the BBR flow control algorithm instead of Hysteria CC.'));
|
||||
o.default = o.disabled;
|
||||
o.depends({type: 'hysteria2', hysteria_up_mbps: '', hysteria_down_mbps: ''});
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_general', form.ListValue, 'hysteria_obfs_type', _('Obfuscate type'));
|
||||
o.value('', _('Disable'));
|
||||
o.value('salamander', _('Salamander'));
|
||||
o.value('gecko', _('Gecko'));
|
||||
o.depends('type', 'hysteria2');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_general', hm.GenValue, 'hysteria_obfs_password', _('Obfuscate password'),
|
||||
_('Enabling obfuscation will make the server incompatible with standard QUIC connections, losing the ability to masquerade with HTTP/3.'));
|
||||
o.password = true;
|
||||
o.rmempty = false;
|
||||
o.depends('type', 'hysteria');
|
||||
o.depends({type: 'hysteria2', hysteria_obfs_type: /.+/});
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_general', form.Value, 'hysteria_obfs_min_packet_size', _('Obfuscate minimum packet size'));
|
||||
o.placeholder = '512'
|
||||
o.depends('hysteria_obfs_type', 'gecko');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_general', form.Value, 'hysteria_obfs_max_packet_size', _('Obfuscate maximum packet size'));
|
||||
o.placeholder = '1200'
|
||||
o.depends('hysteria_obfs_type', 'gecko');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_general', form.Value, 'hysteria_masquerade', _('Masquerade'),
|
||||
_('HTTP3 server behavior when authentication fails.<br/>A 404 page will be returned if empty.'));
|
||||
o.placeholder = 'file:///var/www or http://127.0.0.1:8080'
|
||||
o.depends('type', 'hysteria2');
|
||||
o.modalonly = true;
|
||||
|
||||
/* Hysteria2 Realmserver fields */
|
||||
o = s.taboption('field_general', form.Value, 'hysteria2_realmserver_token', _('Pre-shared key'));
|
||||
o.placeholder = 'public';
|
||||
o.rmempty = false;
|
||||
o.depends('type', 'hysteria2-realm');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_general', form.Value, 'hysteria2_realmserver_max_realms', _('Max realms'));
|
||||
o.datatype = 'uinteger';
|
||||
o.placeholder = '65536';
|
||||
o.depends('type', 'hysteria2-realm');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_general', form.Value, 'hysteria2_realmserver_max_realms_per_ip', _('Max realms per client IP'));
|
||||
o.datatype = 'uinteger';
|
||||
o.placeholder = '4';
|
||||
o.depends('type', 'hysteria2-realm');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_general', form.Value, 'hysteria2_realmserver_trusted_proxy_header', _('Trusted proxy header'),
|
||||
_('Header to read real client IP from (e.g. X-Forwarded-For)'));
|
||||
o.depends('type', 'hysteria2-realm');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_general', form.Value, 'hysteria2_realmserver_realm_name_pattern', _('Realm name pattern'));
|
||||
o.default = '^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$';
|
||||
o.rmempty = false;
|
||||
o.depends('type', 'hysteria2-realm');
|
||||
o.modalonly = true;
|
||||
|
||||
/* TrustTunnel fields */
|
||||
@ -622,6 +622,7 @@ function renderListeners(s, uciconfig, isClient) {
|
||||
if (isClient) {
|
||||
o = s.taboption('field_general', form.Value, 'routing_mark', _('Routing mark (Fwmark)'));
|
||||
o.datatype = 'uinteger';
|
||||
o.modalonly = false;
|
||||
o.editable = true;
|
||||
|
||||
o = s.taboption('field_general', hm.ListValue, 'rule', _('Sub rule'),
|
||||
@ -633,6 +634,7 @@ function renderListeners(s, uciconfig, isClient) {
|
||||
...hm.loadLabelValues(this.config, 'subrule-group')
|
||||
], section_id);
|
||||
}
|
||||
o.modalonly = false;
|
||||
o.editable = true;
|
||||
|
||||
o = s.taboption('field_general', hm.ListValue, 'proxy', _('Proxy group'),
|
||||
@ -647,6 +649,7 @@ function renderListeners(s, uciconfig, isClient) {
|
||||
...hm.loadLabelValues(this.config, 'proxy_group')
|
||||
], section_id);
|
||||
}
|
||||
o.modalonly = false;
|
||||
o.editable = true;
|
||||
}
|
||||
|
||||
@ -947,8 +950,8 @@ function renderListeners(s, uciconfig, isClient) {
|
||||
let def_alpn;
|
||||
|
||||
switch (type) {
|
||||
case 'hysteria2':
|
||||
case 'tuic':
|
||||
case 'hysteria2':
|
||||
def_alpn = ['h3'];
|
||||
break;
|
||||
case 'hysteria2-realm':
|
||||
@ -1032,7 +1035,7 @@ function renderListeners(s, uciconfig, isClient) {
|
||||
hm.tls_client_auth_types.forEach((res) => {
|
||||
o.value.apply(o, res);
|
||||
})
|
||||
o.depends({tls: '1', type: /^(http|socks|mixed|vmess|vless|trojan|anytls|hysteria2|hysteria2-realm|tuic|trusttunnel)$/});
|
||||
o.depends({tls: '1', type: /^(http|socks|mixed|vmess|vless|trojan|anytls|tuic|hysteria2|hysteria2-realm|trusttunnel)$/});
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_tls', form.Value, 'tls_client_auth_cert_path', _('Client Auth Certificate path') + _(' (mTLS)'),
|
||||
@ -1041,7 +1044,7 @@ function renderListeners(s, uciconfig, isClient) {
|
||||
o.validate = function(/* ... */) {
|
||||
return hm.validateMTLSClientAuth.call(this, 'tls_client_auth_type', ...arguments);
|
||||
}
|
||||
o.depends({tls: '1', type: /^(http|socks|mixed|vmess|vless|trojan|anytls|hysteria2|hysteria2-realm|tuic|trusttunnel)$/});
|
||||
o.depends({tls: '1', type: /^(http|socks|mixed|vmess|vless|trojan|anytls|tuic|hysteria2|hysteria2-realm|trusttunnel)$/});
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_tls', form.Button, '_upload_client_auth_cert', _('Upload certificate') + _(' (mTLS)'),
|
||||
@ -1090,13 +1093,13 @@ function renderListeners(s, uciconfig, isClient) {
|
||||
|
||||
return node;
|
||||
}
|
||||
o.depends({tls: '1', type: /^(http|socks|mixed|vmess|vless|trojan|anytls|hysteria2|hysteria2-realm|tuic|trusttunnel)$/});
|
||||
o.depends({tls: '1', type: /^(http|socks|mixed|vmess|vless|trojan|anytls|tuic|hysteria2|hysteria2-realm|trusttunnel)$/});
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_tls', hm.CopyValue, 'tls_ech_config', _('ECH config'),
|
||||
_('This ECH parameter needs to be added to the HTTPS record of the domain.'));
|
||||
o.placeholder = 'AEn+DQBFKwAgACABWIHUGj4u+PIggYXcR5JF0gYk3dCRioBW8uJq9H4mKAAIAAEAAQABAANAEnB1YmxpYy50bHMtZWNoLmRldgAA';
|
||||
o.depends({tls: '1', type: /^(http|socks|mixed|vmess|vless|trojan|anytls|hysteria2|hysteria2-realm|tuic|trusttunnel)$/});
|
||||
o.depends({tls: '1', type: /^(http|socks|mixed|vmess|vless|trojan|anytls|tuic|hysteria2|hysteria2-realm|trusttunnel)$/});
|
||||
o.modalonly = true;
|
||||
|
||||
// uTLS fields
|
||||
@ -1235,7 +1238,7 @@ function renderListeners(s, uciconfig, isClient) {
|
||||
/* Multiplex fields */
|
||||
o = s.taboption('field_general', form.Flag, 'smux_enabled', _('Multiplex'));
|
||||
o.default = o.disabled;
|
||||
o.depends({type: /^(shadowsocks|vmess|vless|trojan|tuic|hysteria2|sudoku)$/});
|
||||
o.depends({type: /^(shadowsocks|sudoku|vmess|vless|trojan|tuic|hysteria2)$/});
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('field_multiplex', form.Flag, 'smux_padding', _('Enable padding'));
|
||||
|
||||
@ -130,7 +130,7 @@ const parseProviderYaml = hm.parseYaml.extend({
|
||||
override_prefix: this.jq(cfg, "override.additional-prefix"),
|
||||
override_suffix: this.jq(cfg, "override.additional-suffix"),
|
||||
override_replace: (this.jq(cfg, "override.proxy-name") || []).map((obj) => JSON.stringify(obj)), // array.string: array.object
|
||||
// Configuration Items
|
||||
// Other configuration items
|
||||
override_tfo: this.bool2str(this.jq(cfg, "override.tfo")), // bool
|
||||
override_mptcp: this.bool2str(this.jq(cfg, "override.mptcp")), // bool
|
||||
override_udp: this.bool2str(this.jq(cfg, "override.udp")), // bool
|
||||
@ -306,7 +306,7 @@ return view.extend({
|
||||
so = ss.taboption('field_general', form.Value, 'password', _('Password'));
|
||||
so.password = true;
|
||||
so.validate = hm.validateAuthPassword;
|
||||
so.depends({type: /^(http|socks5|mieru|trojan|anytls|hysteria2|tuic|trusttunnel|ssh)$/});
|
||||
so.depends({type: /^(http|socks5|mieru|trojan|anytls|tuic|hysteria2|trusttunnel|ssh)$/});
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', hm.TextValue, 'headers', _('HTTP header'));
|
||||
@ -315,75 +315,6 @@ return view.extend({
|
||||
so.depends('type', 'http');
|
||||
so.modalonly = true;
|
||||
|
||||
/* Hysteria / Hysteria2 fields */
|
||||
so = ss.taboption('field_general', form.DynamicList, 'hysteria_ports', _('Ports pool'));
|
||||
so.datatype = 'or(port, portrange)';
|
||||
so.depends({type: /^(hysteria|hysteria2)$/});
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Value, 'hysteria_hop_interval', _('Port hop interval'),
|
||||
_('In seconds. <code>%s</code> will be used if empty.').format('30'));
|
||||
so.placeholder = '15 OR 15-30';
|
||||
so.depends('type', 'hysteria2');
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Value, 'hysteria_up_mbps', _('Max upload speed'),
|
||||
_('In Mbps.'));
|
||||
so.datatype = 'uinteger';
|
||||
so.depends({type: /^(hysteria|hysteria2)$/});
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Value, 'hysteria_down_mbps', _('Max download speed'),
|
||||
_('In Mbps.'));
|
||||
so.datatype = 'uinteger';
|
||||
so.depends({type: /^(hysteria|hysteria2)$/});
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.ListValue, 'hysteria_obfs_type', _('Obfuscate type'));
|
||||
so.value('', _('Disable'));
|
||||
so.value('salamander', _('Salamander'));
|
||||
so.value('gecko', _('Gecko'));
|
||||
so.depends('type', 'hysteria2');
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Value, 'hysteria_obfs_password', _('Obfuscate password'),
|
||||
_('Enabling obfuscation will make the server incompatible with standard QUIC connections, losing the ability to masquerade with HTTP/3.'));
|
||||
so.password = true;
|
||||
so.rmempty = false;
|
||||
so.depends('type', 'hysteria');
|
||||
so.depends({type: 'hysteria2', hysteria_obfs_type: /.+/});
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Value, 'hysteria_obfs_min_packet_size', _('Obfuscate minimum packet size'));
|
||||
so.placeholder = '512'
|
||||
so.depends('hysteria_obfs_type', 'gecko');
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Value, 'hysteria_obfs_max_packet_size', _('Obfuscate maximum packet size'));
|
||||
so.placeholder = '1200'
|
||||
so.depends('hysteria_obfs_type', 'gecko');
|
||||
so.modalonly = true;
|
||||
|
||||
/* SSH fields */
|
||||
so = ss.taboption('field_general', form.TextValue, 'ssh_priv_key', _('Priv-key'));
|
||||
so.depends('type', 'ssh');
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Value, 'ssh_priv_key_passphrase', _('Priv-key passphrase'));
|
||||
so.password = true;
|
||||
so.depends({type: 'ssh', ssh_priv_key: /.+/});
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.DynamicList, 'ssh_host_key_algorithms', _('Host-key algorithms'));
|
||||
so.placeholder = 'rsa';
|
||||
so.depends('type', 'ssh');
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.DynamicList, 'ssh_host_key', _('Host-key'));
|
||||
so.placeholder = 'ssh-rsa AAAAB3NzaC1yc2EAA...';
|
||||
so.depends({type: 'ssh', ssh_host_key_algorithms: /.+/});
|
||||
so.modalonly = true;
|
||||
|
||||
/* Shadowsocks fields */
|
||||
so = ss.taboption('field_general', form.ListValue, 'shadowsocks_chipher', _('Chipher'));
|
||||
so.default = hm.shadowsocks_cipher_methods[1][0];
|
||||
@ -574,6 +505,100 @@ return view.extend({
|
||||
so.depends({type: 'snell', snell_version: /^(4|5)$/});
|
||||
so.modalonly = true;
|
||||
|
||||
/* VMess / VLESS fields */
|
||||
so = ss.taboption('field_general', form.Value, 'vmess_uuid', _('UUID'));
|
||||
so.rmempty = false;
|
||||
so.validate = hm.validateUUID;
|
||||
so.depends({type: /^(vmess|vless)$/});
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.ListValue, 'vless_flow', _('Flow'));
|
||||
so.default = hm.vless_flow[0][0];
|
||||
hm.vless_flow.forEach((res) => {
|
||||
so.value.apply(so, res);
|
||||
})
|
||||
so.depends('type', 'vless');
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Value, 'vmess_alterid', _('Alter ID'));
|
||||
so.datatype = 'uinteger';
|
||||
so.default = '0';
|
||||
so.depends('type', 'vmess');
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.ListValue, 'vmess_chipher', _('Chipher'));
|
||||
so.default = 'auto';
|
||||
so.value('auto', _('auto'));
|
||||
so.value('none', _('none'));
|
||||
so.value('zero', _('zero'));
|
||||
so.value('aes-128-gcm', _('aes-128-gcm'));
|
||||
so.value('chacha20-poly1305', _('chacha20-poly1305'));
|
||||
so.depends('type', 'vmess');
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Flag, 'vmess_global_padding', _('Global padding'),
|
||||
_('Protocol parameter. Will waste traffic randomly if enabled (enabled by default in v2ray and cannot be disabled).'));
|
||||
so.default = so.enabled;
|
||||
so.depends('type', 'vmess');
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Flag, 'vmess_authenticated_length', _('Authenticated length'),
|
||||
_('Protocol parameter. Enable length block encryption.'));
|
||||
so.default = so.disabled;
|
||||
so.depends('type', 'vmess');
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.ListValue, 'vmess_packet_encoding', _('Packet encoding'));
|
||||
so.value('', _('none'));
|
||||
so.value('packetaddr', _('packet addr (v2ray-core v5+)'));
|
||||
so.value('xudp', _('Xudp (Xray-core)'));
|
||||
so.depends({type: /^(vmess|vless)$/});
|
||||
so.modalonly = true;
|
||||
|
||||
/* Trojan fields */
|
||||
so = ss.taboption('field_general', form.Flag, 'trojan_ss_enabled', _('Shadowsocks encrypt'));
|
||||
so.default = so.disabled;
|
||||
so.depends('type', 'trojan');
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.ListValue, 'trojan_ss_chipher', _('Shadowsocks chipher'));
|
||||
so.default = hm.trojan_cipher_methods[0][0];
|
||||
hm.trojan_cipher_methods.forEach((res) => {
|
||||
so.value.apply(so, res);
|
||||
})
|
||||
so.depends({type: 'trojan', trojan_ss_enabled: '1'});
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Value, 'trojan_ss_password', _('Shadowsocks password'));
|
||||
so.password = true;
|
||||
so.validate = function(section_id, value) {
|
||||
const encmode = this.section.getOption('trojan_ss_chipher').formvalue(section_id);
|
||||
return hm.validateShadowsocksPassword.call(this, encmode, section_id, value);
|
||||
}
|
||||
so.depends({type: 'trojan', trojan_ss_enabled: '1'});
|
||||
so.modalonly = true;
|
||||
|
||||
/* AnyTLS fields */
|
||||
so = ss.taboption('field_general', form.Value, 'anytls_idle_session_check_interval', _('Idle session check interval'),
|
||||
_('In seconds.'));
|
||||
so.placeholder = '30';
|
||||
so.validate = hm.validateTimeDuration;
|
||||
so.depends('type', 'anytls');
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Value, 'anytls_idle_session_timeout', _('Idle session timeout'),
|
||||
_('In seconds.'));
|
||||
so.placeholder = '30';
|
||||
so.validate = hm.validateTimeDuration;
|
||||
so.depends('type', 'anytls');
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Value, 'anytls_min_idle_session', _('Min of idle sessions to keep'));
|
||||
so.datatype = 'uinteger';
|
||||
so.placeholder = '0';
|
||||
so.depends('type', 'anytls');
|
||||
so.modalonly = true;
|
||||
|
||||
/* TUIC fields */
|
||||
so = ss.taboption('field_general', form.Value, 'uuid', _('UUID'));
|
||||
so.rmempty = false;
|
||||
@ -644,165 +669,53 @@ return view.extend({
|
||||
so.depends('type', 'tuic');
|
||||
so.modalonly = true;
|
||||
|
||||
/* Trojan fields */
|
||||
so = ss.taboption('field_general', form.Flag, 'trojan_ss_enabled', _('Shadowsocks encrypt'));
|
||||
so.default = so.disabled;
|
||||
so.depends('type', 'trojan');
|
||||
/* Hysteria / Hysteria2 fields */
|
||||
so = ss.taboption('field_general', form.DynamicList, 'hysteria_ports', _('Ports pool'));
|
||||
so.datatype = 'or(port, portrange)';
|
||||
so.depends({type: /^(hysteria|hysteria2)$/});
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.ListValue, 'trojan_ss_chipher', _('Shadowsocks chipher'));
|
||||
so.default = hm.trojan_cipher_methods[0][0];
|
||||
hm.trojan_cipher_methods.forEach((res) => {
|
||||
so.value.apply(so, res);
|
||||
})
|
||||
so.depends({type: 'trojan', trojan_ss_enabled: '1'});
|
||||
so = ss.taboption('field_general', form.Value, 'hysteria_hop_interval', _('Port hop interval'),
|
||||
_('In seconds. <code>%s</code> will be used if empty.').format('30'));
|
||||
so.placeholder = '15 OR 15-30';
|
||||
so.depends('type', 'hysteria2');
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Value, 'trojan_ss_password', _('Shadowsocks password'));
|
||||
so.password = true;
|
||||
so.validate = function(section_id, value) {
|
||||
const encmode = this.section.getOption('trojan_ss_chipher').formvalue(section_id);
|
||||
return hm.validateShadowsocksPassword.call(this, encmode, section_id, value);
|
||||
}
|
||||
so.depends({type: 'trojan', trojan_ss_enabled: '1'});
|
||||
so.modalonly = true;
|
||||
|
||||
/* AnyTLS fields */
|
||||
so = ss.taboption('field_general', form.Value, 'anytls_idle_session_check_interval', _('Idle session check interval'),
|
||||
_('In seconds.'));
|
||||
so.placeholder = '30';
|
||||
so.validate = hm.validateTimeDuration;
|
||||
so.depends('type', 'anytls');
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Value, 'anytls_idle_session_timeout', _('Idle session timeout'),
|
||||
_('In seconds.'));
|
||||
so.placeholder = '30';
|
||||
so.validate = hm.validateTimeDuration;
|
||||
so.depends('type', 'anytls');
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Value, 'anytls_min_idle_session', _('Min of idle sessions to keep'));
|
||||
so = ss.taboption('field_general', form.Value, 'hysteria_up_mbps', _('Max upload speed'),
|
||||
_('In Mbps.'));
|
||||
so.datatype = 'uinteger';
|
||||
so.placeholder = '0';
|
||||
so.depends('type', 'anytls');
|
||||
so.depends({type: /^(hysteria|hysteria2)$/});
|
||||
so.modalonly = true;
|
||||
|
||||
/* VMess / VLESS fields */
|
||||
so = ss.taboption('field_general', form.Value, 'vmess_uuid', _('UUID'));
|
||||
so.rmempty = false;
|
||||
so.validate = hm.validateUUID;
|
||||
so.depends({type: /^(vmess|vless)$/});
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.ListValue, 'vless_flow', _('Flow'));
|
||||
so.default = hm.vless_flow[0][0];
|
||||
hm.vless_flow.forEach((res) => {
|
||||
so.value.apply(so, res);
|
||||
})
|
||||
so.depends('type', 'vless');
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Value, 'vmess_alterid', _('Alter ID'));
|
||||
so = ss.taboption('field_general', form.Value, 'hysteria_down_mbps', _('Max download speed'),
|
||||
_('In Mbps.'));
|
||||
so.datatype = 'uinteger';
|
||||
so.default = '0';
|
||||
so.depends('type', 'vmess');
|
||||
so.depends({type: /^(hysteria|hysteria2)$/});
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.ListValue, 'vmess_chipher', _('Chipher'));
|
||||
so.default = 'auto';
|
||||
so.value('auto', _('auto'));
|
||||
so.value('none', _('none'));
|
||||
so.value('zero', _('zero'));
|
||||
so.value('aes-128-gcm', _('aes-128-gcm'));
|
||||
so.value('chacha20-poly1305', _('chacha20-poly1305'));
|
||||
so.depends('type', 'vmess');
|
||||
so = ss.taboption('field_general', form.ListValue, 'hysteria_obfs_type', _('Obfuscate type'));
|
||||
so.value('', _('Disable'));
|
||||
so.value('salamander', _('Salamander'));
|
||||
so.value('gecko', _('Gecko'));
|
||||
so.depends('type', 'hysteria2');
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Flag, 'vmess_global_padding', _('Global padding'),
|
||||
_('Protocol parameter. Will waste traffic randomly if enabled (enabled by default in v2ray and cannot be disabled).'));
|
||||
so.default = so.enabled;
|
||||
so.depends('type', 'vmess');
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Flag, 'vmess_authenticated_length', _('Authenticated length'),
|
||||
_('Protocol parameter. Enable length block encryption.'));
|
||||
so.default = so.disabled;
|
||||
so.depends('type', 'vmess');
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.ListValue, 'vmess_packet_encoding', _('Packet encoding'));
|
||||
so.value('', _('none'));
|
||||
so.value('packetaddr', _('packet addr (v2ray-core v5+)'));
|
||||
so.value('xudp', _('Xudp (Xray-core)'));
|
||||
so.depends({type: /^(vmess|vless)$/});
|
||||
so.modalonly = true;
|
||||
|
||||
/* Masque fields */
|
||||
so = ss.taboption('field_general', form.Value, 'masque_private_key', _('Private key'),
|
||||
_('Base64 encoded ECDSA private key on the NIST P-256 curve.'));
|
||||
so = ss.taboption('field_general', form.Value, 'hysteria_obfs_password', _('Obfuscate password'),
|
||||
_('Enabling obfuscation will make the server incompatible with standard QUIC connections, losing the ability to masquerade with HTTP/3.'));
|
||||
so.password = true;
|
||||
so.validate = L.bind(hm.validateBase64Key, so, 164);
|
||||
so.rmempty = false;
|
||||
so.depends('type', 'masque');
|
||||
so.depends('type', 'hysteria');
|
||||
so.depends({type: 'hysteria2', hysteria_obfs_type: /.+/});
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Value, 'masque_endpoint_public_key', _('Endpoint pubkic key'),
|
||||
_('Base64 encoded ECDSA public key on the NIST P-256 curve.'));
|
||||
so.validate = L.bind(hm.validateBase64Key, so, 124);
|
||||
so.rmempty = false;
|
||||
so.depends('type', 'masque');
|
||||
so = ss.taboption('field_general', form.Value, 'hysteria_obfs_min_packet_size', _('Obfuscate minimum packet size'));
|
||||
so.placeholder = '512'
|
||||
so.depends('hysteria_obfs_type', 'gecko');
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Value, 'masque_ip', _('Local address'),
|
||||
_('The %s address used by local machine in the Cloudflare WARP network.').format('IPv4'));
|
||||
so.datatype = 'ip4addr(1)';
|
||||
so.placeholder = '172.16.0.2';
|
||||
so.rmempty = false;
|
||||
so.depends({type: 'masque', masque_network: /^(|h2)$/});
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Value, 'masque_ipv6', _('Local IPv6 address'),
|
||||
_('The %s address used by local machine in the Cloudflare WARP network.').format('IPv6'));
|
||||
so.datatype = 'ip6addr(1)';
|
||||
so.depends({type: 'masque', masque_network: /^(|h2)$/});
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Value, 'masque_mtu', _('MTU'));
|
||||
so.datatype = 'range(0,9000)';
|
||||
so.placeholder = '1280';
|
||||
so.depends({type: 'masque', masque_network: /^(|h2)$/});
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.ListValue, 'masque_network', _('Network'));
|
||||
so.default = '';
|
||||
so.value('', _('h3'));
|
||||
so.value('h3-l4proxy', _('h3-l4proxy'));
|
||||
so.value('h2', _('h2'));
|
||||
so.validate = function(section_id, value) {
|
||||
const udp = this.section.getUIElement(section_id, 'udp').node.querySelector('input');
|
||||
|
||||
// Force disabled
|
||||
if (value === 'h3-l4proxy') {
|
||||
udp.checked = false;
|
||||
udp.disabled = true;
|
||||
} else
|
||||
udp.removeAttribute('disabled');
|
||||
|
||||
return true;
|
||||
}
|
||||
so.depends('type', 'masque');
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Flag, 'masque_remote_dns_resolve', _('Remote DNS resolve'),
|
||||
_('Force DNS remote resolution.'));
|
||||
so.default = so.disabled;
|
||||
so.depends('type', 'masque');
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.DynamicList, 'masque_dns', _('DNS server'));
|
||||
so.datatype = 'or(host, hostport)';
|
||||
so.depends('masque_remote_dns_resolve', '1');
|
||||
so = ss.taboption('field_general', form.Value, 'hysteria_obfs_max_packet_size', _('Obfuscate maximum packet size'));
|
||||
so.placeholder = '1200'
|
||||
so.depends('hysteria_obfs_type', 'gecko');
|
||||
so.modalonly = true;
|
||||
|
||||
/* TrustTunnel fields */
|
||||
@ -888,6 +801,93 @@ return view.extend({
|
||||
so.depends('wireguard_remote_dns_resolve', '1');
|
||||
so.modalonly = true;
|
||||
|
||||
/* Masque fields */
|
||||
so = ss.taboption('field_general', form.Value, 'masque_private_key', _('Private key'),
|
||||
_('Base64 encoded ECDSA private key on the NIST P-256 curve.'));
|
||||
so.password = true;
|
||||
so.validate = L.bind(hm.validateBase64Key, so, 164);
|
||||
so.rmempty = false;
|
||||
so.depends('type', 'masque');
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Value, 'masque_endpoint_public_key', _('Endpoint pubkic key'),
|
||||
_('Base64 encoded ECDSA public key on the NIST P-256 curve.'));
|
||||
so.validate = L.bind(hm.validateBase64Key, so, 124);
|
||||
so.rmempty = false;
|
||||
so.depends('type', 'masque');
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Value, 'masque_ip', _('Local address'),
|
||||
_('The %s address used by local machine in the Cloudflare WARP network.').format('IPv4'));
|
||||
so.datatype = 'ip4addr(1)';
|
||||
so.placeholder = '172.16.0.2';
|
||||
so.rmempty = false;
|
||||
so.depends({type: 'masque', masque_network: /^(|h2)$/});
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Value, 'masque_ipv6', _('Local IPv6 address'),
|
||||
_('The %s address used by local machine in the Cloudflare WARP network.').format('IPv6'));
|
||||
so.datatype = 'ip6addr(1)';
|
||||
so.depends({type: 'masque', masque_network: /^(|h2)$/});
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Value, 'masque_mtu', _('MTU'));
|
||||
so.datatype = 'range(0,9000)';
|
||||
so.placeholder = '1280';
|
||||
so.depends({type: 'masque', masque_network: /^(|h2)$/});
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.ListValue, 'masque_network', _('Network'));
|
||||
so.default = '';
|
||||
so.value('', _('h3'));
|
||||
so.value('h3-l4proxy', _('h3-l4proxy'));
|
||||
so.value('h2', _('h2'));
|
||||
so.validate = function(section_id, value) {
|
||||
const udp = this.section.getUIElement(section_id, 'udp').node.querySelector('input');
|
||||
|
||||
// Force disabled
|
||||
if (value === 'h3-l4proxy') {
|
||||
udp.checked = false;
|
||||
udp.disabled = true;
|
||||
} else
|
||||
udp.removeAttribute('disabled');
|
||||
|
||||
return true;
|
||||
}
|
||||
so.depends('type', 'masque');
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Flag, 'masque_remote_dns_resolve', _('Remote DNS resolve'),
|
||||
_('Force DNS remote resolution.'));
|
||||
so.default = so.disabled;
|
||||
so.depends('type', 'masque');
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.DynamicList, 'masque_dns', _('DNS server'));
|
||||
so.datatype = 'or(host, hostport)';
|
||||
so.depends('masque_remote_dns_resolve', '1');
|
||||
so.modalonly = true;
|
||||
|
||||
/* SSH fields */
|
||||
so = ss.taboption('field_general', form.TextValue, 'ssh_priv_key', _('Priv-key'));
|
||||
so.depends('type', 'ssh');
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Value, 'ssh_priv_key_passphrase', _('Priv-key passphrase'));
|
||||
so.password = true;
|
||||
so.depends({type: 'ssh', ssh_priv_key: /.+/});
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.DynamicList, 'ssh_host_key_algorithms', _('Host-key algorithms'));
|
||||
so.placeholder = 'rsa';
|
||||
so.depends('type', 'ssh');
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.DynamicList, 'ssh_host_key', _('Host-key'));
|
||||
so.placeholder = 'ssh-rsa AAAAB3NzaC1yc2EAA...';
|
||||
so.depends({type: 'ssh', ssh_host_key_algorithms: /.+/});
|
||||
so.modalonly = true;
|
||||
|
||||
/* Plugin fields */
|
||||
so = ss.taboption('field_general', form.ListValue, 'plugin', _('Plugin'));
|
||||
so.value('', _('none'));
|
||||
@ -975,12 +975,12 @@ return view.extend({
|
||||
_('The default value is <code>%s</code>, indicating that only the outer connection timeout is used.').format('0'));
|
||||
so.datatype = 'uinteger';
|
||||
so.placeholder = '30';
|
||||
so.depends({type: /^(masque|openvpn)$/});
|
||||
so.depends({type: /^(openvpn|masque)$/});
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.Flag, 'udp', _('UDP'));
|
||||
so.default = so.disabled;
|
||||
so.depends({type: /^(rematch|direct|socks5|ss|mieru|vmess|vless|trojan|anytls|trusttunnel|masque|wireguard)$/});
|
||||
so.depends({type: /^(rematch|direct|socks5|ss|mieru|vmess|vless|trojan|anytls|trusttunnel|wireguard|masque)$/});
|
||||
so.depends({type: 'snell', snell_version: /^(3|4|5)$/});
|
||||
so.modalonly = true;
|
||||
|
||||
@ -1115,7 +1115,7 @@ return view.extend({
|
||||
|
||||
return true;
|
||||
}
|
||||
so.depends({type: /^(http|socks5|vmess|vless|trojan|anytls|hysteria|hysteria2|tuic|trusttunnel|masque)$/});
|
||||
so.depends({type: /^(http|socks5|vmess|vless|trojan|anytls|tuic|hysteria|hysteria2|trusttunnel|masque)$/});
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_tls', form.Flag, 'tls_disable_sni', _('Disable SNI'),
|
||||
@ -1146,9 +1146,9 @@ return view.extend({
|
||||
case 'snell':
|
||||
def_alpn = ['h2', 'http/1.1']; // when plugin === 'shadow-tls'
|
||||
break;
|
||||
case 'tuic':
|
||||
case 'hysteria':
|
||||
case 'hysteria2':
|
||||
case 'tuic':
|
||||
def_alpn = ['h3'];
|
||||
break;
|
||||
case 'vmess':
|
||||
@ -1171,7 +1171,7 @@ return view.extend({
|
||||
|
||||
return true;
|
||||
}
|
||||
so.depends({tls: '1', type: /^(vmess|vless|trojan|anytls|hysteria|hysteria2|tuic|trusttunnel)$/});
|
||||
so.depends({tls: '1', type: /^(vmess|vless|trojan|anytls|tuic|hysteria|hysteria2|trusttunnel)$/});
|
||||
so.depends({type: /^(ss|snell)$/, plugin: 'shadow-tls'});
|
||||
so.modalonly = true;
|
||||
|
||||
@ -1193,7 +1193,7 @@ return view.extend({
|
||||
'<br/>' +
|
||||
_('This is <strong>DANGEROUS</strong>, your traffic is almost like <strong>PLAIN TEXT</strong>! Use at your own risk!'));
|
||||
so.default = so.disabled;
|
||||
so.depends({tls: '1', type: /^(http|socks5|vmess|vless|trojan|anytls|hysteria|hysteria2|tuic|trusttunnel)$/});
|
||||
so.depends({tls: '1', type: /^(http|socks5|vmess|vless|trojan|anytls|tuic|hysteria|hysteria2|trusttunnel)$/});
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_tls', form.Value, 'tls_cert_path', _('Certificate path') + _(' (mTLS)'),
|
||||
@ -1226,7 +1226,7 @@ return view.extend({
|
||||
|
||||
so = ss.taboption('field_tls', form.Flag, 'tls_ech', _('Enable ECH'));
|
||||
so.default = so.disabled;
|
||||
so.depends({tls: '1', type: /^(vmess|vless|trojan|anytls|hysteria|hysteria2|tuic)$/});
|
||||
so.depends({tls: '1', type: /^(vmess|vless|trojan|anytls|tuic|hysteria|hysteria2)$/});
|
||||
so.depends({type: 'ss', plugin: /^(v2ray-plugin|gost-plugin)$/});
|
||||
so.modalonly = true;
|
||||
|
||||
@ -1899,7 +1899,7 @@ return view.extend({
|
||||
so = ss.taboption('field_override', form.DummyValue, '_config_items', null);
|
||||
so.load = function() {
|
||||
return '<a target="_blank" href="%s" rel="noreferrer noopener">%s</a>'
|
||||
.format('https://wiki.metacubex.one/config/proxy-providers/#_2', _('Configuration Items'));
|
||||
.format('https://wiki.metacubex.one/config/proxy-providers/#override_1', _('Other configuration items'));
|
||||
}
|
||||
so.rawhtml = true;
|
||||
so.depends({type: 'inline', '!reverse': true});
|
||||
|
||||
@ -566,7 +566,7 @@ msgid "Complete"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/fchomo/node.js:1898
|
||||
msgid "Configuration Items"
|
||||
msgid "Other configuration items"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/fchomo/listeners.js:653
|
||||
@ -1442,7 +1442,7 @@ msgid "Hysteria2"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/fchomo.js:167
|
||||
msgid "Hysteria2 Realm"
|
||||
msgid "Hysteria2 Realm Server"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/fchomo/listeners.js:121
|
||||
|
||||
@ -580,8 +580,8 @@ msgid "Complete"
|
||||
msgstr "完成"
|
||||
|
||||
#: htdocs/luci-static/resources/view/fchomo/node.js:1898
|
||||
msgid "Configuration Items"
|
||||
msgstr "配置项"
|
||||
msgid "Other configuration items"
|
||||
msgstr "其他配置项"
|
||||
|
||||
#: htdocs/luci-static/resources/fchomo/listeners.js:653
|
||||
#: htdocs/luci-static/resources/view/fchomo/node.js:955
|
||||
@ -1468,8 +1468,8 @@ msgid "Hysteria2"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/fchomo.js:167
|
||||
msgid "Hysteria2 Realm"
|
||||
msgstr "Hysteria2 Realm"
|
||||
msgid "Hysteria2 Realm Server"
|
||||
msgstr "Hysteria2 Realm 服务器"
|
||||
|
||||
#: htdocs/luci-static/resources/fchomo/listeners.js:121
|
||||
#: htdocs/luci-static/resources/view/fchomo/node.js:235
|
||||
|
||||
@ -580,8 +580,8 @@ msgid "Complete"
|
||||
msgstr "完成"
|
||||
|
||||
#: htdocs/luci-static/resources/view/fchomo/node.js:1898
|
||||
msgid "Configuration Items"
|
||||
msgstr "配置項"
|
||||
msgid "Other configuration items"
|
||||
msgstr "其他配置項"
|
||||
|
||||
#: htdocs/luci-static/resources/fchomo/listeners.js:653
|
||||
#: htdocs/luci-static/resources/view/fchomo/node.js:955
|
||||
@ -1468,8 +1468,8 @@ msgid "Hysteria2"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/fchomo.js:167
|
||||
msgid "Hysteria2 Realm"
|
||||
msgstr "Hysteria2 Realm"
|
||||
msgid "Hysteria2 Realm Server"
|
||||
msgstr "Hysteria2 Realm 伺服器"
|
||||
|
||||
#: htdocs/luci-static/resources/fchomo/listeners.js:121
|
||||
#: htdocs/luci-static/resources/view/fchomo/node.js:235
|
||||
|
||||
@ -490,7 +490,7 @@ uci.foreach(uciconf, ucinode, (cfg) => {
|
||||
"target-rematch-name": cfg.target_rematch_name,
|
||||
"target-sub-rule": cfg.target_sub_rule,
|
||||
|
||||
/* HTTP / SOCKS / Shadowsocks / VMess / VLESS / Trojan / hysteria2 / TUIC / WireGuard / Masque */
|
||||
/* HTTP / SOCKS / Shadowsocks / VMess / VLESS / Trojan / TUIC / hysteria2 / WireGuard / Masque */
|
||||
username: cfg.username,
|
||||
uuid: cfg.vmess_uuid || cfg.uuid,
|
||||
cipher: cfg.vmess_chipher || cfg.shadowsocks_chipher,
|
||||
@ -502,35 +502,6 @@ uci.foreach(uciconf, ucinode, (cfg) => {
|
||||
"remote-dns-resolve": strToBool(cfg.masque_remote_dns_resolve ?? cfg.wireguard_remote_dns_resolve),
|
||||
dns: cfg.masque_dns || cfg.wireguard_dns,
|
||||
|
||||
/* Hysteria / Hysteria2 */
|
||||
ports: isEmpty(cfg.hysteria_ports) ? null : join(',', cfg.hysteria_ports),
|
||||
"hop-interval": strToInt(cfg.hysteria_hop_interval), // @DEBUG ERROR data type *utils.IntRanges[uint16]
|
||||
up: cfg.hysteria_up_mbps ? cfg.hysteria_up_mbps + ' Mbps' : null,
|
||||
down: cfg.hysteria_down_mbps ? cfg.hysteria_down_mbps + ' Mbps' : null,
|
||||
obfs: cfg.hysteria_obfs_type,
|
||||
"obfs-password": cfg.hysteria_obfs_password,
|
||||
"obfs-min-packet-size": strToInt(cfg.hysteria_obfs_min_packet_size),
|
||||
"obfs-max-packet-size": strToInt(cfg.hysteria_obfs_max_packet_size),
|
||||
"realm-opts": cfg.hysteria2_realm === '1' ? {
|
||||
enable: true,
|
||||
"server-url": cfg.hysteria2_realm_server_url,
|
||||
token: cfg.hysteria2_realm_token,
|
||||
"realm-id": cfg.hysteria2_realm_id,
|
||||
"stun-servers": cfg.hysteria2_realm_stun_servers,
|
||||
// @TLS of server-url
|
||||
//sni,
|
||||
//alpn,
|
||||
//"skip-cert-verify",
|
||||
//fingerprint,
|
||||
//certificate,
|
||||
//"private-key"
|
||||
} : null,
|
||||
|
||||
/* SSH */
|
||||
"private-key-passphrase": cfg.ssh_priv_key_passphrase,
|
||||
"host-key-algorithms": cfg.ssh_host_key_algorithms,
|
||||
"host-key": cfg.ssh_host_key,
|
||||
|
||||
/* Shadowsocks */
|
||||
|
||||
/* Mieru */
|
||||
@ -564,17 +535,13 @@ uci.foreach(uciconf, ucinode, (cfg) => {
|
||||
version: cfg.snell_version,
|
||||
reuse: strToBool(cfg.snell_reuse),
|
||||
|
||||
/* TUIC */
|
||||
ip: cfg.tuic_ip,
|
||||
"udp-relay-mode": cfg.tuic_udp_relay_mode,
|
||||
"udp-over-stream": strToBool(cfg.tuic_udp_over_stream),
|
||||
"udp-over-stream-version": cfg.tuic_udp_over_stream_version,
|
||||
"max-udp-relay-packet-size": strToInt(cfg.tuic_max_udp_relay_packet_size) || null,
|
||||
"fast-open": strToBool(cfg.tuic_fast_open),
|
||||
"reduce-rtt": strToBool(cfg.tuic_reduce_rtt),
|
||||
"heartbeat-interval": strToInt(cfg.tuic_heartbeat) || null,
|
||||
"request-timeout": strToInt(cfg.tuic_request_timeout) || null,
|
||||
"max-open-streams": strToInt(cfg.tuic_max_open_streams) || null,
|
||||
/* VMess / VLESS */
|
||||
flow: cfg.vless_flow,
|
||||
alterId: strToInt(cfg.vmess_alterid),
|
||||
"global-padding": cfg.type === 'vmess' ? (cfg.vmess_global_padding === '0' ? false : true) : null,
|
||||
"authenticated-length": strToBool(cfg.vmess_authenticated_length),
|
||||
"packet-encoding": cfg.vmess_packet_encoding,
|
||||
encryption: cfg.vless_encryption === '1' ? cfg.vless_encryption_encryption : null,
|
||||
|
||||
/* Trojan */
|
||||
"ss-opts": cfg.trojan_ss_enabled === '1' ? {
|
||||
@ -588,16 +555,41 @@ uci.foreach(uciconf, ucinode, (cfg) => {
|
||||
"idle-session-timeout": durationToSecond(cfg.anytls_idle_session_timeout),
|
||||
"min-idle-session": strToInt(cfg.anytls_min_idle_session),
|
||||
|
||||
/* VMess / VLESS */
|
||||
flow: cfg.vless_flow,
|
||||
alterId: strToInt(cfg.vmess_alterid),
|
||||
"global-padding": cfg.type === 'vmess' ? (cfg.vmess_global_padding === '0' ? false : true) : null,
|
||||
"authenticated-length": strToBool(cfg.vmess_authenticated_length),
|
||||
"packet-encoding": cfg.vmess_packet_encoding,
|
||||
encryption: cfg.vless_encryption === '1' ? cfg.vless_encryption_encryption : null,
|
||||
/* TUIC */
|
||||
ip: cfg.tuic_ip,
|
||||
"udp-relay-mode": cfg.tuic_udp_relay_mode,
|
||||
"udp-over-stream": strToBool(cfg.tuic_udp_over_stream),
|
||||
"udp-over-stream-version": cfg.tuic_udp_over_stream_version,
|
||||
"max-udp-relay-packet-size": strToInt(cfg.tuic_max_udp_relay_packet_size) || null,
|
||||
"fast-open": strToBool(cfg.tuic_fast_open),
|
||||
"reduce-rtt": strToBool(cfg.tuic_reduce_rtt),
|
||||
"heartbeat-interval": strToInt(cfg.tuic_heartbeat) || null,
|
||||
"request-timeout": strToInt(cfg.tuic_request_timeout) || null,
|
||||
"max-open-streams": strToInt(cfg.tuic_max_open_streams) || null,
|
||||
|
||||
/* Masque */
|
||||
network: cfg.masque_network || null,
|
||||
/* Hysteria / Hysteria2 */
|
||||
ports: isEmpty(cfg.hysteria_ports) ? null : join(',', cfg.hysteria_ports),
|
||||
"hop-interval": strToInt(cfg.hysteria_hop_interval), // @DEBUG ERROR data type *utils.IntRanges[uint16]
|
||||
up: cfg.hysteria_up_mbps ? cfg.hysteria_up_mbps + ' Mbps' : null,
|
||||
down: cfg.hysteria_down_mbps ? cfg.hysteria_down_mbps + ' Mbps' : null,
|
||||
obfs: cfg.hysteria_obfs_type,
|
||||
"obfs-password": cfg.hysteria_obfs_password,
|
||||
"obfs-min-packet-size": strToInt(cfg.hysteria_obfs_min_packet_size),
|
||||
"obfs-max-packet-size": strToInt(cfg.hysteria_obfs_max_packet_size),
|
||||
"realm-opts": cfg.hysteria2_realm === '1' ? {
|
||||
enable: true,
|
||||
"server-url": cfg.hysteria2_realm_server_url,
|
||||
token: cfg.hysteria2_realm_token,
|
||||
"realm-id": cfg.hysteria2_realm_id,
|
||||
"stun-servers": cfg.hysteria2_realm_stun_servers,
|
||||
// @TLS of server-url
|
||||
//sni,
|
||||
//alpn,
|
||||
//"skip-cert-verify",
|
||||
//fingerprint,
|
||||
//certificate,
|
||||
//"private-key"
|
||||
} : null,
|
||||
|
||||
/* TrustTunnel */
|
||||
"health-check": cfg.type === 'trusttunnel' ? (cfg.trusttunnel_health_check === '0' ? false : true) : null,
|
||||
@ -609,6 +601,14 @@ uci.foreach(uciconf, ucinode, (cfg) => {
|
||||
reserved: cfg.wireguard_reserved,
|
||||
"persistent-keepalive": strToInt(cfg.wireguard_persistent_keepalive),
|
||||
|
||||
/* Masque */
|
||||
network: cfg.masque_network || null,
|
||||
|
||||
/* SSH */
|
||||
"private-key-passphrase": cfg.ssh_priv_key_passphrase,
|
||||
"host-key-algorithms": cfg.ssh_host_key_algorithms,
|
||||
"host-key": cfg.ssh_host_key,
|
||||
|
||||
/* Plugin fields */
|
||||
...(cfg.plugin ? (
|
||||
cfg.type === 'snell' ? {
|
||||
@ -820,7 +820,7 @@ uci.foreach(uciconf, uciprov, (cfg) => {
|
||||
"additional-prefix": cfg.override_prefix,
|
||||
"additional-suffix": cfg.override_suffix,
|
||||
"proxy-name": isEmpty(cfg.override_replace) ? null : map(cfg.override_replace, obj => json(obj)),
|
||||
// Configuration Items
|
||||
// Other configuration items
|
||||
tfo: strToBool(cfg.override_tfo),
|
||||
mptcp: strToBool(cfg.override_mptcp),
|
||||
udp: (cfg.override_udp === '0') ? null : true,
|
||||
|
||||
@ -246,37 +246,6 @@ export function parseListener(cfg, isClient, label) {
|
||||
...arrToObj([[cfg.uuid, cfg.password]])
|
||||
} : null),
|
||||
|
||||
/* Hysteria2 */
|
||||
up: strToInt(cfg.hysteria_up_mbps),
|
||||
down: strToInt(cfg.hysteria_down_mbps),
|
||||
"ignore-client-bandwidth": strToBool(cfg.hysteria_ignore_client_bandwidth),
|
||||
obfs: cfg.hysteria_obfs_type,
|
||||
"obfs-password": cfg.hysteria_obfs_password,
|
||||
"obfs-min-packet-size": strToInt(cfg.hysteria_obfs_min_packet_size),
|
||||
"obfs-max-packet-size": strToInt(cfg.hysteria_obfs_max_packet_size),
|
||||
masquerade: cfg.hysteria_masquerade,
|
||||
"realm-opts": cfg.hysteria2_realm === '1' ? {
|
||||
enable: true,
|
||||
"server-url": cfg.hysteria2_realm_server_url,
|
||||
token: cfg.hysteria2_realm_token,
|
||||
"realm-id": cfg.hysteria2_realm_id,
|
||||
"stun-servers": cfg.hysteria2_realm_stun_servers,
|
||||
// @TLS of server-url
|
||||
//sni,
|
||||
//alpn,
|
||||
//"skip-cert-verify",
|
||||
//fingerprint,
|
||||
//certificate,
|
||||
//"private-key"
|
||||
} : null,
|
||||
|
||||
/* Hysteria2 Realmserver */
|
||||
token: cfg.hysteria2_realmserver_token,
|
||||
"max-realms": strToInt(cfg.hysteria2_realmserver_max_realms),
|
||||
"max-realms-per-ip": strToInt(cfg.hysteria2_realmserver_max_realms_per_ip),
|
||||
"trusted-proxy-header": cfg.hysteria2_realmserver_trusted_proxy_header,
|
||||
"realm-name-pattern": cfg.hysteria2_realmserver_realm_name_pattern,
|
||||
|
||||
/* Shadowsocks */
|
||||
cipher: cfg.shadowsocks_chipher,
|
||||
password: cfg.shadowsocks_password,
|
||||
@ -308,10 +277,8 @@ export function parseListener(cfg, isClient, label) {
|
||||
psk: cfg.snell_psk,
|
||||
version: cfg.snell_version,
|
||||
|
||||
/* Tuic */
|
||||
"max-idle-time": durationToSecond(cfg.tuic_max_idle_time),
|
||||
"authentication-timeout": durationToSecond(cfg.tuic_authentication_timeout),
|
||||
"max-udp-relay-packet-size": strToInt(cfg.tuic_max_udp_relay_packet_size),
|
||||
/* VMess / VLESS */
|
||||
decryption: cfg.vless_decryption === '1' ? parseVlessEncryption(cfg.vless_encryption_hmpayload, 'server') : null,
|
||||
|
||||
/* Trojan */
|
||||
"ss-option": cfg.trojan_ss_enabled === '1' ? {
|
||||
@ -323,8 +290,43 @@ export function parseListener(cfg, isClient, label) {
|
||||
/* AnyTLS */
|
||||
"padding-scheme": cfg.anytls_padding_scheme,
|
||||
|
||||
/* VMess / VLESS */
|
||||
decryption: cfg.vless_decryption === '1' ? parseVlessEncryption(cfg.vless_encryption_hmpayload, 'server') : null,
|
||||
/* Tuic */
|
||||
"max-idle-time": durationToSecond(cfg.tuic_max_idle_time),
|
||||
"authentication-timeout": durationToSecond(cfg.tuic_authentication_timeout),
|
||||
"max-udp-relay-packet-size": strToInt(cfg.tuic_max_udp_relay_packet_size),
|
||||
|
||||
/* Hysteria2 */
|
||||
up: strToInt(cfg.hysteria_up_mbps),
|
||||
down: strToInt(cfg.hysteria_down_mbps),
|
||||
"ignore-client-bandwidth": strToBool(cfg.hysteria_ignore_client_bandwidth),
|
||||
obfs: cfg.hysteria_obfs_type,
|
||||
"obfs-password": cfg.hysteria_obfs_password,
|
||||
"obfs-min-packet-size": strToInt(cfg.hysteria_obfs_min_packet_size),
|
||||
"obfs-max-packet-size": strToInt(cfg.hysteria_obfs_max_packet_size),
|
||||
masquerade: cfg.hysteria_masquerade,
|
||||
"realm-opts": cfg.hysteria2_realm === '1' ? {
|
||||
enable: true,
|
||||
"server-url": cfg.hysteria2_realm_server_url,
|
||||
token: cfg.hysteria2_realm_token,
|
||||
"realm-id": cfg.hysteria2_realm_id,
|
||||
"stun-servers": cfg.hysteria2_realm_stun_servers,
|
||||
// @TLS of server-url
|
||||
//sni,
|
||||
//alpn,
|
||||
//"skip-cert-verify",
|
||||
//fingerprint,
|
||||
//certificate,
|
||||
//"private-key"
|
||||
} : null,
|
||||
|
||||
/* Hysteria2 Realmserver */
|
||||
token: cfg.hysteria2_realmserver_token,
|
||||
"max-realms": strToInt(cfg.hysteria2_realmserver_max_realms),
|
||||
"max-realms-per-ip": strToInt(cfg.hysteria2_realmserver_max_realms_per_ip),
|
||||
"trusted-proxy-header": cfg.hysteria2_realmserver_trusted_proxy_header,
|
||||
"realm-name-pattern": cfg.hysteria2_realmserver_realm_name_pattern,
|
||||
|
||||
/* TrustTunnel */
|
||||
|
||||
/* Tunnel */
|
||||
target: cfg.tunnel_target,
|
||||
|
||||
@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-passwall
|
||||
PKG_VERSION:=26.7.1
|
||||
PKG_RELEASE:=177
|
||||
PKG_RELEASE:=178
|
||||
PKG_PO_VERSION:=$(PKG_VERSION)
|
||||
|
||||
PKG_CONFIG_DEPENDS:= \
|
||||
|
||||
@ -109,6 +109,7 @@ function index()
|
||||
for _, com in ipairs(coms.order) do
|
||||
entry({"admin", "services", appname, "check_" .. com}, call("com_check", com)).leaf = true
|
||||
entry({"admin", "services", appname, "update_" .. com}, call("com_update", com)).leaf = true
|
||||
entry({"admin", "services", appname, "version_" .. com}, call("com_version", com)).leaf = true
|
||||
end
|
||||
|
||||
--[[Backup]]
|
||||
@ -881,6 +882,11 @@ function com_update(comname)
|
||||
http_write_json(json)
|
||||
end
|
||||
|
||||
function com_version(comname)
|
||||
local version = api.get_app_version(comname)
|
||||
http_write_json_ok(version)
|
||||
end
|
||||
|
||||
function read_rulelist()
|
||||
local rule_type = http.formvalue("type")
|
||||
local rule_path
|
||||
|
||||
@ -1,22 +1,24 @@
|
||||
local api = require "luci.passwall.api"
|
||||
local com = require "luci.passwall.com"
|
||||
local appname = "passwall"
|
||||
|
||||
m = Map(appname)
|
||||
api.set_apply_on_parse(m)
|
||||
|
||||
-- [[ App Settings ]]--
|
||||
s = m:section(TypedSection, "global_app", translate("App Update"),
|
||||
"<font color='red'>" ..
|
||||
translate("Please confirm that your firmware supports FPU.") ..
|
||||
"</font>")
|
||||
s = m:section(TypedSection, "global_app", translate("App Update"))
|
||||
s.anonymous = true
|
||||
s:append(Template(appname .. "/app_update/app_version"))
|
||||
|
||||
local app_version = Template(appname .. "/app_update/app_version")
|
||||
app_version.api = api
|
||||
app_version.config = m.config
|
||||
app_version.com = com
|
||||
s:append(app_version)
|
||||
|
||||
o = s:option(Flag, "github_proxy", translate("GitHub Proxy"), translate("Use gh-proxy instead of proxy nodes for component updates."))
|
||||
o.default = 0
|
||||
|
||||
local k, v
|
||||
local com = require "luci.passwall.com"
|
||||
for _, k in ipairs(com.order) do
|
||||
v = com[k]
|
||||
if k ~= "chinadns-ng" then
|
||||
|
||||
@ -229,13 +229,8 @@ end
|
||||
o = s:option(Flag, "boot_update", translate("Update Once on Boot"), translate("Updates the subscription the first time PassWall runs automatically after each system boot."))
|
||||
o.default = 0
|
||||
|
||||
---- Enable auto update subscribe
|
||||
o = s:option(Flag, "auto_update", translate("Enable auto update subscribe"))
|
||||
o.default = 0
|
||||
o.rmempty = false
|
||||
|
||||
---- Week Update
|
||||
o = s:option(ListValue, "week_update", translate("Update Mode"))
|
||||
o = s:option(ListValue, "update_week_mode", translate("Auto Update Mode"))
|
||||
o:value("", translate("Disable"))
|
||||
o:value(8, translate("Loop Mode"))
|
||||
o:value(7, translate("Every day"))
|
||||
o:value(1, translate("Every Monday"))
|
||||
@ -245,29 +240,30 @@ o:value(4, translate("Every Thursday"))
|
||||
o:value(5, translate("Every Friday"))
|
||||
o:value(6, translate("Every Saturday"))
|
||||
o:value(0, translate("Every Sunday"))
|
||||
o.default = 7
|
||||
o:depends("auto_update", true)
|
||||
o.rmempty = true
|
||||
|
||||
---- Time Update
|
||||
o = s:option(ListValue, "time_update", translate("Update Time(every day)"))
|
||||
for t = 0, 23 do o:value(t, t .. ":00") end
|
||||
o.default = 0
|
||||
o:depends("week_update", "0")
|
||||
o:depends("week_update", "1")
|
||||
o:depends("week_update", "2")
|
||||
o:depends("week_update", "3")
|
||||
o:depends("week_update", "4")
|
||||
o:depends("week_update", "5")
|
||||
o:depends("week_update", "6")
|
||||
o:depends("week_update", "7")
|
||||
o.rmempty = true
|
||||
o = s:option(Value, "update_time_mode", translate("Update Time"))
|
||||
for t = 0, 23 do o:value(t .. ":00") end
|
||||
o.default = "0:00"
|
||||
o.validate = function(self, value)
|
||||
local b = api.is_timehhmm(value)
|
||||
if b then
|
||||
return value
|
||||
end
|
||||
return nil
|
||||
end
|
||||
o:depends("update_week_mode", "0")
|
||||
o:depends("update_week_mode", "1")
|
||||
o:depends("update_week_mode", "2")
|
||||
o:depends("update_week_mode", "3")
|
||||
o:depends("update_week_mode", "4")
|
||||
o:depends("update_week_mode", "5")
|
||||
o:depends("update_week_mode", "6")
|
||||
o:depends("update_week_mode", "7")
|
||||
|
||||
---- Interval Update
|
||||
o = s:option(ListValue, "interval_update", translate("Update Interval(hour)"))
|
||||
o = s:option(ListValue, "update_interval_mode", translate("Update Interval(hour)"))
|
||||
for t = 1, 24 do o:value(t, t .. " " .. translate("hour")) end
|
||||
o.default = 2
|
||||
o:depends("week_update", "8")
|
||||
o:depends("update_week_mode", "8")
|
||||
o.rmempty = true
|
||||
|
||||
o = s:option(ListValue, "access_mode", translate("Subscribe URL Access Method"))
|
||||
|
||||
@ -29,7 +29,9 @@ o.rmempty = true
|
||||
for index, value in ipairs({"stop", "start", "restart"}) do
|
||||
o = s:option(ListValue, value .. "_week_mode", translate(value .. " automatically mode"))
|
||||
o:value("", translate("Disable"))
|
||||
o:value(8, translate("Loop Mode"))
|
||||
if value == "restart" then
|
||||
o:value(8, translate("Loop Mode"))
|
||||
end
|
||||
o:value(7, translate("Every day"))
|
||||
o:value(1, translate("Every Monday"))
|
||||
o:value(2, translate("Every Tuesday"))
|
||||
@ -38,9 +40,16 @@ for index, value in ipairs({"stop", "start", "restart"}) do
|
||||
o:value(5, translate("Every Friday"))
|
||||
o:value(6, translate("Every Saturday"))
|
||||
o:value(0, translate("Every Sunday"))
|
||||
o = s:option(ListValue, value .. "_time_mode", translate(value .. " Time(Every day)"))
|
||||
for t = 0, 23 do o:value(t, t .. ":00") end
|
||||
o.default = 0
|
||||
o = s:option(Value, value .. "_time_mode", translate(value .. " Time"))
|
||||
for t = 0, 23 do o:value(t .. ":00") end
|
||||
o.default = "0:00"
|
||||
o.validate = function(self, value)
|
||||
local b = api.is_timehhmm(value)
|
||||
if b then
|
||||
return value
|
||||
end
|
||||
return nil
|
||||
end
|
||||
o:depends(value .. "_week_mode", "0")
|
||||
o:depends(value .. "_week_mode", "1")
|
||||
o:depends(value .. "_week_mode", "2")
|
||||
|
||||
@ -97,13 +97,8 @@ if has_xray or has_singbox then
|
||||
end
|
||||
end
|
||||
|
||||
---- Auto Update
|
||||
o = s:option(Flag, "auto_update", translate("Enable auto update rules"))
|
||||
o.default = 0
|
||||
o.rmempty = false
|
||||
|
||||
---- Week Update
|
||||
o = s:option(ListValue, "week_update", translate("Update Mode"))
|
||||
o = s:option(ListValue, "update_week_mode", translate("Auto Update Mode"))
|
||||
o:value("", translate("Disable"))
|
||||
o:value(8, translate("Loop Mode"))
|
||||
o:value(7, translate("Every day"))
|
||||
o:value(1, translate("Every Monday"))
|
||||
@ -113,29 +108,30 @@ o:value(4, translate("Every Thursday"))
|
||||
o:value(5, translate("Every Friday"))
|
||||
o:value(6, translate("Every Saturday"))
|
||||
o:value(0, translate("Every Sunday"))
|
||||
o.default = 7
|
||||
o:depends("auto_update", true)
|
||||
o.rmempty = true
|
||||
|
||||
---- Time Update
|
||||
o = s:option(ListValue, "time_update", translate("Update Time(every day)"))
|
||||
for t = 0, 23 do o:value(t, t .. ":00") end
|
||||
o.default = 0
|
||||
o:depends("week_update", "0")
|
||||
o:depends("week_update", "1")
|
||||
o:depends("week_update", "2")
|
||||
o:depends("week_update", "3")
|
||||
o:depends("week_update", "4")
|
||||
o:depends("week_update", "5")
|
||||
o:depends("week_update", "6")
|
||||
o:depends("week_update", "7")
|
||||
o.rmempty = true
|
||||
o = s:option(Value, "update_time_mode", translate("Update Time"))
|
||||
for t = 0, 23 do o:value(t .. ":00") end
|
||||
o.default = "0:00"
|
||||
o.validate = function(self, value)
|
||||
local b = api.is_timehhmm(value)
|
||||
if b then
|
||||
return value
|
||||
end
|
||||
return nil
|
||||
end
|
||||
o:depends("update_week_mode", "0")
|
||||
o:depends("update_week_mode", "1")
|
||||
o:depends("update_week_mode", "2")
|
||||
o:depends("update_week_mode", "3")
|
||||
o:depends("update_week_mode", "4")
|
||||
o:depends("update_week_mode", "5")
|
||||
o:depends("update_week_mode", "6")
|
||||
o:depends("update_week_mode", "7")
|
||||
|
||||
---- Interval Update
|
||||
o = s:option(ListValue, "interval_update", translate("Update Interval(hour)"))
|
||||
o = s:option(ListValue, "update_interval_mode", translate("Update Interval(hour)"))
|
||||
for t = 1, 24 do o:value(t, t .. " " .. translate("hour")) end
|
||||
o.default = 2
|
||||
o:depends("week_update", "8")
|
||||
o:depends("update_week_mode", "8")
|
||||
o.rmempty = true
|
||||
|
||||
---- 更新选项,始终被js隐藏
|
||||
|
||||
@ -152,9 +152,10 @@ if load_balancing_options then -- [[ Load balancing Start ]]
|
||||
o:depends({ [_n("node_add_mode")] = "batch" })
|
||||
local descrStr = "Example: <code>^A && B && !C && D$</code><br>"
|
||||
descrStr = descrStr .. "This means the node remark must start with A (^), include B, exclude C (!), and end with D ($).<br>"
|
||||
descrStr = descrStr .. "Conditions are joined by <code>&&</code>, and their order does not affect the result."
|
||||
o.description = translate(descrStr) .. string.format("<br><font color='red'>%s</font>",
|
||||
translate("Keep the match scope small. Too many nodes can impact router performance."))
|
||||
descrStr = descrStr .. "Conditions are joined by <code>&&</code> (AND), and their order does not affect the result.<br>"
|
||||
descrStr = descrStr .. "Multiple groups can be separated by <code>||</code> (OR), matching succeeds if any group matches.<br>"
|
||||
descrStr = descrStr .. "Example: <code>A && B || C && D</code> means (A AND B) OR (C AND D)."
|
||||
o.description = translate(descrStr)
|
||||
|
||||
o = s:option(ListValue, _n("balancingStrategy"), translate("Balancing Strategy"))
|
||||
o:depends({ [_n("protocol")] = "_balancing" })
|
||||
|
||||
@ -151,9 +151,10 @@ if load_urltest_options then -- [[ URLTest Start ]]
|
||||
o:depends({ [_n("node_add_mode")] = "batch" })
|
||||
local descrStr = "Example: <code>^A && B && !C && D$</code><br>"
|
||||
descrStr = descrStr .. "This means the node remark must start with A (^), include B, exclude C (!), and end with D ($).<br>"
|
||||
descrStr = descrStr .. "Conditions are joined by <code>&&</code>, and their order does not affect the result."
|
||||
o.description = translate(descrStr) .. string.format("<br><font color='red'>%s</font>",
|
||||
translate("Keep the match scope small. Too many nodes can impact router performance."))
|
||||
descrStr = descrStr .. "Conditions are joined by <code>&&</code> (AND), and their order does not affect the result.<br>"
|
||||
descrStr = descrStr .. "Multiple groups can be separated by <code>||</code> (OR), matching succeeds if any group matches.<br>"
|
||||
descrStr = descrStr .. "Example: <code>A && B || C && D</code> means (A AND B) OR (C AND D)."
|
||||
o.description = translate(descrStr)
|
||||
|
||||
o = s:option(Value, _n("urltest_url"), translate("Probe URL"))
|
||||
o:depends({ [_n("protocol")] = "_urltest" })
|
||||
|
||||
@ -348,6 +348,18 @@ function strToTable(str)
|
||||
return loadstring("return " .. str)()
|
||||
end
|
||||
|
||||
function is_timehhmm(timeStr)
|
||||
local hour, minute = string.match(timeStr, "^(%d?%d):(%d%d)$")
|
||||
if hour and minute then
|
||||
hour = tonumber(hour)
|
||||
minute = tonumber(minute)
|
||||
if hour >= 0 and hour <= 23 and minute >= 0 and minute <= 59 then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function is_normal_node(e)
|
||||
if e and e.type and e.protocol and (e.protocol == "_balancing" or e.protocol == "_shunt" or e.protocol == "_iface" or e.protocol == "_urltest") then
|
||||
return false
|
||||
@ -1522,11 +1534,22 @@ end
|
||||
function match_node_rule(name, rule)
|
||||
if not name then return false end
|
||||
if not rule or rule == "" then return true end
|
||||
-- split rule by || into OR groups
|
||||
local function split_or(expr)
|
||||
local t = {}
|
||||
for part in (expr .. "||"):gmatch("(.-)%|%|") do
|
||||
part = trim(part)
|
||||
if part ~= "" then
|
||||
table.insert(t, part)
|
||||
end
|
||||
end
|
||||
return t
|
||||
end
|
||||
-- split rule by &&
|
||||
local function split_and(expr)
|
||||
local t = {}
|
||||
for part in expr:gmatch("[^&]+") do
|
||||
part = part:gsub("^%s+", ""):gsub("%s+$", "")
|
||||
for part in (expr .. "&&"):gmatch("(.-)%&%&") do
|
||||
part = trim(part)
|
||||
if part ~= "" then
|
||||
table.insert(t, part)
|
||||
end
|
||||
@ -1557,13 +1580,22 @@ function match_node_rule(name, rule)
|
||||
-- contains
|
||||
return str:find(cond, 1, true) ~= nil
|
||||
end
|
||||
-- AND logic
|
||||
for _, cond in ipairs(split_and(rule)) do
|
||||
if not match_cond(name, cond) then
|
||||
return false
|
||||
-- check if all conditions in AND group match
|
||||
local function match_and_group(str, group_expr)
|
||||
for _, cond in ipairs(split_and(group_expr)) do
|
||||
if not match_cond(str, cond) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
-- OR logic: return true if any group matches
|
||||
for _, group in ipairs(split_or(rule)) do
|
||||
if match_and_group(name, group) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return true
|
||||
return false
|
||||
end
|
||||
|
||||
function get_core(field, candidates)
|
||||
|
||||
@ -900,10 +900,10 @@ function gen_config(var)
|
||||
fragment_table = {
|
||||
type = "fragment",
|
||||
settings = {
|
||||
packets = xray_settings.fragment_packets,
|
||||
lengths = #lengths > 0 and lengths or nil,
|
||||
delays = #delays > 0 and delays or nil,
|
||||
maxSplit = xray_settings.fragment_maxSplit
|
||||
packets = xray_settings.fragment_packets or "tlshello",
|
||||
lengths = #lengths > 0 and lengths or {"3-5","6-8","10-20"},
|
||||
delays = #delays > 0 and delays or {"10-20"},
|
||||
maxSplit = xray_settings.fragment_maxSplit or "3-6"
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<div id="app_version">
|
||||
<%
|
||||
local api = require "luci.passwall.api"
|
||||
local com = require "luci.passwall.com"
|
||||
local version = {}
|
||||
local api = self.api
|
||||
local com = self.com
|
||||
-%>
|
||||
|
||||
<script type="text/javascript">
|
||||
@ -194,14 +194,14 @@ local version = {}
|
||||
|
||||
<%for _, k in ipairs(com.order) do
|
||||
local v = com[k]
|
||||
version[k] = api.get_app_version(k)%>
|
||||
%>
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title"><%=v.name%>
|
||||
<%:Version%>
|
||||
</label>
|
||||
<div class="cbi-value-field">
|
||||
<!--div class="cbi-value-description"-->
|
||||
<span>【 <%=version[k] ~="" and version[k] or translate("Null") %> 】</span>
|
||||
<span>【 <span class="com_version" key="<%=k%>"><%=translate("Null")%></span> 】</span>
|
||||
<input class="btn cbi-button cbi-button-apply" type="button" id="_<%=k%>-check_btn"
|
||||
onclick="onBtnClick(this,'<%=k%>');" value="<%:Check update%>" />
|
||||
<input class="btn cbi-button cbi-button-apply" type="button" id="_<%=k%>-force_btn"
|
||||
@ -211,3 +211,27 @@ local version = {}
|
||||
</div>
|
||||
</div>
|
||||
<%end%>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
let coms = document.getElementsByClassName("com_version");
|
||||
if (coms.length > 0) {
|
||||
for (let i = 0; i < coms.length; i++) {
|
||||
let key = coms[i].getAttribute("key");
|
||||
coms[i].innerHTML = "<%=translate("Collecting data...")%>";
|
||||
XHR.get('<%=api.url("version_")%>' + key, null, function(x, result) {
|
||||
if (x.status == 200 && result.code == 1) {
|
||||
let data = result.data;
|
||||
let t = "<%=translate("Null")%>";
|
||||
if (data && data != "")
|
||||
t = data;
|
||||
coms[i].innerHTML = t;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
//]]>
|
||||
</script>
|
||||
</div>
|
||||
|
||||
@ -532,14 +532,15 @@ msgstr "节点匹配规则"
|
||||
msgid ""
|
||||
"Example: <code>^A && B && !C && D$</code><br>"
|
||||
"This means the node remark must start with A (^), include B, exclude C (!), and end with D ($).<br>"
|
||||
"Conditions are joined by <code>&&</code>, and their order does not affect the result."
|
||||
"Conditions are joined by <code>&&</code> (AND), and their order does not affect the result.<br>"
|
||||
"Multiple groups can be separated by <code>||</code> (OR), matching succeeds if any group matches.<br>"
|
||||
"Example: <code>A && B || C && D</code> means (A AND B) OR (C AND D)."
|
||||
msgstr ""
|
||||
"示例:<code>^A && B && !C && D$</code><br>"
|
||||
"表示节点备注需同时满足:以 A 开头(^)、包含 B、不包含 C(!)、并以 D 结尾($)。<br>"
|
||||
"多个条件使用 <code>&&</code> 连接,条件顺序不影响结果。"
|
||||
|
||||
msgid "Keep the match scope small. Too many nodes can impact router performance."
|
||||
msgstr "建议尽量缩小匹配范围,节点过多会增加路由器负载。"
|
||||
"多个条件使用 <code>&&</code>(与)连接,条件顺序不影响结果。<br>"
|
||||
"多组条件之间可使用 <code>||</code>(或)分隔,任意一组匹配即视为成功。<br>"
|
||||
"示例:<code>A && B || C && D</code> 表示 (A 且 B) 或 (C 且 D)。"
|
||||
|
||||
msgid "Balancing Strategy"
|
||||
msgstr "负载均衡策略"
|
||||
@ -823,8 +824,8 @@ msgstr "单位:分钟"
|
||||
msgid "stop automatically mode"
|
||||
msgstr "定时关闭模式"
|
||||
|
||||
msgid "stop Time(Every day)"
|
||||
msgstr "关闭时间(每天)"
|
||||
msgid "stop Time"
|
||||
msgstr "关闭时间"
|
||||
|
||||
msgid "stop Interval(Hour)"
|
||||
msgstr "关闭间隔(小时)"
|
||||
@ -832,8 +833,8 @@ msgstr "关闭间隔(小时)"
|
||||
msgid "start automatically mode"
|
||||
msgstr "定时开启模式"
|
||||
|
||||
msgid "start Time(Every day)"
|
||||
msgstr "开启时间(每天)"
|
||||
msgid "start Time"
|
||||
msgstr "开启时间"
|
||||
|
||||
msgid "start Interval(Hour)"
|
||||
msgstr "开启间隔(小时)"
|
||||
@ -841,8 +842,8 @@ msgstr "开启间隔(小时)"
|
||||
msgid "restart automatically mode"
|
||||
msgstr "定时重启模式"
|
||||
|
||||
msgid "restart Time(Every day)"
|
||||
msgstr "重启时间(每天)"
|
||||
msgid "restart Time"
|
||||
msgstr "重启时间"
|
||||
|
||||
msgid "restart Interval(Hour)"
|
||||
msgstr "重启间隔(小时)"
|
||||
@ -1057,17 +1058,14 @@ msgstr "中国域名列表(Chnlist)更新URL"
|
||||
msgid "Rule status"
|
||||
msgstr "规则版本"
|
||||
|
||||
msgid "Enable auto update rules"
|
||||
msgstr "开启自动更新规则"
|
||||
|
||||
msgid "Update Time(every day)"
|
||||
msgstr "更新时间(每天)"
|
||||
msgid "Update Time"
|
||||
msgstr "更新时间"
|
||||
|
||||
msgid "Update Interval(hour)"
|
||||
msgstr "更新间隔(小时)"
|
||||
|
||||
msgid "Update Mode"
|
||||
msgstr "更新模式"
|
||||
msgid "Auto Update Mode"
|
||||
msgstr "自动更新模式"
|
||||
|
||||
msgid "Loop Mode"
|
||||
msgstr "循环"
|
||||
@ -1177,9 +1175,6 @@ msgstr "移动中"
|
||||
msgid "App Update"
|
||||
msgstr "组件更新"
|
||||
|
||||
msgid "Please confirm that your firmware supports FPU."
|
||||
msgstr "请确认你的固件支持 FPU。"
|
||||
|
||||
msgid "if you want to run from memory, change the path, /tmp beginning then save the application and update it manually."
|
||||
msgstr "如果你希望从内存中运行,请更改路径,/tmp 开头,然后保存应用后,再手动更新。"
|
||||
|
||||
|
||||
@ -55,17 +55,12 @@ config global_other
|
||||
option show_node_info '0'
|
||||
|
||||
config global_rules
|
||||
option auto_update '1'
|
||||
option chnlist_update '1'
|
||||
option chnroute_update '1'
|
||||
option chnroute6_update '1'
|
||||
option gfwlist_update '1'
|
||||
option geosite_update '1'
|
||||
option geoip_update '1'
|
||||
option enable_geoview '1'
|
||||
option geo2rule '1'
|
||||
option week_update '7'
|
||||
option time_update '4'
|
||||
option geosite_update '0'
|
||||
option geoip_update '0'
|
||||
list gfwlist_url 'https://cdn.jsdelivr.net/gh/Loyalsoldier/v2ray-rules-dat@release/gfw.txt'
|
||||
list chnroute_url 'https://ispip.clang.cn/all_cn.txt'
|
||||
list chnroute_url 'https://cdn.jsdelivr.net/gh/gaoyifan/china-operator-ip@ip-lists/china.txt'
|
||||
@ -74,8 +69,8 @@ config global_rules
|
||||
list chnlist_url 'https://cdn.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/accelerated-domains.china.conf'
|
||||
list chnlist_url 'https://cdn.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/apple.china.conf'
|
||||
option v2ray_location_asset '/usr/share/v2ray/'
|
||||
option geoip_url 'https://cdn.jsdelivr.net/gh/Loyalsoldier/geoip@release/geoip.dat'
|
||||
option geosite_url 'https://cdn.jsdelivr.net/gh/Loyalsoldier/v2ray-rules-dat@release/geosite.dat'
|
||||
option geoip_url 'https://github.com/Loyalsoldier/geoip/releases/latest/download/geoip.dat'
|
||||
option geosite_url 'https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat'
|
||||
|
||||
config global_app
|
||||
option geoview_file '/usr/bin/geoview'
|
||||
|
||||
@ -74,7 +74,7 @@ check_run_environment() {
|
||||
run_ipt2socks() {
|
||||
local flag proto tcp_tproxy local_port socks_address socks_port socks_username socks_password log_file
|
||||
local _extra_param=""
|
||||
eval_set_val $@
|
||||
eval_set_val "$@"
|
||||
[ -n "$log_file" ] || log_file="/dev/null"
|
||||
socks_address=$(get_host_ip "ipv4" ${socks_address})
|
||||
[ -n "$socks_username" ] && [ -n "$socks_password" ] && _extra_param="${_extra_param} -a $socks_username -k $socks_password"
|
||||
@ -100,7 +100,7 @@ run_singbox() {
|
||||
local flag type node tcp_redir_port tcp_proxy_way udp_redir_port socks_address socks_port socks_username socks_password http_address http_port http_username http_password
|
||||
local dns_listen_port direct_dns_query_strategy direct_dns_port direct_dns_udp_server direct_dns_tcp_server remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh remote_dns_client_ip remote_fakedns remote_dns_query_strategy dns_cache dns_socks_address dns_socks_port
|
||||
local loglevel log_file config_file server_host server_port no_run
|
||||
eval_set_val $@
|
||||
eval_set_val "$@"
|
||||
[ -z "$type" ] && {
|
||||
type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
|
||||
[ "$type" != "sing-box" ] && [ -n "$SINGBOX_BIN" ] && type="sing-box"
|
||||
@ -198,7 +198,7 @@ run_xray() {
|
||||
local flag type node tcp_redir_port tcp_proxy_way udp_redir_port socks_address socks_port socks_username socks_password http_address http_port http_username http_password
|
||||
local dns_listen_port direct_dns_query_strategy direct_dns_port direct_dns_udp_server direct_dns_tcp_server remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh remote_dns_client_ip remote_fakedns remote_dns_query_strategy dns_cache dns_socks_address dns_socks_port
|
||||
local loglevel log_file config_file server_host server_port no_run
|
||||
eval_set_val $@
|
||||
eval_set_val "$@"
|
||||
[ -z "$type" ] && {
|
||||
type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
|
||||
[ "$type" != "xray" ] && [ -n "$XRAY_BIN" ] && type="xray"
|
||||
@ -287,7 +287,7 @@ run_xray() {
|
||||
run_dns2socks() {
|
||||
local flag socks socks_address socks_port socks_username socks_password listen_address listen_port dns cache log_file
|
||||
local _extra_param=""
|
||||
eval_set_val $@
|
||||
eval_set_val "$@"
|
||||
[ -n "$flag" ] && flag="_${flag}"
|
||||
[ -n "$log_file" ] || log_file="/dev/null"
|
||||
dns=$(get_first_dns dns 53 | sed 's/#/:/g')
|
||||
@ -305,11 +305,11 @@ run_dns2socks() {
|
||||
run_chinadns_ng() {
|
||||
local _flag _listen_port _dns_local _dns_trust _no_ipv6_trust _use_direct_list _use_proxy_list _gfwlist _chnlist _default_mode _default_tag _no_logic_log _tcp_node _remote_fakedns _filter_https
|
||||
local _extra_param=""
|
||||
eval_set_val $@
|
||||
eval_set_val "$@"
|
||||
|
||||
local _CONF_FILE=$TMP_ACL_PATH/$_flag/chinadns_ng.conf
|
||||
local _LOG_FILE="/dev/null"
|
||||
[ "$(config_t_get global log_chinadns_ng "0")" == "1" ] && _LOG_FILE=$TMP_ACL_PATH/$_flag/chinadns_ng.log
|
||||
[ "$(config_t_get global log_chinadns_ng "0")" = "1" ] && _LOG_FILE=$TMP_ACL_PATH/$_flag/chinadns_ng.log
|
||||
|
||||
_extra_param="-FLAG ${_flag} -TCP_NODE ${_tcp_node} -LISTEN_PORT ${_listen_port} -DNS_LOCAL ${_dns_local} -DNS_TRUST ${_dns_trust}"
|
||||
_extra_param="${_extra_param} -USE_DIRECT_LIST ${_use_direct_list} -USE_PROXY_LIST ${_use_proxy_list} -USE_BLOCK_LIST ${_use_block_list}"
|
||||
@ -323,7 +323,7 @@ run_chinadns_ng() {
|
||||
|
||||
run_socks() {
|
||||
local flag node bind socks_port config_file http_port http_config_file relay_port log_file no_run
|
||||
eval_set_val $@
|
||||
eval_set_val "$@"
|
||||
[ -n "$config_file" ] && [ -z "$(echo ${config_file} | grep $TMP_PATH)" ] && config_file=$TMP_PATH/$config_file
|
||||
[ -n "$http_port" ] || http_port=0
|
||||
[ -n "$http_config_file" ] && [ -z "$(echo ${http_config_file} | grep $TMP_PATH)" ] && http_config_file=$TMP_PATH/$http_config_file
|
||||
@ -367,14 +367,14 @@ run_socks() {
|
||||
error_msg="某种原因,此 Socks 服务的相关配置已失联,启动中止!"
|
||||
fi
|
||||
|
||||
if [ "$type" == "sing-box" ] || [ "$type" == "xray" ]; then
|
||||
if [ "$type" = "sing-box" ] || [ "$type" = "xray" ]; then
|
||||
local protocol=$(config_n_get $node protocol)
|
||||
if [ "$protocol" == "_balancing" ] || [ "$protocol" == "_shunt" ] || [ "$protocol" == "_iface" ] || [ "$protocol" == "_urltest" ]; then
|
||||
if [ "$protocol" = "_balancing" ] || [ "$protocol" = "_shunt" ] || [ "$protocol" = "_iface" ] || [ "$protocol" = "_urltest" ]; then
|
||||
unset error_msg
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "${error_msg}" ] && ([ -n "$(config_n_get $node hysteria_hop)" ] || [ -n "$(config_n_get $node hysteria2_hop)" ] || [ "$(config_n_get $node hysteria2_realms)" = "1" ]); then
|
||||
if [ -n "${error_msg}" ] && { [ -n "$(config_n_get $node hysteria_hop)" ] || [ -n "$(config_n_get $node hysteria2_hop)" ] || [ "$(config_n_get $node hysteria2_realms)" = "1" ]; }; then
|
||||
unset error_msg
|
||||
fi
|
||||
|
||||
@ -527,7 +527,7 @@ run_socks() {
|
||||
|
||||
run_redir() {
|
||||
local node proto bind local_port config_file log_file
|
||||
eval_set_val $@
|
||||
eval_set_val "$@"
|
||||
local tcp_node_socks_flag tcp_node_http_flag
|
||||
[ -n "$config_file" ] && [ -z "$(echo ${config_file} | grep $TMP_PATH)" ] && config_file=${GLOBAL_ACL_PATH}/${config_file}
|
||||
if [ -n "$log_file" ] && [ -z "$(echo ${log_file} | grep $TMP_PATH)" ]; then
|
||||
@ -644,7 +644,7 @@ run_redir() {
|
||||
tcp_node_socks_port=$(get_new_port $(config_t_get global tcp_node_socks_port 1070))
|
||||
tcp_node_http_port=$(config_t_get global tcp_node_http_port 0)
|
||||
[ "$tcp_node_http_port" != "0" ] && tcp_node_http=1
|
||||
if [ $PROXY_IPV6 == "1" ]; then
|
||||
if [ $PROXY_IPV6 = "1" ]; then
|
||||
echolog "开启实验性IPv6透明代理(TProxy),请确认您的节点及类型支持IPv6!"
|
||||
fi
|
||||
|
||||
@ -725,7 +725,7 @@ run_redir() {
|
||||
DNSMASQ_FILTER_PROXY_IPV6=0
|
||||
local _remote_dns_client_ip=$(config_t_get global remote_dns_client_ip)
|
||||
[ -n "${_remote_dns_client_ip}" ] && _args="${_args} remote_dns_client_ip=${_remote_dns_client_ip}"
|
||||
[ "${DNS_CACHE}" == "0" ] && _args="${_args} dns_cache=0"
|
||||
[ "${DNS_CACHE}" = "0" ] && _args="${_args} dns_cache=0"
|
||||
resolve_dns_port=${NEXT_DNS_LISTEN_PORT}
|
||||
_args="${_args} dns_listen_port=${resolve_dns_port}"
|
||||
|
||||
@ -811,7 +811,7 @@ run_redir() {
|
||||
DNSMASQ_FILTER_PROXY_IPV6=0
|
||||
local _remote_dns_client_ip=$(config_t_get global remote_dns_client_ip)
|
||||
[ -n "${_remote_dns_client_ip}" ] && _args="${_args} remote_dns_client_ip=${_remote_dns_client_ip}"
|
||||
[ "${DNS_CACHE}" == "0" ] && _args="${_args} dns_cache=0"
|
||||
[ "${DNS_CACHE}" = "0" ] && _args="${_args} dns_cache=0"
|
||||
resolve_dns_port=${NEXT_DNS_LISTEN_PORT}
|
||||
_args="${_args} dns_listen_port=${resolve_dns_port}"
|
||||
|
||||
@ -984,7 +984,7 @@ start_socks() {
|
||||
echolog "分析 Socks 服务的节点配置..."
|
||||
for id in $ids; do
|
||||
local enabled=$(config_n_get $id enabled 0)
|
||||
[ "$enabled" == "0" ] && continue
|
||||
[ "$enabled" = "0" ] && continue
|
||||
local node=$(config_n_get $id node)
|
||||
[ -z "$node" ] && continue
|
||||
local bind_local=$(config_n_get $id bind_local 0)
|
||||
@ -994,7 +994,7 @@ start_socks() {
|
||||
local config_file="SOCKS_${id}.json"
|
||||
local log_file="SOCKS_${id}.log"
|
||||
local log=$(config_n_get $id log 1)
|
||||
[ "$log" == "0" ] && log_file=""
|
||||
[ "$log" = "0" ] && log_file=""
|
||||
local http_port=$(config_n_get $id http_port 0)
|
||||
local http_config_file="HTTP2SOCKS_${id}.json"
|
||||
local enable_autoswitch=$(config_n_get $id enable_autoswitch 0)
|
||||
@ -1012,7 +1012,7 @@ start_socks() {
|
||||
|
||||
socks_node_switch() {
|
||||
local flag new_node
|
||||
eval_set_val $@
|
||||
eval_set_val "$@"
|
||||
[ -n "$flag" ] && [ -n "$new_node" ] && {
|
||||
local prefix pf filename
|
||||
# 结束 SS 插件进程
|
||||
@ -1037,7 +1037,7 @@ socks_node_switch() {
|
||||
local config_file="SOCKS_${flag}.json"
|
||||
local log_file="SOCKS_${flag}.log"
|
||||
local log=$(config_n_get $flag log 1)
|
||||
[ "$log" == "0" ] && log_file=""
|
||||
[ "$log" = "0" ] && log_file=""
|
||||
local http_port=$(config_n_get $flag http_port 0)
|
||||
local http_config_file="HTTP2SOCKS_${flag}.json"
|
||||
LOG_FILE="/dev/null"
|
||||
@ -1045,7 +1045,7 @@ socks_node_switch() {
|
||||
set_cache_var "socks_${flag}" "$new_node"
|
||||
local ENABLED_DEFAULT_ACL=$(get_cache_var "ENABLED_DEFAULT_ACL")
|
||||
local ENABLED_ACLS=$(get_cache_var "ENABLED_ACLS")
|
||||
[ "$ENABLED_DEFAULT_ACL" != "1" -a "$ENABLED_ACLS" != "1" ] && return
|
||||
[ "$ENABLED_DEFAULT_ACL" != "1" ] && [ "$ENABLED_ACLS" != "1" ] && return
|
||||
local USE_TABLES=$(get_cache_var "USE_TABLES")
|
||||
[ -n "$USE_TABLES" ] && source $APP_PATH/${USE_TABLES}.sh filter_direct_node_list
|
||||
}
|
||||
@ -1086,19 +1086,29 @@ start_crontab() {
|
||||
|
||||
build_time() {
|
||||
local w="$1"
|
||||
local h="$2"
|
||||
local expr="0 $h * * $w"
|
||||
[ "$w" = "7" ] && expr="0 $h * * *"
|
||||
local t="$2"
|
||||
local h m
|
||||
if echo "$t" | grep -q ':'; then
|
||||
h="${t%%:*}"
|
||||
m="${t##*:}"
|
||||
else
|
||||
h="$t"
|
||||
m=0
|
||||
fi
|
||||
h=$(printf '%d' "$h")
|
||||
m=$(printf '%d' "$m")
|
||||
local expr="$m $h * * $w"
|
||||
[ "$w" = "7" ] && expr="$m $h * * *"
|
||||
echo "$expr"
|
||||
}
|
||||
|
||||
add_service_cron() {
|
||||
local week="$1"
|
||||
local hour="$2"
|
||||
local time="$2"
|
||||
local action="$3"
|
||||
local logmsg="$4"
|
||||
[ -z "$week" ] && return
|
||||
local svr_t=$(build_time "$week" "$hour")
|
||||
local svr_t=$(build_time "$week" "$time")
|
||||
if [ "$week" = "8" ]; then
|
||||
update_loop=1
|
||||
else
|
||||
@ -1115,12 +1125,11 @@ start_crontab() {
|
||||
add_service_cron "$(config_t_get global_delay restart_week_mode)" "$(config_t_get global_delay restart_time_mode)" "restart" "配置定时任务:自动重启服务。"
|
||||
|
||||
# ===== rule update =====
|
||||
local autoupdate=$(config_t_get global_rules auto_update)
|
||||
local weekupdate=$(config_t_get global_rules week_update)
|
||||
local dayupdate=$(config_t_get global_rules time_update)
|
||||
if [ "$autoupdate" = "1" ]; then
|
||||
local rule_t=$(build_time "$weekupdate" "$dayupdate")
|
||||
if [ "$weekupdate" = "8" ]; then
|
||||
local rules_update_week_mode=$(config_t_get global_rules update_week_mode)
|
||||
local rules_update_time_mode=$(config_t_get global_rules update_time_mode)
|
||||
if [ -n "$rules_update_week_mode" ]; then
|
||||
local rule_t=$(build_time "$rules_update_week_mode" "$rules_update_time_mode")
|
||||
if [ "$rules_update_week_mode" = "8" ]; then
|
||||
update_loop=1
|
||||
else
|
||||
echo "$rule_t lua $APP_PATH/rule_update.lua log all cron > /dev/null 2>&1 &" >>/etc/crontabs/root
|
||||
@ -1131,25 +1140,25 @@ start_crontab() {
|
||||
# ===== subscribe =====
|
||||
local TMP_SUB_PATH=$TMP_PATH/sub_crontabs
|
||||
mkdir -p "$TMP_SUB_PATH"
|
||||
local item cfgid remark week_update time_update
|
||||
local item cfgid remark sub_update_week_mode sub_update_time_mode
|
||||
for item in $(uci show ${CONFIG} | grep "=subscribe_list" | cut -d '.' -sf 2 | cut -d '=' -sf 1); do
|
||||
if [ "$(config_n_get "$item" auto_update 0)" = "1" ]; then
|
||||
sub_update_week_mode=$(config_n_get $item update_week_mode)
|
||||
if [ -n "$sub_update_week_mode" ]; then
|
||||
cfgid=$(uci show ${CONFIG}.$item | head -n 1 | cut -d '.' -sf 2 | cut -d '=' -sf 1)
|
||||
remark=$(config_n_get "$item" remark)
|
||||
week_update=$(config_n_get "$item" week_update)
|
||||
time_update=$(config_n_get "$item" time_update)
|
||||
echo "$cfgid" >> "$TMP_SUB_PATH/${week_update}_${time_update}"
|
||||
sub_update_time_mode=$(config_n_get $item update_time_mode)
|
||||
echo "$cfgid" >> "$TMP_SUB_PATH/${sub_update_week_mode}_${sub_update_time_mode}"
|
||||
echolog "配置定时任务:自动更新【$remark】订阅。"
|
||||
fi
|
||||
done
|
||||
if [ -d "$TMP_SUB_PATH" ]; then
|
||||
local name cfgids
|
||||
for name in $(ls "$TMP_SUB_PATH"); do
|
||||
week_update=${name%_*}
|
||||
time_update=${name#*_}
|
||||
sub_update_week_mode=${name%_*}
|
||||
sub_update_time_mode=${name#*_}
|
||||
cfgids=$(tr '\n' ',' < "$TMP_SUB_PATH/$name" | sed 's/,$//')
|
||||
local sub_t=$(build_time "$week_update" "$time_update")
|
||||
if [ "$week_update" = "8" ]; then
|
||||
local sub_t=$(build_time "$sub_update_week_mode" "$sub_update_time_mode")
|
||||
if [ "$sub_update_week_mode" = "8" ]; then
|
||||
update_loop=1
|
||||
else
|
||||
echo "$sub_t lua $APP_PATH/subscribe.lua start $cfgids cron > /dev/null 2>&1 &" >>/etc/crontabs/root
|
||||
@ -1253,7 +1262,7 @@ start_dns() {
|
||||
local log_file=$TMP_PATH/DNS.log
|
||||
local log_file=/dev/null
|
||||
local _args="type=$DNS_MODE config_file=$config_file log_file=$log_file"
|
||||
[ "${DNS_CACHE}" == "0" ] && _args="${_args} dns_cache=0"
|
||||
[ "${DNS_CACHE}" = "0" ] && _args="${_args} dns_cache=0"
|
||||
_args="${_args} direct_dns_query_strategy=${DIRECT_DNS_QUERY_STRATEGY}"
|
||||
_args="${_args} remote_dns_query_strategy=${REMOTE_DNS_QUERY_STRATEGY}"
|
||||
DNSMASQ_FILTER_PROXY_IPV6=0
|
||||
@ -1292,7 +1301,7 @@ start_dns() {
|
||||
local log_file=$TMP_PATH/DNS.log
|
||||
local log_file=/dev/null
|
||||
local _args="type=$DNS_MODE config_file=$config_file log_file=$log_file"
|
||||
[ "${DNS_CACHE}" == "0" ] && _args="${_args} dns_cache=0"
|
||||
[ "${DNS_CACHE}" = "0" ] && _args="${_args} dns_cache=0"
|
||||
_args="${_args} direct_dns_query_strategy=${DIRECT_DNS_QUERY_STRATEGY}"
|
||||
_args="${_args} remote_dns_query_strategy=${REMOTE_DNS_QUERY_STRATEGY}"
|
||||
DNSMASQ_FILTER_PROXY_IPV6=0
|
||||
@ -1363,7 +1372,7 @@ start_dns() {
|
||||
rm -rf $TMP_PATH2/dnsmasq_default*
|
||||
local group_domestic=$(config_t_get global group_domestic)
|
||||
local smartdns_remote_dns=$(config_t_get global smartdns_remote_dns)
|
||||
if [ -n "${smartdns_remote_dns}" -a "${smartdns_remote_dns}" != "nil" ]; then
|
||||
if [ -n "${smartdns_remote_dns}" ] && [ "${smartdns_remote_dns}" != "nil" ]; then
|
||||
smartdns_remote_dns=$(echo ${smartdns_remote_dns} | tr -s ' ' '|')
|
||||
else
|
||||
smartdns_remote_dns="tcp://1.1.1.1"
|
||||
@ -1430,13 +1439,13 @@ start_dns() {
|
||||
|
||||
[ "$USE_DEFAULT_DNS" = "remote" ] && {
|
||||
dnsmasq_version=$(dnsmasq -v | grep -i "Dnsmasq version " | awk '{print $3}')
|
||||
[ "$(expr $dnsmasq_version \>= 2.87)" == 0 ] && echolog "Dnsmasq版本低于2.87,有可能无法正常使用!!!"
|
||||
[ "$(check_ver "$dnsmasq_version" "2.87")" = "1" ] && echolog "Dnsmasq版本低于2.87,有可能无法正常使用!!!"
|
||||
}
|
||||
|
||||
local DNSMASQ_TUN_DNS=$(get_first_dns TUN_DNS 53)
|
||||
local RUN_NEW_DNSMASQ=1
|
||||
RUN_NEW_DNSMASQ=${DNS_REDIRECT}
|
||||
if [ "${RUN_NEW_DNSMASQ}" == "0" ]; then
|
||||
if [ "${RUN_NEW_DNSMASQ}" = "0" ]; then
|
||||
#The old logic will be removed in the future.
|
||||
#Run a copy dnsmasq instance, DNS hijack that don't need a proxy devices.
|
||||
[ "1" = "0" ] && {
|
||||
@ -1542,7 +1551,7 @@ acl_app() {
|
||||
|
||||
local acl_path=${TMP_ACL_PATH}/$sid
|
||||
mkdir -p ${acl_path}
|
||||
[ -n "${source_list}" ] && echo -e "${source_list}" | sed '/^$/d' > ${acl_path}/source_list
|
||||
[ -n "${source_list}" ] && printf "%b\n" "${source_list}" | sed '/^$/d' > ${acl_path}/source_list
|
||||
|
||||
use_global_config=${use_global_config:-0}
|
||||
[ "${use_global_config}" = "1" ] && {
|
||||
@ -1627,7 +1636,7 @@ acl_app() {
|
||||
_dns_port=$dns_port
|
||||
if [ "$dns_mode" = "dns2socks" ]; then
|
||||
run_dns2socks flag=acl_${sid} socks_address=127.0.0.1 socks_port=$socks_port listen_address=0.0.0.0 listen_port=${_dns_port} dns=$remote_dns cache=1
|
||||
elif [ "$dns_mode" = "sing-box" -o "$dns_mode" = "xray" ]; then
|
||||
elif [ "$dns_mode" = "sing-box" ] || [ "$dns_mode" = "xray" ]; then
|
||||
config_file=$TMP_ACL_PATH/${tcp_node}_SOCKS_${socks_port}_DNS.json
|
||||
remote_dns_doh=${remote_dns_doh:-https://1.1.1.1/dns-query}
|
||||
local type=${dns_mode}
|
||||
@ -1853,8 +1862,8 @@ start() {
|
||||
nftflag=0
|
||||
USE_TABLES=""
|
||||
check_run_environment
|
||||
if [ "$ENABLED_DEFAULT_ACL" == 1 ] || [ "$ENABLED_ACLS" == 1 ]; then
|
||||
[ "$(uci -q get dhcp.@dnsmasq[0].dns_redirect)" == "1" ] && {
|
||||
if [ "$ENABLED_DEFAULT_ACL" = 1 ] || [ "$ENABLED_ACLS" = 1 ]; then
|
||||
[ "$(uci -q get dhcp.@dnsmasq[0].dns_redirect)" = "1" ] && {
|
||||
uci -q set ${CONFIG}.@global[0].dnsmasq_dns_redirect='1'
|
||||
uci -q commit ${CONFIG}
|
||||
uci -q set dhcp.@dnsmasq[0].dns_redirect='0'
|
||||
@ -1862,7 +1871,7 @@ start() {
|
||||
lua $APP_PATH/helper_dnsmasq.lua restart -LOG 0
|
||||
}
|
||||
fi
|
||||
[ "$ENABLED_DEFAULT_ACL" == 1 ] && {
|
||||
[ "$ENABLED_DEFAULT_ACL" = 1 ] && {
|
||||
mkdir -p ${GLOBAL_ACL_PATH}
|
||||
start_redir TCP
|
||||
start_redir UDP
|
||||
@ -1870,11 +1879,11 @@ start() {
|
||||
}
|
||||
[ -n "$USE_TABLES" ] && source $APP_PATH/${USE_TABLES}.sh start
|
||||
set_cache_var "USE_TABLES" "$USE_TABLES"
|
||||
if [ "$ENABLED_DEFAULT_ACL" == 1 ] || [ "$ENABLED_ACLS" == 1 ]; then
|
||||
if [ "$ENABLED_DEFAULT_ACL" = 1 ] || [ "$ENABLED_ACLS" = 1 ]; then
|
||||
bridge_nf_ipt=$(sysctl -e -n net.bridge.bridge-nf-call-iptables)
|
||||
set_cache_var "bak_bridge_nf_ipt" "$bridge_nf_ipt"
|
||||
sysctl -w net.bridge.bridge-nf-call-iptables=0 >/dev/null 2>&1
|
||||
[ "$PROXY_IPV6" == "1" ] && {
|
||||
[ "$PROXY_IPV6" = "1" ] && {
|
||||
bridge_nf_ip6t=$(sysctl -e -n net.bridge.bridge-nf-call-ip6tables)
|
||||
set_cache_var "bak_bridge_nf_ip6t" "$bridge_nf_ip6t"
|
||||
sysctl -w net.bridge.bridge-nf-call-ip6tables=0 >/dev/null 2>&1
|
||||
@ -1981,7 +1990,7 @@ get_config() {
|
||||
}
|
||||
ENABLED_ACLS=$(config_t_get global acl_enable 0)
|
||||
[ "$ENABLED_ACLS" = 1 ] && {
|
||||
[ "$(uci show ${CONFIG} | grep "@acl_rule" | grep "enabled='1'" | wc -l)" == 0 ] && ENABLED_ACLS=0
|
||||
[ "$(uci show ${CONFIG} | grep "@acl_rule" | grep "enabled='1'" | wc -l)" = 0 ] && ENABLED_ACLS=0
|
||||
}
|
||||
set_cache_var ENABLED_DEFAULT_ACL $ENABLED_DEFAULT_ACL
|
||||
set_cache_var ENABLED_ACLS $ENABLED_ACLS
|
||||
@ -2004,7 +2013,7 @@ get_config() {
|
||||
[ "${TCP_PROXY_MODE}" != "disable" ] && TCP_PROXY_MODE="proxy"
|
||||
[ "${UDP_PROXY_MODE}" != "disable" ] && UDP_PROXY_MODE="proxy"
|
||||
LOCALHOST_PROXY=$(config_t_get global localhost_proxy 1)
|
||||
[ "${LOCALHOST_PROXY}" == 1 ] && {
|
||||
[ "${LOCALHOST_PROXY}" = 1 ] && {
|
||||
LOCALHOST_TCP_PROXY_MODE=$TCP_PROXY_MODE
|
||||
LOCALHOST_UDP_PROXY_MODE=$UDP_PROXY_MODE
|
||||
}
|
||||
@ -2075,13 +2084,13 @@ arg1=$1
|
||||
shift
|
||||
case $arg1 in
|
||||
run_socks)
|
||||
run_socks $@
|
||||
run_socks "$@"
|
||||
;;
|
||||
socks_node_switch)
|
||||
socks_node_switch $@
|
||||
socks_node_switch "$@"
|
||||
;;
|
||||
start)
|
||||
start $@
|
||||
start "$@"
|
||||
;;
|
||||
stop)
|
||||
stop
|
||||
|
||||
@ -38,8 +38,8 @@ ipt_n="$ipt -t nat -w"
|
||||
ipt_m="$ipt -t mangle -w"
|
||||
ip6t_n="$ip6t -t nat -w"
|
||||
ip6t_m="$ip6t -t mangle -w"
|
||||
[ -z "$ip6t" -o -z "$(lsmod | grep 'ip6table_nat')" ] && ip6t_n="eval #$ip6t_n"
|
||||
[ -z "$ip6t" -o -z "$(lsmod | grep 'ip6table_mangle')" ] && ip6t_m="eval #$ip6t_m"
|
||||
[ -z "$ip6t" ] || [ -z "$(lsmod | grep 'ip6table_nat')" ] && ip6t_n="eval #$ip6t_n"
|
||||
[ -z "$ip6t" ] || [ -z "$(lsmod | grep 'ip6table_mangle')" ] && ip6t_m="eval #$ip6t_m"
|
||||
FWI=$(uci -q get firewall.passwall.path 2>/dev/null)
|
||||
FAKE_IP="198.18.0.0/15"
|
||||
FAKE_IP_6="fc00::/18"
|
||||
@ -47,7 +47,7 @@ FAKE_IP_6="fc00::/18"
|
||||
factor() {
|
||||
if [ -z "$1" ] || [ -z "$2" ]; then
|
||||
echo ""
|
||||
elif [ "$1" == "1:65535" ]; then
|
||||
elif [ "$1" = "1:65535" ]; then
|
||||
echo ""
|
||||
else
|
||||
echo "$2 $1"
|
||||
@ -168,7 +168,7 @@ REDIRECT() {
|
||||
local s="-j REDIRECT"
|
||||
[ -n "$1" ] && {
|
||||
local s="$s --to-ports $1"
|
||||
[ "$2" == "TPROXY" ] && {
|
||||
[ "$2" = "TPROXY" ] && {
|
||||
local mark="-m mark --mark ${FWMARK}"
|
||||
s="${mark} -j TPROXY --on-port $1"
|
||||
}
|
||||
@ -195,11 +195,11 @@ get_jump_ipt() {
|
||||
}
|
||||
|
||||
load_acl() {
|
||||
([ "$ENABLED_ACLS" == 1 ] || ([ "$ENABLED_DEFAULT_ACL" == 1 ] && [ "$CLIENT_PROXY" == 1 ])) && echolog " - 访问控制:"
|
||||
[ "$ENABLED_ACLS" == 1 ] && {
|
||||
{ [ "$ENABLED_ACLS" = "1" ] || { [ "$ENABLED_DEFAULT_ACL" = "1" ] && [ "$CLIENT_PROXY" = "1" ]; }; } && echolog " - 访问控制:"
|
||||
[ "$ENABLED_ACLS" = 1 ] && {
|
||||
acl_app
|
||||
for sid in $(ls -F ${TMP_ACL_PATH} | grep '/$' | awk -F '/' '{print $1}' | grep -v 'default'); do
|
||||
eval $(uci -q show "${CONFIG}.${sid}" | cut -d'.' -sf 3-)
|
||||
eval "$(uci -q show "${CONFIG}.${sid}" | cut -d'.' -sf 3-)"
|
||||
|
||||
tcp_no_redir_ports=${tcp_no_redir_ports:-default}
|
||||
udp_no_redir_ports=${udp_no_redir_ports:-default}
|
||||
@ -379,7 +379,7 @@ load_acl() {
|
||||
ipset -! create $gfw6_set_name nethash family inet6 maxelem 1048576 timeout 172800
|
||||
}
|
||||
}
|
||||
[ "${use_shunt_tcp}" = "1" -o "${use_shunt_udp}" = "1" ] && {
|
||||
[ "${use_shunt_tcp}" = "1" ] || [ "${use_shunt_udp}" = "1" ] && {
|
||||
[ "${use_global_config}" = "0" ] && {
|
||||
shunt_set_name="psw_${sid}_shunt"
|
||||
shunt6_set_name="psw_${sid}_shunt6"
|
||||
@ -403,16 +403,16 @@ load_acl() {
|
||||
[ -z "$(get_cache_var "ACL_${sid}_tcp_default")" ] && echolog " - ${msg}使用与全局配置不相同节点,已将DNS强制重定向到专用 DNS 服务器。"
|
||||
fi
|
||||
|
||||
[ -n "$tcp_port" -o -n "$udp_port" ] && {
|
||||
[ -n "$tcp_port" ] || [ -n "$udp_port" ] && {
|
||||
[ "${use_block_list}" = "1" ] && $ipt_m -A PSW $(comment "$remarks") ${_ipt_source} $(dst $IPSET_BLOCK) -j DROP
|
||||
[ "${use_direct_list}" = "1" ] && $ipt_tmp -A PSW $(comment "$remarks") ${_ipt_source} $(dst $IPSET_WHITE) -j RETURN
|
||||
[ "$PROXY_IPV6" == "1" ] && [ "$_ipv4" != "1" ] && {
|
||||
[ "$PROXY_IPV6" = "1" ] && [ "$_ipv4" != "1" ] && {
|
||||
[ "${use_block_list}" = "1" ] && $ip6t_m -A PSW $(comment "$remarks") ${_ipt_source} $(dst $IPSET_BLOCK6) -j DROP 2>/dev/null
|
||||
[ "${use_direct_list}" = "1" ] && $ip6t_m -A PSW $(comment "$remarks") ${_ipt_source} $(dst $IPSET_WHITE6) -j RETURN 2>/dev/null
|
||||
}
|
||||
|
||||
[ "$tcp_proxy_drop_ports" != "disable" ] && {
|
||||
[ "$PROXY_IPV6" == "1" ] && [ "$_ipv4" != "1" ] && {
|
||||
[ "$PROXY_IPV6" = "1" ] && [ "$_ipv4" != "1" ] && {
|
||||
[ "${use_fakedns}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source}" $tcp_proxy_drop_ports "-d $FAKE_IP_6 -j DROP" 2>/dev/null
|
||||
[ "${use_proxy_list}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source}" $tcp_proxy_drop_ports "$(dst $black6_set_name) -j DROP" 2>/dev/null
|
||||
[ "${use_gfw_list}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source}" $tcp_proxy_drop_ports "$(dst $gfw6_set_name) -j DROP" 2>/dev/null
|
||||
@ -430,7 +430,7 @@ load_acl() {
|
||||
}
|
||||
|
||||
[ "$udp_proxy_drop_ports" != "disable" ] && {
|
||||
[ "$PROXY_IPV6" == "1" ] && [ "$_ipv4" != "1" ] && {
|
||||
[ "$PROXY_IPV6" = "1" ] && [ "$_ipv4" != "1" ] && {
|
||||
[ "${use_fakedns}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "$remarks") -p udp ${_ipt_source}" $udp_proxy_drop_ports "-d $FAKE_IP_6 -j DROP" 2>/dev/null
|
||||
[ "${use_proxy_list}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "$remarks") -p udp ${_ipt_source}" $udp_proxy_drop_ports "$(dst $black6_set_name) -j DROP" 2>/dev/null
|
||||
[ "${use_gfw_list}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "$remarks") -p udp ${_ipt_source}" $udp_proxy_drop_ports "$(dst $gfw6_set_name) -j DROP" 2>/dev/null
|
||||
@ -469,7 +469,7 @@ load_acl() {
|
||||
[ "${tcp_proxy_mode}" != "disable" ] && $ipt_n -A PSW $(comment "$remarks") -p icmp ${_ipt_source} $(REDIRECT)
|
||||
}
|
||||
|
||||
[ "$accept_icmpv6" = "1" ] && [ "$PROXY_IPV6" == "1" ] && [ "$_ipv4" != "1" ] && {
|
||||
[ "$accept_icmpv6" = "1" ] && [ "$PROXY_IPV6" = "1" ] && [ "$_ipv4" != "1" ] && {
|
||||
[ "${use_fakedns}" = "1" ] && $ip6t_n -A PSW $(comment "$remarks") -p ipv6-icmp ${_ipt_source} -d $FAKE_IP_6 $(REDIRECT) 2>/dev/null
|
||||
[ "${use_proxy_list}" = "1" ] && $ip6t_n -A PSW $(comment "$remarks") -p ipv6-icmp ${_ipt_source} $(dst $black6_set_name) $(REDIRECT) 2>/dev/null
|
||||
[ "${use_gfw_list}" = "1" ] && $ip6t_n -A PSW $(comment "$remarks") -p ipv6-icmp ${_ipt_source} $(dst $gfw6_set_name) $(REDIRECT) 2>/dev/null
|
||||
@ -486,7 +486,7 @@ load_acl() {
|
||||
[ "${tcp_proxy_mode}" != "disable" ] && add_port_rules "$ipt_tmp -A PSW $(comment "$remarks") -p tcp ${_ipt_source}" $tcp_redir_ports "${ipt_j}"
|
||||
[ -n "${is_tproxy}" ] && $ipt_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source} $(REDIRECT $tcp_port TPROXY)
|
||||
|
||||
[ "$PROXY_IPV6" == "1" ] && [ "$_ipv4" != "1" ] && {
|
||||
[ "$PROXY_IPV6" = "1" ] && [ "$_ipv4" != "1" ] && {
|
||||
[ "${use_fakedns}" = "1" ] && $ip6t_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source} -d $FAKE_IP_6 -j PSW_RULE 2>/dev/null
|
||||
[ "${use_proxy_list}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source}" $tcp_redir_ports "$(dst $black6_set_name) -j PSW_RULE" 2>/dev/null
|
||||
[ "${use_gfw_list}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source}" $tcp_redir_ports "$(dst $gfw6_set_name) -j PSW_RULE" 2>/dev/null
|
||||
@ -517,7 +517,7 @@ load_acl() {
|
||||
[ "${udp_proxy_mode}" != "disable" ] && add_port_rules "$ipt_m -A PSW $(comment "$remarks") -p udp ${_ipt_source}" $udp_redir_ports "-j PSW_RULE"
|
||||
$ipt_m -A PSW $(comment "$remarks") -p udp ${_ipt_source} $(REDIRECT $udp_port TPROXY)
|
||||
|
||||
[ "$PROXY_IPV6" == "1" ] && [ "$_ipv4" != "1" ] && {
|
||||
[ "$PROXY_IPV6" = "1" ] && [ "$_ipv4" != "1" ] && {
|
||||
[ "${use_fakedns}" = "1" ] && $ip6t_m -A PSW $(comment "$remarks") -p udp ${_ipt_source} -d $FAKE_IP_6 -j PSW_RULE 2>/dev/null
|
||||
[ "${use_proxy_list}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "$remarks") -p udp ${_ipt_source}" $udp_redir_ports "$(dst $black6_set_name) -j PSW_RULE" 2>/dev/null
|
||||
[ "${use_gfw_list}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "$remarks") -p udp ${_ipt_source}" $udp_redir_ports "$(dst $gfw6_set_name) -j PSW_RULE" 2>/dev/null
|
||||
@ -540,7 +540,7 @@ load_acl() {
|
||||
done
|
||||
}
|
||||
|
||||
[ "$ENABLED_DEFAULT_ACL" == 1 ] && [ "$CLIENT_PROXY" == 1 ] && {
|
||||
[ "$ENABLED_DEFAULT_ACL" = 1 ] && [ "$CLIENT_PROXY" = 1 ] && {
|
||||
msg="【默认】,"
|
||||
local ipt_tmp=$ipt_n
|
||||
[ -n "${is_tproxy}" ] && ipt_tmp=$ipt_m
|
||||
@ -586,22 +586,22 @@ load_acl() {
|
||||
$ip6t_n -A PSW_DNS $(comment "默认") -p tcp --dport 53 -j REDIRECT --to-ports ${DNS_REDIRECT} 2>/dev/null
|
||||
fi
|
||||
|
||||
[ -n "${TCP_PROXY_MODE}" -o -n "${UDP_PROXY_MODE}" ] && {
|
||||
[ -n "${TCP_PROXY_MODE}" ] || [ -n "${UDP_PROXY_MODE}" ] && {
|
||||
[ "${USE_BLOCK_LIST}" = "1" ] && $ipt_m -A PSW $(comment "默认") $(dst $IPSET_BLOCK) -j DROP
|
||||
[ "${USE_DIRECT_LIST}" = "1" ] && $ipt_tmp -A PSW $(comment "默认") $(dst $IPSET_WHITE) -j RETURN
|
||||
[ "$PROXY_IPV6" == "1" ] && {
|
||||
[ "$PROXY_IPV6" = "1" ] && {
|
||||
[ "${USE_BLOCK_LIST}" = "1" ] && $ip6t_m -A PSW $(comment "默认") $(dst $IPSET_BLOCK6) -j DROP 2>/dev/null
|
||||
[ "${USE_DIRECT_LIST}" = "1" ] && $ip6t_m -A PSW $(comment "默认") $(dst $IPSET_WHITE6) -j RETURN 2>/dev/null
|
||||
}
|
||||
|
||||
[ "$TCP_PROXY_DROP_PORTS" != "disable" ] && {
|
||||
[ "$PROXY_IPV6" == "1" ] && {
|
||||
[ "$PROXY_IPV6" = "1" ] && {
|
||||
[ "${USE_FAKEDNS}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p tcp" $TCP_PROXY_DROP_PORTS "-d $FAKE_IP_6 -j DROP"
|
||||
[ "${USE_PROXY_LIST}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p tcp" $TCP_PROXY_DROP_PORTS "$(dst $IPSET_BLACK6) -j DROP"
|
||||
[ "${USE_GFW_LIST}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p tcp" $TCP_PROXY_DROP_PORTS "$(dst $IPSET_GFW6) -j DROP"
|
||||
[ "${CHN_LIST}" != "0" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p tcp" $TCP_PROXY_DROP_PORTS "$(dst $IPSET_CHN6) $(get_jump_ipt ${CHN_LIST} "-j DROP")"
|
||||
[ "${USE_SHUNT_TCP}" = "1" ] && $ip6t_m -A PSW $(comment "默认") -p tcp $TCP_PROXY_DROP_PORTS "$(dst $IPSET_SHUNT6) -j DROP"
|
||||
[ "${TCP_PROXY_MODE}" != "disable" ] && $ip6t_m -A PSW $(comment "默认") -p tcp $TCP_PROXY_DROP_PORTS "-j DROP"
|
||||
[ "${USE_SHUNT_TCP}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p tcp" $TCP_PROXY_DROP_PORTS "$(dst $IPSET_SHUNT6) -j DROP"
|
||||
[ "${TCP_PROXY_MODE}" != "disable" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p tcp" $TCP_PROXY_DROP_PORTS "-j DROP"
|
||||
}
|
||||
[ "${USE_FAKEDNS}" = "1" ] && add_port_rules "$ipt_m -A PSW $(comment "默认") -p tcp" $TCP_PROXY_DROP_PORTS "-d $FAKE_IP -j DROP"
|
||||
[ "${USE_PROXY_LIST}" = "1" ] && add_port_rules "$ipt_m -A PSW $(comment "默认") -p tcp" $TCP_PROXY_DROP_PORTS "$(dst $IPSET_BLACK) -j DROP"
|
||||
@ -613,12 +613,12 @@ load_acl() {
|
||||
}
|
||||
|
||||
[ "$UDP_PROXY_DROP_PORTS" != "disable" ] && {
|
||||
[ "$PROXY_IPV6" == "1" ] && {
|
||||
[ "$PROXY_IPV6" = "1" ] && {
|
||||
[ "${USE_FAKEDNS}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p udp" $UDP_PROXY_DROP_PORTS "-d $FAKE_IP_6 -j DROP"
|
||||
[ "${USE_PROXY_LIST}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p udp" $UDP_PROXY_DROP_PORTS "$(dst $IPSET_BLACK6) -j DROP"
|
||||
[ "${USE_GFW_LIST}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p udp" $UDP_PROXY_DROP_PORTS "$(dst $IPSET_GFW6) -j DROP"
|
||||
[ "${CHN_LIST}" != "0" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p udp" $UDP_PROXY_DROP_PORTS "$(dst $IPSET_CHN6) $(get_jump_ipt ${CHN_LIST} "-j DROP")"
|
||||
[ "${USE_SHUNT_TCP}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p udp" $UDP_PROXY_DROP_PORTS "$(dst $IPSET_SHUNT6) -j DROP"
|
||||
[ "${USE_SHUNT_UDP}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p udp" $UDP_PROXY_DROP_PORTS "$(dst $IPSET_SHUNT6) -j DROP"
|
||||
[ "${UDP_PROXY_MODE}" != "disable" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p udp" $UDP_PROXY_DROP_PORTS "-j DROP"
|
||||
}
|
||||
[ "${USE_FAKEDNS}" = "1" ] && add_port_rules "$ipt_m -A PSW $(comment "默认") -p udp" $UDP_PROXY_DROP_PORTS "-d $FAKE_IP -j DROP"
|
||||
@ -656,7 +656,7 @@ load_acl() {
|
||||
[ "${TCP_PROXY_MODE}" != "disable" ] && $ipt_n -A PSW $(comment "默认") -p icmp $(REDIRECT)
|
||||
}
|
||||
|
||||
[ "$accept_icmpv6" = "1" ] && [ "$PROXY_IPV6" == "1" ] && {
|
||||
[ "$accept_icmpv6" = "1" ] && [ "$PROXY_IPV6" = "1" ] && {
|
||||
[ "${USE_FAKEDNS}" = "1" ] && $ip6t_n -A PSW $(comment "默认") -p ipv6-icmp -d $FAKE_IP_6 $(REDIRECT)
|
||||
[ "${USE_PROXY_LIST}" = "1" ] && $ip6t_n -A PSW $(comment "默认") -p ipv6-icmp $(dst $IPSET_BLACK6) $(REDIRECT)
|
||||
[ "${USE_GFW_LIST}" = "1" ] && $ip6t_n -A PSW $(comment "默认") -p ipv6-icmp $(dst $IPSET_GFW6) $(REDIRECT)
|
||||
@ -673,7 +673,7 @@ load_acl() {
|
||||
[ "${TCP_PROXY_MODE}" != "disable" ] && add_port_rules "$ipt_tmp -A PSW $(comment "默认") -p tcp" $TCP_REDIR_PORTS "${ipt_j}"
|
||||
[ -n "${is_tproxy}" ]&& $ipt_tmp -A PSW $(comment "默认") -p tcp $(REDIRECT $TCP_REDIR_PORT TPROXY)
|
||||
|
||||
[ "$PROXY_IPV6" == "1" ] && {
|
||||
[ "$PROXY_IPV6" = "1" ] && {
|
||||
[ "${USE_FAKEDNS}" = "1" ] && $ip6t_m -A PSW $(comment "默认") -p tcp -d $FAKE_IP_6 -j PSW_RULE
|
||||
[ "${USE_PROXY_LIST}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p tcp" $TCP_REDIR_PORTS "$(dst $IPSET_BLACK6) -j PSW_RULE"
|
||||
[ "${USE_GFW_LIST}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p tcp" $TCP_REDIR_PORTS "$(dst $IPSET_GFW6) -j PSW_RULE"
|
||||
@ -692,7 +692,7 @@ load_acl() {
|
||||
|
||||
# 加载UDP默认代理模式
|
||||
if [ -n "${UDP_PROXY_MODE}" ]; then
|
||||
[ -n "$UDP_NODE" -o "$TCP_UDP" = "1" ] && {
|
||||
[ -n "$UDP_NODE" ] || [ "$TCP_UDP" = "1" ] && {
|
||||
if is_socks_wrap "$UDP_NODE"; then
|
||||
msg2="${msg}使用 UDP 节点[Socks 配置($(config_n_get ${UDP_NODE#Socks_} port) 端口)](TPROXY:${UDP_REDIR_PORT})"
|
||||
else
|
||||
@ -707,7 +707,7 @@ load_acl() {
|
||||
[ "${UDP_PROXY_MODE}" != "disable" ] && add_port_rules "$ipt_m -A PSW $(comment "默认") -p udp" $UDP_REDIR_PORTS "-j PSW_RULE"
|
||||
$ipt_m -A PSW $(comment "默认") -p udp $(REDIRECT $UDP_REDIR_PORT TPROXY)
|
||||
|
||||
[ "$PROXY_IPV6" == "1" ] && {
|
||||
[ "$PROXY_IPV6" = "1" ] && {
|
||||
[ "${USE_FAKEDNS}" = "1" ] && $ip6t_m -A PSW $(comment "默认") -p udp -d $FAKE_IP_6 -j PSW_RULE
|
||||
[ "${USE_PROXY_LIST}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p udp" $UDP_REDIR_PORTS "$(dst $IPSET_BLACK6) -j PSW_RULE"
|
||||
[ "${USE_GFW_LIST}" = "1" ] && add_port_rules "$ip6t_m -A PSW $(comment "默认") -p udp" $UDP_REDIR_PORTS "$(dst $IPSET_GFW6) -j PSW_RULE"
|
||||
@ -782,7 +782,7 @@ filter_node() {
|
||||
local port=$(config_n_get "$node" port)
|
||||
local hop=$(config_n_get "$node" hysteria2_hop)
|
||||
[ -n "$hop" ] && port="${port:+$port,}$hop"
|
||||
[ -z "$address" -o -z "$port" ] && return 1
|
||||
[ -z "$address" ] || [ -z "$port" ] && return 1
|
||||
filter_server_port "$address" "$port" "$stream"
|
||||
}
|
||||
|
||||
@ -1145,7 +1145,7 @@ add_firewall_rule() {
|
||||
|
||||
[ "$TCP_UDP" = "1" ] && [ -z "$UDP_NODE" ] && UDP_NODE=$TCP_NODE
|
||||
|
||||
[ "$ENABLED_DEFAULT_ACL" == 1 ] && {
|
||||
[ "$ENABLED_DEFAULT_ACL" = 1 ] && {
|
||||
local ipt_tmp=$ipt_n
|
||||
if [ -n "${is_tproxy}" ]; then
|
||||
ipt_tmp=$ipt_m
|
||||
@ -1186,7 +1186,7 @@ add_firewall_rule() {
|
||||
}
|
||||
fi
|
||||
|
||||
[ -n "${LOCALHOST_TCP_PROXY_MODE}" -o -n "${LOCALHOST_UDP_PROXY_MODE}" ] && {
|
||||
[ -n "${LOCALHOST_TCP_PROXY_MODE}" ] || [ -n "${LOCALHOST_UDP_PROXY_MODE}" ] && {
|
||||
[ "$TCP_PROXY_DROP_PORTS" != "disable" ] && {
|
||||
[ "${USE_FAKEDNS}" = "1" ] && add_port_rules "$ipt_m -A PSW_OUTPUT -p tcp" $TCP_PROXY_DROP_PORTS "-d $FAKE_IP -j DROP"
|
||||
[ "${USE_PROXY_LIST}" = "1" ] && add_port_rules "$ipt_m -A PSW_OUTPUT -p tcp" $TCP_PROXY_DROP_PORTS "$(dst $IPSET_BLACK) -j DROP"
|
||||
@ -1273,7 +1273,7 @@ add_firewall_rule() {
|
||||
insert_rule_before "$ipt_m" "OUTPUT" "mwan3" "$(comment mangle-OUTPUT-PSW) -p tcp -j PSW_OUTPUT"
|
||||
}
|
||||
|
||||
[ "$PROXY_IPV6" == "1" ] && {
|
||||
[ "$PROXY_IPV6" = "1" ] && {
|
||||
[ -n "${LOCALHOST_TCP_PROXY_MODE}" ] && {
|
||||
[ "${USE_FAKEDNS}" = "1" ] && $ip6t_m -A PSW_OUTPUT -p tcp -d $FAKE_IP_6 -j PSW_RULE
|
||||
[ "${USE_PROXY_LIST}" = "1" ] && add_port_rules "$ip6t_m -A PSW_OUTPUT -p tcp" $TCP_REDIR_PORTS "$(dst $IPSET_BLACK6) -j PSW_RULE"
|
||||
@ -1289,12 +1289,12 @@ add_firewall_rule() {
|
||||
fi
|
||||
|
||||
# 加载路由器自身代理 UDP
|
||||
if [ -n "$UDP_NODE" -o "$TCP_UDP" = "1" ]; then
|
||||
if [ -n "$UDP_NODE" ] || [ "$TCP_UDP" = "1" ]; then
|
||||
_proxy_udp_access() {
|
||||
[ -n "${2}" ] || return 0
|
||||
if echo "${2}" | grep -q -v ':'; then
|
||||
ipset -q test $IPSET_LAN ${2}
|
||||
[ $? == 0 ] && {
|
||||
[ $? = 0 ] && {
|
||||
echolog " - 上游 DNS 服务器 ${2} 已在直接访问的列表中,不强制向 UDP 代理转发对该服务器 UDP/${3} 端口的访问"
|
||||
return 0
|
||||
}
|
||||
@ -1303,7 +1303,7 @@ add_firewall_rule() {
|
||||
echolog " - [$?]将上游 DNS 服务器 ${2}:${3} 加入到路由器自身代理的 UDP 转发链"
|
||||
else
|
||||
ipset -q test $IPSET_LAN6 ${2}
|
||||
[ $? == 0 ] && {
|
||||
[ $? = 0 ] && {
|
||||
echolog " - 上游 DNS 服务器 ${2} 已在直接访问的列表中,不强制向 UDP 代理转发对该服务器 UDP/${3} 端口的访问"
|
||||
return 0
|
||||
}
|
||||
@ -1325,7 +1325,7 @@ add_firewall_rule() {
|
||||
$ipt_m -A PSW $(comment "本机") -p udp -i lo -j RETURN
|
||||
insert_rule_before "$ipt_m" "OUTPUT" "mwan3" "$(comment mangle-OUTPUT-PSW) -p udp -j PSW_OUTPUT"
|
||||
|
||||
[ "$PROXY_IPV6" == "1" ] && {
|
||||
[ "$PROXY_IPV6" = "1" ] && {
|
||||
[ -n "$LOCALHOST_UDP_PROXY_MODE" ] && {
|
||||
[ "${USE_FAKEDNS}" = "1" ] && $ip6t_m -A PSW_OUTPUT -p udp -d $FAKE_IP_6 -j PSW_RULE
|
||||
[ "${USE_PROXY_LIST}" = "1" ] && add_port_rules "$ip6t_m -A PSW_OUTPUT -p udp" $UDP_REDIR_PORTS "$(dst $IPSET_BLACK6) -j PSW_RULE"
|
||||
@ -1425,7 +1425,7 @@ gen_include() {
|
||||
flush_include
|
||||
extract_rules() {
|
||||
local _ipt="${ipt}"
|
||||
[ "$1" == "6" ] && _ipt="${ip6t}"
|
||||
[ "$1" = "6" ] && _ipt="${ip6t}"
|
||||
[ -z "${_ipt}" ] && return
|
||||
|
||||
echo "*$2"
|
||||
@ -1497,7 +1497,7 @@ get_ip6t_bin() {
|
||||
}
|
||||
|
||||
start() {
|
||||
[ "$ENABLED_DEFAULT_ACL" == 0 -a "$ENABLED_ACLS" == 0 ] && return
|
||||
[ "$ENABLED_DEFAULT_ACL" = 0 ] && [ "$ENABLED_ACLS" = 0 ] && return
|
||||
add_firewall_rule
|
||||
gen_include
|
||||
}
|
||||
@ -1505,7 +1505,7 @@ start() {
|
||||
stop() {
|
||||
[ -z "$(command -v echolog)" ] && . "$UTILS_PATH"
|
||||
del_firewall_rule
|
||||
[ $(config_t_get global flush_set_on_reboot "0") = "1" -o $(config_t_get global flush_set "0") = "1" ] && {
|
||||
[ $(config_t_get global flush_set_on_reboot "0") = "1" ] || [ $(config_t_get global flush_set "0") = "1" ] && {
|
||||
uci -q delete ${CONFIG}.@global[0].flush_set
|
||||
uci -q commit ${CONFIG}
|
||||
flush_ipset
|
||||
|
||||
@ -121,13 +121,13 @@ REDIRECT() {
|
||||
local s="counter redirect"
|
||||
[ -n "$1" ] && {
|
||||
local s="$s to :$1"
|
||||
[ "$2" == "TPROXY" ] && {
|
||||
[ "$2" = "TPROXY" ] && {
|
||||
s="counter meta mark ${FWMARK} tproxy to :$1"
|
||||
}
|
||||
[ "$2" == "TPROXY4" ] && {
|
||||
[ "$2" = "TPROXY4" ] && {
|
||||
s="counter meta mark ${FWMARK} tproxy ip to :$1"
|
||||
}
|
||||
[ "$2" == "TPROXY6" ] && {
|
||||
[ "$2" = "TPROXY6" ] && {
|
||||
s="counter meta mark ${FWMARK} tproxy ip6 to :$1"
|
||||
}
|
||||
}
|
||||
@ -175,25 +175,28 @@ insert_nftset() {
|
||||
*) suffix=" timeout $timeout_argument" ;;
|
||||
esac
|
||||
{
|
||||
if [ $# -gt 0 ]; then
|
||||
if [ $# -gt 0 ] && [ $# -le 1000 ]; then
|
||||
printf "%s\n" "$@"
|
||||
elif [ $# -gt 1000 ]; then
|
||||
printf "%s\n" "$*"
|
||||
else
|
||||
cat
|
||||
fi | awk -v s="$suffix" -v n="$nftset_name" -v t="$NFTABLE_NAME" '
|
||||
BEGIN {
|
||||
RS = "[ \t\n\r]+"
|
||||
ORS = ""
|
||||
}
|
||||
$0 != "" {
|
||||
if (first == 0) {
|
||||
printf "add element %s %s { \n", t, n;
|
||||
if (!first) {
|
||||
printf "add element %s %s { \n", t, n
|
||||
first = 1;
|
||||
} else {
|
||||
printf ",\n";
|
||||
print ",\n"
|
||||
}
|
||||
printf "%s%s", $0, s;
|
||||
print $0 s
|
||||
}
|
||||
END {
|
||||
if (first == 1) printf "\n }\n";
|
||||
if (first) print "\n }\n"
|
||||
}
|
||||
'
|
||||
} | nft -f -
|
||||
@ -211,7 +214,7 @@ gen_nftset() {
|
||||
local gc_interval_time="1h"
|
||||
|
||||
if ! nft list set $NFTABLE_NAME $nftset_name >/dev/null 2>&1; then
|
||||
if [ "$timeout_argument_set" == "0" ]; then
|
||||
if [ "$timeout_argument_set" = "0" ]; then
|
||||
nft "add set $NFTABLE_NAME $nftset_name { type $ip_type; flags interval, timeout; auto-merge; }"
|
||||
else
|
||||
nft "add set $NFTABLE_NAME $nftset_name { type $ip_type; flags interval, timeout; timeout $timeout_argument_set; gc-interval $gc_interval_time; auto-merge; }"
|
||||
@ -236,11 +239,11 @@ get_jump_nft() {
|
||||
}
|
||||
|
||||
load_acl() {
|
||||
([ "$ENABLED_ACLS" == 1 ] || ([ "$ENABLED_DEFAULT_ACL" == 1 ] && [ "$CLIENT_PROXY" == 1 ])) && echolog " - 访问控制:"
|
||||
[ "$ENABLED_ACLS" == 1 ] && {
|
||||
{ [ "$ENABLED_ACLS" = "1" ] || { [ "$ENABLED_DEFAULT_ACL" = "1" ] && [ "$CLIENT_PROXY" = "1" ]; }; } && echolog " - 访问控制:"
|
||||
[ "$ENABLED_ACLS" = 1 ] && {
|
||||
acl_app
|
||||
for sid in $(ls -F ${TMP_ACL_PATH} | grep '/$' | awk -F '/' '{print $1}' | grep -v 'default'); do
|
||||
eval $(uci -q show "${CONFIG}.${sid}" | cut -d'.' -sf 3-)
|
||||
eval "$(uci -q show "${CONFIG}.${sid}" | cut -d'.' -sf 3-)"
|
||||
|
||||
tcp_no_redir_ports=${tcp_no_redir_ports:-default}
|
||||
udp_no_redir_ports=${udp_no_redir_ports:-default}
|
||||
@ -409,7 +412,7 @@ load_acl() {
|
||||
gen_nftset $gfw6_set_name ipv6_addr "2d" 0
|
||||
}
|
||||
}
|
||||
[ "${use_shunt_tcp}" = "1" -o "${use_shunt_udp}" = "1" ] && {
|
||||
[ "${use_shunt_tcp}" = "1" ] || [ "${use_shunt_udp}" = "1" ] && {
|
||||
[ "${use_global_config}" = "0" ] && {
|
||||
shunt_set_name="psw_${sid}_shunt"
|
||||
shunt6_set_name="psw_${sid}_shunt6"
|
||||
@ -433,18 +436,18 @@ load_acl() {
|
||||
[ -z "$(get_cache_var "ACL_${sid}_tcp_default")" ] && echolog " - ${msg}使用与全局配置不相同节点,已将DNS强制重定向到专用 DNS 服务器。"
|
||||
fi
|
||||
|
||||
[ -n "$tcp_port" -o -n "$udp_port" ] && {
|
||||
[ -n "$tcp_port" ] || [ -n "$udp_port" ] && {
|
||||
[ "${use_block_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ${_ipt_source} ip daddr @$NFTSET_BLOCK counter drop comment \"$remarks\""
|
||||
[ "${use_block_list}" = "1" ] && [ -z "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME PSW_NAT ${_ipt_source} ip daddr @$NFTSET_BLOCK counter drop comment \"$remarks\""
|
||||
[ "${use_direct_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ${_ipt_source} ip daddr @$NFTSET_WHITE counter return comment \"$remarks\""
|
||||
[ "${use_direct_list}" = "1" ] && [ -z "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME PSW_NAT ${_ipt_source} ip daddr @$NFTSET_WHITE counter return comment \"$remarks\""
|
||||
[ "$PROXY_IPV6" == "1" ] && [ "$_ipv4" != "1" ] && {
|
||||
[ "$PROXY_IPV6" = "1" ] && [ "$_ipv4" != "1" ] && {
|
||||
[ "${use_block_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 ${_ipt_source} ip6 daddr @$NFTSET_BLOCK6 counter drop comment \"$remarks\""
|
||||
[ "${use_direct_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 ${_ipt_source} ip6 daddr @$NFTSET_WHITE6 counter return comment \"$remarks\""
|
||||
}
|
||||
|
||||
[ "$tcp_proxy_drop_ports" != "disable" ] && {
|
||||
[ "$PROXY_IPV6" == "1" ] && [ "$_ipv4" != "1" ] && {
|
||||
[ "$PROXY_IPV6" = "1" ] && [ "$_ipv4" != "1" ] && {
|
||||
[ "${use_fakedns}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp ${_ipt_source} $(factor $tcp_proxy_drop_ports "tcp dport") ip6 daddr $FAKE_IP_6 counter drop comment \"$remarks\"" 2>/dev/null
|
||||
[ "${use_proxy_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp ${_ipt_source} $(factor $tcp_proxy_drop_ports "tcp dport") ip6 daddr @$black6_set_name counter drop comment \"$remarks\"" 2>/dev/null
|
||||
[ "${use_gfw_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp ${_ipt_source} $(factor $tcp_proxy_drop_ports "tcp dport") ip6 daddr @$gfw6_set_name counter drop comment \"$remarks\"" 2>/dev/null
|
||||
@ -462,7 +465,7 @@ load_acl() {
|
||||
}
|
||||
|
||||
[ "$udp_proxy_drop_ports" != "disable" ] && {
|
||||
[ "$PROXY_IPV6" == "1" ] && [ "$_ipv4" != "1" ] && {
|
||||
[ "$PROXY_IPV6" = "1" ] && [ "$_ipv4" != "1" ] && {
|
||||
[ "${use_fakedns}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp ${_ipt_source} $(factor $udp_proxy_drop_ports "udp dport") ip6 daddr $FAKE_IP_6 counter drop comment \"$remarks\"" 2>/dev/null
|
||||
[ "${use_proxy_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp ${_ipt_source} $(factor $udp_proxy_drop_ports "udp dport") ip6 daddr @$black6_set_name counter drop comment \"$remarks\"" 2>/dev/null
|
||||
[ "${use_gfw_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp ${_ipt_source} $(factor $udp_proxy_drop_ports "udp dport") ip6 daddr @$gfw6_set_name counter drop comment \"$remarks\"" 2>/dev/null
|
||||
@ -504,7 +507,7 @@ load_acl() {
|
||||
nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT ip protocol icmp ${_ipt_source} return comment \"$remarks\""
|
||||
}
|
||||
|
||||
[ "$accept_icmpv6" = "1" ] && [ "$PROXY_IPV6" == "1" ] && [ "$_ipv4" != "1" ] && {
|
||||
[ "$accept_icmpv6" = "1" ] && [ "$PROXY_IPV6" = "1" ] && [ "$_ipv4" != "1" ] && {
|
||||
[ "${use_direct_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT meta l4proto icmpv6 ${_ipt_source} ip6 daddr @$NFTSET_WHITE6 counter return comment \"$remarks\"" 2>/dev/null
|
||||
[ "${use_fakedns}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT meta l4proto icmpv6 ${_ipt_source} ip6 daddr $FAKE_IP_6 $(REDIRECT) comment \"$remarks\"" 2>/dev/null
|
||||
[ "${use_proxy_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT meta l4proto icmpv6 ${_ipt_source} ip6 daddr @$black6_set_name $(REDIRECT) comment \"$remarks\"" 2>/dev/null
|
||||
@ -523,7 +526,7 @@ load_acl() {
|
||||
[ "${tcp_proxy_mode}" != "disable" ] && nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") ${nft_j} comment \"$remarks\""
|
||||
[ -n "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp ${_ipt_source} $(REDIRECT $tcp_port TPROXY4) comment \"$remarks\""
|
||||
|
||||
[ "$PROXY_IPV6" == "1" ] && [ "$_ipv4" != "1" ] && {
|
||||
[ "$PROXY_IPV6" = "1" ] && [ "$_ipv4" != "1" ] && {
|
||||
[ "${use_fakedns}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp ${_ipt_source} ip6 daddr $FAKE_IP_6 counter jump PSW_RULE comment \"$remarks\""
|
||||
[ "${use_proxy_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") ip6 daddr @$black6_set_name counter jump PSW_RULE comment \"$remarks\"" 2>/dev/null
|
||||
[ "${use_gfw_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") ip6 daddr @$gfw6_set_name counter jump PSW_RULE comment \"$remarks\"" 2>/dev/null
|
||||
@ -554,7 +557,7 @@ load_acl() {
|
||||
[ "${udp_proxy_mode}" != "disable" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp ${_ipt_source} $(factor $udp_redir_ports "udp dport") counter jump PSW_RULE comment \"$remarks\""
|
||||
nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp ${_ipt_source} $(REDIRECT $udp_port TPROXY4) comment \"$remarks\""
|
||||
|
||||
[ "$PROXY_IPV6" == "1" ] && [ "$_ipv4" != "1" ] && {
|
||||
[ "$PROXY_IPV6" = "1" ] && [ "$_ipv4" != "1" ] && {
|
||||
[ "${use_fakedns}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp ${_ipt_source} ip6 daddr $FAKE_IP_6 counter jump PSW_RULE comment \"$remarks\""
|
||||
[ "${use_proxy_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp ${_ipt_source} $(factor $udp_redir_ports "udp dport") ip6 daddr @$black6_set_name counter jump PSW_RULE comment \"$remarks\"" 2>/dev/null
|
||||
[ "${use_gfw_list}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp ${_ipt_source} $(factor $udp_redir_ports "udp dport") ip6 daddr @$gfw6_set_name counter jump PSW_RULE comment \"$remarks\"" 2>/dev/null
|
||||
@ -577,7 +580,7 @@ load_acl() {
|
||||
done
|
||||
}
|
||||
|
||||
[ "$ENABLED_DEFAULT_ACL" == 1 ] && [ "$CLIENT_PROXY" == 1 ] && {
|
||||
[ "$ENABLED_DEFAULT_ACL" = 1 ] && [ "$CLIENT_PROXY" = 1 ] && {
|
||||
msg="【默认】,"
|
||||
[ "$TCP_NO_REDIR_PORTS" != "disable" ] && {
|
||||
nft "add rule $NFTABLE_NAME $nft_prerouting_chain ip protocol tcp $(factor $TCP_NO_REDIR_PORTS "tcp dport") counter return comment \"默认\""
|
||||
@ -620,18 +623,18 @@ load_acl() {
|
||||
nft "add rule $NFTABLE_NAME PSW_DNS meta l4proto tcp tcp dport 53 counter redirect to :${DNS_REDIRECT} comment \"默认\""
|
||||
fi
|
||||
|
||||
[ -n "${TCP_PROXY_MODE}" -o -n "${UDP_PROXY_MODE}" ] && {
|
||||
[ -n "${TCP_PROXY_MODE}" ] || [ -n "${UDP_PROXY_MODE}" ] && {
|
||||
[ "${USE_BLOCK_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip daddr @$NFTSET_BLOCK counter drop comment \"默认\""
|
||||
[ "${USE_BLOCK_LIST}" = "1" ] && [ -z "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME PSW_NAT ip daddr @$NFTSET_BLOCK counter drop comment \"默认\""
|
||||
[ "${USE_DIRECT_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE ip daddr @$NFTSET_WHITE counter return comment \"默认\""
|
||||
[ "${USE_DIRECT_LIST}" = "1" ] && [ -z "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME PSW_NAT ip daddr @$NFTSET_WHITE counter return comment \"默认\""
|
||||
[ "$PROXY_IPV6" == "1" ] && {
|
||||
[ "$PROXY_IPV6" = "1" ] && {
|
||||
[ "${USE_BLOCK_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 ip6 daddr @$NFTSET_BLOCK6 counter drop comment \"默认\""
|
||||
[ "${USE_DIRECT_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 ip6 daddr @$NFTSET_WHITE6 counter return comment \"默认\""
|
||||
}
|
||||
|
||||
[ "$TCP_PROXY_DROP_PORTS" != "disable" ] && {
|
||||
[ "$PROXY_IPV6" == "1" ] && {
|
||||
[ "$PROXY_IPV6" = "1" ] && {
|
||||
[ "${USE_FAKEDNS}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp $(factor $TCP_PROXY_DROP_PORTS "tcp dport") ip6 daddr $FAKE_IP_6 counter drop comment \"默认\""
|
||||
[ "${USE_PROXY_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp $(factor $TCP_PROXY_DROP_PORTS "tcp dport") ip6 daddr @$NFTSET_BLACK6 counter drop comment \"默认\""
|
||||
[ "${USE_GFW_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp $(factor $TCP_PROXY_DROP_PORTS "tcp dport") ip6 daddr @$NFTSET_GFW6 counter drop comment \"默认\""
|
||||
@ -650,7 +653,7 @@ load_acl() {
|
||||
}
|
||||
|
||||
[ "$UDP_PROXY_DROP_PORTS" != "disable" ] && {
|
||||
[ "$PROXY_IPV6" == "1" ] && {
|
||||
[ "$PROXY_IPV6" = "1" ] && {
|
||||
[ "${USE_FAKEDNS}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp $(factor $UDP_PROXY_DROP_PORTS "udp dport") ip6 daddr $FAKE_IP_6 counter drop comment \"默认\""
|
||||
[ "${USE_PROXY_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp $(factor $UDP_PROXY_DROP_PORTS "udp dport") ip6 daddr @$NFTSET_BLACK6 counter drop comment \"默认\""
|
||||
[ "${USE_GFW_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp $(factor $UDP_PROXY_DROP_PORTS "udp dport") ip6 daddr @$NFTSET_GFW6 counter drop comment \"默认\""
|
||||
@ -697,7 +700,7 @@ load_acl() {
|
||||
nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT ip protocol icmp return comment \"默认\""
|
||||
}
|
||||
|
||||
[ "$accept_icmpv6" = "1" ] && [ "$PROXY_IPV6" == "1" ] && {
|
||||
[ "$accept_icmpv6" = "1" ] && [ "$PROXY_IPV6" = "1" ] && {
|
||||
[ "${USE_DIRECT_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT ip6 daddr @$NFTSET_WHITE6 counter return comment \"默认\""
|
||||
[ "${USE_FAKEDNS}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT meta l4proto icmpv6 ip6 daddr $FAKE_IP_6 $(REDIRECT) comment \"默认\""
|
||||
[ "${USE_PROXY_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT meta l4proto icmpv6 ip6 daddr @$NFTSET_BLACK6 $(REDIRECT) comment \"默认\""
|
||||
@ -717,7 +720,7 @@ load_acl() {
|
||||
[ -n "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp $(REDIRECT $TCP_REDIR_PORT TPROXY4) comment \"默认\""
|
||||
nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp counter return comment \"默认\""
|
||||
|
||||
[ "$PROXY_IPV6" == "1" ] && {
|
||||
[ "$PROXY_IPV6" = "1" ] && {
|
||||
[ "${USE_FAKEDNS}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp ip6 daddr $FAKE_IP_6 counter jump PSW_RULE comment \"默认\""
|
||||
[ "${USE_PROXY_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp $(factor $TCP_REDIR_PORTS "tcp dport") ip6 daddr @$NFTSET_BLACK6 counter jump PSW_RULE comment \"默认\""
|
||||
[ "${USE_GFW_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp $(factor $TCP_REDIR_PORTS "tcp dport") ip6 daddr @$NFTSET_GFW6 counter jump PSW_RULE comment \"默认\""
|
||||
@ -734,7 +737,7 @@ load_acl() {
|
||||
|
||||
# 加载UDP默认代理模式
|
||||
if [ -n "${UDP_PROXY_MODE}" ]; then
|
||||
[ -n "$UDP_NODE" -o "$TCP_UDP" = "1" ] && {
|
||||
[ -n "$UDP_NODE" ] || [ "$TCP_UDP" = "1" ] && {
|
||||
if is_socks_wrap "$UDP_NODE"; then
|
||||
msg2="${msg}使用 UDP 节点[Socks 配置($(config_n_get ${UDP_NODE#Socks_} port) 端口)](TPROXY:${UDP_REDIR_PORT})"
|
||||
else
|
||||
@ -750,7 +753,7 @@ load_acl() {
|
||||
nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp $(REDIRECT $UDP_REDIR_PORT TPROXY4) comment \"默认\""
|
||||
nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp counter return comment \"默认\""
|
||||
|
||||
[ "$PROXY_IPV6" == "1" ] && {
|
||||
[ "$PROXY_IPV6" = "1" ] && {
|
||||
[ "${USE_FAKEDNS}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp ip6 daddr $FAKE_IP_6 counter jump PSW_RULE comment \"默认\""
|
||||
[ "${USE_PROXY_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp $(factor $UDP_REDIR_PORTS "udp dport") ip6 daddr @$NFTSET_BLACK6 counter jump PSW_RULE comment \"默认\""
|
||||
[ "${USE_GFW_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp $(factor $UDP_REDIR_PORTS "udp dport") ip6 daddr @$NFTSET_GFW6 counter jump PSW_RULE comment \"默认\""
|
||||
@ -823,7 +826,7 @@ filter_node() {
|
||||
local port=$(config_n_get "$node" port)
|
||||
local hop=$(config_n_get "$node" hysteria2_hop)
|
||||
[ -n "$hop" ] && port="${port:+$port,}$hop"
|
||||
[ -z "$address" -o -z "$port" ] && return 1
|
||||
[ -z "$address" ] || [ -z "$port" ] && return 1
|
||||
filter_server_port "$address" "$port" "$stream"
|
||||
}
|
||||
|
||||
@ -1201,7 +1204,7 @@ add_firewall_rule() {
|
||||
}
|
||||
|
||||
# jump chains
|
||||
[ "$PROXY_IPV6" == "1" ] && {
|
||||
[ "$PROXY_IPV6" = "1" ] && {
|
||||
nft "add rule $NFTABLE_NAME mangle_prerouting meta nfproto {ipv6} counter jump PSW_MANGLE_V6"
|
||||
nft "add rule $NFTABLE_NAME mangle_output meta nfproto {ipv6} counter jump PSW_OUTPUT_MANGLE_V6 comment \"PSW_OUTPUT_MANGLE\""
|
||||
|
||||
@ -1213,7 +1216,7 @@ add_firewall_rule() {
|
||||
|
||||
[ "$TCP_UDP" = "1" ] && [ -z "$UDP_NODE" ] && UDP_NODE=$TCP_NODE
|
||||
|
||||
[ "$ENABLED_DEFAULT_ACL" == 1 ] && {
|
||||
[ "$ENABLED_DEFAULT_ACL" = 1 ] && {
|
||||
msg="【路由器本机】,"
|
||||
|
||||
[ "$TCP_NO_REDIR_PORTS" != "disable" ] && {
|
||||
@ -1247,7 +1250,7 @@ add_firewall_rule() {
|
||||
}
|
||||
fi
|
||||
|
||||
[ -n "${LOCALHOST_TCP_PROXY_MODE}" -o -n "${LOCALHOST_UDP_PROXY_MODE}" ] && {
|
||||
[ -n "${LOCALHOST_TCP_PROXY_MODE}" ] || [ -n "${LOCALHOST_UDP_PROXY_MODE}" ] && {
|
||||
[ "$TCP_PROXY_DROP_PORTS" != "disable" ] && {
|
||||
[ "${USE_FAKEDNS}" = "1" ] && nft add rule $NFTABLE_NAME $nft_output_chain ip protocol tcp ip daddr $FAKE_IP $(factor $TCP_PROXY_DROP_PORTS "tcp dport") counter drop
|
||||
[ "${USE_PROXY_LIST}" = "1" ] && nft add rule $NFTABLE_NAME $nft_output_chain ip protocol tcp ip daddr @$NFTSET_BLACK $(factor $TCP_PROXY_DROP_PORTS "tcp dport") counter drop
|
||||
@ -1297,7 +1300,7 @@ add_firewall_rule() {
|
||||
echolog " - [$?]将上游 DNS 服务器 [${2}]:${3} 加入到路由器自身代理的 TCP 转发链,请确保您的节点支持IPv6,并开启IPv6透明代理!"
|
||||
fi
|
||||
}
|
||||
[ "$TCP_PROXY_DNS" == 1 ] && hosts_foreach REMOTE_DNS _proxy_tcp_access 53
|
||||
[ "$TCP_PROXY_DNS" = 1 ] && hosts_foreach REMOTE_DNS _proxy_tcp_access 53
|
||||
|
||||
[ "$accept_icmp" = "1" ] && {
|
||||
[ "${USE_FAKEDNS}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_ICMP_REDIRECT oif lo ip protocol icmp ip daddr $FAKE_IP counter redirect"
|
||||
@ -1340,7 +1343,7 @@ add_firewall_rule() {
|
||||
[ -n "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME mangle_output ip protocol tcp counter jump PSW_OUTPUT_MANGLE comment \"PSW_OUTPUT_MANGLE\""
|
||||
[ -z "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME nat_output ip protocol tcp counter jump PSW_OUTPUT_NAT"
|
||||
|
||||
[ "$PROXY_IPV6" == "1" ] && {
|
||||
[ "$PROXY_IPV6" = "1" ] && {
|
||||
[ -n "${LOCALHOST_TCP_PROXY_MODE}" ] && {
|
||||
[ "${USE_FAKEDNS}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 meta l4proto tcp ip6 daddr $FAKE_IP_6 counter jump PSW_RULE"
|
||||
[ "${USE_PROXY_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 meta l4proto tcp ip6 daddr @$NFTSET_BLACK6 $(factor $TCP_REDIR_PORTS "tcp dport") counter jump PSW_RULE"
|
||||
@ -1355,12 +1358,12 @@ add_firewall_rule() {
|
||||
fi
|
||||
|
||||
# 加载路由器自身代理 UDP
|
||||
if [ -n "$UDP_NODE" -o "$TCP_UDP" = "1" ]; then
|
||||
if [ -n "$UDP_NODE" ] || [ "$TCP_UDP" = "1" ]; then
|
||||
_proxy_udp_access() {
|
||||
[ -n "${2}" ] || return 0
|
||||
if echo "${2}" | grep -q -v ':'; then
|
||||
nft "get element $NFTABLE_NAME $NFTSET_LAN {${2}}" &>/dev/null
|
||||
[ $? == 0 ] && {
|
||||
[ $? = 0 ] && {
|
||||
echolog " - 上游 DNS 服务器 ${2} 已在直接访问的列表中,不强制向 UDP 代理转发对该服务器 UDP/${3} 端口的访问"
|
||||
return 0
|
||||
}
|
||||
@ -1369,7 +1372,7 @@ add_firewall_rule() {
|
||||
echolog " - [$?]将上游 DNS 服务器 ${2}:${3} 加入到路由器自身代理的 UDP 转发链"
|
||||
else
|
||||
nft "get element $NFTABLE_NAME $NFTSET_LAN6 {${2}}" &>/dev/null
|
||||
[ $? == 0 ] && {
|
||||
[ $? = 0 ] && {
|
||||
echolog " - 上游 DNS 服务器 ${2} 已在直接访问的列表中,不强制向 UDP 代理转发对该服务器 UDP/${3} 端口的访问"
|
||||
return 0
|
||||
}
|
||||
@ -1391,7 +1394,7 @@ add_firewall_rule() {
|
||||
nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp iif lo counter return comment \"本机\""
|
||||
nft "add rule $NFTABLE_NAME mangle_output ip protocol udp counter jump PSW_OUTPUT_MANGLE comment \"PSW_OUTPUT_MANGLE\""
|
||||
|
||||
[ "$PROXY_IPV6" == "1" ] && {
|
||||
[ "$PROXY_IPV6" = "1" ] && {
|
||||
[ -n "${LOCALHOST_UDP_PROXY_MODE}" ] && {
|
||||
[ "${USE_FAKEDNS}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 meta l4proto udp ip6 daddr $FAKE_IP_6 counter jump PSW_RULE"
|
||||
[ "${USE_PROXY_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 meta l4proto udp ip6 daddr @$NFTSET_BLACK6 $(factor $UDP_REDIR_PORTS "udp dport") counter jump PSW_RULE"
|
||||
@ -1512,7 +1515,7 @@ gen_include() {
|
||||
}
|
||||
|
||||
start() {
|
||||
[ "$ENABLED_DEFAULT_ACL" == 0 -a "$ENABLED_ACLS" == 0 ] && return
|
||||
[ "$ENABLED_DEFAULT_ACL" = 0 ] && [ "$ENABLED_ACLS" = 0 ] && return
|
||||
add_firewall_rule
|
||||
gen_include
|
||||
}
|
||||
@ -1520,7 +1523,7 @@ start() {
|
||||
stop() {
|
||||
[ -z "$(command -v echolog)" ] && . "$UTILS_PATH"
|
||||
del_firewall_rule
|
||||
[ $(config_t_get global flush_set_on_reboot "0") = "1" -o $(config_t_get global flush_set "0") = "1" ] && {
|
||||
[ $(config_t_get global flush_set_on_reboot "0") = "1" ] || [ $(config_t_get global flush_set "0") = "1" ] && {
|
||||
uci -q delete ${CONFIG}.@global[0].flush_set
|
||||
uci -q commit ${CONFIG}
|
||||
#flush_table
|
||||
|
||||
@ -18,24 +18,6 @@ do
|
||||
|
||||
if [ "$CFG_UPDATE_INT" -ne 0 ]; then
|
||||
|
||||
stop_week_mode=$(config_t_get global_delay stop_week_mode)
|
||||
stop_interval_mode=$(config_t_get global_delay stop_interval_mode)
|
||||
stop_interval_mode=$(expr "$stop_interval_mode" \* 60)
|
||||
if [ -n "$stop_week_mode" ]; then
|
||||
[ "$stop_week_mode" = "8" ] && {
|
||||
[ "$(expr "$CFG_UPDATE_INT" % "$stop_interval_mode")" -eq 0 ] && { /etc/init.d/$CONFIG stop > /dev/null 2>&1 & }
|
||||
}
|
||||
fi
|
||||
|
||||
start_week_mode=$(config_t_get global_delay start_week_mode)
|
||||
start_interval_mode=$(config_t_get global_delay start_interval_mode)
|
||||
start_interval_mode=$(expr "$start_interval_mode" \* 60)
|
||||
if [ -n "$start_week_mode" ]; then
|
||||
[ "$start_week_mode" = "8" ] && {
|
||||
[ "$(expr "$CFG_UPDATE_INT" % "$start_interval_mode")" -eq 0 ] && { /etc/init.d/$CONFIG start > /dev/null 2>&1 & }
|
||||
}
|
||||
fi
|
||||
|
||||
restart_week_mode=$(config_t_get global_delay restart_week_mode)
|
||||
restart_interval_mode=$(config_t_get global_delay restart_interval_mode)
|
||||
restart_interval_mode=$(expr "$restart_interval_mode" \* 60)
|
||||
@ -45,36 +27,35 @@ do
|
||||
}
|
||||
fi
|
||||
|
||||
autoupdate=$(config_t_get global_rules auto_update)
|
||||
weekupdate=$(config_t_get global_rules week_update)
|
||||
hourupdate=$(config_t_get global_rules interval_update)
|
||||
hourupdate=$(expr "$hourupdate" \* 60)
|
||||
if [ "$autoupdate" = "1" ]; then
|
||||
[ "$weekupdate" = "8" ] && {
|
||||
[ "$(expr "$CFG_UPDATE_INT" % "$hourupdate")" -eq 0 ] && { lua $APP_PATH/rule_update.lua log all cron > /dev/null 2>&1 & }
|
||||
rules_update_week_mode=$(config_t_get global_rules update_week_mode)
|
||||
rules_update_interval_mode=$(config_t_get global_rules update_interval_mode)
|
||||
rules_update_interval_mode=$(expr "$rules_update_interval_mode" \* 60)
|
||||
if [ -n "$rules_update_week_mode" ]; then
|
||||
[ "$rules_update_week_mode" = "8" ] && {
|
||||
[ "$(expr "$CFG_UPDATE_INT" % "$rules_update_interval_mode")" -eq 0 ] && { lua $APP_PATH/rule_update.lua log all cron > /dev/null 2>&1 & }
|
||||
}
|
||||
fi
|
||||
|
||||
TMP_SUB_PATH=$TMP_PATH/sub_tasks
|
||||
mkdir -p $TMP_SUB_PATH
|
||||
for item in $(uci show ${CONFIG} | grep "=subscribe_list" | cut -d '.' -sf 2 | cut -d '=' -sf 1); do
|
||||
if [ "$(config_n_get $item auto_update 0)" = "1" ]; then
|
||||
sub_update_week_mode=$(config_n_get $item update_week_mode)
|
||||
if [ -n "$sub_update_week_mode" ]; then
|
||||
cfgid=$(uci show ${CONFIG}.$item | head -n 1 | cut -d '.' -sf 2 | cut -d '=' -sf 1)
|
||||
remark=$(config_n_get $item remark)
|
||||
week_update=$(config_n_get $item week_update)
|
||||
hour_update=$(config_n_get $item interval_update)
|
||||
echo "$cfgid" >> $TMP_SUB_PATH/${week_update}_${hour_update}
|
||||
sub_update_interval_mode=$(config_n_get $item update_interval_mode)
|
||||
echo "$cfgid" >> $TMP_SUB_PATH/${sub_update_week_mode}_${sub_update_interval_mode}
|
||||
fi
|
||||
done
|
||||
|
||||
[ -d "${TMP_SUB_PATH}" ] && {
|
||||
for name in $(ls ${TMP_SUB_PATH}); do
|
||||
week_update=$(echo $name | awk -F '_' '{print $1}')
|
||||
hour_update=$(echo $name | awk -F '_' '{print $2}')
|
||||
hour_update=$(expr "$hour_update" \* 60)
|
||||
sub_update_week_mode=${name%_*}
|
||||
sub_update_interval_mode=${name#*_}
|
||||
sub_update_interval_mode=$(expr "$sub_update_interval_mode" \* 60)
|
||||
cfgids=$(echo -n $(cat ${TMP_SUB_PATH}/${name}) | sed 's# #,#g')
|
||||
[ "$week_update" = "8" ] && {
|
||||
[ "$(expr "$CFG_UPDATE_INT" % "$hour_update")" -eq 0 ] && { lua $APP_PATH/subscribe.lua start $cfgids cron > /dev/null 2>&1 & }
|
||||
[ "$sub_update_week_mode" = "8" ] && {
|
||||
[ "$(expr "$CFG_UPDATE_INT" % "$sub_update_interval_mode")" -eq 0 ] && { lua $APP_PATH/subscribe.lua start $cfgids cron > /dev/null 2>&1 & }
|
||||
}
|
||||
|
||||
done
|
||||
|
||||
@ -89,7 +89,7 @@ get_host_ip() {
|
||||
[ -z "$count" ] && count=3
|
||||
local isip=""
|
||||
local ip=""
|
||||
if [ "$1" == "ipv6" ]; then
|
||||
if [ "$1" = "ipv6" ]; then
|
||||
isip=$(echo $host | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}")
|
||||
if [ -n "$isip" ]; then
|
||||
ip=$(echo "$host" | tr -d '[]')
|
||||
@ -100,7 +100,7 @@ get_host_ip() {
|
||||
fi
|
||||
[ -z "$isip" ] && {
|
||||
local t=4
|
||||
[ "$1" == "ipv6" ] && t=6
|
||||
[ "$1" = "ipv6" ] && t=6
|
||||
local vpsrip=$(resolveip -$t -t $count $host | awk 'NR==1{print}')
|
||||
ip=$vpsrip
|
||||
}
|
||||
@ -113,7 +113,7 @@ get_node_host_ip() {
|
||||
[ -n "$address" ] && {
|
||||
local use_ipv6=$(config_n_get $1 use_ipv6)
|
||||
local network_type="ipv4"
|
||||
[ "$use_ipv6" == "1" ] && network_type="ipv6"
|
||||
[ "$use_ipv6" = "1" ] && network_type="ipv6"
|
||||
ip=$(get_host_ip $network_type $address)
|
||||
}
|
||||
echo $ip
|
||||
@ -220,7 +220,7 @@ get_first_dns() {
|
||||
echo "${2}#${3}"
|
||||
return 1
|
||||
}
|
||||
eval "hosts_foreach \"${__hosts_val}\" __first \"$@\""
|
||||
hosts_foreach "${__hosts_val}" __first "$@"
|
||||
}
|
||||
|
||||
get_last_dns() {
|
||||
@ -231,8 +231,8 @@ get_last_dns() {
|
||||
__last="${2}#${3}"
|
||||
__first=${__first:-${__last}}
|
||||
}
|
||||
eval "hosts_foreach \"${__hosts_val}\" __every \"$@\""
|
||||
[ "${__first}" == "${__last}" ] || echo "${__last}"
|
||||
hosts_foreach "${__hosts_val}" __first "$@"
|
||||
[ "${__first}" = "${__last}" ] || echo "${__last}"
|
||||
}
|
||||
|
||||
normalize_dns() {
|
||||
@ -319,7 +319,7 @@ get_new_port() {
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
[ "$port" -lt $min_port -o "$port" -gt $max_port ] && port=$default_start_port
|
||||
[ "$port" -lt $min_port ] || [ "$port" -gt $max_port ] && port=$default_start_port
|
||||
local start_port="$port"
|
||||
while :; do
|
||||
if [ "$(check_port_exists "$port" "$protocol")" = 0 ]; then
|
||||
@ -346,9 +346,11 @@ check_ver() {
|
||||
local version1="$1"
|
||||
local version2="$2"
|
||||
local i v1 v1_1 v1_2 v1_3 v2 v2_1 v2_2 v2_3
|
||||
IFS='.'; set -- $version1; v1_1=${1:-0}; v1_2=${2:-0}; v1_3=${3:-0}
|
||||
IFS='.'; set -- $version2; v2_1=${1:-0}; v2_2=${2:-0}; v2_3=${3:-0}
|
||||
IFS=
|
||||
local old_ifs="$IFS"
|
||||
IFS='.'
|
||||
set -- $version1; v1_1=${1:-0}; v1_2=${2:-0}; v1_3=${3:-0}
|
||||
set -- $version2; v2_1=${1:-0}; v2_2=${2:-0}; v2_3=${3:-0}
|
||||
IFS="$old_ifs"
|
||||
for i in 1 2 3; do
|
||||
eval v1=\$v1_$i
|
||||
eval v2=\$v2_$i
|
||||
@ -481,8 +483,10 @@ ln_run() {
|
||||
if [ -z "$persist_log_path" ] && [ "$sys_log" != "1" ]; then
|
||||
${file_func:-echolog " - ${ln_name}"} "$@" >${output} 2>&1 &
|
||||
else
|
||||
[ "${output: -1, -7}" == "TCP.log" ] && local protocol="TCP"
|
||||
[ "${output: -1, -7}" == "UDP.log" ] && local protocol="UDP"
|
||||
case "$output" in
|
||||
*TCP.log) local protocol="TCP" ;;
|
||||
*UDP.log) local protocol="UDP" ;;
|
||||
esac
|
||||
if [ -n "${persist_log_path}" ]; then
|
||||
mkdir -p ${persist_log_path}
|
||||
local log_file=${persist_log_path}/passwall_${protocol}_${ln_name}_$(date '+%F').log
|
||||
@ -490,7 +494,7 @@ ln_run() {
|
||||
${file_func:-echolog " - ${ln_name}"} "$@" >> ${log_file} 2>&1 &
|
||||
sys_log=0
|
||||
fi
|
||||
if [ "${sys_log}" == "1" ]; then
|
||||
if [ "${sys_log}" = "1" ]; then
|
||||
echolog "记录 ${ln_name}_${protocol} 到系统日志"
|
||||
${file_func:-echolog " - ${ln_name}"} "$@" 2>&1 | logger -t PASSWALL_${protocol}_${ln_name} &
|
||||
fi
|
||||
|
||||
@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-passwall2
|
||||
PKG_VERSION:=26.7.12
|
||||
PKG_RELEASE:=60
|
||||
PKG_RELEASE:=61
|
||||
PKG_PO_VERSION:=$(PKG_VERSION)
|
||||
|
||||
PKG_CONFIG_DEPENDS:= \
|
||||
|
||||
@ -152,7 +152,9 @@ if load_balancing_options then -- [[ Load balancing Start ]]
|
||||
o:depends({ [_n("node_add_mode")] = "batch" })
|
||||
local descrStr = "Example: <code>^A && B && !C && D$</code><br>"
|
||||
descrStr = descrStr .. "This means the node remark must start with A (^), include B, exclude C (!), and end with D ($).<br>"
|
||||
descrStr = descrStr .. "Conditions are joined by <code>&&</code>, and their order does not affect the result."
|
||||
descrStr = descrStr .. "Conditions are joined by <code>&&</code> (AND), and their order does not affect the result.<br>"
|
||||
descrStr = descrStr .. "Multiple groups can be separated by <code>||</code> (OR), matching succeeds if any group matches.<br>"
|
||||
descrStr = descrStr .. "Example: <code>A && B || C && D</code> means (A AND B) OR (C AND D)."
|
||||
o.description = translate(descrStr)
|
||||
|
||||
o = s:option(ListValue, _n("balancingStrategy"), translate("Balancing Strategy"))
|
||||
|
||||
@ -154,7 +154,9 @@ if load_urltest_options then -- [[ URLTest Start ]]
|
||||
o:depends({ [_n("node_add_mode")] = "batch" })
|
||||
local descrStr = "Example: <code>^A && B && !C && D$</code><br>"
|
||||
descrStr = descrStr .. "This means the node remark must start with A (^), include B, exclude C (!), and end with D ($).<br>"
|
||||
descrStr = descrStr .. "Conditions are joined by <code>&&</code>, and their order does not affect the result."
|
||||
descrStr = descrStr .. "Conditions are joined by <code>&&</code> (AND), and their order does not affect the result.<br>"
|
||||
descrStr = descrStr .. "Multiple groups can be separated by <code>||</code> (OR), matching succeeds if any group matches.<br>"
|
||||
descrStr = descrStr .. "Example: <code>A && B || C && D</code> means (A AND B) OR (C AND D)."
|
||||
o.description = translate(descrStr)
|
||||
|
||||
o = s:option(Value, _n("urltest_url"), translate("Probe URL"))
|
||||
|
||||
@ -1521,11 +1521,22 @@ end
|
||||
function match_node_rule(name, rule)
|
||||
if not name then return false end
|
||||
if not rule or rule == "" then return true end
|
||||
-- split rule by || into OR groups
|
||||
local function split_or(expr)
|
||||
local t = {}
|
||||
for part in (expr .. "||"):gmatch("(.-)%|%|") do
|
||||
part = trim(part)
|
||||
if part ~= "" then
|
||||
table.insert(t, part)
|
||||
end
|
||||
end
|
||||
return t
|
||||
end
|
||||
-- split rule by &&
|
||||
local function split_and(expr)
|
||||
local t = {}
|
||||
for part in expr:gmatch("[^&]+") do
|
||||
part = part:gsub("^%s+", ""):gsub("%s+$", "")
|
||||
for part in (expr .. "&&"):gmatch("(.-)%&%&") do
|
||||
part = trim(part)
|
||||
if part ~= "" then
|
||||
table.insert(t, part)
|
||||
end
|
||||
@ -1556,13 +1567,22 @@ function match_node_rule(name, rule)
|
||||
-- contains
|
||||
return str:find(cond, 1, true) ~= nil
|
||||
end
|
||||
-- AND logic
|
||||
for _, cond in ipairs(split_and(rule)) do
|
||||
if not match_cond(name, cond) then
|
||||
return false
|
||||
-- check if all conditions in AND group match
|
||||
local function match_and_group(str, group_expr)
|
||||
for _, cond in ipairs(split_and(group_expr)) do
|
||||
if not match_cond(str, cond) then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
-- OR logic: return true if any group matches
|
||||
for _, group in ipairs(split_or(rule)) do
|
||||
if match_and_group(name, group) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return true
|
||||
return false
|
||||
end
|
||||
|
||||
function get_core(field, candidates)
|
||||
|
||||
@ -394,11 +394,15 @@ msgstr "قوانین تطبیق گره"
|
||||
msgid ""
|
||||
"Example: <code>^A && B && !C && D$</code><br>"
|
||||
"This means the node remark must start with A (^), include B, exclude C (!), and end with D ($).<br>"
|
||||
"Conditions are joined by <code>&&</code>, and their order does not affect the result."
|
||||
"Conditions are joined by <code>&&</code> (AND), and their order does not affect the result.<br>"
|
||||
"Multiple groups can be separated by <code>||</code> (OR), matching succeeds if any group matches.<br>"
|
||||
"Example: <code>A && B || C && D</code> means (A AND B) OR (C AND D)."
|
||||
msgstr ""
|
||||
"مثال: <code>^A && B && !C && D$</code><br>"
|
||||
"این بدان معناست که توضیحات گره باید با A شروع شود (^)، شامل B باشد، فاقد C باشد (!)، و با D پایان یابد ($).<br>"
|
||||
"شرطها با <code>&&</code> به هم متصل میشوند و ترتیب آنها تاثیری در نتیجه ندارد."
|
||||
"شرطها با <code>&&</code> (و) به هم متصل میشوند و ترتیب آنها تاثیری در نتیجه ندارد.<br>"
|
||||
"چندین گروه شرط میتوانند با <code>||</code> (یا) از هم جدا شوند؛ اگر هر گروهی مطابقت داشته باشد، نتیجه موفقیتآمیز است.<br>"
|
||||
"مثال: <code>A && B || C && D</code> به معنای (A و B) یا (C و D) است."
|
||||
|
||||
|
||||
msgid "Balancing Strategy"
|
||||
|
||||
@ -391,11 +391,15 @@ msgstr "Правила отбора узлов"
|
||||
msgid ""
|
||||
"Example: <code>^A && B && !C && D$</code><br>"
|
||||
"This means the node remark must start with A (^), include B, exclude C (!), and end with D ($).<br>"
|
||||
"Conditions are joined by <code>&&</code>, and their order does not affect the result."
|
||||
"Conditions are joined by <code>&&</code> (AND), and their order does not affect the result.<br>"
|
||||
"Multiple groups can be separated by <code>||</code> (OR), matching succeeds if any group matches.<br>"
|
||||
"Example: <code>A && B || C && D</code> means (A AND B) OR (C AND D)."
|
||||
msgstr ""
|
||||
"Пример: <code>^A && B && !C && D$</code><br>"
|
||||
"Описание узла должно: начинаться с A (^), содержать B, не содержать C (!), заканчиваться на D ($).<br>"
|
||||
"Условия соединяются оператором <code>&&</code>, порядок условий не влияет на результат."
|
||||
"Условия соединяются оператором <code>&&</code> (И), порядок условий не влияет на результат.<br>"
|
||||
"Несколько групп условий можно разделить оператором <code>||</code> (ИЛИ); совпадение любой группы считается успехом.<br>"
|
||||
"Пример: <code>A && B || C && D</code> означает (A И B) ИЛИ (C И D)."
|
||||
|
||||
msgid "Balancing Strategy"
|
||||
msgstr "Алгоритм балансировки"
|
||||
|
||||
@ -391,11 +391,15 @@ msgstr "节点匹配规则"
|
||||
msgid ""
|
||||
"Example: <code>^A && B && !C && D$</code><br>"
|
||||
"This means the node remark must start with A (^), include B, exclude C (!), and end with D ($).<br>"
|
||||
"Conditions are joined by <code>&&</code>, and their order does not affect the result."
|
||||
"Conditions are joined by <code>&&</code> (AND), and their order does not affect the result.<br>"
|
||||
"Multiple groups can be separated by <code>||</code> (OR), matching succeeds if any group matches.<br>"
|
||||
"Example: <code>A && B || C && D</code> means (A AND B) OR (C AND D)."
|
||||
msgstr ""
|
||||
"示例:<code>^A && B && !C && D$</code><br>"
|
||||
"表示节点备注需同时满足:以 A 开头(^)、包含 B、不包含 C(!)、并以 D 结尾($)。<br>"
|
||||
"多个条件使用 <code>&&</code> 连接,条件顺序不影响结果。"
|
||||
"多个条件使用 <code>&&</code>(与)连接,条件顺序不影响结果。<br>"
|
||||
"多组条件之间可使用 <code>||</code>(或)分隔,任意一组匹配即视为成功。<br>"
|
||||
"示例:<code>A && B || C && D</code> 表示 (A 且 B) 或 (C 且 D)。"
|
||||
|
||||
msgid "Balancing Strategy"
|
||||
msgstr "负载均衡策略"
|
||||
|
||||
@ -391,11 +391,15 @@ msgstr "節點匹配規則"
|
||||
msgid ""
|
||||
"Example: <code>^A && B && !C && D$</code><br>"
|
||||
"This means the node remark must start with A (^), include B, exclude C (!), and end with D ($).<br>"
|
||||
"Conditions are joined by <code>&&</code>, and their order does not affect the result."
|
||||
"Conditions are joined by <code>&&</code> (AND), and their order does not affect the result.<br>"
|
||||
"Multiple groups can be separated by <code>||</code> (OR), matching succeeds if any group matches.<br>"
|
||||
"Example: <code>A && B || C && D</code> means (A AND B) OR (C AND D)."
|
||||
msgstr ""
|
||||
"示例:<code>^A && B && !C && D$</code><br>"
|
||||
"表示節點備註需同時滿足:以 A 開頭(^)、包含 B、不包含 C(!)、並以 D 結尾($)。<br>"
|
||||
"多個條件使用 <code>&&</code> 連接,條件順序不影響結果。"
|
||||
"多個條件使用 <code>&&</code>(與)連接,條件順序不影響結果。<br>"
|
||||
"多組條件之間可使用 <code>||</code>(或)分隔,任意一組匹配即視為成功。<br>"
|
||||
"示例:<code>A && B || C && D</code> 表示 (A 且 B) 或 (C 且 D)。"
|
||||
|
||||
msgid "Balancing Strategy"
|
||||
msgstr "負載均衡策略"
|
||||
|
||||
@ -160,25 +160,28 @@ insert_nftset() {
|
||||
*) suffix=" timeout $timeout_argument" ;;
|
||||
esac
|
||||
{
|
||||
if [ $# -gt 0 ]; then
|
||||
if [ $# -gt 0 ] && [ $# -le 1000 ]; then
|
||||
printf "%s\n" "$@"
|
||||
elif [ $# -gt 1000 ]; then
|
||||
printf "%s\n" "$*"
|
||||
else
|
||||
cat
|
||||
fi | awk -v s="$suffix" -v n="$nftset_name" -v t="$NFTABLE_NAME" '
|
||||
BEGIN {
|
||||
RS = "[ \t\n\r]+"
|
||||
ORS = ""
|
||||
}
|
||||
$0 != "" {
|
||||
if (first == 0) {
|
||||
printf "add element %s %s { \n", t, n;
|
||||
if (!first) {
|
||||
printf "add element %s %s { \n", t, n
|
||||
first = 1;
|
||||
} else {
|
||||
printf ",\n";
|
||||
print ",\n"
|
||||
}
|
||||
printf "%s%s", $0, s;
|
||||
print $0 s
|
||||
}
|
||||
END {
|
||||
if (first == 1) printf "\n }\n";
|
||||
if (first) print "\n }\n"
|
||||
}
|
||||
'
|
||||
} | nft -f -
|
||||
|
||||
@ -4456,6 +4456,16 @@ return view.extend({
|
||||
|
||||
uci.set('network', nameval, 'device', staDevice);
|
||||
}
|
||||
else if (hwtype == 'qcawifi' || hwtype == 'qcawificfg80211') {
|
||||
const radioName = radioDev.getName();
|
||||
const radioMatch = radioName.match(/^wifi(\d+)$/);
|
||||
const radioVifs = uci.sections('wireless', 'wifi-iface')
|
||||
.filter(section => section.device == radioName);
|
||||
const vifIndex = radioVifs.findIndex(section => section['.name'] == section_id);
|
||||
|
||||
if (radioMatch && vifIndex >= 0)
|
||||
uci.set('network', nameval, 'device', 'ath%s%s'.format(radioMatch[1], vifIndex || ''));
|
||||
}
|
||||
|
||||
firewall.deleteNetwork(net.getName());
|
||||
|
||||
@ -4540,7 +4550,8 @@ return view.extend({
|
||||
|
||||
if (bss.ssid != null) {
|
||||
bssid = s2.option(form.Flag, 'bssid', _('Lock to BSSID'), _('Instead of joining any network with a matching SSID, only connect to the BSSID <code>%h</code>.').format(bss.bssid));
|
||||
bssid.default = (uci.get('wireless', radioDev.getName(), 'type') == 'mt_dbdc') ? '1' : '0';
|
||||
const radioType = uci.get('wireless', radioDev.getName(), 'type');
|
||||
bssid.default = ['mt_dbdc', 'qcawifi', 'qcawificfg80211'].includes(radioType) ? '1' : '0';
|
||||
}
|
||||
|
||||
zone = s2.option(widgets.ZoneSelect, 'zone', _('Create / Assign firewall-zone'), _('Choose the firewall zone you want to assign to this interface. Select <em>unspecified</em> to remove the interface from the associated zone or fill out the <em>custom</em> field to define a new zone and attach the interface to it.'));
|
||||
|
||||
@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=mptcp
|
||||
PKG_VERSION:=6.1
|
||||
PKG_RELEASE:=6
|
||||
PKG_RELEASE:=7
|
||||
|
||||
PKG_MAINTAINER:=Ycarus (Yannick Chabanois) <ycarus@zugaina.org>
|
||||
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
|
||||
|
||||
@ -202,6 +202,12 @@ interface_multipath_settings() {
|
||||
uci -q set openmptcprouter.${config}.multipath="$mode"
|
||||
}
|
||||
[ "$mode" != "off" ] && {
|
||||
# LRO, TSO and UFO break MPTCP packets scheduling, always disable them on multipath interfaces
|
||||
[ -n "$iface" ] && {
|
||||
for offload in lro tso ufo; do
|
||||
ethtool -K $iface $offload off >/dev/null 2>&1
|
||||
done
|
||||
}
|
||||
[ -n "$mptcpintf" ] && mptcpintf="$mptcpintf $iface"
|
||||
[ -z "$mptcpintf" ] && mptcpintf="$iface"
|
||||
[ -z "$mptcpmintf" ] && mptcpmintf="$config"
|
||||
|
||||
@ -10,12 +10,12 @@ include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=natflow
|
||||
PKG_VERSION:=20260531
|
||||
PKG_RELEASE:=45
|
||||
PKG_RELEASE:=46
|
||||
|
||||
PKG_SOURCE:=$(PKG_VERSION).tar.xz
|
||||
PKG_SOURCE_URL:=https://github.com/ptpt52/natflow.git
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_VERSION:=0a3d1131b6a5094959f6441ef435b2b3b6fa4819
|
||||
PKG_SOURCE_VERSION:=5bf4ff4efbdab184c5c2f4e27bf0604726589bd3
|
||||
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
|
||||
PKG_MAINTAINER:=Chen Minqiang <ptpt52@gmail.com>
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=nps
|
||||
PKG_VERSION:=0.26.35
|
||||
PKG_RELEASE:=10
|
||||
PKG_VERSION:=0.26.36
|
||||
PKG_RELEASE:=11
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/yisier/nps/tar.gz/v$(PKG_VERSION)?
|
||||
|
||||
@ -8,12 +8,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=torrserver
|
||||
PKG_VERSION:=MatriX.142
|
||||
PKG_RELEASE:=13
|
||||
PKG_VERSION:=MatriX.142.1
|
||||
PKG_RELEASE:=14
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://github.com/YouROK/TorrServer.git
|
||||
PKG_SOURCE_VERSION:=f0585eb7dfc92e0e5fdcb17a7e7eead212201e7d
|
||||
PKG_SOURCE_VERSION:=fa0e1ecb701e78826e3226e582a6ba0e76718a61
|
||||
PKG_MIRROR_HASH:=skip
|
||||
|
||||
PKG_MAINTAINER:=Konstantine Shevlakov <shevlakov@132lan.ru>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user