mirror of
https://github.com/itdoginfo/podkop.git
synced 2025-12-09 21:17:03 +03:00
refactor: intermediate refactoring commit
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.idea
|
||||
@@ -220,6 +220,7 @@ function createAdditionalSection(mainSection, network) {
|
||||
o.rmempty = false;
|
||||
o.ucisection = 'main';
|
||||
|
||||
// TODO(ampetelin): Can be moved to advanced settings in luci
|
||||
// Extra IPs and exclusions (main section)
|
||||
o = mainSection.taboption('basic', form.Flag, 'exclude_from_ip_enabled', _('IP for exclusion'), _('Specify local IP addresses that will never use the configured route'));
|
||||
o.default = '0';
|
||||
|
||||
@@ -234,18 +234,18 @@ function createConfigSection(section, map, network) {
|
||||
return true;
|
||||
};
|
||||
|
||||
o = s.taboption('basic', form.Flag, 'domain_list_enabled', _('Community Lists'));
|
||||
o = s.taboption('basic', form.Flag, 'community_list_enabled', _('Community Lists'));
|
||||
o.default = '0';
|
||||
o.rmempty = false;
|
||||
o.ucisection = s.section;
|
||||
|
||||
o = s.taboption('basic', form.DynamicList, 'domain_list', _('Service List'), _('Select predefined service for routing') + ' <a href="https://github.com/itdoginfo/allow-domains" target="_blank">github.com/itdoginfo/allow-domains</a>');
|
||||
o = s.taboption('basic', form.DynamicList, 'community_list', _('Service List'), _('Select predefined service for routing') + ' <a href="https://github.com/itdoginfo/allow-domains" target="_blank">github.com/itdoginfo/allow-domains</a>');
|
||||
o.placeholder = 'Service list';
|
||||
Object.entries(constants.DOMAIN_LIST_OPTIONS).forEach(([key, label]) => {
|
||||
o.value(key, _(label));
|
||||
});
|
||||
|
||||
o.depends('domain_list_enabled', '1');
|
||||
o.depends('community_list_enabled', '1');
|
||||
o.rmempty = false;
|
||||
o.ucisection = s.section;
|
||||
|
||||
@@ -302,7 +302,7 @@ function createConfigSection(section, map, network) {
|
||||
}
|
||||
};
|
||||
|
||||
o = s.taboption('basic', form.ListValue, 'custom_domains_list_type', _('User Domain List Type'), _('Select how to add your custom domains'));
|
||||
o = s.taboption('basic', form.ListValue, 'user_domains_list_type', _('User Domain List Type'), _('Select how to add your custom domains'));
|
||||
o.value('disabled', _('Disabled'));
|
||||
o.value('dynamic', _('Dynamic List'));
|
||||
o.value('text', _('Text List'));
|
||||
@@ -310,9 +310,9 @@ function createConfigSection(section, map, network) {
|
||||
o.rmempty = false;
|
||||
o.ucisection = s.section;
|
||||
|
||||
o = s.taboption('basic', form.DynamicList, 'custom_domains', _('User Domains'), _('Enter domain names without protocols (example: sub.example.com or example.com)'));
|
||||
o = s.taboption('basic', form.DynamicList, 'user_domains', _('User Domains'), _('Enter domain names without protocols (example: sub.example.com or example.com)'));
|
||||
o.placeholder = 'Domains list';
|
||||
o.depends('custom_domains_list_type', 'dynamic');
|
||||
o.depends('user_domains_list_type', 'dynamic');
|
||||
o.rmempty = false;
|
||||
o.ucisection = s.section;
|
||||
o.validate = function (section_id, value) {
|
||||
@@ -324,9 +324,10 @@ function createConfigSection(section, map, network) {
|
||||
return true;
|
||||
};
|
||||
|
||||
o = s.taboption('basic', form.TextValue, 'custom_domains_text', _('User Domains List'), _('Enter domain names separated by comma, space or newline. You can add comments after //'));
|
||||
// TODO: Is it possible to save not as an option (but as a split list)?
|
||||
o = s.taboption('basic', form.TextValue, 'user_domains', _('User Domains List'), _('Enter domain names separated by comma, space or newline. You can add comments after //'));
|
||||
o.placeholder = 'example.com, sub.example.com\n// Social networks\ndomain.com test.com // personal domains';
|
||||
o.depends('custom_domains_list_type', 'text');
|
||||
o.depends('user_domains_list_type', 'text');
|
||||
o.rows = 8;
|
||||
o.rmempty = false;
|
||||
o.ucisection = s.section;
|
||||
@@ -365,14 +366,14 @@ function createConfigSection(section, map, network) {
|
||||
return true;
|
||||
};
|
||||
|
||||
o = s.taboption('basic', form.Flag, 'custom_local_domains_list_enabled', _('Local Domain Lists'), _('Use the list from the router filesystem'));
|
||||
o = s.taboption('basic', form.Flag, 'local_domains_list_enabled', _('Local Domain Lists'), _('Use the list from the router filesystem'));
|
||||
o.default = '0';
|
||||
o.rmempty = false;
|
||||
o.ucisection = s.section;
|
||||
|
||||
o = s.taboption('basic', form.DynamicList, 'custom_local_domains', _('Local Domain Lists Path'), _('Enter the list file path'));
|
||||
o = s.taboption('basic', form.DynamicList, 'local_domains_list', _('Local Domain Lists Path'), _('Enter the list file path'));
|
||||
o.placeholder = '/path/file.lst';
|
||||
o.depends('custom_local_domains_list_enabled', '1');
|
||||
o.depends('local_domains_list_enabled', '1');
|
||||
o.rmempty = false;
|
||||
o.ucisection = s.section;
|
||||
o.validate = function (section_id, value) {
|
||||
@@ -384,14 +385,14 @@ function createConfigSection(section, map, network) {
|
||||
return true;
|
||||
};
|
||||
|
||||
o = s.taboption('basic', form.Flag, 'custom_download_domains_list_enabled', _('Remote Domain Lists'), _('Download and use domain lists from remote URLs'));
|
||||
o = s.taboption('basic', form.Flag, 'remote_domains_list_enabled', _('Remote Domain Lists'), _('Download and use domain lists from remote URLs'));
|
||||
o.default = '0';
|
||||
o.rmempty = false;
|
||||
o.ucisection = s.section;
|
||||
|
||||
o = s.taboption('basic', form.DynamicList, 'custom_download_domains', _('Remote Domain URLs'), _('Enter full URLs starting with http:// or https://'));
|
||||
o = s.taboption('basic', form.DynamicList, 'remote_domains_list', _('Remote Domain URLs'), _('Enter full URLs starting with http:// or https://'));
|
||||
o.placeholder = 'URL';
|
||||
o.depends('custom_download_domains_list_enabled', '1');
|
||||
o.depends('remote_domains_list_enabled', '1');
|
||||
o.rmempty = false;
|
||||
o.ucisection = s.section;
|
||||
o.validate = function (section_id, value) {
|
||||
@@ -399,7 +400,7 @@ function createConfigSection(section, map, network) {
|
||||
return validateUrl(value);
|
||||
};
|
||||
|
||||
o = s.taboption('basic', form.ListValue, 'custom_subnets_list_enabled', _('User Subnet List Type'), _('Select how to add your custom subnets'));
|
||||
o = s.taboption('basic', form.ListValue, 'user_subnets_list_type', _('User Subnet List Type'), _('Select how to add your custom subnets'));
|
||||
o.value('disabled', _('Disabled'));
|
||||
o.value('dynamic', _('Dynamic List'));
|
||||
o.value('text', _('Text List (comma/space/newline separated)'));
|
||||
@@ -407,9 +408,9 @@ function createConfigSection(section, map, network) {
|
||||
o.rmempty = false;
|
||||
o.ucisection = s.section;
|
||||
|
||||
o = s.taboption('basic', form.DynamicList, 'custom_subnets', _('User Subnets'), _('Enter subnets in CIDR notation (example: 103.21.244.0/22) or single IP addresses'));
|
||||
o = s.taboption('basic', form.DynamicList, 'user_subnets', _('User Subnets'), _('Enter subnets in CIDR notation (example: 103.21.244.0/22) or single IP addresses'));
|
||||
o.placeholder = 'IP or subnet';
|
||||
o.depends('custom_subnets_list_enabled', 'dynamic');
|
||||
o.depends('user_subnets_list_type', 'dynamic');
|
||||
o.rmempty = false;
|
||||
o.ucisection = s.section;
|
||||
o.validate = function (section_id, value) {
|
||||
@@ -432,9 +433,10 @@ function createConfigSection(section, map, network) {
|
||||
return true;
|
||||
};
|
||||
|
||||
o = s.taboption('basic', form.TextValue, 'custom_subnets_text', _('User Subnets List'), _('Enter subnets in CIDR notation or single IP addresses, separated by comma, space or newline. You can add comments after //'));
|
||||
// TODO: Is it possible to save not as an option (but as a split list)?
|
||||
o = s.taboption('basic', form.TextValue, 'user_subnets', _('User Subnets List'), _('Enter subnets in CIDR notation or single IP addresses, separated by comma, space or newline. You can add comments after //'));
|
||||
o.placeholder = '103.21.244.0/22\n// Google DNS\n8.8.8.8\n1.1.1.1/32, 9.9.9.9 // Cloudflare and Quad9';
|
||||
o.depends('custom_subnets_list_enabled', 'text');
|
||||
o.depends('user_subnets_list_type', 'text');
|
||||
o.rows = 10;
|
||||
o.rmempty = false;
|
||||
o.ucisection = s.section;
|
||||
@@ -489,14 +491,14 @@ function createConfigSection(section, map, network) {
|
||||
return true;
|
||||
};
|
||||
|
||||
o = s.taboption('basic', form.Flag, 'custom_download_subnets_list_enabled', _('Remote Subnet Lists'), _('Download and use subnet lists from remote URLs'));
|
||||
o = s.taboption('basic', form.Flag, 'remote_subnets_list_enabled', _('Remote Subnet Lists'), _('Download and use subnet lists from remote URLs'));
|
||||
o.default = '0';
|
||||
o.rmempty = false;
|
||||
o.ucisection = s.section;
|
||||
|
||||
o = s.taboption('basic', form.DynamicList, 'custom_download_subnets', _('Remote Subnet URLs'), _('Enter full URLs starting with http:// or https://'));
|
||||
o = s.taboption('basic', form.DynamicList, 'remote_subnets_list', _('Remote Subnet URLs'), _('Enter full URLs starting with http:// or https://'));
|
||||
o.placeholder = 'URL';
|
||||
o.depends('custom_download_subnets_list_enabled', '1');
|
||||
o.depends('remote_subnets_list_enabled', '1');
|
||||
o.rmempty = false;
|
||||
o.ucisection = s.section;
|
||||
o.validate = function (section_id, value) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
27
podkop/files/usr/lib/constants.sh
Normal file
27
podkop/files/usr/lib/constants.sh
Normal file
@@ -0,0 +1,27 @@
|
||||
SB_CONFIG="/etc/sing-box/config.json"
|
||||
# Log
|
||||
SB_DEFAULT_LOG_LEVEL="warn"
|
||||
# DNS
|
||||
SB_DNS_SERVER_TAG="dns-server"
|
||||
SB_SPLIT_DNS_SERVER_TAG="split-dns-server"
|
||||
SB_FAKEIP_DNS_SERVER_TAG="fakeip-server"
|
||||
FAKEIP="198.18.0.0/15" # TODO(ampetelin): renaming is needed
|
||||
SB_DNS_DOMAIN_RESOLVER_TAG="dns-domain-resolver"
|
||||
SB_FAKEIP_DNS_RULE_TAG="fakeip-dns-rule-tag"
|
||||
SB_INVERT_FAKEIP_DNS_RULE_TAG="invert-fakeip-dns-rule-tag"
|
||||
# Inbounds
|
||||
SB_TPROXY_INBOUND_TAG="tproxy-in"
|
||||
SB_TPROXY_INBOUND_ADDRESS="127.0.0.1"
|
||||
SB_TPROXY_INBOUND_PORT=1602
|
||||
SB_DNS_INBOUND_TAG="dns-in"
|
||||
SB_DNS_INBOUND_ADDRESS="127.0.0.42"
|
||||
SB_DNS_INBOUND_PORT=53
|
||||
SB_MIXED_INBOUND_TAG="mixed-in"
|
||||
SB_MIXED_INBOUND_ADDRESS="0.0.0.0"
|
||||
SB_MIXED_INBOUND_PORT=2080
|
||||
SB_SERVICE_MIXED_INBOUND_TAG="service-mixed-in"
|
||||
SB_SERVICE_MIXED_INBOUND_ADDRESS="127.0.0.1"
|
||||
SB_SERVICE_MIXED_INBOUND_PORT=4534
|
||||
# Outbounds
|
||||
SB_DIRECT_OUTBOUND_TAG="direct-out"
|
||||
SB_MAIN_OUTBOUND_TAG="main-out"
|
||||
178
podkop/files/usr/lib/helpers.sh
Normal file
178
podkop/files/usr/lib/helpers.sh
Normal file
@@ -0,0 +1,178 @@
|
||||
# Check if string is valid IPv4
|
||||
is_ipv4() {
|
||||
local ip="$1"
|
||||
local regex="^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$"
|
||||
[[ $ip =~ $regex ]]
|
||||
}
|
||||
|
||||
# Check if string is valid IPv4 with CIDR mask
|
||||
is_ipv4_cidr() {
|
||||
local ip="$1"
|
||||
local regex="^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}(\/(3[0-2]|2[0-9]|1[0-9]|[0-9]))$"
|
||||
[[ $ip =~ $regex ]]
|
||||
}
|
||||
|
||||
# Checks if the given string is a valid base64-encoded sequence
|
||||
is_base64() {
|
||||
local str="$1"
|
||||
|
||||
if echo "$str" | base64 -d > /dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# Checks if the given file exists
|
||||
file_exists() {
|
||||
local filepath="$1"
|
||||
|
||||
if [[ -f "$filepath" ]]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Extracts and returns the file extension from the given URL
|
||||
get_url_file_extension() {
|
||||
local url="$1"
|
||||
local file_extension="${url##*.}"
|
||||
|
||||
echo "$file_extension"
|
||||
}
|
||||
|
||||
# Returns the inbound tag name by appending the postfix to the given section
|
||||
get_inbound_tag_by_section() {
|
||||
local section="$1"
|
||||
local postfix="in"
|
||||
|
||||
echo "$section-$postfix"
|
||||
}
|
||||
|
||||
# Returns the outbound tag name by appending the postfix to the given section
|
||||
get_outbound_tag_by_section() {
|
||||
local section="$1"
|
||||
local postfix="out"
|
||||
|
||||
echo "$section-$postfix"
|
||||
}
|
||||
|
||||
# Constructs and returns a ruleset tag using section, name, optional type, and a fixed postfix
|
||||
get_rule_set_tag() {
|
||||
local section="$1"
|
||||
local name="$2"
|
||||
local type="${3:-}"
|
||||
local postfix="ruleset"
|
||||
|
||||
if [ -n "$type" ]; then
|
||||
echo "$section-$name-$type-$postfix"
|
||||
else
|
||||
echo "$section-$name-$postfix"
|
||||
fi
|
||||
}
|
||||
|
||||
# Determines the ruleset format based on the file extension (json → source, srs → binary)
|
||||
get_rule_set_format_by_file_extension() {
|
||||
local file_extension="$1"
|
||||
|
||||
local format
|
||||
case "$file_extension" in
|
||||
json) format="source" ;;
|
||||
srs) format="binary" ;;
|
||||
*)
|
||||
log "Unsupported file extension: .$file_extension"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "$format"
|
||||
}
|
||||
|
||||
# Converts a comma-separated string into a JSON array string
|
||||
comma_string_to_json_array() {
|
||||
local input="$1"
|
||||
|
||||
if [ -z "$input" ]; then
|
||||
echo "[]"
|
||||
return
|
||||
fi
|
||||
|
||||
local replaced="${input//,/\",\"}"
|
||||
|
||||
echo "[\"$replaced\"]"
|
||||
}
|
||||
|
||||
# Decodes a URL-encoded string
|
||||
url_decode() {
|
||||
local encoded="$1"
|
||||
printf '%b' "$(echo "$encoded" | sed 's/+/ /g; s/%/\\x/g')"
|
||||
}
|
||||
|
||||
# Extracts the userinfo (username[:password]) part from a URL
|
||||
url_get_userinfo() {
|
||||
local url="$1"
|
||||
echo "$url" | sed -n 's#^[^:]*://\([^@]*\)@.*#\1#p'
|
||||
}
|
||||
|
||||
# Extracts the host part from a URL
|
||||
url_get_host() {
|
||||
local url="$1"
|
||||
echo "$url" | sed -n 's#^[^:]*://[^@]*@\([^:/?#]*\).*#\1#p'
|
||||
}
|
||||
|
||||
# Extracts the port number from a URL
|
||||
url_get_port() {
|
||||
local url="$1"
|
||||
echo "$url" | sed -n 's#^[^:]*://[^@]*@[^:/?#]*:\([0-9]*\).*#\1#p'
|
||||
}
|
||||
|
||||
# Extracts the value of a specific query parameter from a URL
|
||||
url_get_query_param() {
|
||||
local url="$1"
|
||||
local param="$2"
|
||||
|
||||
local raw
|
||||
raw=$(echo "$url" | sed -n "s/.*[?&]$param=\([^&?#]*\).*/\1/p")
|
||||
|
||||
[ -z "$raw" ] && echo "" && return
|
||||
|
||||
echo "$raw"
|
||||
}
|
||||
|
||||
# Extracts the basename (filename without extension) from a URL
|
||||
url_get_basename() {
|
||||
local url="$1"
|
||||
|
||||
local filename="${url##*/}"
|
||||
local basename="${filename%%.*}"
|
||||
|
||||
echo "$basename"
|
||||
}
|
||||
|
||||
# Decodes and returns a base64-encoded string
|
||||
base64_decode() {
|
||||
local str="$1"
|
||||
local decoded_url
|
||||
|
||||
decoded_url="$(echo "$str" | base64 -d 2> /dev/null)"
|
||||
|
||||
echo "$decoded_url"
|
||||
}
|
||||
|
||||
# Generates a unique 16-character ID based on the current timestamp and a random number
|
||||
gen_id() {
|
||||
printf '%s%s' "$(date +%s)" "$RANDOM" | md5sum | cut -c1-16
|
||||
}
|
||||
|
||||
# Migrates a configuration key in an OpenWrt config file from old_key_name to new_key_name
|
||||
migrate_config_key() {
|
||||
local config="$1"
|
||||
local key_type="$2"
|
||||
local old_key_name="$3"
|
||||
local new_key_name="$4"
|
||||
|
||||
if grep -q "$key_type $old_key_name" "$config"; then
|
||||
log "Deprecated $key_type found: $old_key_name migrating to $new_key_name" "migration"
|
||||
sed -i "s/$key_type $old_key_name/$key_type $new_key_name/g" "$config"
|
||||
fi
|
||||
}
|
||||
210
podkop/files/usr/lib/sing_box_config_facade.sh
Normal file
210
podkop/files/usr/lib/sing_box_config_facade.sh
Normal file
@@ -0,0 +1,210 @@
|
||||
PODKOP_LIB="/usr/lib/podkop"
|
||||
. "$PODKOP_LIB/helpers.sh"
|
||||
. "$PODKOP_LIB/sing_box_config_manager.sh"
|
||||
|
||||
sing_box_cf_add_dns_server() {
|
||||
local config="$1"
|
||||
local type="$2"
|
||||
local tag="$3"
|
||||
local server_address="$4"
|
||||
local path="$5"
|
||||
local headers="$6"
|
||||
local domain_resolver="$7"
|
||||
local detour="$8"
|
||||
|
||||
case "$type" in
|
||||
udp)
|
||||
config=$(sing_box_cm_add_udp_dns_server "$config" "$tag" "$server_address" 53 "$domain_resolver" "$detour")
|
||||
;;
|
||||
dot)
|
||||
config=$(sing_box_cm_add_tls_dns_server "$config" "$tag" "$server_address" 853 "$domain_resolver" "$detour")
|
||||
;;
|
||||
doh)
|
||||
config=$(
|
||||
sing_box_cm_add_https_dns_server "$config" "$tag" "$server_address" 443 "$path" "$headers" \
|
||||
"$domain_resolver" "$detour"
|
||||
)
|
||||
;;
|
||||
*)
|
||||
log "Unsupported DNS server type: $type" "sing-box"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "$config"
|
||||
}
|
||||
|
||||
sing_box_cf_add_mixed_inbound_and_route_rule() {
|
||||
local config="$1"
|
||||
local tag="$2"
|
||||
local listen_address="$3"
|
||||
local listen_port="$4"
|
||||
local outbound="$5"
|
||||
|
||||
config=$(sing_box_cm_add_mixed_inbound "$config" "$tag" "$listen_address" "$listen_port")
|
||||
config=$(sing_box_cm_add_route_rule "$config" "" "$tag" "$outbound")
|
||||
|
||||
echo "$config"
|
||||
}
|
||||
|
||||
sing_box_cf_add_proxy_outbound() {
|
||||
local config="$1"
|
||||
local section="$2"
|
||||
local url="$3"
|
||||
local udp_over_tcp="$4"
|
||||
|
||||
url=$(url_decode "$url")
|
||||
|
||||
local scheme="${url%%://*}"
|
||||
case "$scheme" in
|
||||
vless)
|
||||
local tag host port uuid flow
|
||||
tag=$(get_outbound_tag_by_section "$section")
|
||||
host=$(url_get_host "$url")
|
||||
port=$(url_get_port "$url")
|
||||
uuid=$(url_get_userinfo "$url")
|
||||
flow=$(url_get_query_param "$url" "flow")
|
||||
|
||||
config=$(sing_box_cm_add_vless_outbound "$config" "$tag" "$host" "$port" "$uuid" "$flow")
|
||||
|
||||
local transport
|
||||
transport=$(url_get_query_param "$url" "type")
|
||||
case "$transport" in
|
||||
tcp | raw) ;;
|
||||
ws)
|
||||
local ws_path ws_host ws_early_data
|
||||
ws_path=$(url_get_query_param "$url" "path")
|
||||
ws_host=$(url_get_query_param "$url" "host")
|
||||
ws_early_data=$(url_get_query_param "$url" "ed")
|
||||
|
||||
config=$(sing_box_cm_set_vless_ws_transport "$config" "$tag" "$ws_path" "$ws_host" "$ws_early_data")
|
||||
;;
|
||||
grpc)
|
||||
# TODO(ampetelin): Add handling of optional gRPC parameters; example links are needed.
|
||||
config=$(sing_box_cm_set_vless_grpc_transport "$config" "$tag")
|
||||
;;
|
||||
*)
|
||||
log "Unknown transport '$transport' detected." "sing-box" "error"
|
||||
;;
|
||||
esac
|
||||
|
||||
local security
|
||||
security=$(url_get_query_param "$url" "security")
|
||||
case "$security" in
|
||||
tls | reality)
|
||||
local sni insecure alpn fingerprint public_key short_id
|
||||
sni=$(url_get_query_param "$url" "sni")
|
||||
insecure=$(url_get_query_param "$url" "allowInsecure")
|
||||
alpn=$(comma_string_to_json_array "$(url_get_query_param "$url" "alpn")")
|
||||
fingerprint=$(url_get_query_param "$url" "fp")
|
||||
public_key=$(url_get_query_param "$url" "pbk")
|
||||
short_id=$(url_get_query_param "$url" "sid")
|
||||
|
||||
config=$(
|
||||
sing_box_cm_set_vless_tls \
|
||||
"$config" \
|
||||
"$tag" \
|
||||
"$sni" \
|
||||
"$([ "$insecure" == "1" ] && echo true)" \
|
||||
"$([ "$alpn" == "[]" ] && echo null || echo "$alpn")" \
|
||||
"$fingerprint" \
|
||||
"$public_key" \
|
||||
"$short_id"
|
||||
)
|
||||
;;
|
||||
none) ;;
|
||||
*)
|
||||
log "Unknown security '$security' detected." "sing-box" "error"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
ss)
|
||||
local userinfo tag host port method password udp_over_tcp
|
||||
|
||||
userinfo=$(url_get_userinfo "$url")
|
||||
if is_base64 "$userinfo"; then
|
||||
userinfo=$(base64_decode "$userinfo")
|
||||
fi
|
||||
|
||||
tag=$(get_outbound_tag_by_section "$section")
|
||||
host=$(url_get_host "$url")
|
||||
port=$(url_get_port "$url")
|
||||
method="${userinfo%%:*}"
|
||||
password="${userinfo#*:}"
|
||||
|
||||
config=$(
|
||||
sing_box_cm_add_shadowsocks_outbound \
|
||||
"$config" \
|
||||
"$tag" \
|
||||
"$host" \
|
||||
"$port" \
|
||||
"$method" \
|
||||
"$password" \
|
||||
"" \
|
||||
"$([ "$udp_over_tcp" == "1" ] && echo 2)" # if udp_over_tcp is enabled, enable version 2
|
||||
)
|
||||
;;
|
||||
*)
|
||||
log "Unsupported proxy $scheme type" "sing-box"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "$config"
|
||||
}
|
||||
|
||||
sing_box_cf_add_json_outbound() {
|
||||
local config="$1"
|
||||
local section="$2"
|
||||
local json_outbound="$3"
|
||||
|
||||
local tag
|
||||
tag=$(get_outbound_tag_by_section "$section")
|
||||
|
||||
config=$(sing_box_cm_add_raw_outbound "$config" "$tag" "$json_outbound")
|
||||
|
||||
echo "$config"
|
||||
}
|
||||
|
||||
sing_box_cf_add_interface_outbound() {
|
||||
local config="$1"
|
||||
local section="$2"
|
||||
local interface_name="$3"
|
||||
|
||||
local tag
|
||||
tag=$(get_outbound_tag_by_section "$section")
|
||||
|
||||
config=$(sing_box_cm_add_interface_outbound "$config" "$tag" "$interface_name")
|
||||
|
||||
echo "$config"
|
||||
}
|
||||
|
||||
sing_box_cf_proxy_domain() {
|
||||
local config="$1"
|
||||
local inbound="$2"
|
||||
local domain="$3"
|
||||
local outbound="$4"
|
||||
|
||||
tag="$(gen_id)"
|
||||
config=$(sing_box_cm_add_route_rule "$config" "$tag" "$inbound" "$outbound")
|
||||
config=$(sing_box_cm_patch_route_rule "$config" "$tag" "domain" "$domain")
|
||||
|
||||
echo "$config"
|
||||
}
|
||||
|
||||
sing_box_cf_override_domain_port() {
|
||||
local config="$1"
|
||||
local domain="$2"
|
||||
local port="$3"
|
||||
|
||||
tag="$(gen_id)"
|
||||
config=$(sing_box_cm_add_options_route_rule "$config" "$tag")
|
||||
config=$(sing_box_cm_patch_route_rule "$config" "$tag" "domain" "$domain")
|
||||
config=$(sing_box_cm_patch_route_rule "$config" "$tag" "override_port" "$port")
|
||||
|
||||
echo "$config"
|
||||
}
|
||||
|
||||
sing_box_cf_add_remote_ruleset_with_dns_and_route_rule() {
|
||||
local config="$1"
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
#!/bin/ash
|
||||
#
|
||||
# Module: sing_box_config_manager.sh
|
||||
#
|
||||
@@ -272,9 +271,9 @@ sing_box_cm_add_dns_route_rule() {
|
||||
# Outputs:
|
||||
# Writes updated JSON configuration to stdout
|
||||
# Example:
|
||||
# CONFIG=$(sing_box_cm_patch_dns_route_rule "$CONFIG" "fakeip-dns-rule-id" "rule_set" '"main"')
|
||||
# CONFIG=$(sing_box_cm_patch_dns_route_rule "$CONFIG" "fakeip-dns-rule-id" "rule_set" "main")
|
||||
# CONFIG=$(sing_box_cm_patch_dns_route_rule "$CONFIG" "fakeip-dns-rule-id" "rule_set" '["main","second"]')
|
||||
# CONFIG=$(sing_box_cm_patch_dns_route_rule "$CONFIG" "fakeip-dns-rule-id" "domain" '"example.com"')
|
||||
# CONFIG=$(sing_box_cm_patch_dns_route_rule "$CONFIG" "fakeip-dns-rule-id" "domain" "example.com")
|
||||
#######################################
|
||||
sing_box_cm_patch_dns_route_rule() {
|
||||
local config="$1"
|
||||
@@ -282,12 +281,14 @@ sing_box_cm_patch_dns_route_rule() {
|
||||
local key="$3"
|
||||
local value="$4"
|
||||
|
||||
value=$(_normalize_arg "$value")
|
||||
|
||||
echo "$config" | jq \
|
||||
--arg service_tag "$SERVICE_TAG" \
|
||||
--arg tag "$tag" \
|
||||
--arg key "$key" \
|
||||
--argjson value "$value" \
|
||||
'import "helpers" as h;
|
||||
'import "helpers" as h {"search": "/usr/lib/podkop"};
|
||||
.dns.rules |= map(
|
||||
if .[$service_tag] == $tag then
|
||||
if has($key) then
|
||||
@@ -310,13 +311,15 @@ sing_box_cm_patch_dns_route_rule() {
|
||||
# Outputs:
|
||||
# Writes updated JSON configuration to stdout
|
||||
# Example:
|
||||
# CONFIG=$(sing_box_cm_add_dns_reject_rule "$CONFIG" "query_type" '"HTTPS"')
|
||||
# CONFIG=$(sing_box_cm_add_dns_reject_rule "$CONFIG" "query_type" "HTTPS")
|
||||
#######################################
|
||||
sing_box_cm_add_dns_reject_rule() {
|
||||
local config="$1"
|
||||
local key="$2"
|
||||
local value="$3"
|
||||
|
||||
value=$(_normalize_arg "$value")
|
||||
|
||||
echo "$config" | jq \
|
||||
--arg key "$key" \
|
||||
--argjson value "$value" \
|
||||
@@ -760,7 +763,7 @@ sing_box_cm_set_vless_tls() {
|
||||
+ (if $insecure == "true" then {insecure: true} else {} end)
|
||||
+ (if $alpn != null then {alpn: $alpn} else {} end)
|
||||
+ (if $utls_fingerprint != "" then {
|
||||
ults: {
|
||||
utls: {
|
||||
enabled: true,
|
||||
fingerprint: $utls_fingerprint
|
||||
}
|
||||
@@ -902,7 +905,7 @@ sing_box_cm_add_route_rule() {
|
||||
# Outputs:
|
||||
# Writes updated JSON configuration to stdout
|
||||
# Example:
|
||||
# CONFIG=$(sing_box_cm_patch_route_rule "$CONFIG" "main-route-rule" "rule_set" '"inline-ruleset"')
|
||||
# CONFIG=$(sing_box_cm_patch_route_rule "$CONFIG" "main-route-rule" "rule_set" "inline-ruleset")
|
||||
#######################################
|
||||
sing_box_cm_patch_route_rule() {
|
||||
local config="$1"
|
||||
@@ -910,12 +913,14 @@ sing_box_cm_patch_route_rule() {
|
||||
local key="$3"
|
||||
local value="$4"
|
||||
|
||||
value=$(_normalize_arg "$value")
|
||||
|
||||
echo "$config" | jq \
|
||||
--arg service_tag "$SERVICE_TAG" \
|
||||
--arg tag "$tag" \
|
||||
--arg key "$key" \
|
||||
--argjson value "$value" \
|
||||
'import "helpers" as h;
|
||||
'import "helpers" as h {"search": "/usr/lib/podkop"};
|
||||
.route.rules |= map(
|
||||
if .[$service_tag] == $tag then
|
||||
if has($key) then
|
||||
@@ -938,13 +943,15 @@ sing_box_cm_patch_route_rule() {
|
||||
# Outputs:
|
||||
# Writes updated JSON configuration to stdout
|
||||
# Example:
|
||||
# CONFIG=$(sing_box_cm_add_reject_route_rule "$CONFIG" "protocol" '"quic"')
|
||||
# CONFIG=$(sing_box_cm_add_reject_route_rule "$CONFIG" "protocol" "quic")
|
||||
#######################################
|
||||
sing_box_cm_add_reject_route_rule() {
|
||||
local config="$1"
|
||||
local key="$2"
|
||||
local value="$3"
|
||||
|
||||
value=$(_normalize_arg "$value")
|
||||
|
||||
echo "$config" | jq \
|
||||
--arg key "$key" \
|
||||
--argjson value "$value" \
|
||||
@@ -963,13 +970,15 @@ sing_box_cm_add_reject_route_rule() {
|
||||
# Outputs:
|
||||
# Writes updated JSON configuration to stdout
|
||||
# Example:
|
||||
# CONFIG=$(sing_box_cm_add_hijack_dns_route_rule "$CONFIG" "protocol" '"dns"')
|
||||
# CONFIG=$(sing_box_cm_add_hijack_dns_route_rule "$CONFIG" "protocol" "dns")
|
||||
#######################################
|
||||
sing_box_cm_add_hijack_dns_route_rule() {
|
||||
local config="$1"
|
||||
local key="$2"
|
||||
local value="$3"
|
||||
|
||||
value=$(_normalize_arg "$value")
|
||||
|
||||
echo "$config" | jq \
|
||||
--arg key "$key" \
|
||||
--argjson value "$value" \
|
||||
@@ -1011,7 +1020,7 @@ sing_box_cm_add_options_route_rule() {
|
||||
# Outputs:
|
||||
# Writes updated JSON configuration to stdout
|
||||
# Example:
|
||||
# CONFIG=$(sing_box_cm_sniff_route_rule "$CONFIG" "inbound" '"tproxy-in"')
|
||||
# CONFIG=$(sing_box_cm_sniff_route_rule "$CONFIG" "inbound" "tproxy-in")
|
||||
# CONFIG=$(sing_box_cm_sniff_route_rule "$CONFIG" "inbound" '["tproxy-in","dns-in"]')
|
||||
#######################################
|
||||
sing_box_cm_sniff_route_rule() {
|
||||
@@ -1019,6 +1028,8 @@ sing_box_cm_sniff_route_rule() {
|
||||
local key="$2"
|
||||
local value="$3"
|
||||
|
||||
value=$(_normalize_arg "$value")
|
||||
|
||||
echo "$config" | jq \
|
||||
--arg key "$key" \
|
||||
--argjson value "$value" \
|
||||
@@ -1060,9 +1071,9 @@ sing_box_cm_add_inline_ruleset() {
|
||||
# Outputs:
|
||||
# Writes updated JSON configuration to stdout
|
||||
# Example:
|
||||
# CONFIG=$(sing_box_cm_add_inline_ruleset_rule "$CONFIG" "inline-ruleset" "domain_suffix" '"telegram.org"')
|
||||
# CONFIG=$(sing_box_cm_add_inline_ruleset_rule "$CONFIG" "inline-ruleset" "domain_suffix" '"discord.com"')
|
||||
# CONFIG=$(sing_box_cm_add_inline_ruleset_rule "$CONFIG" "inline-ruleset" "ip_cidr" '"111.111.111.111/32"')
|
||||
# CONFIG=$(sing_box_cm_add_inline_ruleset_rule "$CONFIG" "inline-ruleset" "domain_suffix" "telegram.org")
|
||||
# CONFIG=$(sing_box_cm_add_inline_ruleset_rule "$CONFIG" "inline-ruleset" "domain_suffix" "discord.com")
|
||||
# CONFIG=$(sing_box_cm_add_inline_ruleset_rule "$CONFIG" "inline-ruleset" "ip_cidr" "111.111.111.111/32")
|
||||
#######################################
|
||||
sing_box_cm_add_inline_ruleset_rule() {
|
||||
local config="$1"
|
||||
@@ -1070,11 +1081,13 @@ sing_box_cm_add_inline_ruleset_rule() {
|
||||
local key="$3"
|
||||
local value="$4"
|
||||
|
||||
echo "$config" | jq \
|
||||
value=$(_normalize_arg "$value")
|
||||
|
||||
echo "$config" | jq -L /usr/lib/podkop \
|
||||
--arg tag "$tag" \
|
||||
--arg key "$key" \
|
||||
--argjson value "$value" \
|
||||
'import "helpers" as h;
|
||||
'import "helpers" as h {"search": "/usr/lib/podkop"};
|
||||
.route.rule_set |= map(
|
||||
if .tag == $tag then
|
||||
if has($key) then
|
||||
@@ -1232,4 +1245,13 @@ sing_box_cm_save_config_to_file() {
|
||||
--arg tag "$SERVICE_TAG" \
|
||||
'walk(if type == "object" then del(.[$tag]) else . end)' \
|
||||
> "$file_path"
|
||||
}
|
||||
}
|
||||
|
||||
_normalize_arg() {
|
||||
local value="$1"
|
||||
if echo "$value" | jq -e . > /dev/null 2>&1; then
|
||||
printf '%s' "$value"
|
||||
else
|
||||
printf '%s' "$value" | jq -R .
|
||||
fi
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user