Merge pull request #290 from itdoginfo/feat/exclusion

feat: Add 'exclusion' connection type with direct route rule
This commit is contained in:
Kirill Sobakin
2026-01-21 17:34:47 +03:00
committed by GitHub
3 changed files with 54 additions and 9 deletions

View File

@@ -15,6 +15,7 @@ function createSectionContent(section) {
o.value("proxy", "Proxy"); o.value("proxy", "Proxy");
o.value("vpn", "VPN"); o.value("vpn", "VPN");
o.value("block", "Block"); o.value("block", "Block");
o.value("exclusion", "Exclusion");
o = section.option( o = section.option(
form.ListValue, form.ListValue,
@@ -641,6 +642,8 @@ function createSectionContent(section) {
); );
o.placeholder = "192.168.1.2 or 192.168.1.0/24"; o.placeholder = "192.168.1.2 or 192.168.1.0/24";
o.rmempty = true; o.rmempty = true;
o.depends("connection_type", "proxy");
o.depends("connection_type", "vpn");
o.validate = function (section_id, value) { o.validate = function (section_id, value) {
// Optional // Optional
if (!value || value.length === 0) { if (!value || value.length === 0) {
@@ -666,6 +669,8 @@ function createSectionContent(section) {
); );
o.default = "0"; o.default = "0";
o.rmempty = false; o.rmempty = false;
o.depends("connection_type", "proxy");
o.depends("connection_type", "vpn");
o = section.option( o = section.option(
form.Value, form.Value,

View File

@@ -748,6 +748,9 @@ configure_outbound_handler() {
block) block)
log "Connection type 'block' detected for the $section section no outbound will be created (handled via reject route rules)" log "Connection type 'block' detected for the $section section no outbound will be created (handled via reject route rules)"
;; ;;
exclusion)
log "Connection type 'exclusion' detected for the $section section no outbound will be created (handled via route rules)"
;;
*) *)
log "Unknown connection type '$connection_type' for the $section section. Aborted." "fatal" log "Unknown connection type '$connection_type' for the $section section. Aborted." "fatal"
exit 1 exit 1
@@ -817,6 +820,7 @@ sing_box_configure_route() {
config=$(sing_box_cf_override_domain_port "$config" "$FAKEIP_TEST_DOMAIN" 8443) config=$(sing_box_cf_override_domain_port "$config" "$FAKEIP_TEST_DOMAIN" 8443)
configure_common_reject_route_rule configure_common_reject_route_rule
configure_common_direct_route_rule
local routing_excluded_ips local routing_excluded_ips
config_get routing_excluded_ips "settings" "routing_excluded_ips" config_get routing_excluded_ips "settings" "routing_excluded_ips"
@@ -848,7 +852,7 @@ include_source_ips_in_routing_handler() {
configure_common_reject_route_rule() { configure_common_reject_route_rule() {
local block_sections block_section_lists_enabled local block_sections block_section_lists_enabled
block_sections="$(get_block_sections)" block_sections="$(get_sections_by_connection_type "block")"
block_section_lists_enabled=0 block_section_lists_enabled=0
if [ -n "$block_sections" ]; then if [ -n "$block_sections" ]; then
@@ -866,6 +870,27 @@ configure_common_reject_route_rule() {
fi fi
} }
configure_common_direct_route_rule() {
local exclusion_sections exclusion_section_list_enabled
exclusion_sections="$(get_sections_by_connection_type "exclusion")"
exclusion_section_list_enabled=0
if [ -n "$exclusion_sections" ]; then
for exclusion_section in $exclusion_sections; do
if section_has_enabled_lists "$exclusion_section"; then
exclusion_section_list_enabled=1
break
fi
done
if [ "$exclusion_section_list_enabled" -eq 1 ]; then
config=$(sing_box_cm_add_route_rule "$config" "$SB_EXCLUSION_RULE_TAG" "$SB_TPROXY_INBOUND_TAG" \
"$SB_DIRECT_OUTBOUND_TAG")
else
log "Exclusion sections does not have any enabled list, route rule is not required" "warn"
fi
fi
}
include_source_ip_in_routing_handler() { include_source_ip_in_routing_handler() {
local source_ip="$1" local source_ip="$1"
local rule_tag="$2" local rule_tag="$2"
@@ -900,13 +925,23 @@ configure_routing_for_section_lists() {
config_get remote_subnet_lists "$section" "remote_subnet_lists" config_get remote_subnet_lists "$section" "remote_subnet_lists"
config_get section_connection_type "$section" "connection_type" config_get section_connection_type "$section" "connection_type"
if [ "$section_connection_type" = "block" ]; then case "$section_connection_type" in
route_rule_tag="$SB_REJECT_RULE_TAG" proxy | vpn)
else
route_rule_tag="$(gen_id)" route_rule_tag="$(gen_id)"
outbound_tag=$(get_outbound_tag_by_section "$section") outbound_tag=$(get_outbound_tag_by_section "$section")
config=$(sing_box_cm_add_route_rule "$config" "$route_rule_tag" "$SB_TPROXY_INBOUND_TAG" "$outbound_tag") config=$(sing_box_cm_add_route_rule "$config" "$route_rule_tag" "$SB_TPROXY_INBOUND_TAG" "$outbound_tag")
fi ;;
block)
route_rule_tag="$SB_REJECT_RULE_TAG"
;;
exclusion)
route_rule_tag="$SB_EXCLUSION_RULE_TAG"
;;
*)
log "Unsupported '$section_connection_type' connection type. Skipping routing for '$section' section" "fatal"
exit 1
;;
esac
if [ -n "$community_lists" ]; then if [ -n "$community_lists" ]; then
log "Processing community list routing rules for '$section' section" log "Processing community list routing rules for '$section' section"
@@ -1497,12 +1532,16 @@ get_first_outbound_section() {
echo "$first_section" echo "$first_section"
} }
get_block_sections() { get_sections_by_connection_type() {
uci show podkop | grep "\.connection_type='block'" | cut -d'.' -f2 local connection_type="$1"
uci show podkop | grep "\.connection_type='$connection_type'" | cut -d'.' -f2
} }
block_section_exists() { section_by_connection_type_exists() {
if uci show podkop | grep -q "\.connection_type='block'"; then local connection_type="$1"
if uci show podkop | grep -q "\.connection_type='$connection_type'"; then
return 0 return 0
else else
return 1 return 1

View File

@@ -46,6 +46,7 @@ SB_SERVICE_MIXED_INBOUND_PORT=4534
SB_DIRECT_OUTBOUND_TAG="direct-out" SB_DIRECT_OUTBOUND_TAG="direct-out"
# Route # Route
SB_REJECT_RULE_TAG="reject-rule-tag" SB_REJECT_RULE_TAG="reject-rule-tag"
SB_EXCLUSION_RULE_TAG="exclusion-rule-tag"
# Experimental # Experimental
SB_CLASH_API_CONTROLLER_PORT=9090 SB_CLASH_API_CONTROLLER_PORT=9090