update 2024-01-22 16:23:52
This commit is contained in:
parent
126c9f4f45
commit
92e187d53a
|
@ -17,12 +17,10 @@ PKG_NAME:=luci-app-homeproxy
|
||||||
define Package/luci-app-homeproxy/conffiles
|
define Package/luci-app-homeproxy/conffiles
|
||||||
/etc/config/homeproxy
|
/etc/config/homeproxy
|
||||||
/etc/homeproxy/certs/
|
/etc/homeproxy/certs/
|
||||||
/etc/homeproxy/resources/geoip.db
|
/etc/homeproxy/ruleset/
|
||||||
/etc/homeproxy/resources/geoip.ver
|
|
||||||
/etc/homeproxy/resources/geosite.db
|
|
||||||
/etc/homeproxy/resources/geosite.ver
|
|
||||||
/etc/homeproxy/resources/direct_list.txt
|
/etc/homeproxy/resources/direct_list.txt
|
||||||
/etc/homeproxy/resources/proxy_list.txt
|
/etc/homeproxy/resources/proxy_list.txt
|
||||||
|
/etc/homeproxy/cache.db
|
||||||
endef
|
endef
|
||||||
|
|
||||||
include $(TOPDIR)/feeds/luci/luci.mk
|
include $(TOPDIR)/feeds/luci/luci.mk
|
||||||
|
|
|
@ -287,8 +287,6 @@ return view.extend({
|
||||||
desc.innerHTML = _('Mixed <code>system</code> TCP stack and <code>gVisor</code> UDP stack.')
|
desc.innerHTML = _('Mixed <code>system</code> TCP stack and <code>gVisor</code> UDP stack.')
|
||||||
else if (value === 'gvisor')
|
else if (value === 'gvisor')
|
||||||
desc.innerHTML = _('Based on google/gvisor.');
|
desc.innerHTML = _('Based on google/gvisor.');
|
||||||
else if (value === 'lwip')
|
|
||||||
desc.innerHTML = _('Upstream archived. Not recommended.');
|
|
||||||
else if (value === 'system')
|
else if (value === 'system')
|
||||||
desc.innerHTML = _('Less compatibility and sometimes better performance.');
|
desc.innerHTML = _('Less compatibility and sometimes better performance.');
|
||||||
}
|
}
|
||||||
|
@ -430,9 +428,9 @@ return view.extend({
|
||||||
|
|
||||||
so = ss.option(form.ListValue, 'mode', _('Mode'),
|
so = ss.option(form.ListValue, 'mode', _('Mode'),
|
||||||
_('The default rule uses the following matching logic:<br/>' +
|
_('The default rule uses the following matching logic:<br/>' +
|
||||||
'<code>(domain || domain_suffix || domain_keyword || domain_regex || geosite || geoip || ip_cidr)</code> &&<br/>' +
|
'<code>(domain || domain_suffix || domain_keyword || domain_regex || ip_cidr || ip_is_private)</code> &&<br/>' +
|
||||||
'<code>(port || port_range)</code> &&<br/>' +
|
'<code>(port || port_range)</code> &&<br/>' +
|
||||||
'<code>(source_geoip || source_ip_cidr)</code> &&<br/>' +
|
'<code>(source_ip_cidr || source_ip_is_private)</code> &&<br/>' +
|
||||||
'<code>(source_port || source_port_range)</code> &&<br/>' +
|
'<code>(source_port || source_port_range)</code> &&<br/>' +
|
||||||
'<code>other fields</code>.'));
|
'<code>other fields</code>.'));
|
||||||
so.value('default', _('Default'));
|
so.value('default', _('Default'));
|
||||||
|
@ -476,28 +474,28 @@ return view.extend({
|
||||||
_('Match domain using regular expression.'));
|
_('Match domain using regular expression.'));
|
||||||
so.modalonly = true;
|
so.modalonly = true;
|
||||||
|
|
||||||
so = ss.option(form.DynamicList, 'geosite', _('Geosite'),
|
|
||||||
_('Match geosite.'));
|
|
||||||
so.modalonly = true;
|
|
||||||
|
|
||||||
so = ss.option(form.DynamicList, 'source_geoip', _('Source GeoIP'),
|
|
||||||
_('Match source GeoIP.'));
|
|
||||||
so.modalonly = true;
|
|
||||||
|
|
||||||
so = ss.option(form.DynamicList, 'geoip', _('GeoIP'),
|
|
||||||
_('Match GeoIP.'));
|
|
||||||
so.modalonly = true;
|
|
||||||
|
|
||||||
so = ss.option(form.DynamicList, 'source_ip_cidr', _('Source IP CIDR'),
|
so = ss.option(form.DynamicList, 'source_ip_cidr', _('Source IP CIDR'),
|
||||||
_('Match source IP CIDR.'));
|
_('Match source IP CIDR.'));
|
||||||
so.datatype = 'or(cidr, ipaddr)';
|
so.datatype = 'or(cidr, ipaddr)';
|
||||||
so.modalonly = true;
|
so.modalonly = true;
|
||||||
|
|
||||||
|
so = ss.option(form.Flag, 'source_ip_is_private', _('Private source IP'),
|
||||||
|
_('Match private source IP.'));
|
||||||
|
so.default = so.disabled;
|
||||||
|
so.rmempty = false;
|
||||||
|
so.modalonly = true;
|
||||||
|
|
||||||
so = ss.option(form.DynamicList, 'ip_cidr', _('IP CIDR'),
|
so = ss.option(form.DynamicList, 'ip_cidr', _('IP CIDR'),
|
||||||
_('Match IP CIDR.'));
|
_('Match IP CIDR.'));
|
||||||
so.datatype = 'or(cidr, ipaddr)';
|
so.datatype = 'or(cidr, ipaddr)';
|
||||||
so.modalonly = true;
|
so.modalonly = true;
|
||||||
|
|
||||||
|
so = ss.option(form.Flag, 'ip_is_private', _('Private IP'),
|
||||||
|
_('Match private IP.'));
|
||||||
|
so.default = so.disabled;
|
||||||
|
so.rmempty = false;
|
||||||
|
so.modalonly = true;
|
||||||
|
|
||||||
so = ss.option(form.DynamicList, 'source_port', _('Source port'),
|
so = ss.option(form.DynamicList, 'source_port', _('Source port'),
|
||||||
_('Match source port.'));
|
_('Match source port.'));
|
||||||
so.datatype = 'port';
|
so.datatype = 'port';
|
||||||
|
@ -530,6 +528,28 @@ return view.extend({
|
||||||
_('Match user name.'));
|
_('Match user name.'));
|
||||||
so.modalonly = true;
|
so.modalonly = true;
|
||||||
|
|
||||||
|
so = ss.option(form.MultiValue, 'rule_set', _('Rule set'),
|
||||||
|
_('Match rule set.'));
|
||||||
|
so.load = function(section_id) {
|
||||||
|
delete this.keylist;
|
||||||
|
delete this.vallist;
|
||||||
|
|
||||||
|
this.value('', _('-- Please choose --'));
|
||||||
|
uci.sections(data[0], 'ruleset', (res) => {
|
||||||
|
if (res.enabled === '1')
|
||||||
|
this.value(res['.name'], res.label);
|
||||||
|
});
|
||||||
|
|
||||||
|
return this.super('load', section_id);
|
||||||
|
}
|
||||||
|
so.modalonly = true;
|
||||||
|
|
||||||
|
so = ss.option(form.Flag, 'rule_set_ipcidr_match_source', _('Match source IP via rule set'),
|
||||||
|
_('Make IP CIDR in rule set used to match the source IP.'));
|
||||||
|
so.default = so.disabled;
|
||||||
|
so.rmempty = false;
|
||||||
|
so.modalonly = true;
|
||||||
|
|
||||||
so = ss.option(form.Flag, 'invert', _('Invert'),
|
so = ss.option(form.Flag, 'invert', _('Invert'),
|
||||||
_('Invert match result.'));
|
_('Invert match result.'));
|
||||||
so.default = so.disabled;
|
so.default = so.disabled;
|
||||||
|
@ -712,9 +732,9 @@ return view.extend({
|
||||||
|
|
||||||
so = ss.option(form.ListValue, 'mode', _('Mode'),
|
so = ss.option(form.ListValue, 'mode', _('Mode'),
|
||||||
_('The default rule uses the following matching logic:<br/>' +
|
_('The default rule uses the following matching logic:<br/>' +
|
||||||
'<code>(domain || domain_suffix || domain_keyword || domain_regex || geosite)</code> &&<br/>' +
|
'<code>(domain || domain_suffix || domain_keyword || domain_regex)</code> &&<br/>' +
|
||||||
'<code>(port || port_range)</code> &&<br/>' +
|
'<code>(port || port_range)</code> &&<br/>' +
|
||||||
'<code>(source_geoip || source_ip_cidr)</code> &&<br/>' +
|
'<code>(source_ip_cidr || source_ip_is_private)</code> &&<br/>' +
|
||||||
'<code>(source_port || source_port_range)</code> &&<br/>' +
|
'<code>(source_port || source_port_range)</code> &&<br/>' +
|
||||||
'<code>other fields</code>.'));
|
'<code>other fields</code>.'));
|
||||||
so.value('default', _('Default'));
|
so.value('default', _('Default'));
|
||||||
|
@ -762,10 +782,6 @@ return view.extend({
|
||||||
_('Match domain using regular expression.'));
|
_('Match domain using regular expression.'));
|
||||||
so.modalonly = true;
|
so.modalonly = true;
|
||||||
|
|
||||||
so = ss.option(form.DynamicList, 'geosite', _('Geosite'),
|
|
||||||
_('Match geosite.'));
|
|
||||||
so.modalonly = true;
|
|
||||||
|
|
||||||
so = ss.option(form.DynamicList, 'port', _('Port'),
|
so = ss.option(form.DynamicList, 'port', _('Port'),
|
||||||
_('Match port.'));
|
_('Match port.'));
|
||||||
so.datatype = 'port';
|
so.datatype = 'port';
|
||||||
|
@ -776,15 +792,17 @@ return view.extend({
|
||||||
so.validate = validatePortRange;
|
so.validate = validatePortRange;
|
||||||
so.modalonly = true;
|
so.modalonly = true;
|
||||||
|
|
||||||
so = ss.option(form.DynamicList, 'source_geoip', _('Source GeoIP'),
|
|
||||||
_('Match source GeoIP.'));
|
|
||||||
so.modalonly = true;
|
|
||||||
|
|
||||||
so = ss.option(form.DynamicList, 'source_ip_cidr', _('Source IP CIDR'),
|
so = ss.option(form.DynamicList, 'source_ip_cidr', _('Source IP CIDR'),
|
||||||
_('Match source IP CIDR.'));
|
_('Match source IP CIDR.'));
|
||||||
so.datatype = 'or(cidr, ipaddr)';
|
so.datatype = 'or(cidr, ipaddr)';
|
||||||
so.modalonly = true;
|
so.modalonly = true;
|
||||||
|
|
||||||
|
so = ss.option(form.Flag, 'source_ip_is_private', _('Private source IP'),
|
||||||
|
_('Match private source IP.'));
|
||||||
|
so.default = so.disabled;
|
||||||
|
so.rmempty = false;
|
||||||
|
so.modalonly = true;
|
||||||
|
|
||||||
so = ss.option(form.DynamicList, 'source_port', _('Source port'),
|
so = ss.option(form.DynamicList, 'source_port', _('Source port'),
|
||||||
_('Match source port.'));
|
_('Match source port.'));
|
||||||
so.datatype = 'port';
|
so.datatype = 'port';
|
||||||
|
@ -807,6 +825,22 @@ return view.extend({
|
||||||
_('Match user name.'));
|
_('Match user name.'));
|
||||||
so.modalonly = true;
|
so.modalonly = true;
|
||||||
|
|
||||||
|
so = ss.option(form.MultiValue, 'rule_set', _('Rule set'),
|
||||||
|
_('Match rule set.'));
|
||||||
|
so.load = function(section_id) {
|
||||||
|
delete this.keylist;
|
||||||
|
delete this.vallist;
|
||||||
|
|
||||||
|
this.value('', _('-- Please choose --'));
|
||||||
|
uci.sections(data[0], 'ruleset', (res) => {
|
||||||
|
if (res.enabled === '1')
|
||||||
|
this.value(res['.name'], res.label);
|
||||||
|
});
|
||||||
|
|
||||||
|
return this.super('load', section_id);
|
||||||
|
}
|
||||||
|
so.modalonly = true;
|
||||||
|
|
||||||
so = ss.option(form.Flag, 'invert', _('Invert'),
|
so = ss.option(form.Flag, 'invert', _('Invert'),
|
||||||
_('Invert match result.'));
|
_('Invert match result.'));
|
||||||
so.default = so.disabled;
|
so.default = so.disabled;
|
||||||
|
@ -861,6 +895,94 @@ return view.extend({
|
||||||
/* DNS rules end */
|
/* DNS rules end */
|
||||||
/* Custom routing settings end */
|
/* Custom routing settings end */
|
||||||
|
|
||||||
|
/* Rule set settings start */
|
||||||
|
s.tab('ruleset', _('Rule set'));
|
||||||
|
o = s.taboption('ruleset', form.SectionValue, '_ruleset', form.GridSection, 'ruleset');
|
||||||
|
o.depends('routing_mode', 'custom');
|
||||||
|
|
||||||
|
ss = o.subsection;
|
||||||
|
ss.addremove = true;
|
||||||
|
ss.rowcolors = true;
|
||||||
|
ss.sortable = true;
|
||||||
|
ss.nodescriptions = true;
|
||||||
|
ss.modaltitle = L.bind(hp.loadModalTitle, this, _('Rule set'), _('Add a rule set'), data[0]);
|
||||||
|
ss.sectiontitle = L.bind(hp.loadDefaultLabel, this, data[0]);
|
||||||
|
ss.renderSectionAdd = L.bind(hp.renderSectionAdd, this, ss);
|
||||||
|
|
||||||
|
so = ss.option(form.Value, 'label', _('Label'));
|
||||||
|
so.load = L.bind(hp.loadDefaultLabel, this, data[0]);
|
||||||
|
so.validate = L.bind(hp.validateUniqueValue, this, data[0], 'ruleset', 'label');
|
||||||
|
so.modalonly = true;
|
||||||
|
|
||||||
|
so = ss.option(form.Flag, 'enabled', _('Enable'));
|
||||||
|
so.default = o.enabled;
|
||||||
|
so.rmempty = false;
|
||||||
|
so.editable = true;
|
||||||
|
|
||||||
|
so = ss.option(form.ListValue, 'type', _('Type'));
|
||||||
|
so.value('local', _('Local'));
|
||||||
|
so.value('remote', _('Remote'));
|
||||||
|
so.default = 'remote';
|
||||||
|
so.rmempty = false;
|
||||||
|
|
||||||
|
so = ss.option(form.ListValue, 'format', _('Format'));
|
||||||
|
so.value('source', _('Source file'));
|
||||||
|
so.value('binary', _('Binary file'));
|
||||||
|
so.default = 'source';
|
||||||
|
so.rmempty = false;
|
||||||
|
|
||||||
|
so = ss.option(form.Value, 'path', _('Path'));
|
||||||
|
so.datatype = 'file';
|
||||||
|
so.placeholder = '/etc/homeproxy/ruleset/example.json';
|
||||||
|
so.rmempty = false;
|
||||||
|
so.depends('type', 'local');
|
||||||
|
so.modalonly = true;
|
||||||
|
|
||||||
|
so = ss.option(form.Value, 'url', _('Rule set URL'));
|
||||||
|
so.validate = function(section_id, value) {
|
||||||
|
if (section_id) {
|
||||||
|
if (!value)
|
||||||
|
return _('Expecting: %s').format(_('non-empty value'));
|
||||||
|
|
||||||
|
try {
|
||||||
|
var url = new URL(value);
|
||||||
|
if (!url.hostname)
|
||||||
|
return _('Expecting: %s').format(_('valid URL'));
|
||||||
|
}
|
||||||
|
catch(e) {
|
||||||
|
return _('Expecting: %s').format(_('valid URL'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
so.rmempty = false;
|
||||||
|
so.depends('type', 'remote');
|
||||||
|
so.modalonly = true;
|
||||||
|
|
||||||
|
so = ss.option(form.ListValue, 'outbound', _('Outbound'),
|
||||||
|
_('Tag of the outbound to download rule set.'));
|
||||||
|
so.load = function(section_id) {
|
||||||
|
delete this.keylist;
|
||||||
|
delete this.vallist;
|
||||||
|
|
||||||
|
this.value('direct-out', _('Direct'));
|
||||||
|
uci.sections(data[0], 'routing_node', (res) => {
|
||||||
|
if (res.enabled === '1')
|
||||||
|
this.value(res['.name'], res.label);
|
||||||
|
});
|
||||||
|
|
||||||
|
return this.super('load', section_id);
|
||||||
|
}
|
||||||
|
so.default = 'direct-out';
|
||||||
|
so.rmempty = false;
|
||||||
|
so.depends('type', 'remote');
|
||||||
|
|
||||||
|
so = ss.option(form.Value, 'update_interval', _('Update interval'),
|
||||||
|
_('Update interval of rule set.<br/><code>1d</code> will be used if empty.'));
|
||||||
|
so.depends('type', 'remote');
|
||||||
|
/* Rule set settings end */
|
||||||
|
|
||||||
/* ACL settings start */
|
/* ACL settings start */
|
||||||
s.tab('control', _('Access Control'));
|
s.tab('control', _('Access Control'));
|
||||||
|
|
||||||
|
|
|
@ -1252,7 +1252,7 @@ return view.extend({
|
||||||
s.tab('subscription', _('Subscriptions'));
|
s.tab('subscription', _('Subscriptions'));
|
||||||
|
|
||||||
o = s.taboption('subscription', form.Flag, 'auto_update', _('Auto update'),
|
o = s.taboption('subscription', form.Flag, 'auto_update', _('Auto update'),
|
||||||
_('Auto update subscriptions, GeoIP and GeoSite.'));
|
_('Auto update subscriptions.'));
|
||||||
o.default = o.disabled;
|
o.default = o.disabled;
|
||||||
o.rmempty = false;
|
o.rmempty = false;
|
||||||
|
|
||||||
|
|
|
@ -200,16 +200,6 @@ return view.extend({
|
||||||
s = m.section(form.NamedSection, 'config', 'homeproxy', _('Resources management'));
|
s = m.section(form.NamedSection, 'config', 'homeproxy', _('Resources management'));
|
||||||
s.anonymous = true;
|
s.anonymous = true;
|
||||||
|
|
||||||
if (routing_mode === 'custom') {
|
|
||||||
o = s.option(form.DummyValue, '_geoip_version', _('GeoIP version'));
|
|
||||||
o.cfgvalue = function() { return getResVersion(this, 'geoip') };
|
|
||||||
o.rawhtml = true;
|
|
||||||
|
|
||||||
o = s.option(form.DummyValue, '_geosite_version', _('GeoSite version'));
|
|
||||||
o.cfgvalue = function() { return getResVersion(this, 'geosite') };
|
|
||||||
o.rawhtml = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
o = s.option(form.DummyValue, '_china_ip4_version', _('China IPv4 list version'));
|
o = s.option(form.DummyValue, '_china_ip4_version', _('China IPv4 list version'));
|
||||||
o.cfgvalue = function() { return getResVersion(this, 'china_ip4') };
|
o.cfgvalue = function() { return getResVersion(this, 'china_ip4') };
|
||||||
o.rawhtml = true;
|
o.rawhtml = true;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -25,6 +25,7 @@ uci.load(uciconfig);
|
||||||
|
|
||||||
const uciinfra = 'infra',
|
const uciinfra = 'infra',
|
||||||
ucimain = 'config',
|
ucimain = 'config',
|
||||||
|
uciexp = 'experimental',
|
||||||
ucicontrol = 'control';
|
ucicontrol = 'control';
|
||||||
|
|
||||||
const ucidnssetting = 'dns',
|
const ucidnssetting = 'dns',
|
||||||
|
@ -36,6 +37,7 @@ const uciroutingsetting = 'routing',
|
||||||
uciroutingrule = 'routing_rule';
|
uciroutingrule = 'routing_rule';
|
||||||
|
|
||||||
const ucinode = 'node';
|
const ucinode = 'node';
|
||||||
|
const uciruleset = 'ruleset';
|
||||||
|
|
||||||
const routing_mode = uci.get(uciconfig, ucimain, 'routing_mode') || 'bypass_mainland_china';
|
const routing_mode = uci.get(uciconfig, ucimain, 'routing_mode') || 'bypass_mainland_china';
|
||||||
|
|
||||||
|
@ -207,8 +209,8 @@ function generate_outbound(node) {
|
||||||
padding: (node.multiplex_padding === '1'),
|
padding: (node.multiplex_padding === '1'),
|
||||||
brutal: (node.multiplex_brutal === '1') ? {
|
brutal: (node.multiplex_brutal === '1') ? {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
up_mbps: node.multiplex_brutal_up,
|
up_mbps: strToInt(node.multiplex_brutal_up),
|
||||||
down_mbps: node.multiplex_brutal_down
|
down_mbps: strToInt(node.multiplex_brutal_down)
|
||||||
} : null
|
} : null
|
||||||
} : null,
|
} : null,
|
||||||
tls: (node.tls === '1') ? {
|
tls: (node.tls === '1') ? {
|
||||||
|
@ -297,6 +299,16 @@ function get_resolver(cfg) {
|
||||||
else
|
else
|
||||||
return 'cfg-' + cfg + '-dns';
|
return 'cfg-' + cfg + '-dns';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function get_ruleset(cfg) {
|
||||||
|
if (isEmpty(cfg))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
let rules = [];
|
||||||
|
for (let i in cfg)
|
||||||
|
push(rules, isEmpty(i) ? null : 'cfg-' + i + '-rule');
|
||||||
|
return rules;
|
||||||
|
}
|
||||||
/* Config helper end */
|
/* Config helper end */
|
||||||
|
|
||||||
const config = {};
|
const config = {};
|
||||||
|
@ -407,16 +419,16 @@ if (!isEmpty(main_node)) {
|
||||||
domain_suffix: cfg.domain_suffix,
|
domain_suffix: cfg.domain_suffix,
|
||||||
domain_keyword: cfg.domain_keyword,
|
domain_keyword: cfg.domain_keyword,
|
||||||
domain_regex: cfg.domain_regex,
|
domain_regex: cfg.domain_regex,
|
||||||
geosite: cfg.geosite,
|
|
||||||
port: parse_port(cfg.port),
|
port: parse_port(cfg.port),
|
||||||
port_range: cfg.port_range,
|
port_range: cfg.port_range,
|
||||||
source_geoip: cfg.source_geoip,
|
|
||||||
source_ip_cidr: cfg.source_ip_cidr,
|
source_ip_cidr: cfg.source_ip_cidr,
|
||||||
|
source_ip_is_private: (cfg.source_ip_is_private === '1') || null,
|
||||||
source_port: parse_port(cfg.source_port),
|
source_port: parse_port(cfg.source_port),
|
||||||
source_port_range: cfg.source_port_range,
|
source_port_range: cfg.source_port_range,
|
||||||
process_name: cfg.process_name,
|
process_name: cfg.process_name,
|
||||||
process_path: cfg.process_path,
|
process_path: cfg.process_path,
|
||||||
user: cfg.user,
|
user: cfg.user,
|
||||||
|
rule_set: get_ruleset(cfg.rule_set),
|
||||||
invert: (cfg.invert === '1') || null,
|
invert: (cfg.invert === '1') || null,
|
||||||
outbound: get_outbound(cfg.outbound),
|
outbound: get_outbound(cfg.outbound),
|
||||||
server: get_resolver(cfg.server),
|
server: get_resolver(cfg.server),
|
||||||
|
@ -536,16 +548,6 @@ if (!isEmpty(main_node)) {
|
||||||
/* Routing rules start */
|
/* Routing rules start */
|
||||||
/* Default settings */
|
/* Default settings */
|
||||||
config.route = {
|
config.route = {
|
||||||
geoip: !isEmpty(default_outbound) ? {
|
|
||||||
path: HP_DIR + '/resources/geoip.db',
|
|
||||||
download_url: 'https://github.com/1715173329/sing-geoip/releases/latest/download/geoip.db',
|
|
||||||
download_detour: get_outbound(default_outbound)
|
|
||||||
} : null,
|
|
||||||
geosite: !isEmpty(default_outbound) ? {
|
|
||||||
path: HP_DIR + '/resources/geosite.db',
|
|
||||||
download_url: 'https://github.com/1715173329/sing-geosite/releases/latest/download/geosite.db',
|
|
||||||
download_detour: get_outbound(default_outbound)
|
|
||||||
} : null,
|
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
inbound: 'dns-in',
|
inbound: 'dns-in',
|
||||||
|
@ -556,6 +558,7 @@ config.route = {
|
||||||
outbound: 'dns-out'
|
outbound: 'dns-out'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
rule_set: [],
|
||||||
auto_detect_interface: isEmpty(default_interface) ? true : null,
|
auto_detect_interface: isEmpty(default_interface) ? true : null,
|
||||||
default_interface: default_interface
|
default_interface: default_interface
|
||||||
};
|
};
|
||||||
|
@ -590,11 +593,10 @@ if (!isEmpty(main_node)) {
|
||||||
domain_suffix: cfg.domain_suffix,
|
domain_suffix: cfg.domain_suffix,
|
||||||
domain_keyword: cfg.domain_keyword,
|
domain_keyword: cfg.domain_keyword,
|
||||||
domain_regex: cfg.domain_regex,
|
domain_regex: cfg.domain_regex,
|
||||||
geosite: cfg.geosite,
|
|
||||||
source_geoip: cfg.source_geoip,
|
|
||||||
geoip: cfg.geoip,
|
|
||||||
source_ip_cidr: cfg.source_ip_cidr,
|
source_ip_cidr: cfg.source_ip_cidr,
|
||||||
|
source_ip_is_private: (cfg.source_ip_is_private === '1') || null,
|
||||||
ip_cidr: cfg.ip_cidr,
|
ip_cidr: cfg.ip_cidr,
|
||||||
|
ip_is_private: (cfg.ip_is_private === '1') || null,
|
||||||
source_port: parse_port(cfg.source_port),
|
source_port: parse_port(cfg.source_port),
|
||||||
source_port_range: cfg.source_port_range,
|
source_port_range: cfg.source_port_range,
|
||||||
port: parse_port(cfg.port),
|
port: parse_port(cfg.port),
|
||||||
|
@ -602,14 +604,45 @@ if (!isEmpty(main_node)) {
|
||||||
process_name: cfg.process_name,
|
process_name: cfg.process_name,
|
||||||
process_path: cfg.process_path,
|
process_path: cfg.process_path,
|
||||||
user: cfg.user,
|
user: cfg.user,
|
||||||
|
rule_set: get_ruleset(cfg.rule_set),
|
||||||
|
rule_set_ipcidr_match_source: (cfg.rule_set_ipcidr_match_source === '1') || null,
|
||||||
invert: (cfg.invert === '1') || null,
|
invert: (cfg.invert === '1') || null,
|
||||||
outbound: get_outbound(cfg.outbound)
|
outbound: get_outbound(cfg.outbound)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
config.route.final = get_outbound(default_outbound);
|
config.route.final = get_outbound(default_outbound);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Rule set */
|
||||||
|
if (routing_mode === 'custom') {
|
||||||
|
uci.foreach(uciconfig, uciruleset, (cfg) => {
|
||||||
|
if (cfg.enabled !== '1')
|
||||||
|
return null;
|
||||||
|
|
||||||
|
push(config.route.rule_set, {
|
||||||
|
type: cfg.type,
|
||||||
|
tag: 'cfg-' + cfg['.name'] + '-rule',
|
||||||
|
format: cfg.format,
|
||||||
|
path: cfg.path,
|
||||||
|
url: cfg.url,
|
||||||
|
download_detour: get_outbound(cfg.outbound),
|
||||||
|
update_interval: cfg.update_interval
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
/* Routing rules end */
|
/* Routing rules end */
|
||||||
|
|
||||||
|
/* Experimental start */
|
||||||
|
if (routing_mode === 'custom') {
|
||||||
|
config.experimental = {
|
||||||
|
cache_file: {
|
||||||
|
enabled: true,
|
||||||
|
path: HP_DIR + '/cache.db'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/* Experimental end */
|
||||||
|
|
||||||
system('mkdir -p ' + RUN_DIR);
|
system('mkdir -p ' + RUN_DIR);
|
||||||
writefile(RUN_DIR + '/sing-box-c.json', sprintf('%.J\n', removeBlankAttrs(config)));
|
writefile(RUN_DIR + '/sing-box-c.json', sprintf('%.J\n', removeBlankAttrs(config)));
|
||||||
|
|
|
@ -103,8 +103,8 @@ uci.foreach(uciconfig, uciserver, (cfg) => {
|
||||||
padding: (cfg.multiplex_padding === '1'),
|
padding: (cfg.multiplex_padding === '1'),
|
||||||
brutal: (cfg.multiplex_brutal === '1') ? {
|
brutal: (cfg.multiplex_brutal === '1') ? {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
up_mbps: cfg.multiplex_brutal_up,
|
up_mbps: strToInt(cfg.multiplex_brutal_up),
|
||||||
down_mbps: cfg.multiplex_brutal_down
|
down_mbps: strToInt(cfg.multiplex_brutal_down)
|
||||||
} : null
|
} : null
|
||||||
} : null,
|
} : null,
|
||||||
|
|
||||||
|
|
|
@ -9,10 +9,4 @@ for i in "china_ip4" "china_ip6" "gfw_list" "china_list"; do
|
||||||
"$SCRIPTS_DIR"/update_resources.sh "$i"
|
"$SCRIPTS_DIR"/update_resources.sh "$i"
|
||||||
done
|
done
|
||||||
|
|
||||||
if [ "$(uci -q get homeproxy.config.routing_mode)" = "custom" ]; then
|
|
||||||
for i in "geoip" "geosite"; do
|
|
||||||
"$SCRIPTS_DIR"/update_resources.sh "$i"
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
"$SCRIPTS_DIR"/update_subscriptions.uc
|
"$SCRIPTS_DIR"/update_subscriptions.uc
|
||||||
|
|
|
@ -37,51 +37,6 @@ to_upper() {
|
||||||
echo -e "$1" | tr "[a-z]" "[A-Z]"
|
echo -e "$1" | tr "[a-z]" "[A-Z]"
|
||||||
}
|
}
|
||||||
|
|
||||||
check_geodata_update() {
|
|
||||||
local geotype="$1"
|
|
||||||
local georepo="$2"
|
|
||||||
local wget="wget --timeout=10 -q"
|
|
||||||
|
|
||||||
set_lock "set" "$geotype"
|
|
||||||
|
|
||||||
local geodata_ver="$($wget -O- "https://api.github.com/repos/$georepo/releases/latest" | jsonfilter -e "@.tag_name")"
|
|
||||||
if [ -z "$geodata_ver" ]; then
|
|
||||||
log "[$(to_upper "$geotype")] Failed to get the latest version, please retry later."
|
|
||||||
|
|
||||||
set_lock "remove" "$geotype"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
local local_geodata_ver="$(cat "$RESOURCES_DIR/$geotype.ver" 2>"/dev/null" || echo "NOT FOUND")"
|
|
||||||
if [ "$local_geodata_ver" = "$geodata_ver" ]; then
|
|
||||||
log "[$(to_upper "$geotype")] Current version: $geodata_ver."
|
|
||||||
log "[$(to_upper "$geotype")] You're already at the latest version."
|
|
||||||
|
|
||||||
set_lock "remove" "$geotype"
|
|
||||||
return 3
|
|
||||||
else
|
|
||||||
log "[$(to_upper "$geotype")] Local version: $local_geodata_ver, latest version: $geodata_ver."
|
|
||||||
fi
|
|
||||||
|
|
||||||
local geodata_hash
|
|
||||||
$wget "https://github.com/$georepo/releases/download/$geodata_ver/$geotype.db" -O "$RUN_DIR/$geotype.db"
|
|
||||||
geodata_hash="$($wget -O- "https://github.com/$georepo/releases/download/$geodata_ver/$geotype.db.sha256sum" | awk '{print $1}')"
|
|
||||||
if ! echo -e "$geodata_hash $RUN_DIR/$geotype.db" | sha256sum -s -c -; then
|
|
||||||
rm -f "$RUN_DIR/$geotype.db"
|
|
||||||
log "[$(to_upper "$geotype")] Update failed."
|
|
||||||
|
|
||||||
set_lock "remove" "$geotype"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
mv -f "$RUN_DIR/$geotype.db" "$RESOURCES_DIR/$geotype.db"
|
|
||||||
echo -e "$geodata_ver" > "$RESOURCES_DIR/$geotype.ver"
|
|
||||||
log "[$(to_upper "$geotype")] Successfully updated."
|
|
||||||
|
|
||||||
set_lock "remove" "$geotype"
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
check_list_update() {
|
check_list_update() {
|
||||||
local listtype="$1"
|
local listtype="$1"
|
||||||
local listrepo="$2"
|
local listrepo="$2"
|
||||||
|
@ -130,12 +85,6 @@ check_list_update() {
|
||||||
}
|
}
|
||||||
|
|
||||||
case "$1" in
|
case "$1" in
|
||||||
"geoip")
|
|
||||||
check_geodata_update "$1" "1715173329/sing-geoip"
|
|
||||||
;;
|
|
||||||
"geosite")
|
|
||||||
check_geodata_update "$1" "1715173329/sing-geosite"
|
|
||||||
;;
|
|
||||||
"china_ip4")
|
"china_ip4")
|
||||||
check_list_update "$1" "1715173329/IPCIDR-CHINA" "master" "ipv4.txt"
|
check_list_update "$1" "1715173329/IPCIDR-CHINA" "master" "ipv4.txt"
|
||||||
;;
|
;;
|
||||||
|
@ -149,7 +98,7 @@ case "$1" in
|
||||||
check_list_update "$1" "Loyalsoldier/v2ray-rules-dat" "release" "direct-list.txt"
|
check_list_update "$1" "Loyalsoldier/v2ray-rules-dat" "release" "direct-list.txt"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo -e "Usage: $0 <geoip / geosite / china_ip4 / china_ip6 / gfw_list / china_list>"
|
echo -e "Usage: $0 <china_ip4 / china_ip6 / gfw_list / china_list>"
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
|
@ -258,6 +258,11 @@ start_service() {
|
||||||
procd_set_param respawn
|
procd_set_param respawn
|
||||||
procd_close_instance
|
procd_close_instance
|
||||||
|
|
||||||
|
# Prepare ruleset directory for custom routing mode
|
||||||
|
if [ "$routing_mode" = "custom" ]; then
|
||||||
|
[ -d "$HP_DIR/ruleset" ] || mkdir -p "$HP_DIR/ruleset"
|
||||||
|
fi
|
||||||
|
|
||||||
# Update permissions for ujail
|
# Update permissions for ujail
|
||||||
if [ "$outbound_node" != "nil" ]; then
|
if [ "$outbound_node" != "nil" ]; then
|
||||||
echo > "$RUN_DIR/sing-box-c.log"
|
echo > "$RUN_DIR/sing-box-c.log"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (C) 2018-2023 Ruilin Peng (Nick) <pymumu@gmail.com>.
|
# Copyright (C) 2018-2024 Ruilin Peng (Nick) <pymumu@gmail.com>.
|
||||||
#
|
#
|
||||||
# smartdns is free software: you can redistribute it and/or modify
|
# smartdns is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
--
|
--
|
||||||
-- Copyright (C) 2018-2023 Ruilin Peng (Nick) <pymumu@gmail.com>.
|
-- Copyright (C) 2018-2024 Ruilin Peng (Nick) <pymumu@gmail.com>.
|
||||||
--
|
--
|
||||||
-- smartdns is free software: you can redistribute it and/or modify
|
-- smartdns is free software: you can redistribute it and/or modify
|
||||||
-- it under the terms of the GNU General Public License as published by
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
--
|
--
|
||||||
-- Copyright (C) 2018-2023 Ruilin Peng (Nick) <pymumu@gmail.com>.
|
-- Copyright (C) 2018-2024 Ruilin Peng (Nick) <pymumu@gmail.com>.
|
||||||
--
|
--
|
||||||
-- smartdns is free software: you can redistribute it and/or modify
|
-- smartdns is free software: you can redistribute it and/or modify
|
||||||
-- it under the terms of the GNU General Public License as published by
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
--
|
--
|
||||||
-- Copyright (C) 2018-2023 Ruilin Peng (Nick) <pymumu@gmail.com>.
|
-- Copyright (C) 2018-2024 Ruilin Peng (Nick) <pymumu@gmail.com>.
|
||||||
--
|
--
|
||||||
-- smartdns is free software: you can redistribute it and/or modify
|
-- smartdns is free software: you can redistribute it and/or modify
|
||||||
-- it under the terms of the GNU General Public License as published by
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
--
|
--
|
||||||
-- Copyright (C) 2018-2023 Ruilin Peng (Nick) <pymumu@gmail.com>.
|
-- Copyright (C) 2018-2024 Ruilin Peng (Nick) <pymumu@gmail.com>.
|
||||||
--
|
--
|
||||||
-- smartdns is free software: you can redistribute it and/or modify
|
-- smartdns is free software: you can redistribute it and/or modify
|
||||||
-- it under the terms of the GNU General Public License as published by
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
#
|
#
|
||||||
# Copyright (C) 2018-2023 Ruilin Peng (Nick) <pymumu@gmail.com>.
|
# Copyright (C) 2018-2024 Ruilin Peng (Nick) <pymumu@gmail.com>.
|
||||||
#
|
#
|
||||||
# smartdns is free software: you can redistribute it and/or modify
|
# smartdns is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
|
Loading…
Reference in New Issue