update 2025-08-23 09:17:17

This commit is contained in:
actions-user 2025-08-23 09:17:17 +08:00
parent 32f4bb1b24
commit 6927bde2c6
48 changed files with 3750 additions and 2577 deletions

View File

@ -48,17 +48,17 @@ else ifeq ($(ARCH),mips64el)
else ifeq ($(ARCH),i386)
ifneq ($(CONFIG_TARGET_x86_geode)$(CONFIG_TARGET_x86_legacy),)
PKG_ARCH:=chinadns-ng+wolfssl@i386-linux-musl@i686@fast+lto
PKG_HASH:=25a215e1b5c18f8b4f0e7f0a0925fd1c959bbfdfeb3383830d2b645a94077fc6
PKG_HASH:=85e057dd0a0e8913b30471737436ab8b71834c494ed9f9e53544261b1ffdc8d6
else
PKG_ARCH:=chinadns-ng+wolfssl@i386-linux-musl@pentium4@fast+lto
PKG_HASH:=e78feedf8fafc60749dfca576acd05b3df8e4b99912aa77a320971011ca77b1d
PKG_HASH:=2d0f1a05c82f2e21e71a6618c7f1d2e7f46aa6a21535d774d517e87ec00c989b
endif
else ifeq ($(ARCH),x86_64)
PKG_ARCH:=chinadns-ng+wolfssl@x86_64-linux-musl@x86_64@fast+lto
PKG_HASH:=9ad100ef18f7acaecad1aaa07b07029e9e50679fc8f119977878211b1ceb96f0
PKG_HASH:=842ea4e9816efd91d39bc76ead5c4a42e79011757e37c521b4270b675cfcb30c
else ifeq ($(ARCH),riscv64)
PKG_ARCH:=chinadns-ng+wolfssl@riscv64-linux-musl@baseline_rv64@fast+lto
PKG_HASH:=ed4d2cf72c2d48f19dd7678f419ce726bc2a793afc62afd6345e735dd262ca96
PKG_HASH:=7056f47f4d6b20109e007792694dc83e5eac44c9265d7be20f6dc10375b35a9b
else
PKG_HASH:=dummy
endif

View File

@ -6,15 +6,15 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=dns2socks-rust
PKG_VERSION:=0.2.0
PKG_VERSION:=0.2.1
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://github.com/tun2proxy/dns2socks.git
PKG_SOURCE_DATE:=2025-03-19
PKG_SOURCE_VERSION:=5f5805bc5eba6530cec27f76860db1e19c1f2382
PKG_MIRROR_HASH:=f45ff9bff184f6eddbc444fc9a0611a47043e3b3422b7c33459bf7e03f37c37e
PKG_SOURCE_DATE:=2025-08-18
PKG_SOURCE_VERSION:=a23fe67ff4e2a218fcd4726055514c8c2b5299c9
PKG_MIRROR_HASH:=7d2829cc0da6e9eacc5ed97f51f37ee0ce1ea1a10f38f1e4d2a30ae80d237289
PKG_MAINTAINER:=Zxlhhyccc <zxlhhyccc@gmail.com>
PKG_LICENSE:=MIT

View File

@ -9,7 +9,8 @@ LUCI_PKGARCH:=all
LUCI_DEPENDS:= \
+sing-box \
+firewall4 \
+kmod-nft-tproxy
+kmod-nft-tproxy \
+ucode-mod-digest
PKG_NAME:=luci-app-homeproxy

View File

@ -333,13 +333,12 @@ return view.extend({
so.rmempty = false;
so = ss.option(form.Value, 'udp_timeout', _('UDP NAT expiration time'),
_('In seconds. <code>300</code> is used by default.'));
_('In seconds.'));
so.datatype = 'uinteger';
so.default = '300';
so.placeholder = '300';
so.depends('homeproxy.config.proxy_mode', 'redirect_tproxy');
so.depends('homeproxy.config.proxy_mode', 'redirect_tun');
so.depends('homeproxy.config.proxy_mode', 'tun');
so.rmempty = false;
so = ss.option(form.Flag, 'bypass_cn_traffic', _('Bypass CN traffic'),
_('Bypass mainland China traffic via firewall rules by default.'));
@ -348,19 +347,20 @@ return view.extend({
so = ss.option(form.ListValue, 'domain_strategy', _('Domain strategy'),
_('If set, the requested domain name will be resolved to IP before routing.'));
for (let i in hp.dns_strategy)
so.value(i, hp.dns_strategy[i])
so.value(i, hp.dns_strategy[i]);
so = ss.option(form.Flag, 'sniff_override', _('Override destination'),
_('Override the connection destination address with the sniffed domain.'));
so.default = so.enabled;
so.rmempty = false;
so = ss.option(form.ListValue, 'default_outbound', _('Default outbound'));
so = ss.option(form.ListValue, 'default_outbound', _('Default outbound'),
_('Default outbound for connections not matched by any routing rules.'));
so.load = function(section_id) {
delete this.keylist;
delete this.vallist;
this.value('nil', _('Disable'));
this.value('nil', _('Disable (the service)'));
this.value('direct-out', _('Direct'));
this.value('block-out', _('Block'));
uci.sections(data[0], 'routing_node', (res) => {
@ -372,6 +372,24 @@ return view.extend({
}
so.default = 'nil';
so.rmempty = false;
so = ss.option(form.ListValue, 'default_outbound_dns', _('Default outbound DNS'),
_('Default DNS server for resolving domain name in the server address.'));
so.load = function(section_id) {
delete this.keylist;
delete this.vallist;
this.value('default-dns', _('Default DNS (issued by WAN)'));
this.value('system-dns', _('System DNS'));
uci.sections(data[0], 'dns_server', (res) => {
if (res.enabled === '1')
this.value(res['.name'], res.label);
});
return this.super('load', section_id);
}
so.default = 'default-dns';
so.rmempty = false;
/* Routing settings end */
/* Routing nodes start */
@ -406,8 +424,27 @@ return view.extend({
so.validate = L.bind(hp.validateUniqueValue, this, data[0], 'routing_node', 'node');
so.editable = true;
so = ss.option(form.ListValue, 'domain_resolver', _('Domain resolver'),
_('For resolving domain name in the server address.'));
so.load = function(section_id) {
delete this.keylist;
delete this.vallist;
this.value('', _('Default'));
this.value('default-dns', _('Default DNS (issued by WAN)'));
this.value('system-dns', _('System DNS'));
uci.sections(data[0], 'dns_server', (res) => {
if (res.enabled === '1')
this.value(res['.name'], res.label);
});
return this.super('load', section_id);
}
so.depends({'node': 'urltest', '!reverse': true});
so.modalonly = true;
so = ss.option(form.ListValue, 'domain_strategy', _('Domain strategy'),
_('If set, the server domain name will be resolved to IP before connecting.<br/>'));
_('The domain strategy for resolving the domain name in the address.'));
for (let i in hp.dns_strategy)
so.value(i, hp.dns_strategy[i]);
so.depends({'node': 'urltest', '!reverse': true});
@ -629,6 +666,15 @@ return view.extend({
_('Invert match result.'));
so.modalonly = true;
so = ss.taboption('field_other', form.ListValue, 'action', _('Action'));
so.value('route', _('Route'));
so.value('route-options', _('Route options'));
so.value('reject', _('Reject'));
so.value('resolve', _('Resolve'));
so.default = 'route';
so.rmempty = false;
so.editable = true;
so = ss.taboption('field_other', form.ListValue, 'outbound', _('Outbound'),
_('Tag of the target outbound.'));
so.load = function(section_id) {
@ -636,7 +682,6 @@ return view.extend({
delete this.vallist;
this.value('direct-out', _('Direct'));
this.value('block-out', _('Block'));
uci.sections(data[0], 'routing_node', (res) => {
if (res.enabled === '1')
this.value(res['.name'], res.label);
@ -645,16 +690,116 @@ return view.extend({
return this.super('load', section_id);
}
so.rmempty = false;
so.depends('action', 'route');
so.editable = true;
so = ss.taboption('field_other', form.Value, 'override_address', _('Override address'),
_('Override the connection destination address.'));
so.datatype = 'ipaddr';
so.depends('action', 'route');
so.depends('action', 'route-options');
so.modalonly = true;
so = ss.taboption('field_other', form.Value, 'override_port', _('Override port'),
_('Override the connection destination port.'));
so.datatype = 'port';
so.depends('action', 'route');
so.depends('action', 'route-options');
so.modalonly = true;
so = ss.taboption('field_other', form.Flag, 'udp_disable_domain_unmapping', _('Disable UDP domain unmapping'),
_('If enabled, for UDP proxy requests addressed to a domain, the original packet address will be sent in the response instead of the mapped domain.'));
so.depends('action', 'route');
so.depends('action', 'route-options');
so.modalonly = true;
so = ss.taboption('field_other', form.Flag, 'udp_connect', _('connect UDP connections'),
_('If enabled, attempts to connect UDP connection to the destination instead of listen.'));
so.depends('action', 'route');
so.depends('action', 'route-options');
so.modalonly = true;
so = ss.taboption('field_other', form.Value, 'udp_timeout', _('UDP timeout'),
_('Timeout for UDP connections.<br/>Setting a larger value than the UDP timeout in inbounds will have no effect.'));
so.datatype = 'uinteger';
so.depends('action', 'route');
so.depends('action', 'route-options');
so.modalonly = true;
so = ss.taboption('field_other', form.Flag, 'tls_record_fragment', _('TLS record fragment'),
_('Fragment TLS handshake into multiple TLS records.'));
so.depends('action', 'route');
so.depends('action', 'route-options');
so.modalonly = true;
so = ss.taboption('field_other', form.Flag, 'tls_fragment', _('TLS fragment'),
_('Fragment TLS handshakes. Due to poor performance, try <code>%s</code> first.').format(
_('TLS record fragment')));
so.depends('action', 'route');
so.depends('action', 'route-options');
so.modalonly = true;
so = ss.taboption('field_other', form.Value, 'tls_fragment_fallback_delay', _('Fragment fallback delay'),
_('The fallback value in milliseconds used when TLS segmentation cannot automatically determine the wait time.'));
so.datatype = 'uinteger';
so.placeholder = '500';
so.depends('tls_fragment', '1');
so.modalonly = true;
so = ss.taboption('field_other', form.ListValue, 'resolve_server', _('DNS server'),
_('Specifies DNS server tag to use instead of selecting through DNS routing.'));
so.load = function(section_id) {
delete this.keylist;
delete this.vallist;
this.value('', _('Default'));
this.value('default-dns', _('Default DNS (issued by WAN)'));
this.value('system-dns', _('System DNS'));
uci.sections(data[0], 'dns_server', (res) => {
if (res.enabled === '1')
this.value(res['.name'], res.label);
});
return this.super('load', section_id);
}
so.depends('action', 'resolve');
so.modalonly = true;
so = ss.taboption('field_other', form.ListValue, 'reject_method', _('Method'));
so.value('default', _('Reply with TCP RST / ICMP port unreachable'));
so.value('drop', _('Drop packets'));
so.depends('action', 'reject');
so.modalonly = true;
so = ss.taboption('field_other', form.Flag, 'reject_no_drop', _('Don\'t drop packets'),
_('<code>%s</code> will be temporarily overwritten to <code>%s</code> after 50 triggers in 30s if not enabled.').format(
_('Method'), _('Drop packets')));
so.depends('reject_method', 'default');
so.modalonly = true;
so = ss.taboption('field_other', form.ListValue, 'resolve_strategy', _('Resolve strategy'),
_('Domain strategy for resolving the domain names.'));
for (let i in hp.dns_strategy)
so.value(i, hp.dns_strategy[i]);
so.depends('action', 'resolve');
so.modalonly = true;
so = ss.taboption('field_other', form.Flag, 'resolve_disable_cache', _('Disable DNS cache'),
_('Disable DNS cache in this query.'));
so.depends('action', 'resolve');
so.modalonly = true;
so = ss.taboption('field_other', form.Value, 'resolve_rewrite_ttl', _('Rewrite TTL'),
_('Rewrite TTL in DNS responses.'));
so.datatype = 'uinteger';
so.depends('action', 'resolve');
so.modalonly = true;
so = ss.taboption('field_other', form.Value, 'resolve_client_subnet', _('EDNS Client subnet'),
_('Append a <code>edns0-subnet</code> OPT extra record with the specified IP prefix to every query by default.<br/>' +
'If value is an IP address instead of prefix, <code>/32</code> or <code>/128</code> will be appended automatically.'));
so.datatype = 'or(cidr, ipaddr)';
so.depends('action', 'resolve');
so.modalonly = true;
so = ss.taboption('field_host', form.DynamicList, 'domain', _('Domain name'),
@ -741,7 +886,6 @@ return view.extend({
this.value('default-dns', _('Default DNS (issued by WAN)'));
this.value('system-dns', _('System DNS'));
this.value('block-dns', _('Block DNS queries'));
uci.sections(data[0], 'dns_server', (res) => {
if (res.enabled === '1')
this.value(res['.name'], res.label);
@ -800,32 +944,45 @@ return view.extend({
so.rmempty = false;
so.editable = true;
so = ss.option(form.Value, 'address', _('Address'),
_('The address of the dns server. Support UDP, TCP, DoH, DoQ, DoT and RCode.'));
so = ss.option(form.ListValue, 'type', _('Type'));
so.value('udp', _('UDP'));
so.value('tcp', _('TCP'));
so.value('tls', _('TLS'));
so.value('https', _('HTTPS'));
so.value('http3', _('HTTP3'));
so.value('quic', _('QUIC'));
so.default = 'udp';
so.rmempty = false;
so.validate = function(section_id, value) {
if (section_id) {
if (!value)
return _('Expecting: %s').format(_('non-empty value'));
try {
let url = new URL(value.replace(/^.*:\/\//, 'http://'));
if (stubValidator.apply('hostname', url.hostname))
return true;
else if (stubValidator.apply('ip4addr', url.hostname))
return true;
else if (stubValidator.apply('ip6addr', url.hostname.match(/^\[(.+)\]$/)?.[1]))
return true;
else
return _('Expecting: %s').format(_('valid DNS server address'));
} catch(e) {}
so = ss.option(form.Value, 'server', _('Address'),
_('The address of the dns server.'));
so.datatype = 'or(hostname, ipaddr)';
so.rmempty = false;
if (!stubValidator.apply('ipaddr', value))
return _('Expecting: %s').format(_('valid DNS server address'));
}
so = ss.option(form.Value, 'server_port', _('Port'),
_('The port of the DNS server.'));
so.datatype = 'port';
return true;
}
so = ss.option(form.Value, 'path', _('Path'),
_('The path of the DNS server.'));
so.placeholder = '/dns-query';
so.depends('type', 'https');
so.depends('type', 'http3');
so.modalonly = true;
so = ss.option(form.DynamicList, 'headers', _('Headers'),
_('Additional headers to be sent to the DNS server.'));
so.depends('type', 'https');
so.depends('type', 'http3');
so.modalonly = true;
so = ss.option(form.Value, 'tls_sni', _('TLS SNI'),
_('Used to verify the hostname on the returned certificates.'));
so.depends('type', 'tls');
so.depends('type', 'https');
so.depends('type', 'http3');
so.depends('type', 'quic');
so.modalonly = true;
so = ss.option(form.ListValue, 'address_resolver', _('Address resolver'),
_('Tag of a another server to resolve the domain name in the address. Required if address contains domain.'));
@ -865,12 +1022,6 @@ return view.extend({
so.value(i, hp.dns_strategy[i]);
so.modalonly = true;
so = ss.option(form.ListValue, 'resolve_strategy', _('Resolve strategy'),
_('Default domain strategy for resolving the domain names.'));
for (let i in hp.dns_strategy)
so.value(i, hp.dns_strategy[i]);
so.editable = true;
so = ss.option(form.ListValue, 'outbound', _('Outbound'),
_('Tag of an outbound for connecting to the dns server.'));
so.load = function(section_id) {
@ -888,11 +1039,6 @@ return view.extend({
so.default = 'direct-out';
so.rmempty = false;
so.editable = true;
so = ss.option(form.Value, 'client_subnet', _('EDNS Client subnet'),
_('Append a <code>edns0-subnet</code> OPT extra record with the specified IP prefix to every query by default.<br/>' +
'If value is an IP address instead of prefix, <code>/32</code> or <code>/128</code> will be appended automatically.'));
so.datatype = 'or(cidr, ipaddr)';
/* DNS servers end */
/* DNS rules start */
@ -936,6 +1082,7 @@ return view.extend({
so.default = 'default';
so.rmempty = false;
so.readonly = true;
so.modalonly = true;
so = ss.taboption('field_other', form.ListValue, 'ip_version', _('IP version'));
so.value('4', _('IPv4'));
@ -994,23 +1141,14 @@ return view.extend({
_('Invert match result.'));
so.modalonly = true;
so = ss.taboption('field_other', form.MultiValue, 'outbound', _('Outbound'),
_('Match the server name of outbound.'));
so.load = function(section_id) {
delete this.keylist;
delete this.vallist;
this.value('any-out', _('Any'));
this.value('direct-out', _('Direct'));
this.value('block-out', _('Block'));
uci.sections(data[0], 'routing_node', (res) => {
if (res.enabled === '1')
this.value(res['.name'], res.label);
});
return this.super('load', section_id);
}
so.modalonly = true;
so = ss.taboption('field_other', form.ListValue, 'action', _('Action'));
so.value('route', _('Route'));
so.value('route-options', _('Route options'));
so.value('reject', _('Reject'));
so.value('predefined', _('Predefined'));
so.default = 'route';
so.rmempty = false;
so.editable = true;
so = ss.taboption('field_other', form.ListValue, 'server', _('Server'),
_('Tag of the target dns server.'));
@ -1020,7 +1158,6 @@ return view.extend({
this.value('default-dns', _('Default DNS (issued by WAN)'));
this.value('system-dns', _('System DNS'));
this.value('block-dns', _('Block DNS queries'));
uci.sections(data[0], 'dns_server', (res) => {
if (res.enabled === '1')
this.value(res['.name'], res.label);
@ -1030,23 +1167,75 @@ return view.extend({
}
so.rmempty = false;
so.editable = true;
so.depends('action', 'route');
so = ss.taboption('field_other', form.ListValue, 'domain_strategy', _('Domain strategy'),
_('Set domain strategy for this query.'));
for (let i in hp.dns_strategy)
so.value(i, hp.dns_strategy[i]);
so.depends('action', 'route');
so.modalonly = true;
so = ss.taboption('field_other', form.Flag, 'dns_disable_cache', _('Disable dns cache'),
_('Disable cache and save cache in this query.'));
so.depends({'server': 'block-dns', '!reverse': true});
so.depends('action', 'route');
so.depends('action', 'route-options');
so.modalonly = true;
so = ss.taboption('field_other', form.Value, 'rewrite_ttl', _('Rewrite TTL'),
_('Rewrite TTL in DNS responses.'));
so.datatype = 'uinteger';
so.depends({'server': 'block-dns', '!reverse': true});
so.depends('action', 'route');
so.depends('action', 'route-options');
so.modalonly = true;
so = ss.taboption('field_other', form.Value, 'client_subnet', _('EDNS Client subnet'),
_('Append a <code>edns0-subnet</code> OPT extra record with the specified IP prefix to every query by default.<br/>' +
'If value is an IP address instead of prefix, <code>/32</code> or <code>/128</code> will be appended automatically.'));
so.datatype = 'or(cidr, ipaddr)';
so.depends({'server': 'block-dns', '!reverse': true});
so.depends('action', 'route');
so.depends('action', 'route-options');
so.modalonly = true;
so = ss.taboption('field_other', form.ListValue, 'reject_method', _('Method'));
so.value('default', _('Reply with REFUSED'));
so.value('drop', _('Drop requests'));
so.default = 'default';
so.depends('action', 'reject');
so.modalonly = true;
so = ss.taboption('field_other', form.Flag, 'reject_no_drop', _('Don\'t drop requests'),
_('<code>%s</code> will be temporarily overwritten to <code>%s</code> after 50 triggers in 30s if not enabled.').format(
_('Method'), _('Drop requests')));
so.depends('reject_method', 'default');
so.modalonly = true;
so = ss.taboption('field_other', form.ListValue, 'predefined_rcode', _('RCode'),
_('The response code.'));
so.value('NOERROR');
so.value('FORMERR');
so.value('SERVFAIL');
so.value('NXDOMAIN');
so.value('NOTIMP');
so.value('REFUSED');
so.default = 'NOERROR';
so.depends('action', 'predefined');
so.modalonly = true;
so = ss.taboption('field_other', form.DynamicList, 'predefined_answer', _('Answer'),
_('List of text DNS record to respond as answers.'));
so.depends('action', 'predefined');
so.modalonly = true;
so = ss.taboption('field_other', form.DynamicList, 'predefined_ns', _('NS'),
_('List of text DNS record to respond as name servers.'));
so.depends('action', 'predefined');
so.modalonly = true;
so = ss.taboption('field_other', form.DynamicList, 'predefined_extra', _('Extra records'),
_('List of text DNS record to respond as extra records.'));
so.depends('action', 'predefined');
so.modalonly = true;
so = ss.taboption('field_host', form.DynamicList, 'domain', _('Domain name'),
_('Match full domain.'));

View File

@ -25,6 +25,27 @@ function parseShareLink(uri, features) {
uri = uri.split('://');
if (uri[0] && uri[1]) {
switch (uri[0]) {
case 'anytls':
/* https://github.com/anytls/anytls-go/blob/v0.0.8/docs/uri_scheme.md */
url = new URL('http://' + uri[1]);
params = url.searchParams;
/* Check if password exists */
if (!url.username)
return null;
config = {
label: url.hash ? decodeURIComponent(url.hash.slice(1)) : null,
type: 'anytls',
address: url.hostname,
port: url.port || '80',
password: url.username ? decodeURIComponent(url.username) : null,
tls: '1',
tls_sni: params.get('sni'),
tls_insecure: (params.get('insecure') === '1') ? '1' : '0'
};
break;
case 'http':
case 'https':
url = new URL('http://' + uri[1]);
@ -404,6 +425,7 @@ function renderNodeSettings(section, data, features, main_node, routing_mode) {
o = s.option(form.ListValue, 'type', _('Type'));
o.value('direct', _('Direct'));
o.value('anytls', _('AnyTLS'));
o.value('http', _('HTTP'));
if (features.with_quic) {
o.value('hysteria', _('Hysteria'));
@ -440,6 +462,7 @@ function renderNodeSettings(section, data, features, main_node, routing_mode) {
o = s.option(form.Value, 'password', _('Password'));
o.password = true;
o.depends('type', 'anytls');
o.depends('type', 'http');
o.depends('type', 'hysteria2');
o.depends('type', 'shadowsocks');
@ -452,7 +475,7 @@ function renderNodeSettings(section, data, features, main_node, routing_mode) {
o.validate = function(section_id, value) {
if (section_id) {
let type = this.section.formvalue(section_id, 'type');
let required_type = [ 'shadowsocks', 'shadowtls', 'trojan' ];
let required_type = [ 'anytls', 'shadowsocks', 'shadowtls', 'trojan' ];
if (required_type.includes(type)) {
if (type === 'shadowsocks') {
@ -478,6 +501,29 @@ function renderNodeSettings(section, data, features, main_node, routing_mode) {
o.depends('type', 'direct');
o.modalonly = true;
/* AnyTLS config start */
o = s.option(form.Value, 'anytls_idle_session_check_interval', _('Idle session check interval'),
_('Interval checking for idle sessions, in seconds.'));
o.datatype = 'uinteger';
o.placeholder = '30';
o.depends('type', 'anytls');
o.modalonly = true;
o = s.option(form.Value, 'anytls_idle_session_timeout', _('Idle session check timeout'),
_('In the check, close sessions that have been idle for longer than this, in seconds.'));
o.datatype = 'uinteger';
o.placeholder = '30';
o.depends('type', 'anytls');
o.modalonly = true;
o = s.option(form.Value, 'anytls_min_idle_session', _('Minimum idle sessions'),
_('In the check, at least the first <code>n</code> idle sessions are kept open.'));
o.datatype = 'uinteger';
o.placeholder = '0';
o.depends('type', 'anytls');
o.modalonly = true;
/* AnyTLS config end */
/* Hysteria (2) config start */
o = s.option(form.DynamicList, 'hysteria_hopping_port', _('Hopping port'));
o.depends('type', 'hysteria');
@ -555,7 +601,6 @@ function renderNodeSettings(section, data, features, main_node, routing_mode) {
o = s.option(form.Flag, 'hysteria_disable_mtu_discovery', _('Disable Path MTU discovery'),
_('Disables Path MTU Discovery (RFC 8899). Packets will then be at most 1252 (IPv4) / 1232 (IPv6) bytes in size.'));
o.default = o.disabled;
o.depends('type', 'hysteria');
o.modalonly = true;
/* Hysteria (2) config end */
@ -666,14 +711,12 @@ function renderNodeSettings(section, data, features, main_node, routing_mode) {
o = s.option(form.Flag, 'tuic_udp_over_stream', _('UDP over stream'),
_('This is the TUIC port of the UDP over TCP protocol, designed to provide a QUIC stream based UDP relay mode that TUIC does not provide.'));
o.default = o.disabled;
o.depends({'type': 'tuic','tuic_udp_relay_mode': ''});
o.modalonly = true;
o = s.option(form.Flag, 'tuic_enable_zero_rtt', _('Enable 0-RTT handshake'),
_('Enable 0-RTT QUIC connection handshake on the client side. This is not impacting much on the performance, as the protocol is fully multiplexed.<br/>' +
'Disabling this is highly recommended, as it is vulnerable to replay attacks.'));
o.default = o.disabled;
o.depends('type', 'tuic');
o.modalonly = true;
@ -718,7 +761,6 @@ function renderNodeSettings(section, data, features, main_node, routing_mode) {
o = s.option(form.Flag, 'vmess_authenticated_length', _('Authenticated length'),
_('Protocol parameter. Enable length block encryption.'));
o.default = o.disabled;
o.depends('type', 'vmess');
o.modalonly = true;
/* VMess config end */
@ -771,7 +813,6 @@ function renderNodeSettings(section, data, features, main_node, routing_mode) {
if (features.with_grpc) {
o = s.option(form.Flag, 'grpc_permit_without_stream', _('gRPC permit without stream'),
_('If enabled, the client transport sends keepalive pings even with no active connections.'));
o.default = o.disabled;
o.depends('transport', 'grpc');
o.modalonly = true;
}
@ -897,7 +938,6 @@ function renderNodeSettings(section, data, features, main_node, routing_mode) {
/* Mux config start */
o = s.option(form.Flag, 'multiplex', _('Multiplex'));
o.default = o.disabled;
o.depends('type', 'shadowsocks');
o.depends('type', 'trojan');
o.depends('type', 'vless');
@ -927,19 +967,18 @@ function renderNodeSettings(section, data, features, main_node, routing_mode) {
o = s.option(form.Value, 'multiplex_max_streams', _('Maximum streams'),
_('Maximum multiplexed streams in a connection before opening a new connection.<br/>' +
'Conflict with <code>Maximum connections</code> and <code>Minimum streams</code>.'));
'Conflict with <code>%s</code> and <code>%s</code>.').format(
_('Maximum connections'), _('Minimum streams')));
o.datatype = 'uinteger';
o.depends({'multiplex': '1', 'multiplex_max_connections': '', 'multiplex_min_streams': ''});
o.modalonly = true;
o = s.option(form.Flag, 'multiplex_padding', _('Enable padding'));
o.default = o.disabled;
o.depends('multiplex', '1');
o.modalonly = true;
o = s.option(form.Flag, 'multiplex_brutal', _('Enable TCP Brutal'),
_('Enable TCP Brutal congestion control algorithm'));
o.default = o.disabled;
o.depends('multiplex', '1');
o.modalonly = true;
@ -958,7 +997,7 @@ function renderNodeSettings(section, data, features, main_node, routing_mode) {
/* TLS config start */
o = s.option(form.Flag, 'tls', _('TLS'));
o.default = o.disabled;
o.depends('type', 'anytls');
o.depends('type', 'http');
o.depends('type', 'hysteria');
o.depends('type', 'hysteria2');
@ -972,7 +1011,7 @@ function renderNodeSettings(section, data, features, main_node, routing_mode) {
let type = this.map.lookupOption('type', section_id)[0].formvalue(section_id);
let tls = this.map.findElement('id', 'cbid.homeproxy.%s.tls'.format(section_id)).firstElementChild;
if (['hysteria', 'hysteria2', 'shadowtls', 'tuic'].includes(type)) {
if (['anytls', 'hysteria', 'hysteria2', 'shadowtls', 'tuic'].includes(type)) {
tls.checked = true;
tls.disabled = true;
} else {
@ -998,7 +1037,6 @@ function renderNodeSettings(section, data, features, main_node, routing_mode) {
_('Allow insecure connection at TLS client.') +
'<br/>' +
_('This is <strong>DANGEROUS</strong>, your traffic is almost like <strong>PLAIN TEXT</strong>! Use at your own risk!'));
o.default = o.disabled;
o.depends('tls', '1');
o.onchange = allowInsecureConfirm;
o.modalonly = true;
@ -1029,7 +1067,6 @@ function renderNodeSettings(section, data, features, main_node, routing_mode) {
o = s.option(form.Flag, 'tls_self_sign', _('Append self-signed certificate'),
_('If you have the root certificate, use this option instead of allowing insecure.'));
o.default = o.disabled;
o.depends('tls_insecure', '0');
o.modalonly = true;
@ -1053,12 +1090,10 @@ function renderNodeSettings(section, data, features, main_node, routing_mode) {
o = s.option(form.Flag, 'tls_ech', _('Enable ECH'),
_('ECH (Encrypted Client Hello) is a TLS extension that allows a client to encrypt the first part of its ClientHello message.'));
o.depends('tls', '1');
o.default = o.disabled;
o.modalonly = true;
o = s.option(form.Flag, 'tls_ech_enable_pqss', _('Enable PQ signature schemes'));
o.depends('tls_ech', '1');
o.default = o.disabled;
o.modalonly = true;
o = s.option(form.Value, 'tls_ech_config_path', _('ECH config path'),
@ -1107,7 +1142,6 @@ function renderNodeSettings(section, data, features, main_node, routing_mode) {
o.modalonly = true;
o = s.option(form.Flag, 'tls_reality', _('REALITY'));
o.default = o.disabled;
o.depends({'tls': '1', 'type': 'vless'});
o.modalonly = true;
@ -1124,21 +1158,17 @@ function renderNodeSettings(section, data, features, main_node, routing_mode) {
/* Extra settings start */
o = s.option(form.Flag, 'tcp_fast_open', _('TCP fast open'));
o.default = o.disabled;
o.modalonly = true;
o = s.option(form.Flag, 'tcp_multi_path', _('MultiPath TCP'));
o.default = o.disabled;
o.modalonly = true;
o = s.option(form.Flag, 'udp_fragment', _('UDP Fragment'),
_('Enable UDP fragmentation.'));
o.default = o.disabled;
o.modalonly = true;
o = s.option(form.Flag, 'udp_over_tcp', _('UDP over TCP'),
_('Enable the SUoT protocol, requires server support. Conflict with multiplex.'));
o.default = o.disabled;
o.depends('type', 'socks');
o.depends({'type': 'shadowsocks', 'multiplex': '0'});
o.modalonly = true;
@ -1303,7 +1333,6 @@ return view.extend({
o = s.taboption('subscription', form.Flag, 'auto_update', _('Auto update'),
_('Auto update subscriptions and geodata.'));
o.default = o.disabled;
o.rmempty = false;
o = s.taboption('subscription', form.ListValue, 'auto_update_time', _('Update time'));
@ -1314,7 +1343,6 @@ return view.extend({
o = s.taboption('subscription', form.Flag, 'update_via_proxy', _('Update via proxy'),
_('Update subscriptions via proxy.'));
o.default = o.disabled;
o.rmempty = false;
o = s.taboption('subscription', form.DynamicList, 'subscription_url', _('Subscription URL-s'),
@ -1354,7 +1382,6 @@ return view.extend({
_('Allow insecure connection by default when add nodes from subscriptions.') +
'<br/>' +
_('This is <strong>DANGEROUS</strong>, your traffic is almost like <strong>PLAIN TEXT</strong>! Use at your own risk!'));
o.default = o.disabled;
o.rmempty = false;
o.onchange = allowInsecureConfirm;

View File

@ -13,6 +13,7 @@
'require view';
'require homeproxy as hp';
'require tools.widgets as widgets';
const callServiceList = rpc.declare({
object: 'service',
@ -125,7 +126,6 @@ return view.extend({
s = m.section(form.NamedSection, 'server', 'homeproxy', _('Global settings'));
o = s.option(form.Flag, 'enabled', _('Enable'));
o.default = o.disabled;
o.rmempty = false;
s = m.section(form.GridSection, 'server', _('Server settings'));
@ -153,6 +153,7 @@ return view.extend({
o.editable = true;
o = s.option(form.ListValue, 'type', _('Type'));
o.value('anytls', _('AnyTLS'));
o.value('http', _('HTTP'));
if (features.with_quic) {
o.value('hysteria', _('Hysteria'));
@ -188,6 +189,7 @@ return view.extend({
o = s.option(form.Value, 'password', _('Password'));
o.password = true;
o.depends('type', 'anytls');
o.depends({'type': /^(http|mixed|naive|socks)$/, 'username': /[\s\S]/});
o.depends('type', 'hysteria2');
o.depends('type', 'shadowsocks');
@ -207,7 +209,7 @@ return view.extend({
o.validate = function(section_id, value) {
if (section_id) {
let type = this.section.formvalue(section_id, 'type');
let required_type = [ 'http', 'mixed', 'naive', 'socks', 'shadowsocks' ];
let required_type = [ 'anytls', 'http', 'mixed', 'naive', 'socks', 'shadowsocks', 'trojan' ];
if (required_type.includes(type)) {
if (type === 'shadowsocks') {
@ -229,6 +231,12 @@ return view.extend({
}
o.modalonly = true;
/* AnyTLS config */
o = s.option(form.DynamicList, 'anytls_padding_scheme', _('Padding scheme'),
_('AnyTLS padding scheme in array.'));
o.depends('type', 'anytls');
o.modalonly = true;
/* Hysteria (2) config start */
o = s.option(form.ListValue, 'hysteria_protocol', _('Protocol'));
o.value('udp');
@ -312,13 +320,11 @@ return view.extend({
o = s.option(form.Flag, 'hysteria_disable_mtu_discovery', _('Disable Path MTU discovery'),
_('Disables Path MTU Discovery (RFC 8899). Packets will then be at most 1252 (IPv4) / 1232 (IPv6) bytes in size.'));
o.default = o.disabled;
o.depends('type', 'hysteria');
o.modalonly = true;
o = s.option(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_down_mbps': '', 'hysteria_up_mbps': ''});
o.modalonly = true;
@ -374,7 +380,6 @@ return view.extend({
o = s.option(form.Flag, 'tuic_enable_zero_rtt', _('Enable 0-RTT handshake'),
_('Enable 0-RTT QUIC connection handshake on the client side. This is not impacting much on the performance, as the protocol is fully multiplexed.<br/>' +
'Disabling this is highly recommended, as it is vulnerable to replay attacks.'));
o.default = o.disabled;
o.depends('type', 'tuic');
o.modalonly = true;
@ -503,7 +508,6 @@ return view.extend({
/* Mux config start */
o = s.option(form.Flag, 'multiplex', _('Multiplex'));
o.default = o.disabled;
o.depends('type', 'shadowsocks');
o.depends('type', 'trojan');
o.depends('type', 'vless');
@ -511,14 +515,12 @@ return view.extend({
o.modalonly = true;
o = s.option(form.Flag, 'multiplex_padding', _('Enable padding'));
o.default = o.disabled;
o.depends('multiplex', '1');
o.modalonly = true;
if (features.hp_has_tcp_brutal) {
o = s.option(form.Flag, 'multiplex_brutal', _('Enable TCP Brutal'),
_('Enable TCP Brutal congestion control algorithm'));
o.default = o.disabled;
o.depends('multiplex', '1');
o.modalonly = true;
@ -538,7 +540,7 @@ return view.extend({
/* TLS config start */
o = s.option(form.Flag, 'tls', _('TLS'));
o.default = o.disabled;
o.depends('type', 'anytls');
o.depends('type', 'http');
o.depends('type', 'hysteria');
o.depends('type', 'hysteria2');
@ -602,7 +604,6 @@ return view.extend({
if (features.with_acme) {
o = s.option(form.Flag, 'tls_acme', _('Enable ACME'),
_('Use ACME TLS certificate issuer.'));
o.default = o.disabled;
o.depends('tls', '1');
o.modalonly = true;
@ -642,7 +643,6 @@ return view.extend({
o.modalonly = true;
o = s.option(form.Flag, 'tls_dns01_challenge', _('DNS01 challenge'))
o.default = o.disabled;
o.depends('tls_acme', '1');
o.modalonly = true;
@ -675,12 +675,10 @@ return view.extend({
o.modalonly = true;
o = s.option(form.Flag, 'tls_acme_dhc', _('Disable HTTP challenge'));
o.default = o.disabled;
o.depends('tls_dns01_challenge', '0');
o.modalonly = true;
o = s.option(form.Flag, 'tls_acme_dtac', _('Disable TLS ALPN challenge'));
o.default = o.disabled;
o.depends('tls_dns01_challenge', '0');
o.modalonly = true;
@ -699,7 +697,6 @@ return view.extend({
o = s.option(form.Flag, 'tls_acme_external_account', _('External Account Binding'),
_('EAB (External Account Binding) contains information necessary to bind or map an ACME account to some other account known by the CA.' +
'<br/>External account bindings are "used to associate an ACME account with an existing account in a non-ACME system, such as a CA customer database.'));
o.default = o.disabled;
o.depends('tls_acme', '1');
o.modalonly = true;
@ -716,7 +713,6 @@ return view.extend({
if (features.with_reality_server) {
o = s.option(form.Flag, 'tls_reality', _('REALITY'));
o.default = o.disabled;
o.depends({'tls': '1', 'tls_acme': '0', 'type': 'vless'});
o.depends({'tls': '1', 'tls_acme': null, 'type': 'vless'});
o.modalonly = true;
@ -838,18 +834,15 @@ return view.extend({
/* Extra settings start */
o = s.option(form.Flag, 'tcp_fast_open', _('TCP fast open'),
_('Enable tcp fast open for listener.'));
o.default = o.disabled;
o.depends({'network': 'udp', '!reverse': true});
o.modalonly = true;
o = s.option(form.Flag, 'tcp_multi_path', _('MultiPath TCP'));
o.default = o.disabled;
o.depends({'network': 'udp', '!reverse': true});
o.modalonly = true;
o = s.option(form.Flag, 'udp_fragment', _('UDP Fragment'),
_('Enable UDP fragmentation.'));
o.default = o.disabled;
o.depends({'network': 'tcp', '!reverse': true});
o.modalonly = true;
@ -867,6 +860,16 @@ return view.extend({
o.depends('type', 'naive');
o.depends('type', 'shadowsocks');
o.modalonly = true;
o = s.option(widgets.DeviceSelect, 'bind_interface', _('Bind interface'),
_('The network interface to bind to.'));
o.multiple = false;
o.noaliases = true;
o.modalonly = true;
o = s.option(form.Flag, 'reuse_addr', _('Reuse address'),
_('Reuse listener address.'));
o.modalonly = true;
/* Extra settings end */
return m.render();

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -41,7 +41,8 @@
8.144.0.0/14
8.148.0.0/19
8.148.36.0/22
8.148.40.0/22
8.148.40.0/23
8.148.43.0/24
8.148.64.0/18
8.148.128.0/17
8.149.0.0/16
@ -88,7 +89,6 @@
27.192.0.0/11
27.224.0.0/14
31.56.124.0/24
31.57.10.0/24
36.1.0.0/16
36.4.0.0/14
36.16.0.0/12
@ -205,7 +205,8 @@
42.248.0.0/15
43.102.128.0/21
43.102.136.0/22
43.102.144.0/20
43.102.144.0/21
43.102.152.0/22
43.136.0.0/13
43.144.0.0/15
43.192.0.0/16
@ -227,7 +228,6 @@
43.225.120.0/22
43.225.180.0/22
43.225.208.0/22
43.225.216.0/22
43.225.255.0/24
43.226.32.0/19
43.226.64.0/20
@ -255,7 +255,6 @@
43.229.48.0/22
43.229.184.0/23
43.229.216.0/22
43.230.72.0/22
43.230.136.0/22
43.230.220.0/22
43.231.41.0/24
@ -296,7 +295,6 @@
43.242.164.0/22
43.242.180.0/22
43.242.192.0/21
43.242.204.0/22
43.242.252.0/22
43.243.4.0/22
43.243.12.0/22
@ -374,7 +372,6 @@
43.255.84.0/22
43.255.96.0/22
43.255.184.0/22
43.255.192.0/22
43.255.200.0/22
43.255.212.0/22
43.255.224.0/21
@ -388,7 +385,9 @@
44.32.188.0/24
45.9.11.0/24
45.40.192.0/18
45.59.106.0/24
45.65.20.0/22
45.112.232.0/22
45.113.20.0/22
45.113.24.0/22
45.113.40.0/22
@ -405,6 +404,8 @@
45.116.152.0/22
45.116.208.0/22
45.117.8.0/22
45.117.68.0/24
45.117.70.0/23
45.119.60.0/22
45.119.68.0/22
45.119.105.0/24
@ -413,8 +414,6 @@
45.120.164.0/22
45.120.241.0/24
45.120.243.0/24
45.121.52.0/24
45.121.55.0/24
45.123.128.0/22
45.123.168.0/21
45.123.176.0/21
@ -521,6 +520,7 @@
49.112.0.0/13
49.120.0.0/14
49.128.203.0/24
49.128.220.0/24
49.128.223.0/24
49.140.0.0/15
49.208.0.0/14
@ -561,7 +561,8 @@
54.222.70.0/23
54.222.72.0/21
54.222.80.0/21
54.222.88.0/22
54.222.88.0/24
54.222.90.0/23
54.222.96.0/23
54.222.100.0/22
54.222.104.0/21
@ -605,8 +606,7 @@
59.81.102.0/23
59.81.104.0/22
59.82.0.0/17
59.82.128.0/21
59.82.136.0/23
59.82.128.0/20
59.83.192.0/19
59.83.224.0/21
59.83.232.0/22
@ -679,7 +679,31 @@
60.200.0.0/24
60.204.0.0/14
60.208.0.0/12
60.232.0.0/16
60.232.0.0/24
60.232.130.0/23
60.232.132.0/24
60.232.136.0/24
60.232.140.0/24
60.232.144.0/24
60.232.148.0/24
60.232.152.0/24
60.232.156.0/23
60.232.160.0/24
60.232.164.0/24
60.232.172.0/24
60.232.176.0/23
60.232.178.0/24
60.232.180.0/24
60.232.184.0/24
60.232.188.0/24
60.232.192.0/24
60.232.200.0/24
60.232.224.0/24
60.232.244.0/24
60.232.246.0/23
60.232.251.0/24
60.232.252.0/24
60.232.254.0/24
60.235.0.0/16
60.245.128.0/17
60.247.0.0/16
@ -830,7 +854,9 @@
101.204.0.0/14
101.224.0.0/13
101.234.76.0/22
101.236.0.0/16
101.236.0.0/18
101.236.64.0/20
101.236.128.0/17
101.237.0.0/19
101.237.33.0/24
101.237.34.0/23
@ -840,9 +866,13 @@
101.240.0.0/14
101.245.0.0/22
101.245.8.0/23
101.245.16.0/22
101.245.12.0/22
101.245.16.0/21
101.245.32.0/19
101.245.64.0/18
101.245.128.0/22
101.245.136.0/22
101.245.144.0/22
101.246.172.0/22
101.246.176.0/20
101.247.0.0/18
@ -870,7 +900,7 @@
103.4.56.0/22
103.5.192.0/22
103.6.220.0/22
103.7.140.0/22
103.7.140.0/23
103.8.8.0/22
103.8.32.0/22
103.8.52.0/22
@ -889,7 +919,6 @@
103.14.132.0/22
103.14.136.0/22
103.15.4.0/22
103.15.96.0/22
103.16.124.0/22
103.17.40.0/22
103.17.228.0/22
@ -921,7 +950,6 @@
103.26.0.0/22
103.26.64.0/22
103.26.76.0/22
103.27.4.0/22
103.27.24.0/22
103.27.240.0/22
103.28.8.0/24
@ -939,11 +967,11 @@
103.35.254.0/24
103.36.28.0/22
103.36.36.0/22
103.36.60.0/22
103.36.63.0/24
103.36.96.0/22
103.36.132.0/22
103.36.136.0/22
103.36.164.0/22
103.36.165.0/24
103.36.168.0/24
103.36.172.0/22
103.36.192.0/20
@ -951,7 +979,7 @@
103.36.220.0/22
103.37.7.0/24
103.37.12.0/22
103.37.16.0/22
103.37.18.0/23
103.37.44.0/23
103.37.46.0/24
103.37.72.0/22
@ -961,8 +989,6 @@
103.37.160.0/21
103.37.172.0/22
103.38.40.0/22
103.38.76.0/22
103.38.84.0/22
103.38.92.0/23
103.38.116.0/22
103.38.224.0/22
@ -982,7 +1008,6 @@
103.41.116.0/22
103.41.164.0/22
103.41.232.0/23
103.42.8.0/22
103.42.76.0/22
103.42.104.0/22
103.43.134.0/23
@ -993,7 +1018,6 @@
103.44.144.0/22
103.44.168.0/23
103.44.171.0/24
103.44.176.0/22
103.44.236.0/22
103.44.240.0/20
103.45.72.0/21
@ -1010,14 +1034,12 @@
103.46.168.0/22
103.47.48.0/22
103.47.80.0/22
103.48.232.0/22
103.49.12.0/22
103.49.108.0/22
103.49.196.0/24
103.49.198.0/23
103.50.36.0/22
103.50.253.0/24
103.51.62.0/23
103.52.100.0/22
103.52.104.0/23
103.52.172.0/22
103.52.176.0/22
@ -1033,8 +1055,8 @@
103.56.100.0/22
103.56.104.0/22
103.56.152.0/22
103.56.184.0/22
103.57.12.0/22
103.57.136.0/23
103.57.139.0/24
103.59.112.0/22
103.59.124.0/22
@ -1079,7 +1101,7 @@
103.73.204.0/22
103.74.24.0/21
103.74.48.0/22
103.75.104.0/22
103.75.107.0/24
103.75.152.0/22
103.76.60.0/22
103.76.220.0/22
@ -1151,7 +1173,6 @@
103.98.127.0/24
103.98.220.0/22
103.98.248.0/21
103.99.104.0/22
103.100.64.0/22
103.101.124.0/23
103.101.180.0/22
@ -1174,7 +1195,6 @@
103.106.36.0/22
103.106.252.0/22
103.107.0.0/22
103.107.188.0/22
103.107.216.0/21
103.108.244.0/24
103.108.247.0/24
@ -1186,7 +1206,6 @@
103.113.4.0/22
103.114.100.0/22
103.114.158.0/23
103.114.212.0/23
103.114.236.0/22
103.115.92.0/22
103.115.120.0/22
@ -1225,13 +1244,11 @@
103.131.168.0/22
103.131.179.0/24
103.132.22.0/23
103.132.80.0/23
103.132.212.0/23
103.133.128.0/23
103.134.136.0/22
103.135.160.0/22
103.135.192.0/21
103.135.236.0/24
103.137.60.0/24
103.138.156.0/23
103.139.136.0/23
@ -1364,7 +1381,7 @@
103.212.12.0/22
103.212.48.0/23
103.212.109.0/24
103.213.48.0/23
103.213.49.0/24
103.213.50.0/24
103.213.62.0/23
103.213.64.0/19
@ -1430,12 +1447,10 @@
103.233.4.0/22
103.233.52.0/22
103.233.128.0/22
103.233.138.0/24
103.233.162.0/23
103.234.20.0/22
103.234.56.0/22
103.234.128.0/22
103.235.85.0/24
103.235.102.0/23
103.235.136.0/22
103.235.144.0/24
@ -1443,6 +1458,10 @@
103.235.224.0/20
103.235.244.0/22
103.235.248.0/21
103.236.52.0/22
103.236.56.0/21
103.236.64.0/19
103.236.96.0/22
103.236.120.0/22
103.236.244.0/22
103.236.248.0/21
@ -1459,6 +1478,7 @@
103.238.52.0/22
103.238.96.0/23
103.238.98.0/24
103.238.130.0/24
103.238.132.0/22
103.238.144.0/22
103.238.160.0/22
@ -1468,7 +1488,7 @@
103.238.204.0/22
103.239.68.0/22
103.239.152.0/22
103.239.184.0/24
103.239.184.0/23
103.239.187.0/24
103.239.192.0/22
103.239.204.0/22
@ -1480,7 +1500,6 @@
103.240.124.0/22
103.240.244.0/22
103.241.95.0/24
103.241.208.0/23
103.242.128.0/24
103.242.130.0/24
103.242.168.0/23
@ -1518,7 +1537,7 @@
103.251.204.0/24
103.251.207.0/24
103.251.240.0/22
103.252.36.0/22
103.252.36.0/24
103.252.172.0/22
103.252.248.0/22
103.253.60.0/22
@ -1564,7 +1583,11 @@
106.3.80.0/22
106.3.88.0/21
106.3.96.0/22
106.3.128.0/19
106.3.128.0/20
106.3.144.0/22
106.3.148.0/23
106.3.151.0/24
106.3.152.0/21
106.3.192.0/20
106.3.208.0/21
106.3.224.0/21
@ -1583,7 +1606,6 @@
106.14.0.0/15
106.16.0.0/14
106.32.0.0/12
106.48.0.0/21
106.48.16.0/21
106.52.0.0/14
106.56.0.0/14
@ -1745,6 +1767,7 @@
112.132.0.0/16
112.192.0.0/14
112.196.208.0/24
112.196.220.0/24
112.224.0.0/11
113.0.0.0/13
113.8.0.0/15
@ -1858,7 +1881,17 @@
114.112.4.0/23
114.112.24.0/21
114.112.32.0/19
114.112.64.0/19
114.112.64.0/24
114.112.66.0/24
114.112.70.0/24
114.112.72.0/21
114.112.81.0/24
114.112.82.0/24
114.112.85.0/24
114.112.86.0/24
114.112.88.0/24
114.112.91.0/24
114.112.94.0/23
114.112.96.0/21
114.112.104.0/22
114.112.136.0/21
@ -1908,7 +1941,7 @@
115.120.144.0/23
115.120.148.0/22
115.120.152.0/21
115.120.184.0/21
115.120.176.0/20
115.120.192.0/18
115.124.16.0/20
115.148.0.0/14
@ -1920,6 +1953,8 @@
115.174.64.0/19
115.175.0.0/18
115.175.64.0/19
115.175.104.0/22
115.175.108.0/23
115.175.120.0/21
115.175.128.0/18
115.175.192.0/19
@ -1945,7 +1980,8 @@
116.66.48.0/23
116.66.53.0/24
116.66.98.0/24
116.66.120.0/22
116.66.120.0/24
116.66.123.0/24
116.68.136.0/21
116.68.176.0/21
116.70.64.0/18
@ -2035,7 +2071,7 @@
117.32.0.0/13
117.40.0.0/14
117.44.0.0/15
117.48.0.0/18
117.48.32.0/19
117.48.64.0/20
117.48.80.0/21
117.48.88.0/22
@ -2231,7 +2267,7 @@
118.242.24.0/22
118.242.32.0/22
118.242.40.0/24
118.242.236.0/22
118.242.238.0/24
118.244.0.0/21
118.244.128.0/17
118.247.0.0/16
@ -2243,9 +2279,8 @@
119.15.136.0/23
119.15.140.0/23
119.18.208.0/21
119.18.224.0/22
119.18.231.0/24
119.18.232.0/24
119.18.224.0/24
119.18.226.0/24
119.18.234.0/24
119.18.236.0/23
119.23.0.0/16
@ -2368,10 +2403,7 @@
119.253.0.0/20
119.253.32.0/19
119.253.64.0/19
119.253.249.0/24
119.253.252.0/24
119.254.0.0/16
119.255.63.0/24
119.255.128.0/17
120.0.0.0/12
120.24.0.0/14
@ -2440,6 +2472,7 @@
121.39.255.0/24
121.40.0.0/14
121.46.0.0/20
121.46.20.0/22
121.46.128.0/21
121.46.141.0/24
121.46.192.0/21
@ -2449,7 +2482,6 @@
121.46.248.0/22
121.46.252.0/23
121.46.254.0/24
121.47.0.0/16
121.48.0.0/15
121.51.0.0/16
121.52.160.0/19
@ -2580,9 +2612,6 @@
123.8.0.0/13
123.49.192.0/23
123.49.194.0/24
123.49.224.0/24
123.49.229.0/24
123.49.232.0/24
123.49.240.0/24
123.49.242.0/23
123.52.0.0/14
@ -2826,7 +2855,22 @@
140.210.8.0/21
140.210.16.0/20
140.210.32.0/22
140.210.64.0/18
140.210.65.0/24
140.210.67.0/24
140.210.69.0/24
140.210.70.0/24
140.210.72.0/23
140.210.75.0/24
140.210.77.0/24
140.210.78.0/23
140.210.80.0/24
140.210.83.0/24
140.210.84.0/24
140.210.87.0/24
140.210.88.0/22
140.210.92.0/24
140.210.94.0/24
140.210.96.0/19
140.210.128.0/19
140.210.192.0/19
140.210.224.0/20
@ -2838,7 +2882,6 @@
140.249.0.0/16
140.250.0.0/16
140.255.0.0/16
141.11.50.0/23
143.64.0.0/16
144.0.0.0/16
144.7.0.0/17
@ -2891,6 +2934,7 @@
150.242.244.0/22
150.242.248.0/22
150.255.0.0/16
151.241.174.0/24
151.242.65.0/24
152.104.128.0/17
152.136.0.0/16
@ -2903,24 +2947,12 @@
153.118.0.0/15
154.8.48.0/20
154.8.128.0/17
154.19.43.0/24
154.38.104.0/22
154.48.226.0/24
154.48.231.0/24
154.48.235.0/24
154.48.236.0/22
154.48.240.0/24
154.48.247.0/24
154.48.248.0/24
154.48.250.0/23
154.48.237.0/24
154.72.42.0/24
154.72.44.0/24
154.72.47.0/24
154.89.32.0/20
154.89.49.0/24
154.89.50.0/23
154.89.52.0/22
154.89.56.0/21
154.91.158.0/23
154.208.140.0/22
154.208.144.0/20
@ -2940,28 +2972,36 @@
155.102.26.0/23
155.102.28.0/22
155.102.32.0/19
155.102.72.0/24
155.102.111.0/24
155.102.112.0/21
155.102.120.0/23
155.102.127.0/24
155.102.128.0/22
155.102.132.0/23
155.102.135.0/24
155.102.136.0/21
155.102.144.0/20
155.102.160.0/22
155.102.165.0/24
155.102.164.0/23
155.102.166.0/24
155.102.168.0/23
155.102.176.0/23
155.102.180.0/22
155.102.193.0/24
155.102.194.0/23
155.102.196.0/23
155.102.198.0/24
155.102.201.0/24
155.102.200.0/23
155.102.202.0/24
155.102.204.0/23
155.102.208.0/23
155.102.211.0/24
155.102.216.0/22
155.102.220.0/23
155.102.224.0/20
155.102.240.0/23
155.102.242.0/24
155.102.247.0/24
155.102.248.0/23
155.102.253.0/24
@ -3006,11 +3046,11 @@
160.19.208.0/22
160.20.18.0/23
160.22.188.0/24
160.22.244.0/23
160.25.194.0/23
160.30.230.0/23
160.83.110.0/24
160.191.0.0/24
160.202.152.0/22
160.202.212.0/22
160.202.224.0/19
160.250.14.0/23
@ -3039,7 +3079,8 @@
163.181.0.0/23
163.181.2.0/24
163.181.15.0/24
163.181.16.0/22
163.181.17.0/24
163.181.18.0/23
163.181.22.0/23
163.181.25.0/24
163.181.26.0/24
@ -3098,8 +3139,7 @@
163.181.200.0/21
163.181.209.0/24
163.181.210.0/23
163.181.212.0/23
163.181.214.0/24
163.181.212.0/22
163.181.216.0/21
163.181.224.0/23
163.181.228.0/22
@ -3143,9 +3183,6 @@
175.16.0.0/13
175.24.0.0/15
175.27.0.0/16
175.29.107.0/24
175.29.108.0/24
175.29.110.0/23
175.30.0.0/15
175.42.0.0/15
175.44.0.0/16
@ -3183,8 +3220,6 @@
180.89.64.0/19
180.91.192.0/20
180.92.176.0/23
180.94.192.0/20
180.94.208.0/21
180.95.128.0/17
180.96.0.0/11
180.129.128.0/17
@ -3220,7 +3255,8 @@
180.188.32.0/20
180.200.252.0/22
180.201.0.0/16
180.203.0.0/22
180.203.0.0/23
180.203.3.0/24
180.208.0.0/15
180.210.212.0/22
180.212.0.0/15
@ -3258,7 +3294,6 @@
182.174.0.0/15
182.200.0.0/13
182.236.160.0/19
182.238.0.0/16
182.240.0.0/13
182.254.0.0/16
183.0.0.0/10
@ -3283,12 +3318,11 @@
183.192.0.0/10
185.75.173.0/24
185.75.174.0/24
185.78.105.0/24
185.234.212.0/24
188.131.128.0/17
192.55.46.0/24
192.55.68.0/22
192.102.204.0/22
192.102.204.0/23
192.140.160.0/19
192.140.208.0/21
192.144.128.0/17
@ -3312,6 +3346,7 @@
194.127.229.0/24
194.138.202.0/23
194.138.245.0/24
195.114.203.0/24
198.175.100.0/22
198.208.17.0/24
198.208.19.0/24
@ -3404,7 +3439,8 @@
202.111.230.0/24
202.111.240.0/23
202.111.242.0/24
202.111.244.0/24
202.111.244.0/23
202.111.246.0/24
202.112.0.0/13
202.120.0.0/15
202.122.32.0/21
@ -3427,7 +3463,6 @@
202.130.0.0/19
202.130.224.0/20
202.130.240.0/21
202.136.48.0/20
202.136.208.0/21
202.136.216.0/23
202.136.218.0/24
@ -3441,7 +3476,7 @@
202.143.100.0/22
202.144.198.0/23
202.148.96.0/19
202.149.224.0/19
202.149.224.0/20
202.150.16.0/20
202.153.48.0/20
202.158.160.0/19
@ -3461,7 +3496,6 @@
202.189.8.0/21
202.189.16.0/21
202.192.0.0/12
202.222.32.0/19
203.0.104.0/21
203.2.64.0/21
203.2.112.0/21
@ -3624,7 +3658,6 @@
203.86.60.0/23
203.86.62.0/24
203.86.64.0/19
203.86.112.0/24
203.86.116.0/24
203.86.254.0/23
203.88.32.0/19
@ -3745,7 +3778,7 @@
203.194.124.0/24
203.195.64.0/19
203.195.113.0/24
203.195.114.0/23
203.195.114.0/24
203.195.118.0/23
203.195.128.0/17
203.196.0.0/21
@ -3776,7 +3809,6 @@
206.54.9.0/24
206.54.10.0/23
206.54.12.0/22
206.237.112.0/20
207.226.153.0/24
207.226.154.0/24
210.2.0.0/23
@ -3822,7 +3854,10 @@
210.72.128.0/18
210.72.192.0/19
210.72.224.0/20
210.72.240.0/21
210.72.240.0/23
210.72.243.0/24
210.72.245.0/24
210.72.246.0/24
210.73.0.0/16
210.74.0.0/20
210.74.35.0/24
@ -3845,7 +3880,12 @@
210.77.0.0/18
210.77.64.0/19
210.77.128.0/19
210.77.176.0/20
210.77.176.0/22
210.77.180.0/23
210.77.182.0/24
210.77.184.0/23
210.77.189.0/24
210.77.190.0/23
210.77.192.0/18
210.78.128.0/24
210.78.134.0/23
@ -3903,13 +3943,11 @@
211.98.0.0/16
211.99.8.0/21
211.99.16.0/23
211.99.24.0/21
211.99.24.0/23
211.99.26.0/24
211.99.28.0/22
211.99.32.0/19
211.99.64.0/19
211.99.96.0/20
211.99.112.0/22
211.99.116.0/24
211.99.122.0/24
211.99.64.0/18
211.99.128.0/18
211.99.192.0/19
211.100.0.0/17
@ -4006,22 +4044,23 @@
211.159.128.0/17
211.160.0.0/22
211.160.4.0/23
211.160.8.0/22
211.160.14.0/23
211.160.9.0/24
211.160.10.0/23
211.160.16.0/21
211.160.24.0/22
211.160.24.0/24
211.160.26.0/23
211.160.28.0/23
211.160.36.0/23
211.160.46.0/23
211.160.46.0/24
211.160.62.0/23
211.160.72.0/21
211.160.80.0/20
211.160.112.0/22
211.160.120.0/23
211.160.160.0/19
211.160.194.0/23
211.160.195.0/24
211.160.196.0/24
211.160.202.0/23
211.160.203.0/24
211.160.204.0/23
211.160.240.0/20
211.161.0.0/20
@ -4121,7 +4160,6 @@
219.83.160.0/19
219.100.148.0/22
219.117.16.0/20
219.121.224.0/19
219.128.0.0/12
219.144.0.0/14
219.148.0.0/15
@ -4167,7 +4205,7 @@
219.236.0.0/14
219.242.0.0/15
219.244.0.0/14
220.101.192.0/18
220.101.192.0/19
220.112.0.0/22
220.112.8.0/24
220.112.40.0/21
@ -4232,11 +4270,16 @@
220.207.176.0/22
220.207.184.0/22
220.207.254.0/23
220.231.0.0/18
220.231.32.0/20
220.231.128.0/17
220.232.64.0/18
220.234.0.0/16
220.243.128.0/18
220.242.180.0/24
220.243.128.0/20
220.243.153.0/24
220.243.154.0/23
220.243.156.0/23
220.243.176.0/20
220.248.0.0/16
220.249.0.0/17
220.249.128.0/18

View File

@ -1 +1 @@
20250808035959
20250822033443

View File

@ -2,6 +2,7 @@
2001:254::/31
2001:256:100::/48
2001:678:120::/48
2001:678:10d0::/48
2001:67c:ebc::/48
2001:7fa:5::/48
2001:c68::/32
@ -95,6 +96,7 @@
2400:9620::/32
2400:a860:1::/48
2400:a860:2::/47
2400:a860:4::/47
2400:a980::/29
2400:ae00:1981::/48
2400:b200::/32
@ -117,7 +119,6 @@
2401:800::/32
2401:1160::/32
2401:11a0:10::/44
2401:11a0:1500::/40
2401:11a0:d150::/48
2401:11a0:d152::/48
2401:11a0:d158::/48
@ -159,7 +160,7 @@
2401:cb80::/32
2401:cc00::/32
2401:ce00::/32
2401:d0e0:2::/48
2401:d0e0:2::/47
2401:d180::/46
2401:d180:10::/47
2401:d180:111::/48
@ -169,8 +170,7 @@
2401:ec00::/32
2401:f860:86::/47
2401:f860:88::/47
2401:f860:90::/47
2401:f860:93::/48
2401:f860:90::/46
2401:f860:94::/48
2401:f860:100::/40
2401:f860:f100::/40
@ -178,6 +178,7 @@
2402:840:d000::/46
2402:840:e000::/46
2402:840:f000::/38
2402:c60::/48
2402:1440::/32
2402:2000::/32
2402:3180::/46
@ -223,7 +224,9 @@
2402:f000::/32
2402:f140:ff10::/46
2402:f140:ff14::/48
2402:f8c0::/32
2402:f8c0::/47
2402:f8c0:2::/48
2402:f8c0:5::/48
2403:600::/32
2403:c80::/32
2403:1b80::/48
@ -257,7 +260,6 @@
2403:b400::/32
2403:c980::/32
2403:d400::/32
2403:e7c0:1::/48
2403:f4c0::/48
2403:ffc0:1100::/40
2403:ffc0:1200::/39
@ -287,7 +289,7 @@
2404:2280:12e::/48
2404:2280:130::/48
2404:2280:134::/48
2404:2280:136::/47
2404:2280:137::/48
2404:2280:138::/48
2404:2280:13b::/48
2404:2280:13c::/47
@ -346,13 +348,19 @@
2404:2280:20e::/48
2404:2280:210::/46
2404:2280:214::/48
2404:2280:217::/48
2404:2280:216::/47
2404:2280:218::/48
2404:2280:21a::/48
2404:2280:21d::/48
2404:2280:221::/48
2404:2280:265::/48
2404:2280:266::/47
2404:2280:268::/46
2404:2280:26c::/48
2404:2280:271::/48
2404:2280:272::/48
2404:2280:27a::/48
2404:2280:27c::/48
2404:2280:27c::/47
2404:3700::/48
2404:4dc0::/32
2404:6380::/48
@ -361,7 +369,6 @@
2404:6500:dcb3::/48
2404:7180:a000::/48
2404:7180:a010::/48
2404:7180:a021::/48
2404:7180:aa00::/48
2404:7180:aa10::/48
2404:7180:b001::/48
@ -390,7 +397,6 @@
2404:c2c0:c000::/36
2404:c300::/32
2404:c940::/48
2404:d7c0:2::/48
2404:e280::/47
2404:e5c0::/32
2404:e8c0::/32
@ -520,7 +526,6 @@
2407:6c40:1210::/48
2407:6c40:1500::/48
2407:6c40:1600::/40
2407:6c40:1810::/48
2407:8f40:2::/48
2407:9f00::/32
2407:ad80::/32
@ -590,7 +595,6 @@
2408:8181:a000::/40
2408:8181:a220::/44
2408:8181:e000::/40
2408:8182:6000::/40
2408:8182:c000::/40
2408:8183:4000::/40
2408:8183:8000::/40
@ -1106,7 +1110,6 @@
2409:27fb::/48
2409:27fc::/48
2409:27fe::/33
2409:6100::/44
2409:8000::/20
240a:2000::/40
240a:2001:100::/40
@ -1184,6 +1187,7 @@
240e::/20
2602:2e0:ff::/48
2602:f7ee:ee::/48
2602:f92a:e100::/44
2602:f93b:400::/38
2602:f9ba:a8::/48
2602:f9ba:10c::/48
@ -1235,8 +1239,8 @@
2a04:f580:9280::/48
2a04:f580:9290::/48
2a06:1180:1000::/48
2a06:3605::/32
2a06:3606::/31
2a06:3603::/32
2a06:3604::/30
2a06:9f81:4600::/43
2a06:9f81:4640::/44
2a06:a005:260::/43
@ -1251,10 +1255,9 @@
2a09:b280:ff81::/48
2a09:b280:ff83::/48
2a09:b280:ff84::/47
2a0a:2840:20::/43
2a0a:2840:2000::/48
2a0a:2842::/32
2a0a:2840::/30
2a0a:2845:aab8::/46
2a0a:2845:d647::/48
2a0a:2846::/48
2a0a:6040:ec00::/40
2a0a:6044:6600::/40
@ -1262,6 +1265,7 @@
2a0b:2542::/48
2a0b:4340:a6::/48
2a0b:4e07:b8::/47
2a0c:9a40:84e0::/48
2a0c:9a40:9e00::/43
2a0c:b641:571::/48
2a0e:97c0:83f::/48
@ -1319,6 +1323,7 @@
2a0f:7803:fe82::/48
2a0f:7d07::/32
2a0f:85c1:ba5::/48
2a0f:85c1:ca0::/44
2a0f:9400:6110::/48
2a0f:9400:7700::/48
2a0f:ac00::/29
@ -1327,30 +1332,34 @@
2a10:ccc0:d00::/46
2a10:ccc0:d0a::/47
2a10:ccc0:d0c::/47
2a10:ccc6:66c4::/48
2a10:ccc6:66c6::/48
2a10:ccc6:66c9::/48
2a10:ccc6:66ca::/48
2a10:ccc6:66cd::/48
2a10:ccc6:66cc::/47
2a12:f8c3::/36
2a13:1800::/48
2a13:1800:10::/48
2a13:1800:80::/44
2a13:1800:300::/44
2a13:1801:180::/43
2a13:a5c3:ff10::/44
2a13:a5c3:ff21::/48
2a13:a5c3:ff50::/44
2a13:a5c7:1800::/40
2a13:a5c7:2100::/48
2a13:a5c7:2102::/48
2a13:a5c7:2121::/48
2a13:a5c7:2801::/48
2a13:a5c7:2803::/48
2a13:a5c7:3100::/43
2a13:a5c7:3108::/48
2a13:a5c7:31a0::/43
2a13:aac4:f000::/44
2a14:7c0:4a01::/48
2a14:4c41::/32
2a14:67c1:20::/44
2a14:67c1:70::/47
2a14:67c1:73::/48
2a14:67c1:74::/48
2a14:67c1:702::/47
2a14:67c1:704::/48
@ -1364,7 +1373,8 @@
2a14:67c1:a061::/48
2a14:67c1:a064::/48
2a14:67c1:a090::/46
2a14:67c1:a094::/47
2a14:67c1:a095::/48
2a14:67c1:a096::/48
2a14:67c1:a099::/48
2a14:67c1:a100::/43
2a14:67c1:b000::/48
@ -1374,17 +1384,24 @@
2a14:67c1:b100::/46
2a14:67c1:b105::/48
2a14:67c1:b107::/48
2a14:67c1:b130::/47
2a14:67c1:b132::/48
2a14:67c1:b130::/48
2a14:67c1:b132::/47
2a14:67c1:b134::/47
2a14:67c1:b4a1::/48
2a14:67c1:b4a2::/48
2a14:67c1:b4c0::/45
2a14:67c1:b4d0::/44
2a14:67c1:b4e0::/43
2a14:67c1:b500::/48
2a14:67c1:b549::/48
2a14:67c1:b561::/48
2a14:67c1:b563::/48
2a14:67c1:b566::/48
2a14:67c1:b581::/48
2a14:67c1:b582::/48
2a14:67c1:b588::/47
2a14:67c1:b590::/48
2a14:67c1:b599::/48
2a14:67c5:1900::/40
2a14:7580:9200::/40
2a14:7580:9400::/39

View File

@ -1 +1 @@
20250808035959
20250822033443

View File

@ -54617,7 +54617,6 @@ itiankong.com
itiankong.net
itianliao.com
itiexue.net
itiger.com
itigergrowth.com
itigergrowtha.com
itigerup.com
@ -61793,7 +61792,6 @@ kovemoto.com
kowa-dental.com
kowa103.com
kowloonhospital.com
kox.moe
koyuki.cc
kpblw.com
kpbyd.com
@ -70630,7 +70628,6 @@ mowan123.com
moweather.com
mowgz.com
mowowo.com
mox.moe
moxfive.xyz
moxiai.com
moxian.com
@ -71461,8 +71458,6 @@ mypharma.com
mypian.com
mypiao.com
mypiaojia.com
mypikpak.com
mypikpak.net
mypitaya.com
mypity.com
mypiwik.com
@ -71729,7 +71724,6 @@ naitta.com
naiveadmin.com
naiveblue.com
naiwch.com
naixi.net
naixuecha.com
naiyouxuexi.com
najingtech.com
@ -97561,7 +97555,6 @@ ustarl.com
ustbtc.com
ustc.edu
ustcers.com
ustclug.org
ustui.com
usuredata.com
usuuu.com
@ -98607,7 +98600,6 @@ voidking.com
voip366.com
vojs.tv
vokop.com
vol.moe
volc-dns.com
volc-dns.net
volc-dns.pub
@ -104816,7 +104808,6 @@ xiaomei.cc
xiaomeiti.com
xiaomeng1235.com
xiaomi.com
xiaomi.eu
xiaomi.hk
xiaomi.net
xiaomi.org
@ -106602,6 +106593,7 @@ xn--4xup5j.com
xn--54q23ckxiyx0e.com
xn--54q249denfzw9a.net
xn--54q40czz0g7xp.com
xn--55qw42g
xn--55qw7biqf7g3d004h8yuw1ctrt04sep1cjfb.com
xn--55qwa79fh6ku8czve.com
xn--55qx2ag79c1iq.com

View File

@ -1 +1 @@
202508072216
202508212214

View File

@ -511,6 +511,7 @@ bestvpnusa.com
bet365.com
betaclouds.net
betfair.com
betterhash.net
betternet.co
bettervpn.com
bettween.com
@ -537,6 +538,7 @@ bild.de
biliworld.com
billypan.com
binance.com
binance.org
binancezh.cc
binux.me
bird.so
@ -548,6 +550,7 @@ bitchute.com
bitcointalk.org
bitcoinworld.com
bitfinex.com
bitget.com
bithumb.com
bitmex.com
bitshare.com
@ -1043,6 +1046,7 @@ clipconverter.cc
clipfish.de
cloud.dify.ai
cloud.mail.ru
cloudflare-dns.com
cloudflare-ipfs.com
cloudfunctions.net
club1069.com
@ -1266,6 +1270,7 @@ delicious.com
demo.unlock-music.dev
democrats.org
demosisto.hk
deno.dev
depositphotos.com
desc.se
desipro.de
@ -1334,6 +1339,7 @@ dnvod.tv
doc.new
docker.com
docker.io
docs.deno.com
docs.new
doctorvoice.org
documentingreality.com
@ -1856,6 +1862,7 @@ fuq.com
furbo.org
furhhdl.org
furinkan.com
furrybar.com
futurechinaforum.org
futuremessage.org
fux.com
@ -2366,6 +2373,7 @@ hentaivideoworld.com
heqinglian.net
heritage.org
herokuapp.com
herominers.com
hexieshe.com
hexieshe.xyz
hexxeh.net
@ -2662,6 +2670,7 @@ indiatoday.in
indiemerch.com
inews-api.tvb.com
info-graf.fr
infura.io
inherit.live
initiativesforchina.org
inkbunny.net
@ -2735,9 +2744,11 @@ isupportuyghurs.org
itaiwan.gov.tw
italiatibet.org
itasoftware.com
itch.io
itemdb.com
itemfix.com
ithelp.ithome.com.tw
itiger.com
itsaol.com
itshidden.com
itsky.it
@ -3086,6 +3097,7 @@ lsmwebcast.com
lsxszzg.com
ltn.com.tw
luckydesigner.space
luckymobile.ca
ludepress.com
luke54.com
luke54.org
@ -3159,6 +3171,7 @@ matters.news
matters.town
matthewdgreen.wordpress.com
mattwilcox.net
maven.neoforged.net
maxing.jp
mayimayi.com
mcadforums.com
@ -3207,6 +3220,7 @@ mesotw.com
messenger.com
meta.com
metafilter.com
metamask.io
metart.com
metarthunter.com
meteorshowersonline.com
@ -3429,6 +3443,7 @@ nationalreview.com
nationsonline.org
nationwide.com
naughtyamerica.com
naver.com
navyfamily.navy.mil
navyreserve.navy.mil
naweeklytimes.com
@ -3753,6 +3768,7 @@ palacemoon.com
paljorpublications.com
paltalk.com
panamapapers.sueddeutsche.de
pancakeswap.finance
pandafan.pub
pandapow.co
pandapow.net
@ -3819,6 +3835,7 @@ periscope.tv
perplexity.ai
persecutionblog.com
persiankitty.com
pewresearch.org
phapluan.org
phayul.com
philborges.com
@ -3948,6 +3965,7 @@ prism-break.org
prisoneralert.com
pritunl.com
privacybox.de
privacyguides.org
private.com
privateinternetaccess.com
privatepaste.com
@ -4601,6 +4619,7 @@ suroot.com
surrenderat20.net
svsfx.com
swagbucks.com
swapspace.co
swissinfo.ch
swissvpn.net
switch1.jp
@ -5130,6 +5149,7 @@ uderzo.it
udn.com
udn.com.tw
udnbkk.com
udomain.hk
uforadio.com.tw
ufreevpn.com
ugo.com
@ -5170,6 +5190,7 @@ unseen.is
unstable.icu
unwire.hk
uocn.org
upbit.com
updates.tdesktop.com
upghsbc.com
upholdjustice.org
@ -5591,7 +5612,6 @@ www.monlamit.org
www.moztw.org
www.msn.com
www.nbc.com
www.nodeloc.com
www.owind.com
www.oxid.it
www.powerpointninja.com

View File

@ -1 +1 @@
202508072216
202508212214

View File

@ -13,9 +13,8 @@ import { connect } from 'ubus';
import { cursor } from 'uci';
import {
isEmpty, strToBool, strToInt,
removeBlankAttrs, validation,
HP_DIR, RUN_DIR
isEmpty, parseURL, strToBool, strToInt, strToTime,
removeBlankAttrs, validation, HP_DIR, RUN_DIR
} from 'homeproxy';
const ubus = connect();
@ -53,10 +52,13 @@ const dns_port = uci.get(uciconfig, uciinfra, 'dns_port') || '5333';
const ntp_server = uci.get(uciconfig, uciinfra, 'ntp_server') || 'time.apple.com';
let main_node, main_udp_node, dedicated_udp_node, default_outbound, domain_strategy, sniff_override,
dns_server, china_dns_server, dns_default_strategy, dns_default_server, dns_disable_cache,
dns_disable_cache_expire, dns_independent_cache, dns_client_subnet, cache_file_store_rdrc,
cache_file_rdrc_timeout, direct_domain_list, proxy_domain_list;
const ipv6_support = uci.get(uciconfig, ucimain, 'ipv6_support') || '0';
let main_node, main_udp_node, dedicated_udp_node, default_outbound, default_outbound_dns,
domain_strategy, sniff_override, dns_server, china_dns_server, dns_default_strategy,
dns_default_server, dns_disable_cache, dns_disable_cache_expire, dns_independent_cache,
dns_client_subnet, cache_file_store_rdrc, cache_file_rdrc_timeout, direct_domain_list,
proxy_domain_list;
if (routing_mode !== 'custom') {
main_node = uci.get(uciconfig, ucimain, 'main_node') || 'nil';
@ -72,6 +74,7 @@ if (routing_mode !== 'custom') {
if (isEmpty(china_dns_server) || type(china_dns_server) !== 'string' || china_dns_server === 'wan')
china_dns_server = wan_dns;
}
dns_default_strategy = (ipv6_support !== '1') ? 'ipv4_only' : null;
direct_domain_list = trim(readfile(HP_DIR + '/resources/direct_list.txt'));
if (direct_domain_list)
@ -95,21 +98,25 @@ if (routing_mode !== 'custom') {
/* Routing settings */
default_outbound = uci.get(uciconfig, uciroutingsetting, 'default_outbound') || 'nil';
default_outbound_dns = uci.get(uciconfig, uciroutingsetting, 'default_outbound_dns') || 'default-dns';
domain_strategy = uci.get(uciconfig, uciroutingsetting, 'domain_strategy');
sniff_override = uci.get(uciconfig, uciroutingsetting, 'sniff_override');
}
const proxy_mode = uci.get(uciconfig, ucimain, 'proxy_mode') || 'redirect_tproxy',
ipv6_support = uci.get(uciconfig, ucimain, 'ipv6_support') || '0',
default_interface = uci.get(uciconfig, ucicontrol, 'bind_interface');
const mixed_port = uci.get(uciconfig, uciinfra, 'mixed_port') || '5330';
let self_mark, redirect_port, tproxy_port,
tun_name, tun_addr4, tun_addr6, tun_mtu,
tcpip_stack, endpoint_independent_nat, udp_timeout;
udp_timeout = uci.get(uciconfig, 'infra', 'udp_timeout');
let self_mark, redirect_port, tproxy_port, tun_name,
tun_addr4, tun_addr6, tun_mtu, tcpip_stack,
endpoint_independent_nat, udp_timeout;
if (routing_mode === 'custom')
udp_timeout = uci.get(uciconfig, uciroutingsetting, 'udp_timeout');
else
udp_timeout = uci.get(uciconfig, 'infra', 'udp_timeout');
if (match(proxy_mode, /redirect/)) {
self_mark = uci.get(uciconfig, 'infra', 'self_mark') || '100';
redirect_port = uci.get(uciconfig, 'infra', 'redirect_port') || '5331';
@ -143,6 +150,22 @@ function parse_port(strport) {
}
function parse_dnserver(server_addr, default_protocol) {
if (isEmpty(server_addr))
return null;
if (!match(server_addr, /:\/\//))
server_addr = (default_protocol || 'udp') + '://' + server_addr;
server_addr = parseURL(server_addr);
return {
type: server_addr.protocol,
server: server_addr.hostname,
server_port: strToInt(server_addr.port),
path: (server_addr.pathname !== '/') ? server_addr.pathname : null,
}
}
function parse_dnsquery(strquery) {
if (type(strquery) !== 'array' || isEmpty(strquery))
return null;
@ -210,8 +233,12 @@ function generate_outbound(node) {
override_address: node.override_address,
override_port: strToInt(node.override_port),
proxy_protocol: strToInt(node.proxy_protocol),
/* AnyTLS */
idle_session_check_interval: strToTime(node.anytls_idle_session_check_interval),
idle_session_timeout: strToTime(node.anytls_idle_session_timeout),
min_idle_session: strToInt(node.anytls_min_idle_session),
/* Hysteria (2) */
hop_interval: node.hysteria_hop_interval ? (node.hysteria_hop_interval + 's') : null,
hop_interval: strToTime(node.hysteria_hop_interval),
up_mbps: strToInt(node.hysteria_up_mbps),
down_mbps: strToInt(node.hysteria_down_mbps),
obfs: node.hysteria_obfs_type ? {
@ -241,13 +268,13 @@ function generate_outbound(node) {
udp_relay_mode: node.tuic_udp_relay_mode,
udp_over_stream: strToBool(node.tuic_udp_over_stream),
zero_rtt_handshake: strToBool(node.tuic_enable_zero_rtt),
heartbeat: node.tuic_heartbeat ? (node.tuic_heartbeat + 's') : null,
heartbeat: strToTime(node.tuic_heartbeat),
/* VLESS / VMess */
flow: node.vless_flow,
alter_id: strToInt(node.vmess_alterid),
security: node.vmess_encrypt,
global_padding: node.vmess_global_padding ? (node.vmess_global_padding === '1') : null,
authenticated_length: node.vmess_authenticated_length ? (node.vmess_authenticated_length === '1') : null,
global_padding: strToBool(node.vmess_global_padding),
authenticated_length: strToBool(node.vmess_authenticated_length),
packet_encoding: node.packet_encoding,
multiplex: (node.multiplex === '1') ? {
@ -256,7 +283,7 @@ function generate_outbound(node) {
max_connections: strToInt(node.multiplex_max_connections),
min_streams: strToInt(node.multiplex_min_streams),
max_streams: strToInt(node.multiplex_max_streams),
padding: (node.multiplex_padding === '1'),
padding: strToBool(node.multiplex_padding),
brutal: (node.multiplex_brutal === '1') ? {
enabled: true,
up_mbps: strToInt(node.multiplex_brutal_up),
@ -266,7 +293,7 @@ function generate_outbound(node) {
tls: (node.tls === '1') ? {
enabled: true,
server_name: node.tls_sni,
insecure: (node.tls_insecure === '1'),
insecure: strToBool(node.tls_insecure),
alpn: node.tls_alpn,
min_version: node.tls_min_version,
max_version: node.tls_max_version,
@ -274,7 +301,7 @@ function generate_outbound(node) {
certificate_path: node.tls_cert_path,
ech: (node.tls_ech === '1') ? {
enabled: true,
pq_signature_schemes_enabled: (node.tls_ech_enable_pqss === '1'),
pq_signature_schemes_enabled: strToBool(node.tls_ech_enable_pqss),
config: node.tls_ech_config,
config_path: node.tls_ech_config_path
} : null,
@ -299,8 +326,8 @@ function generate_outbound(node) {
max_early_data: strToInt(node.websocket_early_data),
early_data_header_name: node.websocket_early_data_header,
service_name: node.grpc_servicename,
idle_timeout: node.http_idle_timeout ? (node.http_idle_timeout + 's') : null,
ping_timeout: node.http_ping_timeout ? (node.http_ping_timeout + 's') : null,
idle_timeout: (node.http_idle_timeout),
ping_timeout: (node.http_ping_timeout),
permit_without_stream: strToBool(node.grpc_permit_without_stream)
} : null,
udp_over_tcp: (node.udp_over_tcp === '1') ? {
@ -349,7 +376,6 @@ function get_resolver(cfg) {
return null;
switch (cfg) {
case 'block-dns':
case 'default-dns':
case 'system-dns':
return cfg;
@ -384,8 +410,7 @@ config.ntp = {
enabled: true,
server: ntp_server,
detour: 'direct-out',
/* TODO: disable this until we have sing-box 1.12 */
/* domain_resolver: 'default-dns', */
domain_resolver: 'default-dns',
};
/* DNS start */
@ -394,32 +419,21 @@ config.dns = {
servers: [
{
tag: 'default-dns',
address: wan_dns,
type: 'udp',
server: wan_dns,
detour: 'direct-out'
},
{
tag: 'system-dns',
address: 'local',
type: 'local',
detour: 'direct-out'
},
{
tag: 'block-dns',
address: 'rcode://refused'
}
],
rules: [
/* TODO: remove this once we have sing-box 1.12 */
/* NTP domain must be resolved by default DNS */
{
domain: ntp_server,
action: 'route',
server: 'default-dns'
}
],
rules: [],
strategy: dns_default_strategy,
disable_cache: (dns_disable_cache === '1'),
disable_expire: (dns_disable_cache_expire === '1'),
independent_cache: (dns_independent_cache === '1'),
disable_cache: strToBool(dns_disable_cache),
disable_expire: strToBool(dns_disable_cache_expire),
independent_cache: strToBool(dns_independent_cache),
client_subnet: dns_client_subnet
};
@ -427,21 +441,15 @@ if (!isEmpty(main_node)) {
/* Main DNS */
push(config.dns.servers, {
tag: 'main-dns',
address: !match(dns_server, /:\/\//) ? 'tcp://' + (validation('ip6addr', dns_server) ? `[${dns_server}]` : dns_server) : dns_server,
strategy: (ipv6_support !== '1') ? 'ipv4_only' : null,
address_resolver: 'default-dns',
address_strategy: (ipv6_support !== '1') ? 'ipv4_only' : null,
detour: 'main-out'
domain_resolver: {
server: 'default-dns',
strategy: (ipv6_support !== '1') ? 'ipv4_only' : null
},
detour: 'main-out',
...parse_dnserver(dns_server, 'tcp')
});
config.dns.final = 'main-dns';
/* Avoid DNS loop */
push(config.dns.rules, {
outbound: 'any',
action: 'route',
server: 'default-dns'
});
if (length(direct_domain_list))
push(config.dns.rules, {
rule_set: 'direct-domain',
@ -460,9 +468,12 @@ if (!isEmpty(main_node)) {
if (routing_mode === 'bypass_mainland_china') {
push(config.dns.servers, {
tag: 'china-dns',
address: china_dns_server,
address_resolver: 'default-dns',
detour: 'direct-out'
domain_resolver: {
server: 'default-dns',
strategy: 'prefer_ipv6'
},
detour: 'direct-out',
...parse_dnserver(china_dns_server)
});
if (length(proxy_domain_list))
@ -475,7 +486,8 @@ if (!isEmpty(main_node)) {
push(config.dns.rules, {
rule_set: 'geosite-cn',
action: 'route',
server: 'china-dns'
server: 'china-dns',
strategy: 'prefer_ipv6'
});
push(config.dns.rules, {
type: 'logical',
@ -490,7 +502,8 @@ if (!isEmpty(main_node)) {
}
],
action: 'route',
server: 'china-dns'
server: 'china-dns',
strategy: 'prefer_ipv6'
});
}
} else if (!isEmpty(default_outbound)) {
@ -501,13 +514,20 @@ if (!isEmpty(main_node)) {
push(config.dns.servers, {
tag: 'cfg-' + cfg['.name'] + '-dns',
address: cfg.address,
address: cfg.address,
address_resolver: get_resolver(cfg.address_resolver),
address_strategy: cfg.address_strategy,
strategy: cfg.resolve_strategy,
detour: get_outbound(cfg.outbound),
client_subnet: cfg.client_subnet
type: cfg.type,
server: cfg.server,
server_port: strToInt(cfg.server_port),
path: cfg.path,
headers: cfg.headers,
tls: cfg.tls_sni ? {
enabled: true,
server_name: cfg.tls_sni
} : null,
domain_resolver: {
server: get_resolver(cfg.address_resolver),
strategy: cfg.address_strategy
},
detour: get_outbound(cfg.outbound)
});
});
@ -528,9 +548,9 @@ if (!isEmpty(main_node)) {
port: parse_port(cfg.port),
port_range: cfg.port_range,
source_ip_cidr: cfg.source_ip_cidr,
source_ip_is_private: (cfg.source_ip_is_private === '1') || null,
source_ip_is_private: strToBool(cfg.source_ip_is_private),
ip_cidr: cfg.ip_cidr,
ip_is_private: (cfg.ip_is_private === '1') || null,
ip_is_private: strToBool(cfg.ip_is_private),
source_port: parse_port(cfg.source_port),
source_port_range: cfg.source_port_range,
process_name: cfg.process_name,
@ -538,15 +558,21 @@ if (!isEmpty(main_node)) {
process_path_regex: cfg.process_path_regex,
user: cfg.user,
rule_set: get_ruleset(cfg.rule_set),
rule_set_ip_cidr_match_source: (cfg.rule_set_ip_cidr_match_source === '1') || null,
invert: (cfg.invert === '1') || null,
rule_set_ip_cidr_match_source: strToBool(cfg.rule_set_ip_cidr_match_source),
invert: strToBool(cfg.invert),
outbound: get_outbound(cfg.outbound),
action: (cfg.server === 'block-dns') ? 'reject' : 'route',
action: cfg.action,
server: get_resolver(cfg.server),
disable_cache: (cfg.dns_disable_cache === '1') || null,
strategy: cfg.domain_strategy,
disable_cache: strToBool(cfg.dns_disable_cache),
rewrite_ttl: strToInt(cfg.rewrite_ttl),
client_subnet: cfg.client_subnet
client_subnet: cfg.client_subnet,
method: cfg.reject_method,
no_drop: strToBool(cfg.reject_no_drop),
rcode: cfg.predefined_rcode,
answer: cfg.predefined_answer,
ns: cfg.predefined_ns,
extra: cfg.predefined_extra
});
});
@ -572,9 +598,9 @@ push(config.inbounds, {
tag: 'mixed-in',
listen: '::',
listen_port: int(mixed_port),
udp_timeout: udp_timeout ? (udp_timeout + 's') : null,
udp_timeout: strToTime(udp_timeout),
sniff: true,
sniff_override_destination: (sniff_override === '1'),
sniff_override_destination: strToBool(sniff_override),
set_system_proxy: false
});
@ -586,7 +612,7 @@ if (match(proxy_mode, /redirect/))
listen: '::',
listen_port: int(redirect_port),
sniff: true,
sniff_override_destination: (sniff_override === '1')
sniff_override_destination: strToBool(sniff_override)
});
if (match(proxy_mode, /tproxy/))
push(config.inbounds, {
@ -596,9 +622,9 @@ if (match(proxy_mode, /tproxy/))
listen: '::',
listen_port: int(tproxy_port),
network: 'udp',
udp_timeout: udp_timeout ? (udp_timeout + 's') : null,
udp_timeout: strToTime(udp_timeout),
sniff: true,
sniff_override_destination: (sniff_override === '1')
sniff_override_destination: strToBool(sniff_override)
});
if (match(proxy_mode, /tun/))
push(config.inbounds, {
@ -610,10 +636,10 @@ if (match(proxy_mode, /tun/))
mtu: strToInt(tun_mtu),
auto_route: false,
endpoint_independent_nat: strToBool(endpoint_independent_nat),
udp_timeout: udp_timeout ? (udp_timeout + 's') : null,
udp_timeout: strToTime(udp_timeout),
stack: tcpip_stack,
sniff: true,
sniff_override_destination: (sniff_override === '1')
sniff_override_destination: strToBool(sniff_override)
});
/* Inbound end */
@ -646,7 +672,7 @@ if (!isEmpty(main_node)) {
type: 'urltest',
tag: 'main-out',
outbounds: map(main_urltest_nodes, (k) => `cfg-${k}-out`),
interval: main_urltest_interval ? (main_urltest_interval + 's') : null,
interval: strToTime(main_urltest_interval),
tolerance: strToInt(main_urltest_tolerance),
idle_timeout: (strToInt(main_urltest_interval) > 1800) ? `${main_urltest_interval * 2}s` : null,
});
@ -658,7 +684,6 @@ if (!isEmpty(main_node)) {
config.endpoints[length(config.endpoints)-1].tag = 'main-out';
} else {
push(config.outbounds, generate_outbound(main_node_cfg));
config.outbounds[length(config.outbounds)-1].domain_strategy = (ipv6_support !== '1') ? 'prefer_ipv4' : null;
config.outbounds[length(config.outbounds)-1].tag = 'main-out';
}
}
@ -672,7 +697,7 @@ if (!isEmpty(main_node)) {
type: 'urltest',
tag: 'main-udp-out',
outbounds: map(main_udp_urltest_nodes, (k) => `cfg-${k}-out`),
interval: main_udp_urltest_interval ? (main_udp_urltest_interval + 's') : null,
interval: strToTime(main_udp_urltest_interval),
tolerance: strToInt(main_udp_urltest_tolerance),
idle_timeout: (strToInt(main_udp_urltest_interval) > 1800) ? `${main_udp_urltest_interval * 2}s` : null,
});
@ -681,11 +706,9 @@ if (!isEmpty(main_node)) {
const main_udp_node_cfg = uci.get_all(uciconfig, main_udp_node) || {};
if (main_udp_node_cfg.type === 'wireguard') {
push(config.endpoints, generate_endpoint(main_udp_node_cfg));
config.endpoints[length(config.endpoints)-1].domain_strategy = (ipv6_support !== '1') ? 'prefer_ipv4' : null;
config.endpoints[length(config.endpoints)-1].tag = 'main-udp-out';
} else {
push(config.outbounds, generate_outbound(main_udp_node_cfg));
config.outbounds[length(config.outbounds)-1].domain_strategy = (ipv6_support !== '1') ? 'prefer_ipv4' : null;
config.outbounds[length(config.outbounds)-1].tag = 'main-udp-out';
}
}
@ -694,11 +717,9 @@ if (!isEmpty(main_node)) {
const urltest_node = uci.get_all(uciconfig, i) || {};
if (urltest_node.type === 'wireguard') {
push(config.endpoints, generate_endpoint(urltest_node));
config.endpoints[length(config.endpoints)-1].domain_strategy = (ipv6_support !== '1') ? 'prefer_ipv4' : null;
config.endpoints[length(config.endpoints)-1].tag = 'cfg-' + i + '-out';
} else {
push(config.outbounds, generate_outbound(urltest_node));
config.outbounds[length(config.outbounds)-1].domain_strategy = (ipv6_support !== '1') ? 'prefer_ipv4' : null;
config.outbounds[length(config.outbounds)-1].tag = 'cfg-' + i + '-out';
}
}
@ -716,24 +737,32 @@ if (!isEmpty(main_node)) {
tag: 'cfg-' + cfg['.name'] + '-out',
outbounds: map(cfg.urltest_nodes, (k) => `cfg-${k}-out`),
url: cfg.urltest_url,
interval: cfg.urltest_interval ? (cfg.urltest_interval + 's') : null,
interval: strToTime(cfg.urltest_interval),
tolerance: strToInt(cfg.urltest_tolerance),
idle_timeout: cfg.urltest_idle_timeout ? (cfg.urltest_idle_timeout + 's') : null,
interrupt_exist_connections: (cfg.urltest_interrupt_exist_connections === '1')
idle_timeout: strToTime(cfg.urltest_idle_timeout),
interrupt_exist_connections: strToBool(cfg.urltest_interrupt_exist_connections)
});
urltest_nodes = [...urltest_nodes, ...filter(cfg.urltest_nodes, (l) => !~index(urltest_nodes, l))];
} else {
const outbound = uci.get_all(uciconfig, cfg.node) || {};
if (outbound.type === 'wireguard') {
push(config.endpoints, generate_endpoint(outbound));
config.endpoints[length(config.endpoints)-1].domain_strategy = cfg.domain_strategy;
config.endpoints[length(config.endpoints)-1].bind_interface = cfg.bind_interface;
config.endpoints[length(config.endpoints)-1].detour = get_outbound(cfg.outbound);
if (cfg.domain_resolver || cfg.domain_strategy)
config.endpoints[length(config.endpoints)-1].domain_resolver = {
server: get_resolver(cfg.domain_resolver || default_outbound_dns),
strategy: cfg.domain_strategy
};
} else {
push(config.outbounds, generate_outbound(outbound));
config.outbounds[length(config.outbounds)-1].domain_strategy = cfg.domain_strategy;
config.outbounds[length(config.outbounds)-1].bind_interface = cfg.bind_interface;
config.outbounds[length(config.outbounds)-1].detour = get_outbound(cfg.outbound);
if (cfg.domain_resolver || cfg.domain_strategy)
config.outbounds[length(config.outbounds)-1].domain_resolver = {
server: get_resolver(cfg.domain_resolver || default_outbound_dns),
strategy: cfg.domain_strategy
};
}
push(routing_nodes, cfg.node);
}
@ -774,6 +803,13 @@ config.route = {
/* Routing rules */
if (!isEmpty(main_node)) {
/* Avoid DNS loop */
config.route.default_domain_resolver = {
action: 'route',
server: 'default-dns',
strategy: (ipv6_support !== '1') ? 'prefer_ipv4' : null
};
/* Direct list */
if (length(direct_domain_list))
push(config.route.rules, {
@ -844,6 +880,11 @@ if (!isEmpty(main_node)) {
if (isEmpty(config.route.rule_set))
config.route.rule_set = null;
} else if (!isEmpty(default_outbound)) {
config.route.default_domain_resolver = {
action: 'resolve',
server: get_resolver(default_outbound_dns)
};
if (domain_strategy)
push(config.route.rules, {
action: 'resolve',
@ -863,9 +904,9 @@ if (!isEmpty(main_node)) {
domain_keyword: cfg.domain_keyword,
domain_regex: cfg.domain_regex,
source_ip_cidr: cfg.source_ip_cidr,
source_ip_is_private: (cfg.source_ip_is_private === '1') || null,
source_ip_is_private: strToBool(cfg.source_ip_is_private),
ip_cidr: cfg.ip_cidr,
ip_is_private: (cfg.ip_is_private === '1') || null,
ip_is_private: strToBool(cfg.ip_is_private),
source_port: parse_port(cfg.source_port),
source_port_range: cfg.source_port_range,
port: parse_port(cfg.port),
@ -875,13 +916,19 @@ if (!isEmpty(main_node)) {
process_path_regex: cfg.process_path_regex,
user: cfg.user,
rule_set: get_ruleset(cfg.rule_set),
rule_set_ip_cidr_match_source: (cfg.rule_set_ip_cidr_match_source === '1') || null,
rule_set_ip_cidr_accept_empty: (cfg.rule_set_ip_cidr_accept_empty === '1') || null,
invert: (cfg.invert === '1') || null,
action: (cfg.outbound === 'block-out') ? 'reject' : 'route',
rule_set_ip_cidr_match_source: strToBool(cfg.rule_set_ip_cidr_match_source),
rule_set_ip_cidr_accept_empty: strToBool(cfg.rule_set_ip_cidr_accept_empty),
invert: strToBool(cfg.invert),
action: cfg.action,
outbound: get_outbound(cfg.outbound),
override_address: cfg.override_address,
override_port: strToInt(cfg.override_port),
outbound: get_outbound(cfg.outbound),
udp_disable_domain_unmapping: strToBool(cfg.udp_disable_domain_unmapping),
udp_connect: strToBool(cfg.udp_connect),
udp_timeout: strToTime(cfg.udp_timeout),
tls_fragment: strToBool(cfg.tls_fragment),
tls_fragment_fallback_delay: strToTime(cfg.tls_fragment_fallback_delay),
tls_record_fragment: strToBool(cfg.tls_record_fragment)
});
});
@ -911,8 +958,8 @@ if (routing_mode in ['bypass_mainland_china', 'custom']) {
cache_file: {
enabled: true,
path: RUN_DIR + '/cache.db',
store_rdrc: (cache_file_store_rdrc === '1') || null,
rdrc_timeout: cache_file_rdrc_timeout ? (cache_file_rdrc_timeout + 's') : null,
store_rdrc: strToBool(cache_file_store_rdrc),
rdrc_timeout: strToTime(cache_file_rdrc_timeout),
}
};
}

View File

@ -11,7 +11,7 @@ import { writefile } from 'fs';
import { cursor } from 'uci';
import {
isEmpty, strToBool, strToInt,
isEmpty, strToBool, strToInt, strToTime,
removeBlankAttrs, HP_DIR, RUN_DIR
} from 'homeproxy';
@ -45,12 +45,17 @@ uci.foreach(uciconfig, uciserver, (cfg) => {
listen: cfg.address || '::',
listen_port: strToInt(cfg.port),
bind_interface: cfg.bind_interface,
reuse_addr: strToBool(cfg.reuse_addr),
tcp_fast_open: strToBool(cfg.tcp_fast_open),
tcp_multi_path: strToBool(cfg.tcp_multi_path),
udp_fragment: strToBool(cfg.udp_fragment),
udp_timeout: cfg.udp_timeout ? (cfg.udp_timeout + 's') : null,
udp_timeout: strToTime(cfg.udp_timeout),
network: cfg.network,
/* AnyTLS */
padding_scheme: cfg.anytls_padding_scheme,
/* Hysteria */
up_mbps: strToInt(cfg.hysteria_up_mbps),
down_mbps: strToInt(cfg.hysteria_down_mbps),
@ -71,11 +76,11 @@ uci.foreach(uciconfig, uciserver, (cfg) => {
/* Tuic */
congestion_control: cfg.tuic_congestion_control,
auth_timeout: cfg.tuic_auth_timeout ? (cfg.tuic_auth_timeout + 's') : null,
auth_timeout: strToTime(cfg.tuic_auth_timeout),
zero_rtt_handshake: strToBool(cfg.tuic_enable_zero_rtt),
heartbeat: cfg.tuic_heartbeat ? (cfg.tuic_heartbeat + 's') : null,
heartbeat: strToTime(cfg.tuic_heartbeat),
/* HTTP / Hysteria (2) / Mixed / Socks / Trojan / Tuic / VLESS / VMess */
/* AnyTLS / HTTP / Hysteria (2) / Mixed / Socks / Trojan / Tuic / VLESS / VMess */
users: (cfg.type !== 'shadowsocks') ? [
{
name: !(cfg.type in ['http', 'mixed', 'naive', 'socks']) ? 'cfg-' + cfg['.name'] + '-server' : null,
@ -97,7 +102,7 @@ uci.foreach(uciconfig, uciserver, (cfg) => {
multiplex: (cfg.multiplex === '1') ? {
enabled: true,
padding: (cfg.multiplex_padding === '1'),
padding: strToBool(cfg.multiplex_padding),
brutal: (cfg.multiplex_brutal === '1') ? {
enabled: true,
up_mbps: strToInt(cfg.multiplex_brutal_up),
@ -120,8 +125,8 @@ uci.foreach(uciconfig, uciserver, (cfg) => {
default_server_name: cfg.tls_acme_dsn,
email: cfg.tls_acme_email,
provider: cfg.tls_acme_provider,
disable_http_challenge: (cfg.tls_acme_dhc === '1'),
disable_tls_alpn_challenge: (cfg.tls_acme_dtac === '1'),
disable_http_challenge: strToBool(cfg.tls_acme_dhc),
disable_tls_alpn_challenge: (cfg.tls_acme_dtac),
alternative_http_port: strToInt(cfg.tls_acme_ahp),
alternative_tls_port: strToInt(cfg.tls_acme_atp),
external_account: (cfg.tls_acme_external_account === '1') ? {
@ -145,7 +150,7 @@ uci.foreach(uciconfig, uciserver, (cfg) => {
enabled: true,
private_key: cfg.tls_reality_private_key,
short_id: cfg.tls_reality_short_id,
max_time_difference: cfg.tls_reality_max_time_difference ? (cfg.max_time_difference + 's') : null,
max_time_difference: strToTime(cfg.tls_reality_max_time_difference),
handshake: {
server: cfg.tls_reality_server_addr,
server_port: strToInt(cfg.tls_reality_server_port)
@ -164,8 +169,8 @@ uci.foreach(uciconfig, uciserver, (cfg) => {
max_early_data: strToInt(cfg.websocket_early_data),
early_data_header_name: cfg.websocket_early_data_header,
service_name: cfg.grpc_servicename,
idle_timeout: cfg.http_idle_timeout ? (cfg.http_idle_timeout + 's') : null,
ping_timeout: cfg.http_ping_timeout ? (cfg.http_ping_timeout + 's') : null
idle_timeout: strToTime(cfg.http_idle_timeout),
ping_timeout: strToTime(cfg.http_ping_timeout)
} : null
});
});

View File

@ -52,14 +52,6 @@ export function executeCommand(...args) {
};
};
export function calcStringMD5(str) {
if (!str || type(str) !== 'string')
return null;
const output = executeCommand(`/bin/echo -n ${shellQuote(str)} | /usr/bin/md5sum | /usr/bin/awk '{print $1}'`) || {};
return trim(output.stdout);
};
export function getTime(epoch) {
const local_time = localtime(epoch);
return replace(replace(sprintf(
@ -99,6 +91,10 @@ export function strToInt(str) {
return !isEmpty(str) ? (int(str) || null) : null;
};
export function strToTime(str) {
return str ? (str + 's') : null;
};
export function removeBlankAttrs(res) {
let content;

View File

@ -8,7 +8,7 @@
'use strict';
import { cursor } from 'uci';
import { isEmpty } from 'homeproxy';
import { isEmpty, parseURL } from 'homeproxy';
const uci = cursor();
@ -20,6 +20,7 @@ const uciinfra = 'infra',
ucimain = 'config',
ucinode = 'node',
ucidns = 'dns',
ucidnsserver = 'dns_server',
ucidnsrule = 'dns_rule',
ucirouting = 'routing',
uciroutingnode = 'routing_node',
@ -72,11 +73,122 @@ if (uci.get(uciconfig, ucimain, 'routing_port') === 'all')
if (uci.get(uciconfig, 'experimental'))
uci.delete(uciconfig, 'experimental');
/* block-dns was removed from built-in dns servers */
const default_dns_server = uci.get(uciconfig, ucidns, 'default_server');
if (default_dns_server === 'block-dns') {
/* append a rule at last to block all DNS queries */
uci.set(uciconfig, '_migration_dns_final_block', ucidnsrule);
uci.set(uciconfig, '_migration_dns_final_block', 'label', 'migration_final_block_dns');
uci.set(uciconfig, '_migration_dns_final_block', 'enabled', '1');
uci.set(uciconfig, '_migration_dns_final_block', 'mode', 'default');
uci.set(uciconfig, '_migration_dns_final_block', 'action', 'reject');
uci.set(uciconfig, ucidns, 'default_server', 'default-dns');
}
const dns_server_migration = {};
/* DNS servers options */
uci.foreach(uciconfig, ucidnsserver, (cfg) => {
/* legacy format was deprecated in sb 1.12 */
if (cfg.address) {
const addr = parseURL((!match(cfg.address, /:\/\//) ? 'udp://' : '') + cfg.address);
/* RCode was moved into DNS rules */
if (addr.protocol === 'rcode') {
dns_server_migration[cfg['.name']] = { action: 'predefined' };
switch (addr.hostname) {
case 'success':
dns_server_migration[cfg['.name']].rcode = 'NOERROR';
break;
case 'format_error':
dns_server_migration[cfg['.name']].rcode = 'FORMERR';
break;
case 'server_failure':
dns_server_migration[cfg['.name']].rcode = 'SERVFAIL';
break;
case 'name_error':
dns_server_migration[cfg['.name']].rcode = 'NXDOMAIN';
break;
case 'not_implemented':
dns_server_migration[cfg['.name']].rcode = 'NOTIMP';
break;
case 'refused':
default:
dns_server_migration[cfg['.name']].rcode = 'REFUSED';
break;
}
uci.delete(uciconfig, cfg['.name']);
return;
}
uci.set(uciconfig, cfg['.name'], 'type', addr.protocol);
uci.set(uciconfig, cfg['.name'], 'server', addr.hostname);
uci.set(uciconfig, cfg['.name'], 'server_port', addr.port);
uci.set(uciconfig, cfg['.name'], 'path', (addr.pathname !== '/') ? addr.pathname : null);
uci.delete(uciconfig, cfg['.name'], 'address');
}
if (cfg.strategy) {
if (cfg['.name'] === default_dns_server)
uci.set(uciconfig, ucidns, 'default_strategy', cfg.strategy);
dns_server_migration[cfg['.name']] = { strategy: cfg.strategy };
uci.delete(uciconfig, cfg['.name'], 'strategy');
}
if (cfg.client_subnet) {
if (cfg['.name'] === default_dns_server)
uci.set(uciconfig, ucidns, 'client_subnet', cfg.client_subnet);
if (isEmpty(dns_server_migration[cfg['.name']]))
dns_server_migration[cfg['.name']] = {};
dns_server_migration[cfg['.name']].client_subnet = cfg.client_subnet;
uci.delete(uciconfig, cfg['.name'], 'client_subnet');
}
});
/* DNS rules options */
uci.foreach(uciconfig, ucidnsrule, (cfg) => {
/* outbound was removed in sb 1.12 */
if (cfg.outbound) {
uci.delete(uciconfig, cfg['.name']);
if (!cfg.enabled)
return;
map(cfg.outbound, (outbound) => {
switch (outbound) {
case 'direct-out':
case 'block-out':
break;
case 'any-out':
uci.set(uciconfig, ucirouting, 'default_outbound_dns', cfg.server);
break;
default:
uci.set(uciconfig, cfg.outbound, 'domain_resolver', cfg.server);
break;
}
});
return;
}
/* rule_set_ipcidr_match_source was renamed in sb 1.10 */
if (cfg.rule_set_ipcidr_match_source === '1')
uci.rename(uciconfig, cfg['.name'], 'rule_set_ipcidr_match_source', 'rule_set_ip_cidr_match_source');
/* block-dns was moved into action in sb 1.11 */
if (cfg.server === 'block-dns') {
uci.set(uciconfig, cfg['.name'], 'action', 'reject');
uci.delete(uciconfig, cfg['.name'], 'server');
} else if (!cfg.action) {
/* add missing 'action' field */
uci.set(uciconfig, cfg['.name'], 'action', 'route');
}
/* strategy and client_subnet were moved into dns rules */
if (dns_server_migration[cfg.server]) {
if (dns_server_migration[cfg.server].strategy)
uci.set(uciconfig, cfg['.name'], 'strategy', dns_server_migration[cfg.server].strategy);
if (dns_server_migration[cfg.server].client_subnet)
uci.set(uciconfig, cfg['.name'], 'client_subnet', dns_server_migration[cfg.server].client_subnet);
}
});
/* nodes options */
@ -95,6 +207,15 @@ uci.foreach(uciconfig, uciroutingrule, (cfg) => {
/* rule_set_ipcidr_match_source was renamed in sb 1.10 */
if (cfg.rule_set_ipcidr_match_source === '1')
uci.rename(uciconfig, cfg['.name'], 'rule_set_ipcidr_match_source', 'rule_set_ip_cidr_match_source');
/* block-out was moved into action in sb 1.11 */
if (cfg.outbound === 'block-out') {
uci.set(uciconfig, cfg['.name'], 'action', 'reject');
uci.delete(uciconfig, cfg['.name'], 'outbound');
} else if (!cfg.action) {
/* add missing 'action' field */
uci.set(uciconfig, cfg['.name'], 'action', 'route');
}
});
/* server options */

View File

@ -7,6 +7,7 @@
'use strict';
import { md5 } from 'digest';
import { open } from 'fs';
import { connect } from 'ubus';
import { cursor } from 'uci';
@ -15,9 +16,8 @@ import { urldecode, urlencode } from 'luci.http';
import { init_action } from 'luci.sys';
import {
calcStringMD5, wGET, decodeBase64Str,
getTime, isEmpty, parseURL, validation,
HP_DIR, RUN_DIR
wGET, decodeBase64Str, getTime, isEmpty, parseURL,
validation, HP_DIR, RUN_DIR
} from 'homeproxy';
/* UCI config start */
@ -101,6 +101,23 @@ function parse_uri(uri) {
uri = split(trim(uri), '://');
switch (uri[0]) {
case 'anytls':
/* https://github.com/anytls/anytls-go/blob/v0.0.8/docs/uri_scheme.md */
url = parseURL('http://' + uri[1]) || {};
params = url.searchParams || {};
config = {
label: url.hash ? urldecode(url.hash) : null,
type: 'anytls',
address: url.hostname,
port: url.port,
password: urldecode(url.username),
tls: '1',
tls_sni: params.sni,
tls_insecure: (params.insecure === '1') ? '1' : '0'
};
break;
case 'http':
case 'https':
url = parseURL('http://' + uri[1]) || {};
@ -464,7 +481,7 @@ function main() {
for (let url in subscription_urls) {
url = replace(url, /#.*$/, '');
const groupHash = calcStringMD5(url);
const groupHash = md5(url);
node_cache[groupHash] = {};
const res = wGET(url, user_agent);
@ -495,8 +512,8 @@ function main() {
const label = config.label;
config.label = null;
const confHash = calcStringMD5(sprintf('%J', config)),
nameHash = calcStringMD5(label);
const confHash = md5(sprintf('%J', config)),
nameHash = md5(label);
config.label = label;
if (filter_check(config.label))
@ -566,7 +583,7 @@ function main() {
if (node.isExisting)
return null;
const nameHash = calcStringMD5(node.label);
const nameHash = md5(node.label);
uci.set(uciconfig, nameHash, 'node');
map(keys(node), (v) => uci.set(uciconfig, nameHash, v, node[v]));

View File

@ -250,7 +250,7 @@ start_service() {
[ "$outbound_node" = "nil" ] || utpl -S "$HP_DIR/scripts/firewall_post.ut" > "$RUN_DIR/fw4_post.nft"
fw4 reload >"/dev/null" 2>&1
log "$(sing-box version | awk 'NR==1{print $1,$3}') started."
log "sing-box $(sing-box version -n) started."
}
stop_service() {

View File

@ -16,8 +16,6 @@
"/etc/nikki/run/config.yaml": ["read"],
"/etc/nikki/run/providers/rule/*": ["read"],
"/etc/nikki/run/providers/proxy/*": ["read"],
"/etc/nikki/nftables/reserved_ip.nft": ["read"],
"/etc/nikki/nftables/reserved_ip6.nft": ["read"],
"/var/log/nikki/*.log": ["read"]
}
},
@ -32,8 +30,6 @@
"/etc/nikki/run/config.yaml": ["write"],
"/etc/nikki/run/providers/rule/*": ["write"],
"/etc/nikki/run/providers/proxy/*": ["write"],
"/etc/nikki/nftables/reserved_ip.nft": ["write"],
"/etc/nikki/nftables/reserved_ip6.nft": ["write"],
"/var/log/nikki/*.log": ["write"]
}
}

View File

@ -448,6 +448,9 @@ function clear_all_nodes()
end)
uci:foreach(appname, "subscribe_list", function(t)
uci:delete(appname, t[".name"], "md5")
uci:delete(appname, t[".name"], "chain_proxy")
uci:delete(appname, t[".name"], "preproxy_node")
uci:delete(appname, t[".name"], "to_node")
end)
api.uci_save(uci, appname, true, true)
@ -518,6 +521,16 @@ function delete_select_nodes()
uci:delete(appname, t[".name"], "fallback_node")
end
end)
uci:foreach(appname, "subscribe_list", function(t)
if t["preproxy_node"] == w then
uci:delete(appname, t[".name"], "preproxy_node")
uci:delete(appname, t[".name"], "chain_proxy")
end
if t["to_node"] == w then
uci:delete(appname, t[".name"], "to_node")
uci:delete(appname, t[".name"], "chain_proxy")
end
end)
if (uci:get(appname, w, "add_mode") or "0") == "2" then
local add_from = uci:get(appname, w, "add_from") or ""
if add_from ~= "" then
@ -633,20 +646,29 @@ function create_backup()
end
function restore_backup()
local result = { status = "error", message = "unknown error" }
local ok, err = pcall(function()
local filename = http.formvalue("filename")
local chunk = http.formvalue("chunk")
local chunk_index = tonumber(http.formvalue("chunk_index") or "-1")
local total_chunks = tonumber(http.formvalue("total_chunks") or "-1")
if not filename or not chunk then
http_write_json({ status = "error", message = "Missing filename or chunk" })
if not filename then
result = { status = "error", message = "Missing filename" }
return
end
if not chunk then
result = { status = "error", message = "Missing chunk data" }
return
end
local file_path = "/tmp/" .. filename
local decoded = nixio.bin.b64decode(chunk)
if not decoded then
result = { status = "error", message = "Base64 decode failed" }
return
end
local fp = io.open(file_path, "a+")
if not fp then
http_write_json({ status = "error", message = "Failed to open file for writing: " .. file_path })
result = { status = "error", message = "Failed to open file: " .. file_path }
return
end
fp:write(decoded)
@ -667,19 +689,21 @@ function restore_backup()
api.log(" * 重启 PassWall 服务中…\n")
luci.sys.call('/etc/init.d/passwall restart > /dev/null 2>&1 &')
luci.sys.call('/etc/init.d/passwall_server restart > /dev/null 2>&1 &')
result = { status = "success", message = "Upload completed", path = file_path }
else
api.log(" * PassWall 配置文件解压失败,请重试!")
result = { status = "error", message = "Decompression failed" }
end
luci.sys.call("rm -rf " .. temp_dir)
fs.remove(file_path)
http_write_json({ status = "success", message = "Upload completed", path = file_path })
else
http_write_json({ status = "success", message = "Chunk received" })
result = { status = "success", message = "Chunk received" }
end
end)
if not ok then
http_write_json({ status = "error", message = tostring(err) })
result = { status = "error", message = tostring(err) }
end
http_write_json(result)
end
function geo_view()

View File

@ -91,6 +91,16 @@ function s.remove(e, t)
m:del(s[".name"], "fallback_node")
end
end)
m.uci:foreach(appname, "subscribe_list", function(s)
if s["preproxy_node"] == t then
m:del(s[".name"], "preproxy_node")
m:del(s[".name"], "chain_proxy")
end
if s["to_node"] == t then
m:del(s[".name"], "to_node")
m:del(s[".name"], "chain_proxy")
end
end)
if (m:get(t, "add_mode") or "0") == "2" then
local add_from = m:get(t, "add_from") or ""
if add_from ~= "" then

View File

@ -56,6 +56,18 @@ if has_hysteria2 then
local s = "hysteria2"
table.insert(hysteria2_type, s)
end
local nodes_table = {}
for k, e in ipairs(api.get_valid_nodes()) do
if e.node_type == "normal" then
nodes_table[#nodes_table + 1] = {
id = e[".name"],
remark = e["remark"],
type = e["type"],
add_mode = e["add_mode"],
chain_proxy = e["chain_proxy"]
}
end
end
s = m:section(NamedSection, arg[1])
s.addremove = false
@ -210,4 +222,29 @@ o:value("curl", "Curl")
o:value("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0", "Edge for Linux")
o:value("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0", "Edge for Windows")
o = s:option(ListValue, "chain_proxy", translate("Chain Proxy"))
o:value("", translate("Close(Not use)"))
o:value("1", translate("Preproxy Node"))
o:value("2", translate("Landing Node"))
local descrStr = "Chained proxy works only with Xray or Sing-box nodes.<br>"
descrStr = descrStr .. "The chained node must be the same type as your subscription node (Xray with Xray, Sing-box with Sing-box).<br>"
descrStr = descrStr .. "You can only use manual or imported nodes as chained nodes."
descrStr = translate(descrStr) .. "<br>" .. translate("Only support a layer of proxy.")
o = s:option(ListValue, "preproxy_node", translate("Preproxy Node"))
o:depends({ ["chain_proxy"] = "1" })
o.description = descrStr
o = s:option(ListValue, "to_node", translate("Landing Node"))
o:depends({ ["chain_proxy"] = "2" })
o.description = descrStr
for k, v in pairs(nodes_table) do
if (v.type == "Xray" or v.type == "sing-box") and (not v.chain_proxy or v.chain_proxy == "") and v.add_mode ~= "2" then
s.fields["preproxy_node"]:value(v.id, v.remark)
s.fields["to_node"]:value(v.id, v.remark)
end
end
return m

View File

@ -184,7 +184,6 @@ local api = require "luci.passwall.api"
const chunk = base64Data.substring(currentChunk * chunkSize, (currentChunk + 1) * chunkSize);
const xhr = new XMLHttpRequest();
xhr.open("POST", '<%= api.url("restore_backup") %>', true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
@ -203,12 +202,12 @@ local api = require "luci.passwall.api"
}
}
};
xhr.send(
"filename=" + encodeURIComponent(file.name) +
"&chunk=" + encodeURIComponent(chunk) +
"&chunk_index=" + currentChunk +
"&total_chunks=" + totalChunks
);
const formData = new FormData();
formData.append("filename", file.name);
formData.append("chunk", chunk);
formData.append("chunk_index", currentChunk);
formData.append("total_chunks", totalChunks);
xhr.send(formData);
} else {
//alert("Upload completed.");
document.getElementById("upload-btn").value = "<%:UL Restore%>";

View File

@ -1795,6 +1795,15 @@ msgstr "落地节点"
msgid "Only support a layer of proxy."
msgstr "仅支持一层代理。"
msgid ""
"Chained proxy works only with Xray or Sing-box nodes.<br>"
"The chained node must be the same type as your subscription node (Xray with Xray, Sing-box with Sing-box).<br>"
"You can only use manual or imported nodes as chained nodes."
msgstr ""
"链式代理仅支持 Xray 与 Sing-box 节点。<br>"
"链式节点需与订阅节点类型一致Xray 对应 XraySing-box 对应 Sing-box。<br>"
"仅支持手动添加或导入的节点用作链式节点。"
msgid "Only work with using the %s node."
msgstr "与使用 %s 节点时生效。"

View File

@ -36,6 +36,7 @@ local vless_type_default = uci:get(appname, "@global_subscribe[0]", "vless_type"
local hysteria2_type_default = uci:get(appname, "@global_subscribe[0]", "hysteria2_type") or "hysteria2"
local domain_strategy_default = uci:get(appname, "@global_subscribe[0]", "domain_strategy") or ""
local domain_strategy_node = ""
local preproxy_node_group, to_node_group, chain_node_type = "", "", ""
-- 判断是否过滤节点关键字
local filter_keyword_mode_default = uci:get(appname, "@global_subscribe[0]", "filter_keyword_mode") or "0"
local filter_keyword_discard_list_default = uci:get(appname, "@global_subscribe[0]", "filter_discard_list") or {}
@ -1714,6 +1715,16 @@ local function update_node(manual)
if kkk == "type" and vvv == "sing-box" then
uci:set(appname, cfgid, "domain_strategy", domain_strategy_node)
end
-- 订阅组链式代理
if chain_node_type ~= "" and kkk == "type" and vvv == chain_node_type then
if preproxy_node_group ~="" then
uci:set(appname, cfgid, "chain_proxy", "1")
uci:set(appname, cfgid, "preproxy_node", preproxy_node_group)
elseif to_node_group ~= "" then
uci:set(appname, cfgid, "chain_proxy", "2")
uci:set(appname, cfgid, "to_node", to_node_group)
end
end
end
end
end
@ -1916,6 +1927,22 @@ local execute = function()
else
domain_strategy_node = domain_strategy_default
end
-- 订阅组链式代理
local function valid_chain_node(node)
if not node then return "" end
local cp = uci:get(appname, node, "chain_proxy") or ""
local am = uci:get(appname, node, "add_mode") or "0"
chain_node_type = (cp == "" and am ~= "2") and (uci:get(appname, node, "type") or "") or ""
if chain_node_type ~= "Xray" and chain_node_type ~= "sing-box" then
chain_node_type = ""
return ""
end
return node
end
preproxy_node_group = (value.chain_proxy == "1") and valid_chain_node(value.preproxy_node) or ""
to_node_group = (value.chain_proxy == "2") and valid_chain_node(value.to_node) or ""
local ua = value.user_agent
local access_mode = value.access_mode
local result = (not access_mode) and "自动" or (access_mode == "direct" and "直连访问" or (access_mode == "proxy" and "通过代理" or "自动"))

View File

@ -5,7 +5,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall2
PKG_VERSION:=25.8.9
PKG_VERSION:=25.8.22
PKG_RELEASE:=1
PKG_CONFIG_DEPENDS:= \

View File

@ -30,6 +30,11 @@ o = s:option(Value, _n("hop"), translate("Port hopping range"))
o.description = translate("Format as 1000:2000 or 1000-2000 Multiple groups are separated by commas (,).")
o.rewrite_option = o.option
o = s:option(Value, _n("hop_interval"), translate("Hop Interval"), translate("Example:") .. "30s (≥5s)")
o.placeholder = "30s"
o.default = "30s"
o.rewrite_option = o.option
o = s:option(Value, _n("obfs"), translate("Obfs Password"))
o.rewrite_option = o.option
@ -54,9 +59,6 @@ o.rewrite_option = o.option
o = s:option(Value, _n("down_mbps"), translate("Max download Mbps"))
o.rewrite_option = o.option
o = s:option(Value, _n("hop_interval"), translate("Hop Interval"), translate("Example:") .. "30s (≥5s)")
o.rewrite_option = o.option
o = s:option(Value, _n("recv_window"), translate("QUIC stream receive window"))
o.rewrite_option = o.option

View File

@ -61,7 +61,8 @@ for k, e in ipairs(api.get_valid_nodes()) do
nodes_table[#nodes_table + 1] = {
id = e[".name"],
remark = e["remark"],
type = e["type"]
type = e["type"],
chain_proxy = e["chain_proxy"]
}
end
if e.protocol == "_balancing" then
@ -337,6 +338,7 @@ o.default = ""
o:value("", translate("Disable"))
o:value("xtls-rprx-vision")
o:depends({ [_n("protocol")] = "vless", [_n("tls")] = true, [_n("transport")] = "raw" })
o:depends({ [_n("protocol")] = "trojan", [_n("tls")] = true, [_n("transport")] = "raw" })
o = s:option(Flag, _n("tls"), translate("TLS"))
o.default = 0
@ -392,6 +394,13 @@ o.validate = function(self, value)
return api.trim(value:gsub("[\r\n]", ""))
end
o = s:option(ListValue, _n("ech_ForceQuery"), translate("ECH Query Policy"), translate("Controls the policy used when performing DNS queries for ECH configuration."))
o.default = "none"
o:value("none")
o:value("half")
o:value("full")
o:depends({ [_n("ech")] = true })
-- [[ REALITY部分 ]] --
o = s:option(Value, _n("reality_publicKey"), translate("Public Key"))
o:depends({ [_n("tls")] = true, [_n("reality")] = true })
@ -696,7 +705,7 @@ o = s:option(ListValue, _n("to_node"), translate("Landing Node"), translate("Onl
o:depends({ [_n("chain_proxy")] = "2" })
for k, v in pairs(nodes_table) do
if v.type == "Xray" and v.id ~= arg[1] then
if v.type == "Xray" and v.id ~= arg[1] and (not v.chain_proxy or v.chain_proxy == "") then
s.fields[_n("preproxy_node")]:value(v.id, v.remark)
s.fields[_n("to_node")]:value(v.id, v.remark)
end

View File

@ -81,7 +81,8 @@ for k, e in ipairs(api.get_valid_nodes()) do
nodes_table[#nodes_table + 1] = {
id = e[".name"],
remark = e["remark"],
type = e["type"]
type = e["type"],
chain_proxy = e["chain_proxy"]
}
end
if e.protocol == "_iface" then
@ -339,12 +340,18 @@ o.default = ""
o:value("", translate("Disable"))
o:value("xtls-rprx-vision")
o:depends({ [_n("protocol")] = "vless", [_n("tls")] = true })
o:depends({ [_n("protocol")] = "trojan", [_n("tls")] = true })
if singbox_tags:find("with_quic") then
o = s:option(Value, _n("hysteria_hop"), translate("Port hopping range"))
o.description = translate("Format as 1000:2000 or 1000-2000 Multiple groups are separated by commas (,).")
o:depends({ [_n("protocol")] = "hysteria" })
o = s:option(Value, _n("hysteria_hop_interval"), translate("Hop Interval"), translate("Example:") .. "30s (≥5s)")
o.placeholder = "30s"
o.default = "30s"
o:depends({ [_n("protocol")] = "hysteria" })
o = s:option(Value, _n("hysteria_obfs"), translate("Obfs Password"))
o:depends({ [_n("protocol")] = "hysteria" })
@ -425,6 +432,11 @@ if singbox_tags:find("with_quic") then
o.description = translate("Format as 1000:2000 or 1000-2000 Multiple groups are separated by commas (,).")
o:depends({ [_n("protocol")] = "hysteria2" })
o = s:option(Value, _n("hysteria2_hop_interval"), translate("Hop Interval"), translate("Example:") .. "30s (≥5s)")
o.placeholder = "30s"
o.default = "30s"
o:depends({ [_n("protocol")] = "hysteria2" })
o = s:option(Value, _n("hysteria2_up_mbps"), translate("Max upload Mbps"))
o:depends({ [_n("protocol")] = "hysteria2" })
@ -526,30 +538,30 @@ if singbox_tags:find("with_utls") then
o:value("firefox")
o:value("edge")
o:value("safari")
-- o:value("360")
o:value("360")
o:value("qq")
o:value("ios")
-- o:value("android")
o:value("android")
o:value("random")
-- o:value("randomized")
o:value("randomized")
o.default = "chrome"
o:depends({ [_n("tls")] = true, [_n("utls")] = true })
o:depends({ [_n("utls")] = true })
-- [[ REALITY部分 ]] --
o = s:option(Flag, _n("reality"), translate("REALITY"))
o.default = 0
o:depends({ [_n("protocol")] = "vless", [_n("utls")] = true })
o:depends({ [_n("protocol")] = "vmess", [_n("utls")] = true })
o:depends({ [_n("protocol")] = "shadowsocks", [_n("utls")] = true })
o:depends({ [_n("protocol")] = "socks", [_n("utls")] = true })
o:depends({ [_n("protocol")] = "trojan", [_n("utls")] = true })
o:depends({ [_n("protocol")] = "anytls", [_n("utls")] = true })
o:depends({ [_n("protocol")] = "vless", [_n("tls")] = true })
o:depends({ [_n("protocol")] = "vmess", [_n("tls")] = true })
o:depends({ [_n("protocol")] = "shadowsocks", [_n("tls")] = true })
o:depends({ [_n("protocol")] = "socks", [_n("tls")] = true })
o:depends({ [_n("protocol")] = "trojan", [_n("tls")] = true })
o:depends({ [_n("protocol")] = "anytls", [_n("tls")] = true })
o = s:option(Value, _n("reality_publicKey"), translate("Public Key"))
o:depends({ [_n("utls")] = true, [_n("reality")] = true })
o:depends({ [_n("reality")] = true })
o = s:option(Value, _n("reality_shortId"), translate("Short Id"))
o:depends({ [_n("utls")] = true, [_n("reality")] = true })
o:depends({ [_n("reality")] = true })
end
o = s:option(ListValue, _n("transport"), translate("Transport"))
@ -801,7 +813,7 @@ o = s:option(ListValue, _n("to_node"), translate("Landing Node"), translate("Onl
o:depends({ [_n("chain_proxy")] = "2" })
for k, v in pairs(nodes_table) do
if v.type == "sing-box" and v.id ~= arg[1] then
if v.type == "sing-box" and v.id ~= arg[1] and (not v.chain_proxy or v.chain_proxy == "") then
s.fields[_n("preproxy_node")]:value(v.id, v.remark)
s.fields[_n("to_node")]:value(v.id, v.remark)
end

View File

@ -321,7 +321,11 @@ function gen_outbound(flag, node, tag, proxy_table)
end
protocol_table = {
server_ports = next(server_ports) and server_ports or nil,
hop_interval = next(server_ports) and "30s" or nil,
hop_interval = (function()
if not next(server_ports) then return nil end
local v = tonumber((node.hysteria_hop_interval or "30s"):match("^%d+"))
return (v and v >= 5) and (v .. "s") or "30s"
end)(),
up_mbps = tonumber(node.hysteria_up_mbps),
down_mbps = tonumber(node.hysteria_down_mbps),
obfs = node.hysteria_obfs,
@ -397,7 +401,11 @@ function gen_outbound(flag, node, tag, proxy_table)
end
protocol_table = {
server_ports = next(server_ports) and server_ports or nil,
hop_interval = next(server_ports) and "30s" or nil,
hop_interval = (function()
if not next(server_ports) then return nil end
local v = tonumber((node.hysteria2_hop_interval or "30s"):match("^%d+"))
return (v and v >= 5) and (v .. "s") or "30s"
end)(),
up_mbps = (node.hysteria2_up_mbps and tonumber(node.hysteria2_up_mbps)) and tonumber(node.hysteria2_up_mbps) or nil,
down_mbps = (node.hysteria2_down_mbps and tonumber(node.hysteria2_down_mbps)) and tonumber(node.hysteria2_down_mbps) or nil,
obfs = {

View File

@ -155,7 +155,8 @@ function gen_outbound(flag, node, tag, proxy_table)
serverName = node.tls_serverName,
allowInsecure = (node.tls_allowInsecure == "1") and true or false,
fingerprint = (node.type == "Xray" and node.utls == "1" and node.fingerprint and node.fingerprint ~= "") and node.fingerprint or nil,
echConfigList = (node.ech == "1") and node.ech_config or nil
echConfigList = (node.ech == "1") and node.ech_config or nil,
echForceQuery = (node.ech == "1") and (node.ech_ForceQuery or "none") or nil
} or nil,
realitySettings = (node.stream_security == "reality") and {
serverName = node.tls_serverName,
@ -1060,6 +1061,7 @@ function gen_config(var)
domains = {}
string.gsub(e.domain_list, '[^' .. "\r\n" .. ']+', function(w)
if w:find("#") == 1 then return end
if w:find("rule-set:", 1, true) == 1 or w:find("rs:") == 1 then return end
table.insert(domains, w)
table.insert(domain_table.domain, w)
end)
@ -1073,6 +1075,7 @@ function gen_config(var)
ip = {}
string.gsub(e.ip_list, '[^' .. "\r\n" .. ']+', function(w)
if w:find("#") == 1 then return end
if w:find("rule-set:", 1, true) == 1 or w:find("rs:") == 1 then return end
table.insert(ip, w)
end)
if #ip == 0 then ip = nil end

View File

@ -284,10 +284,6 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
params += opt.query("spx", dom_prefix + "reality_spiderX");
params += opt.query("pqv", dom_prefix + "reality_mldsa65Verify");
}
if (opt.get(dom_prefix + "flow") && opt.get(dom_prefix + "flow").value) {
let v_flow = opt.get(dom_prefix + "flow").value;
params += "&flow=" + v_flow;
}
params += "&security=" + v_security;
params += opt.query("alpn", dom_prefix + "alpn");
params += opt.query("sni", dom_prefix + "tls_serverName");
@ -960,11 +956,10 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
if (queryParam.security == "tls") {
opt.set(dom_prefix + 'tls', true);
opt.set(dom_prefix + 'reality', false);
opt.set(dom_prefix + 'flow', queryParam.flow || '');
opt.set(dom_prefix + 'alpn', queryParam.alpn || 'default');
opt.set(dom_prefix + 'tls_serverName', queryParam.sni || '');
opt.set(dom_prefix + 'tls_allowInsecure', true);
if (queryParam.allowinsecure === '0' || queryParam.insecure === '0') {
if ((queryParam.allowinsecure ?? '0') === '0' && (queryParam.insecure ?? '0') === '0') {
opt.set(dom_prefix + 'tls_allowInsecure', false);
}
if (queryParam.fp && queryParam.fp.trim() != "") {
@ -978,7 +973,6 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
if (queryParam.security == "reality") {
opt.set(dom_prefix + 'tls', true);
opt.set(dom_prefix + 'reality', true);
opt.set(dom_prefix + 'flow', queryParam.flow || '');
opt.set(dom_prefix + 'alpn', queryParam.alpn || 'default');
opt.set(dom_prefix + 'tls_serverName', queryParam.sni || '');
if (queryParam.fp && queryParam.fp.trim() != "") {
@ -1205,9 +1199,11 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
}
tls_serverName = tls_serverName || "";
opt.set(dom_prefix + 'tls_serverName', tls_serverName);
opt.set(dom_prefix + 'flow', (queryParam.flow || '').replace('-udp443', ''));
opt.set(dom_prefix + 'alpn', queryParam.alpn || 'default');
}
opt.set(dom_prefix + 'tls_allowInsecure', true);
if (queryParam.allowinsecure === '0' || queryParam.insecure === '0') {
if ((queryParam.allowinsecure ?? '0') === '0' && (queryParam.insecure ?? '0') === '0') {
opt.set(dom_prefix + 'tls_allowInsecure', false);
}
@ -1342,11 +1338,11 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
if (queryParam.security == "tls") {
opt.set(dom_prefix + 'tls', true);
opt.set(dom_prefix + 'reality', false);
opt.set(dom_prefix + 'flow', queryParam.flow || '');
opt.set(dom_prefix + 'flow', (queryParam.flow || '').replace('-udp443', ''));
opt.set(dom_prefix + 'alpn', queryParam.alpn || 'default');
opt.set(dom_prefix + 'tls_serverName', queryParam.sni || '');
opt.set(dom_prefix + 'tls_allowInsecure', true);
if (queryParam.allowinsecure === '0' || queryParam.insecure === '0') {
if ((queryParam.allowinsecure ?? '0') === '0' && (queryParam.insecure ?? '0') === '0') {
opt.set(dom_prefix + 'tls_allowInsecure', false);
}
if (queryParam.fp && queryParam.fp.trim() != "") {
@ -1360,7 +1356,7 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
if (queryParam.security == "reality") {
opt.set(dom_prefix + 'tls', true);
opt.set(dom_prefix + 'reality', true);
opt.set(dom_prefix + 'flow', queryParam.flow || '');
opt.set(dom_prefix + 'flow', (queryParam.flow || '').replace('-udp443', ''));
opt.set(dom_prefix + 'alpn', queryParam.alpn || 'default');
opt.set(dom_prefix + 'tls_serverName', queryParam.sni || '');
if (queryParam.fp && queryParam.fp.trim() != "") {
@ -1539,7 +1535,7 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
opt.set(dom_prefix + 'tuic_alpn', queryParam.alpn || 'default');
opt.set(dom_prefix + 'tls_serverName', queryParam.sni || '');
opt.set(dom_prefix + 'tls_allowInsecure', true);
if (queryParam.allowinsecure === '0' || queryParam.insecure === '0') {
if ((queryParam.allowinsecure ?? '0') === '0' && (queryParam.insecure ?? '0') === '0') {
opt.set(dom_prefix + 'tls_allowInsecure', false);
}
if (hash) {
@ -1579,11 +1575,10 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
if (queryParam.security == "tls") {
opt.set(dom_prefix + 'tls', true);
opt.set(dom_prefix + 'reality', false);
opt.set(dom_prefix + 'flow', queryParam.flow || '');
opt.set(dom_prefix + 'alpn', queryParam.alpn || 'default');
opt.set(dom_prefix + 'tls_serverName', queryParam.sni || '');
opt.set(dom_prefix + 'tls_allowInsecure', true);
if (queryParam.allowinsecure === '0' || queryParam.insecure === '0') {
if ((queryParam.allowinsecure ?? '0') === '0' && (queryParam.insecure ?? '0') === '0') {
opt.set(dom_prefix + 'tls_allowInsecure', false);
}
if (queryParam.fp && queryParam.fp.trim() != "") {
@ -1594,7 +1589,6 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
if (queryParam.security == "reality") {
opt.set(dom_prefix + 'tls', true);
opt.set(dom_prefix + 'reality', true);
opt.set(dom_prefix + 'flow', queryParam.flow || '');
opt.set(dom_prefix + 'alpn', queryParam.alpn || 'default');
opt.set(dom_prefix + 'tls_serverName', queryParam.sni || '');
if (queryParam.fp && queryParam.fp.trim() != "") {

View File

@ -1576,6 +1576,12 @@ msgstr "后量子对等证书签名方案"
msgid "Disable adaptive sizing of TLS records"
msgstr "禁用 TLS 记录的自适应大小调整"
msgid "ECH Query Policy"
msgstr "ECH 查询策略"
msgid "Controls the policy used when performing DNS queries for ECH configuration."
msgstr "控制使用 DNS 查询 ECH 配置时的策略。"
msgid "Enable Multipath TCP, need to be enabled in both server and client configuration."
msgstr "启用 Multipath TCP需在服务端和客户端配置中同时启用。"

View File

@ -336,6 +336,15 @@ eval_cache_var() {
[ -s "$TMP_PATH/var" ] && eval $(cat "$TMP_PATH/var")
}
has_1_65535() {
local val="$1"
val=${val//:/-}
case ",$val," in
*,1-65535,*) return 0 ;;
*) return 1 ;;
esac
}
run_xray() {
local flag node redir_port tcp_proxy_way socks_address socks_port socks_username socks_password http_address http_port http_username http_password
local dns_listen_port direct_dns_query_strategy remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh remote_dns_client_ip remote_dns_detour remote_fakedns remote_dns_query_strategy dns_cache write_ipset_direct
@ -1146,11 +1155,10 @@ acl_app() {
index=$(expr $index + 1)
local enabled sid remarks sources interface tcp_no_redir_ports udp_no_redir_ports node direct_dns_query_strategy write_ipset_direct remote_dns_protocol remote_dns remote_dns_doh remote_dns_client_ip remote_dns_detour remote_fakedns remote_dns_query_strategy
local _ip _mac _iprange _ipset _ip_or_mac source_list config_file
sid=$(uci -q show "${CONFIG}.${item}" | grep "=acl_rule" | awk -F '=' '{print $1}' | awk -F '.' '{print $2}')
local sid=$(uci -q show "${CONFIG}.${item}" | grep "=acl_rule" | awk -F '=' '{print $1}' | awk -F '.' '{print $2}')
[ "$(config_n_get $sid enabled)" = "1" ] || continue
eval $(uci -q show "${CONFIG}.${item}" | cut -d'.' -sf 3-)
[ "$enabled" = "1" ] || continue
if [ -n "${sources}" ]; then
for s in $sources; do
local s2
@ -1183,7 +1191,9 @@ acl_app() {
udp_no_redir_ports=${udp_no_redir_ports:-default}
[ "$tcp_no_redir_ports" = "default" ] && tcp_no_redir_ports=$TCP_NO_REDIR_PORTS
[ "$udp_no_redir_ports" = "default" ] && udp_no_redir_ports=$UDP_NO_REDIR_PORTS
[ "$tcp_no_redir_ports" == "1:65535" ] && [ "$udp_no_redir_ports" == "1:65535" ] && unset node
if has_1_65535 "$tcp_no_redir_ports" && has_1_65535 "$udp_no_redir_ports"; then
unset node
fi
[ -n "$node" ] && {
tcp_proxy_mode="global"

View File

@ -418,7 +418,7 @@ load_acl() {
[ -n "${is_tproxy}" ] && ipt_tmp=$ipt_m
[ "$tcp_no_redir_ports" != "disable" ] && {
if [ "$tcp_no_redir_ports" != "1:65535" ]; then
if ! has_1_65535 "$tcp_no_redir_ports"; then
[ "$_ipv4" != "1" ] && add_port_rules "$ip6t_m -A PSW2 $(comment "$remarks") ${_ipt_source} -p tcp" $tcp_no_redir_ports "-j RETURN" 2>/dev/null
add_port_rules "$ipt_tmp -A PSW2 $(comment "$remarks") ${_ipt_source} -p tcp" $tcp_no_redir_ports "-j RETURN"
echolog " - ${msg}不代理 TCP 端口[${tcp_no_redir_ports}]"
@ -430,7 +430,7 @@ load_acl() {
}
[ "$udp_no_redir_ports" != "disable" ] && {
if [ "$udp_no_redir_ports" != "1:65535" ]; then
if ! has_1_65535 "$udp_no_redir_ports"; then
[ "$_ipv4" != "1" ] && add_port_rules "$ip6t_m -A PSW2 $(comment "$remarks") ${_ipt_source} -p udp" $udp_no_redir_ports "-j RETURN" 2>/dev/null
add_port_rules "$ipt_m -A PSW2 $(comment "$remarks") ${_ipt_source} -p udp" $udp_no_redir_ports "-j RETURN"
echolog " - ${msg}不代理 UDP 端口[${udp_no_redir_ports}]"
@ -526,7 +526,7 @@ load_acl() {
[ "$TCP_NO_REDIR_PORTS" != "disable" ] && {
add_port_rules "$ip6t_m -A PSW2 $(comment "默认") -p tcp" $TCP_NO_REDIR_PORTS "-j RETURN"
add_port_rules "$ipt_tmp -A PSW2 $(comment "默认") -p tcp" $TCP_NO_REDIR_PORTS "-j RETURN"
if [ "$TCP_NO_REDIR_PORTS" != "1:65535" ]; then
if ! has_1_65535 "$TCP_NO_REDIR_PORTS"; then
echolog " - ${msg}不代理 TCP 端口[${TCP_NO_REDIR_PORTS}]"
else
TCP_PROXY_MODE="disable"
@ -537,7 +537,7 @@ load_acl() {
[ "$UDP_NO_REDIR_PORTS" != "disable" ] && {
add_port_rules "$ip6t_m -A PSW2 $(comment "默认") -p udp" $UDP_NO_REDIR_PORTS "-j RETURN"
add_port_rules "$ipt_tmp -A PSW2 $(comment "默认") -p udp" $UDP_NO_REDIR_PORTS "-j RETURN"
if [ "$UDP_NO_REDIR_PORTS" != "1:65535" ]; then
if ! has_1_65535 "$UDP_NO_REDIR_PORTS"; then
echolog " - ${msg}不代理 UDP 端口[${UDP_NO_REDIR_PORTS}]"
else
UDP_PROXY_MODE="disable"
@ -871,7 +871,7 @@ add_firewall_rule() {
[ "$TCP_NO_REDIR_PORTS" != "disable" ] && {
add_port_rules "$ipt_tmp -A PSW2_OUTPUT -p tcp" $TCP_NO_REDIR_PORTS "-j RETURN"
add_port_rules "$ip6t_m -A PSW2_OUTPUT -p tcp" $TCP_NO_REDIR_PORTS "-j RETURN"
if [ "$TCP_NO_REDIR_PORTS" != "1:65535" ]; then
if ! has_1_65535 "$TCP_NO_REDIR_PORTS"; then
echolog " - ${msg}不代理 TCP 端口[${TCP_NO_REDIR_PORTS}]"
else
unset TCP_LOCALHOST_PROXY
@ -882,7 +882,7 @@ add_firewall_rule() {
[ "$UDP_NO_REDIR_PORTS" != "disable" ] && {
add_port_rules "$ipt_m -A PSW2_OUTPUT -p udp" $UDP_NO_REDIR_PORTS "-j RETURN"
add_port_rules "$ip6t_m -A PSW2_OUTPUT -p udp" $UDP_NO_REDIR_PORTS "-j RETURN"
if [ "$UDP_NO_REDIR_PORTS" != "1:65535" ]; then
if ! has_1_65535 "$UDP_NO_REDIR_PORTS"; then
echolog " - ${msg}不代理 UDP 端口[${UDP_NO_REDIR_PORTS}]"
else
unset UDP_LOCALHOST_PROXY

View File

@ -432,7 +432,7 @@ load_acl() {
msg="$remarks】,${msg}"
[ "$tcp_no_redir_ports" != "disable" ] && {
if [ "$tcp_no_redir_ports" != "1:65535" ]; then
if ! has_1_65535 "$tcp_no_redir_ports"; then
nft "add rule $NFTABLE_NAME $nft_prerouting_chain ${_ipt_source} ip protocol tcp $(factor $tcp_no_redir_ports "tcp dport") counter return comment \"$remarks\""
[ "$_ipv4" != "1" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 ${_ipt_source} meta l4proto tcp $(factor $tcp_no_redir_ports "tcp dport") counter return comment \"$remarks\""
echolog " - ${msg}不代理 TCP 端口[${tcp_no_redir_ports}]"
@ -444,7 +444,7 @@ load_acl() {
}
[ "$udp_no_redir_ports" != "disable" ] && {
if [ "$udp_no_redir_ports" != "1:65535" ]; then
if ! has_1_65535 "$udp_no_redir_ports"; then
nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp ${_ipt_source} $(factor $udp_no_redir_ports "udp dport") counter return comment \"$remarks\""
[ "$_ipv4" != "1" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp ${_ipt_source} $(factor $udp_no_redir_ports "udp dport") counter return comment \"$remarks\"" 2>/dev/null
echolog " - ${msg}不代理 UDP 端口[${udp_no_redir_ports}]"
@ -544,7 +544,7 @@ load_acl() {
[ "$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 \"默认\""
nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp $(factor $TCP_NO_REDIR_PORTS "tcp dport") counter return comment \"默认\""
if [ "$TCP_NO_REDIR_PORTS" != "1:65535" ]; then
if ! has_1_65535 "$TCP_NO_REDIR_PORTS"; then
echolog " - ${msg}不代理 TCP 端口[${TCP_NO_REDIR_PORTS}]"
else
TCP_PROXY_MODE="disable"
@ -555,7 +555,7 @@ load_acl() {
[ "$UDP_NO_REDIR_PORTS" != "disable" ] && {
nft "add $NFTABLE_NAME PSW2_MANGLE ip protocol udp $(factor $UDP_NO_REDIR_PORTS "udp dport") counter return comment \"默认\""
nft "add $NFTABLE_NAME PSW2_MANGLE_V6 counter meta l4proto udp $(factor $UDP_NO_REDIR_PORTS "udp dport") counter return comment \"默认\""
if [ "$UDP_NO_REDIR_PORTS" != "1:65535" ]; then
if ! has_1_65535 "$UDP_NO_REDIR_PORTS"; then
echolog " - ${msg}不代理 UDP 端口[${UDP_NO_REDIR_PORTS}]"
else
UDP_PROXY_MODE="disable"
@ -893,7 +893,7 @@ add_firewall_rule() {
[ "$TCP_NO_REDIR_PORTS" != "disable" ] && {
nft "add rule $NFTABLE_NAME $nft_output_chain ip protocol tcp $(factor $TCP_NO_REDIR_PORTS "tcp dport") counter return"
nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto tcp $(factor $TCP_NO_REDIR_PORTS "tcp dport") counter return"
if [ "$TCP_NO_REDIR_PORTS" != "1:65535" ]; then
if ! has_1_65535 "$TCP_NO_REDIR_PORTS"; then
echolog " - ${msg}不代理 TCP 端口[${TCP_NO_REDIR_PORTS}]"
else
unset TCP_LOCALHOST_PROXY
@ -904,7 +904,7 @@ add_firewall_rule() {
[ "$UDP_NO_REDIR_PORTS" != "disable" ] && {
nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip protocol udp $(factor $UDP_NO_REDIR_PORTS "udp dport") counter return"
nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto udp $(factor $UDP_NO_REDIR_PORTS "udp dport") counter return"
if [ "$UDP_NO_REDIR_PORTS" != "1:65535" ]; then
if ! has_1_65535 "$UDP_NO_REDIR_PORTS"; then
echolog " - ${msg}不代理 UDP 端口[${UDP_NO_REDIR_PORTS}]"
else
unset UDP_LOCALHOST_PROXY

View File

@ -1042,8 +1042,8 @@ local function processData(szType, content, add_mode, add_from)
end
result.encryption = params.encryption or "none"
result.flow = params.flow or nil
result.flow = params.flow and params.flow:gsub("-udp443", "") or nil
result.alpn = params.alpn
if result.type == "sing-box" and (result.transport == "mkcp" or result.transport == "xhttp" or result.transport == "splithttp") then
log("跳过节点:" .. result.remarks .."因Sing-Box不支持" .. szType .. "协议的" .. result.transport .. "传输方式需更换Xray。")
@ -1194,7 +1194,7 @@ local function processData(szType, content, add_mode, add_from)
result.encryption = params.encryption or "none"
result.flow = params.flow or nil
result.flow = params.flow and params.flow:gsub("-udp443", "") or nil
result.tls = "0"
if params.security == "tls" or params.security == "reality" then
@ -1272,7 +1272,6 @@ local function processData(szType, content, add_mode, add_from)
else
result.address = host_port
end
result.protocol = params.protocol
result.hysteria_obfs = params.obfsParam
result.hysteria_auth_type = "string"
result.hysteria_auth_password = params.auth

View File

@ -408,6 +408,7 @@ o:depends("type", "ssr")
-- [[ Hysteria2 ]]--
o = s:option(Value, "hy2_auth", translate("Users Authentication"))
o:depends("type", "hysteria2")
o.password = true
o.rmempty = false
o = s:option(Flag, "flag_port_hopping", translate("Enable Port Hopping"))
@ -455,6 +456,7 @@ o.placeholder = "salamander"
o = s:option(Value, "salamander", translate("Obfuscation Password"))
o:depends({type = "hysteria2", flag_obfs = "1"})
o.password = true
o.rmempty = true
o.placeholder = "cry_me_a_r1ver"
@ -575,6 +577,7 @@ o.default="auto"
-- [[ TUIC ]]
-- TuicNameId
o = s:option(Value, "tuic_uuid", translate("TUIC User UUID"))
o.password = true
o.rmempty = true
o.default = uuid
o:depends("type", "tuic")
@ -588,6 +591,7 @@ o:depends("type", "tuic")
-- Tuic Password
o = s:option(Value, "tuic_passwd", translate("TUIC User Password"))
o.password = true
o.rmempty = true
o.default = ""
o:depends("type", "tuic")
@ -675,6 +679,7 @@ o:depends({type = "v2ray", v2ray_protocol = "vmess"})
-- VmessId
o = s:option(Value, "vmess_id", translate("Vmess/VLESS ID (UUID)"))
o.password = true
o.rmempty = true
o.default = uuid
o:depends({type = "v2ray", v2ray_protocol = "vmess"})
@ -792,7 +797,7 @@ o:depends("transport", "splithttp")
o.rmempty = true
-- [[ XHTTP部分 ]]--
o = s:option(ListValue, "xhttp_alpn", translate("XHTTP Alpn"))
o = s:option(ListValue, "xhttp_alpn", translate("XHTTP ALPN"))
o.default = ""
o:value("", translate("Default"))
o:value("h3")
@ -1179,10 +1184,13 @@ o:depends("xtls", true)
o:depends("reality", true)
o.rmempty = true
o = s:option(DynamicList, "tls_alpn", translate("TLS ALPN"))
o = s:option(ListValue, "tls_alpn", translate("TLS ALPN"))
o.default = ""
o:value("", translate("Default"))
o:value("h3")
o:value("spdy/3.1")
o:value("h3,spdy/3.1")
o:depends("type", "tuic")
o.default = "h3"
o.rmempty = true
-- [[ allowInsecure ]]--
o = s:option(Flag, "insecure", translate("allowInsecure"))

View File

@ -480,7 +480,7 @@ function import_ssr_url(btn, urlname, sid) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.xhttp_mode')[0].value = ssm.mode;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.xhttp_host')[0].value = ssm.host;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.xhttp_path')[0].value = ssm.path;
if (params.get("extra") && params.get("extra").trim() !== "") {
if (ssm.extra !== "" && ssm.extra !== undefined) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_xhttp_extra')[0].checked = true; // 设置 enable_xhttp_extra 为 true
document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_xhttp_extra')[0].dispatchEvent(event); // 触发事件
document.getElementsByName('cbid.shadowsocksr.' + sid + '.xhttp_extra')[0].value = ssm.extra;
@ -500,17 +500,19 @@ function import_ssr_url(btn, urlname, sid) {
if (ssm.tls == "tls") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].checked = true;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].dispatchEvent(event);
if (ssm.fq !== "" && ssm.fq !== undefined) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.fingerprint')[0].value = ssm.fp;
}
if (ssm.net == "xhttp") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.xhttp_alpn')[0].value = ssm.alpn;
}
document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls_host')[0].value = ssm.sni || ssm.host;
}
if (ssm.tls == "tls") {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_ech')[0].checked = true;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_ech')[0].dispatchEvent(event);
if (ssm.ech !== "" && ssm.ech !== undefined) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_ech')[0].checked = true; // 设置 enable_ech 为 true
document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_ech')[0].dispatchEvent(event); // 触发事件
document.getElementsByName('cbid.shadowsocksr.' + sid + '.ech_config')[0].value = ssm.ech;
}
}
if (ssm.mux !== undefined) {
document.getElementsByName('cbid.shadowsocksr.' + sid + '.mux')[0].checked = true;
document.getElementsByName('cbid.shadowsocksr.' + sid + '.mux')[0].dispatchEvent(event);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -212,7 +212,19 @@ end
security = (server.xtls == '1') and "xtls" or (server.tls == '1') and "tls" or (server.reality == '1') and "reality" or nil,
tlsSettings = (server.tls == '1') and {
-- tls
alpn = (server.transport == "xhttp" and server.xhttp_alpn ~= "") and server.xhttp_alpn or server.tls_alpn,
alpn = (server.transport == "xhttp") and (function()
local alpn = {}
if server.xhttp_alpn and server.xhttp_alpn ~= "" then
string.gsub(server.xhttp_alpn, '[^,]+', function(w)
table.insert(alpn, w)
end)
end
if #alpn > 0 then
return alpn
else
return nil
end
end)() or nil,
fingerprint = server.fingerprint,
allowInsecure = (server.insecure == "1"),
serverName = server.tls_host,
@ -580,7 +592,19 @@ local tuic = {
timeout = server.timeout and server.timeout .. "s" or nil,
gc_interval = server.gc_interval and server.gc_interval .. "s" or nil,
gc_lifetime = server.gc_lifetime and server.gc_lifetime .. "s" or nil,
alpn = server.tls_alpn,
alpn = (server.type == "tuic") and (function()
local alpn = {}
if server.tls_alpn and server.tls_alpn ~= "" then
string.gsub(server.tls_alpn, '[^,]+', function(w)
table.insert(alpn, w)
end)
end
if #alpn > 0 then
return alpn
else
return nil
end
end)() or nil,
disable_sni = (server.disable_sni == "1") and true or false,
zero_rtt_handshake = (server.zero_rtt_handshake == "1") and true or false,
send_window = tonumber(server.send_window),

View File

@ -3,5 +3,3 @@
/etc/nikki/mixin.yaml
/etc/nikki/run/providers/rule/
/etc/nikki/run/providers/proxy/
/etc/nikki/nftables/reserved_ip.nft
/etc/nikki/nftables/reserved_ip6.nft

View File

@ -70,8 +70,8 @@
push(lan_access_control, access_control);
});
const reserved_ip = uci_array(uci.get('momo', 'proxy', 'reserved_ip'));
const reserved_ip6 = uci_array(uci.get('momo', 'proxy', 'reserved_ip6'));
const reserved_ip = uci_array(uci.get('nikki', 'proxy', 'reserved_ip'));
const reserved_ip6 = uci_array(uci.get('nikki', 'proxy', 'reserved_ip6'));
const bypass_dscp = uci_array(uci.get('nikki', 'proxy', 'bypass_dscp'));
const bypass_china_mainland_ip = uci_bool(uci.get('nikki', 'proxy', 'bypass_china_mainland_ip'));
const proxy_tcp_dport = split((uci.get('nikki', 'proxy', 'proxy_tcp_dport') ?? '0-65535'), ' ');