update 2024-01-22 16:23:52

This commit is contained in:
github-actions[bot] 2024-01-22 16:23:52 +08:00
parent 126c9f4f45
commit 92e187d53a
17 changed files with 868 additions and 665 deletions

View File

@ -17,12 +17,10 @@ PKG_NAME:=luci-app-homeproxy
define Package/luci-app-homeproxy/conffiles
/etc/config/homeproxy
/etc/homeproxy/certs/
/etc/homeproxy/resources/geoip.db
/etc/homeproxy/resources/geoip.ver
/etc/homeproxy/resources/geosite.db
/etc/homeproxy/resources/geosite.ver
/etc/homeproxy/ruleset/
/etc/homeproxy/resources/direct_list.txt
/etc/homeproxy/resources/proxy_list.txt
/etc/homeproxy/cache.db
endef
include $(TOPDIR)/feeds/luci/luci.mk

View File

@ -287,8 +287,6 @@ return view.extend({
desc.innerHTML = _('Mixed <code>system</code> TCP stack and <code>gVisor</code> UDP stack.')
else if (value === 'gvisor')
desc.innerHTML = _('Based on google/gvisor.');
else if (value === 'lwip')
desc.innerHTML = _('Upstream archived. Not recommended.');
else if (value === 'system')
desc.innerHTML = _('Less compatibility and sometimes better performance.');
}
@ -430,9 +428,9 @@ return view.extend({
so = ss.option(form.ListValue, 'mode', _('Mode'),
_('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>(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>other fields</code>.'));
so.value('default', _('Default'));
@ -476,28 +474,28 @@ return view.extend({
_('Match domain using regular expression.'));
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'),
_('Match source IP CIDR.'));
so.datatype = 'or(cidr, ipaddr)';
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'),
_('Match IP CIDR.'));
so.datatype = 'or(cidr, ipaddr)';
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'),
_('Match source port.'));
so.datatype = 'port';
@ -530,6 +528,28 @@ return view.extend({
_('Match user name.'));
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'),
_('Invert match result.'));
so.default = so.disabled;
@ -712,9 +732,9 @@ return view.extend({
so = ss.option(form.ListValue, 'mode', _('Mode'),
_('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>(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>other fields</code>.'));
so.value('default', _('Default'));
@ -762,10 +782,6 @@ return view.extend({
_('Match domain using regular expression.'));
so.modalonly = true;
so = ss.option(form.DynamicList, 'geosite', _('Geosite'),
_('Match geosite.'));
so.modalonly = true;
so = ss.option(form.DynamicList, 'port', _('Port'),
_('Match port.'));
so.datatype = 'port';
@ -776,15 +792,17 @@ return view.extend({
so.validate = validatePortRange;
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'),
_('Match source IP CIDR.'));
so.datatype = 'or(cidr, ipaddr)';
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'),
_('Match source port.'));
so.datatype = 'port';
@ -807,6 +825,22 @@ return view.extend({
_('Match user name.'));
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'),
_('Invert match result.'));
so.default = so.disabled;
@ -861,6 +895,94 @@ return view.extend({
/* DNS rules 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 */
s.tab('control', _('Access Control'));

View File

@ -1252,7 +1252,7 @@ return view.extend({
s.tab('subscription', _('Subscriptions'));
o = s.taboption('subscription', form.Flag, 'auto_update', _('Auto update'),
_('Auto update subscriptions, GeoIP and GeoSite.'));
_('Auto update subscriptions.'));
o.default = o.disabled;
o.rmempty = false;

View File

@ -200,16 +200,6 @@ return view.extend({
s = m.section(form.NamedSection, 'config', 'homeproxy', _('Resources management'));
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.cfgvalue = function() { return getResVersion(this, 'china_ip4') };
o.rawhtml = true;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -25,6 +25,7 @@ uci.load(uciconfig);
const uciinfra = 'infra',
ucimain = 'config',
uciexp = 'experimental',
ucicontrol = 'control';
const ucidnssetting = 'dns',
@ -36,6 +37,7 @@ const uciroutingsetting = 'routing',
uciroutingrule = 'routing_rule';
const ucinode = 'node';
const uciruleset = 'ruleset';
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'),
brutal: (node.multiplex_brutal === '1') ? {
enabled: true,
up_mbps: node.multiplex_brutal_up,
down_mbps: node.multiplex_brutal_down
up_mbps: strToInt(node.multiplex_brutal_up),
down_mbps: strToInt(node.multiplex_brutal_down)
} : null
} : null,
tls: (node.tls === '1') ? {
@ -297,6 +299,16 @@ function get_resolver(cfg) {
else
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 */
const config = {};
@ -407,16 +419,16 @@ if (!isEmpty(main_node)) {
domain_suffix: cfg.domain_suffix,
domain_keyword: cfg.domain_keyword,
domain_regex: cfg.domain_regex,
geosite: cfg.geosite,
port: parse_port(cfg.port),
port_range: cfg.port_range,
source_geoip: cfg.source_geoip,
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_range: cfg.source_port_range,
process_name: cfg.process_name,
process_path: cfg.process_path,
user: cfg.user,
rule_set: get_ruleset(cfg.rule_set),
invert: (cfg.invert === '1') || null,
outbound: get_outbound(cfg.outbound),
server: get_resolver(cfg.server),
@ -536,16 +548,6 @@ if (!isEmpty(main_node)) {
/* Routing rules start */
/* Default settings */
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: [
{
inbound: 'dns-in',
@ -556,6 +558,7 @@ config.route = {
outbound: 'dns-out'
}
],
rule_set: [],
auto_detect_interface: isEmpty(default_interface) ? true : null,
default_interface: default_interface
};
@ -590,11 +593,10 @@ if (!isEmpty(main_node)) {
domain_suffix: cfg.domain_suffix,
domain_keyword: cfg.domain_keyword,
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_is_private: (cfg.source_ip_is_private === '1') || null,
ip_cidr: cfg.ip_cidr,
ip_is_private: (cfg.ip_is_private === '1') || null,
source_port: parse_port(cfg.source_port),
source_port_range: cfg.source_port_range,
port: parse_port(cfg.port),
@ -602,14 +604,45 @@ if (!isEmpty(main_node)) {
process_name: cfg.process_name,
process_path: cfg.process_path,
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,
outbound: get_outbound(cfg.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 */
/* Experimental start */
if (routing_mode === 'custom') {
config.experimental = {
cache_file: {
enabled: true,
path: HP_DIR + '/cache.db'
}
};
}
/* Experimental end */
system('mkdir -p ' + RUN_DIR);
writefile(RUN_DIR + '/sing-box-c.json', sprintf('%.J\n', removeBlankAttrs(config)));

View File

@ -103,8 +103,8 @@ uci.foreach(uciconfig, uciserver, (cfg) => {
padding: (cfg.multiplex_padding === '1'),
brutal: (cfg.multiplex_brutal === '1') ? {
enabled: true,
up_mbps: cfg.multiplex_brutal_up,
down_mbps: cfg.multiplex_brutal_down
up_mbps: strToInt(cfg.multiplex_brutal_up),
down_mbps: strToInt(cfg.multiplex_brutal_down)
} : null
} : null,

View File

@ -9,10 +9,4 @@ for i in "china_ip4" "china_ip6" "gfw_list" "china_list"; do
"$SCRIPTS_DIR"/update_resources.sh "$i"
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

View File

@ -37,51 +37,6 @@ to_upper() {
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() {
local listtype="$1"
local listrepo="$2"
@ -130,12 +85,6 @@ check_list_update() {
}
case "$1" in
"geoip")
check_geodata_update "$1" "1715173329/sing-geoip"
;;
"geosite")
check_geodata_update "$1" "1715173329/sing-geosite"
;;
"china_ip4")
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"
;;
*)
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
;;
esac

View File

@ -258,6 +258,11 @@ start_service() {
procd_set_param respawn
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
if [ "$outbound_node" != "nil" ]; then
echo > "$RUN_DIR/sing-box-c.log"

View File

@ -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
# it under the terms of the GNU General Public License as published by

View File

@ -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
-- it under the terms of the GNU General Public License as published by

View File

@ -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
-- it under the terms of the GNU General Public License as published by

View File

@ -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
-- it under the terms of the GNU General Public License as published by
@ -155,4 +155,4 @@ o = s:option(Value, "addition_arg", translate("Additional Server Args"), transla
o.default = ""
o.rempty = true
return m
return m

View File

@ -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
-- it under the terms of the GNU General Public License as published by

View File

@ -1,6 +1,6 @@
#!/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
# it under the terms of the GNU General Public License as published by