mirror of
https://github.com/itdoginfo/podkop.git
synced 2025-12-06 11:36:50 +03:00
1432 lines
48 KiB
Bash
1432 lines
48 KiB
Bash
#
|
|
# Module: sing_box_config_manager.sh
|
|
#
|
|
# Purpose:
|
|
# This script provides a set of helper functions to simplify creation and management
|
|
# of sing-box configuration.
|
|
#
|
|
# Conventions:
|
|
# - All functions are prefixed with: sing_box_cm_*
|
|
# - "cm" stands for "config manager", shortened by convention
|
|
#
|
|
# Usage:
|
|
# Include this script in your ash script with:
|
|
# . /usr/lib/podkop/sing_box_config_manager.sh
|
|
#
|
|
# After that, sing_box_cm_* functions are available for generating
|
|
# and modifying sing-box JSON configuration.
|
|
|
|
SERVICE_TAG="__service_tag"
|
|
|
|
#######################################
|
|
# Configure the logging section of a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# disabled: boolean, true to disable logging
|
|
# level: string, e.g., "info", "debug", "warn"
|
|
# timestamp: boolean, true to include timestamps
|
|
# Outputs:
|
|
# Writes updated JSON configuration to stdout
|
|
# Example:
|
|
# CONFIG=$(sing_box_cm_configure_log "$CONFIG" false "info" true)
|
|
#######################################
|
|
sing_box_cm_configure_log() {
|
|
local config="$1"
|
|
local disabled="$2"
|
|
local level="$3"
|
|
local timestamp="$4"
|
|
|
|
echo "$config" | jq \
|
|
--argjson disabled "$disabled" \
|
|
--arg level "$level" \
|
|
--argjson timestamp "$timestamp" \
|
|
'.log = {
|
|
disabled: $disabled,
|
|
level: $level,
|
|
timestamp: $timestamp
|
|
}'
|
|
}
|
|
|
|
#######################################
|
|
# Configure the DNS section of a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# final: string, default dns server tag
|
|
# strategy: string, default domain strategy for resolving the domain names
|
|
# independent_cache: boolean, whether to use an independent DNS cache
|
|
# Outputs:
|
|
# Writes updated JSON configuration to stdout
|
|
# Example:
|
|
# CONFIG=$(sing_box_cm_configure_dns "$CONFIG" "direct-out" "ipv4_only" true)
|
|
#######################################
|
|
sing_box_cm_configure_dns() {
|
|
local config="$1"
|
|
local final="$2"
|
|
local strategy="$3"
|
|
local independent_cache="$4"
|
|
|
|
echo "$config" | jq \
|
|
--arg final "$final" \
|
|
--arg strategy "$strategy" \
|
|
--argjson independent_cache "$independent_cache" \
|
|
'.dns = {
|
|
servers: (.dns.servers // []),
|
|
rules: (.dns.rules // []),
|
|
final: $final,
|
|
strategy: $strategy,
|
|
independent_cache: $independent_cache
|
|
}'
|
|
|
|
}
|
|
|
|
#######################################
|
|
# Add a UDP DNS server to the DNS section of a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# tag: string, identifier for the DNS server
|
|
# server_address: string, IP address or hostname of the DNS server
|
|
# server_port: string or number, port of the DNS server
|
|
# domain_resolver: string, domain resolver to use for resolving domain names
|
|
# detour: string, tag of the upstream outbound
|
|
# Outputs:
|
|
# Writes updated JSON configuration to stdout
|
|
# Example:
|
|
# CONFIG=$(sing_box_cm_add_udp_dns_server "$CONFIG" "udp-server" "8.8.8.8" 53)
|
|
#######################################
|
|
sing_box_cm_add_udp_dns_server() {
|
|
local config="$1"
|
|
local tag="$2"
|
|
local server_address="$3"
|
|
local server_port="$4"
|
|
local domain_resolver="$5"
|
|
local detour="$6"
|
|
|
|
echo "$config" | jq \
|
|
--arg tag "$tag" \
|
|
--arg server_address "$server_address" \
|
|
--arg server_port "$server_port" \
|
|
--arg domain_resolver "$domain_resolver" \
|
|
--arg detour "$detour" \
|
|
'.dns.servers += [(
|
|
{
|
|
type: "udp",
|
|
tag: $tag,
|
|
server: $server_address,
|
|
server_port: ($server_port | tonumber)
|
|
}
|
|
+ (if $detour != "" then { detour: $detour } else {} end)
|
|
+ (if $domain_resolver != "" then { domain_resolver: $domain_resolver } else {} end)
|
|
)]'
|
|
}
|
|
|
|
#######################################
|
|
# Add a TLS DNS server to the DNS section of a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# tag: string, identifier for the DNS server
|
|
# server_address: string, IP address or hostname of the DNS server
|
|
# server_port: string or number, port of the DNS server
|
|
# domain_resolver: string, domain resolver to use for resolving domain names
|
|
# detour: string, tag of the upstream outbound
|
|
# Outputs:
|
|
# Writes updated JSON configuration to stdout
|
|
# Example:
|
|
# CONFIG=$(sing_box_cm_add_tls_dns_server "$CONFIG" "dot-server" "1.1.1.1" 853)
|
|
#######################################
|
|
sing_box_cm_add_tls_dns_server() {
|
|
local config="$1"
|
|
local tag="$2"
|
|
local server_address="$3"
|
|
local server_port="$4"
|
|
local domain_resolver="$5"
|
|
local detour="$6"
|
|
|
|
echo "$config" | jq \
|
|
--arg tag "$tag" \
|
|
--arg server_address "$server_address" \
|
|
--arg server_port "$server_port" \
|
|
--arg domain_resolver "$domain_resolver" \
|
|
--arg detour "$detour" \
|
|
'.dns.servers += [(
|
|
{
|
|
type: "tls",
|
|
tag: $tag,
|
|
server: $server_address,
|
|
server_port: ($server_port | tonumber)
|
|
}
|
|
+ (if $detour != "" then { detour: $detour } else {} end)
|
|
+ (if $domain_resolver != "" then { domain_resolver: $domain_resolver } else {} end)
|
|
)]'
|
|
}
|
|
|
|
#######################################
|
|
# Add an HTTPS DNS server to the DNS section of a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# tag: string, identifier for the DNS server
|
|
# server_address: string, IP address or hostname of the DNS server
|
|
# server_port: string or number, port of the DNS server
|
|
# path: string, optional URL path for HTTPS DNS requests
|
|
# headers: string, optional additional headers for HTTPS DNS requests
|
|
# domain_resolver: string, domain resolver to use for resolving domain names
|
|
# detour: string, tag of the upstream outbound
|
|
# Outputs:
|
|
# Writes updated JSON configuration to stdout
|
|
# Example:
|
|
# CONFIG=$(sing_box_cm_add_https_dns_server "$CONFIG" "doh-server" "1.1.1.1" 443)
|
|
#######################################
|
|
sing_box_cm_add_https_dns_server() {
|
|
local config="$1"
|
|
local tag="$2"
|
|
local server_address="$3"
|
|
local server_port="$4"
|
|
local path="$5"
|
|
local headers="$6"
|
|
local domain_resolver="$7"
|
|
local detour="$8"
|
|
|
|
echo "$config" | jq \
|
|
--arg tag "$tag" \
|
|
--arg server_address "$server_address" \
|
|
--arg server_port "$server_port" \
|
|
--arg path "$path" \
|
|
--arg headers "$headers" \
|
|
--arg domain_resolver "$domain_resolver" \
|
|
--arg detour "$detour" \
|
|
'.dns.servers += [(
|
|
{
|
|
type: "https",
|
|
tag: $tag,
|
|
server: $server_address,
|
|
server_port: ($server_port |tonumber)
|
|
}
|
|
+ (if $path != "" then { path: $path } else {} end)
|
|
+ (if $headers != "" then { headers: $headers } else {} end)
|
|
+ (if $detour != "" then { detour: $detour } else {} end)
|
|
+ (if $domain_resolver != "" then { domain_resolver: $domain_resolver } else {} end)
|
|
)]'
|
|
}
|
|
|
|
#######################################
|
|
# Add a FakeIP DNS server to the DNS section of a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# tag: string, identifier for the DNS server
|
|
# inet4_range: string, IPv4 range used for fake IP mapping
|
|
# Outputs:
|
|
# Writes updated JSON configuration to stdout
|
|
# Example:
|
|
# CONFIG=$(sing_box_cm_add_fakeip_dns_server "$CONFIG" "fakeip-server" "198.18.0.0/15")
|
|
#######################################
|
|
sing_box_cm_add_fakeip_dns_server() {
|
|
local config="$1"
|
|
local tag="$2"
|
|
local inet4_range="$3"
|
|
|
|
echo "$config" | jq \
|
|
--arg tag "$tag" \
|
|
--arg inet4_range "$inet4_range" \
|
|
'.dns.servers += [{
|
|
type: "fakeip",
|
|
tag: $tag,
|
|
inet4_range: $inet4_range,
|
|
}]'
|
|
}
|
|
|
|
#######################################
|
|
# Add a DNS routing rule to the DNS section of a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# server: string, target DNS server for the rule
|
|
# tag: string, identifier for the route rule
|
|
# Outputs:
|
|
# Writes updated JSON configuration to stdout
|
|
# Example:
|
|
# CONFIG=$(sing_box_cm_add_dns_route_rule "$CONFIG" "fakeip-server" "fakeip-dns-rule-id")
|
|
#######################################
|
|
sing_box_cm_add_dns_route_rule() {
|
|
local config="$1"
|
|
local server="$2"
|
|
local tag="$3"
|
|
|
|
echo "$config" | jq \
|
|
--arg server "$server" \
|
|
--arg service_tag "$SERVICE_TAG" \
|
|
--arg tag "$tag" \
|
|
'.dns.rules += [{
|
|
action: "route",
|
|
server: $server,
|
|
$service_tag: $tag
|
|
}]'
|
|
}
|
|
|
|
#######################################
|
|
# Patch a DNS routing rule in the DNS section of a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# tag: string, identifier of the rule to patch
|
|
# key: string, the key in the rule to update or add
|
|
# value: JSON value to assign to the key
|
|
# 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","second"]')
|
|
# 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"
|
|
local tag="$2"
|
|
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 {"search": "/usr/lib/podkop"};
|
|
.dns.rules |= map(
|
|
if .[$service_tag] == $tag then
|
|
if has($key) then
|
|
.[$key] |= h::extend_key_value(.; $value)
|
|
else
|
|
. + { ($key): $value }
|
|
end
|
|
else
|
|
.
|
|
end
|
|
)'
|
|
}
|
|
|
|
#######################################
|
|
# Add a DNS reject rule to the DNS section of a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# key: string, the key to set for the reject rule
|
|
# value: JSON value to assign to the key
|
|
# Outputs:
|
|
# Writes updated JSON configuration to stdout
|
|
# Example:
|
|
# 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" \
|
|
'.dns.rules += [{
|
|
action: "reject",
|
|
($key): $value
|
|
}]'
|
|
}
|
|
|
|
#######################################
|
|
# Add a TProxy inbound to the inbounds section of a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# tag: string, identifier for the inbound
|
|
# listen_address: string, IP address to listen on
|
|
# listen_port: number, port to listen on
|
|
# tcp_fast_open: boolean, enable or disable TCP Fast Open
|
|
# udp_fragment: boolean, enable or disable UDP fragmentation
|
|
# Outputs:
|
|
# Writes updated JSON configuration to stdout
|
|
# Example:
|
|
# CONFIG=$(sing_box_cm_add_tproxy_inbound "$CONFIG" "tproxy-in" "127.0.0.1" 6969 true true)
|
|
#######################################
|
|
sing_box_cm_add_tproxy_inbound() {
|
|
local config="$1"
|
|
local tag="$2"
|
|
local listen_address="$3"
|
|
local listen_port="$4"
|
|
local tcp_fast_open="$5"
|
|
local udp_fragment="$6"
|
|
|
|
echo "$config" | jq \
|
|
--arg tag "$tag" \
|
|
--arg listen_address "$listen_address" \
|
|
--argjson listen_port "$listen_port" \
|
|
--argjson tcp_fast_open "$tcp_fast_open" \
|
|
--argjson udp_fragment "$udp_fragment" \
|
|
'.inbounds += [{
|
|
type: "tproxy",
|
|
tag: $tag,
|
|
listen: $listen_address,
|
|
listen_port: $listen_port,
|
|
tcp_fast_open: $tcp_fast_open,
|
|
udp_fragment: $udp_fragment
|
|
}]'
|
|
}
|
|
|
|
#######################################
|
|
# Add a Direct inbound to the inbounds section of a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# tag: string, identifier for the inbound
|
|
# listen_address: string, IP address to listen on
|
|
# listen_port: number, port to listen on
|
|
# Outputs:
|
|
# Writes updated JSON configuration to stdout
|
|
# Example:
|
|
# CONFIG=$(sing_box_cm_add_direct_inbound "$CONFIG" "dns-in" "127.0.0.42" 53)
|
|
#######################################
|
|
sing_box_cm_add_direct_inbound() {
|
|
local config="$1"
|
|
local tag="$2"
|
|
local listen_address="$3"
|
|
local listen_port="$4"
|
|
|
|
echo "$config" | jq \
|
|
--arg tag "$tag" \
|
|
--arg listen_address "$listen_address" \
|
|
--argjson listen_port "$listen_port" \
|
|
'.inbounds += [{
|
|
type: "direct",
|
|
tag: $tag,
|
|
listen: $listen_address,
|
|
listen_port: $listen_port,
|
|
}]'
|
|
}
|
|
|
|
#######################################
|
|
# Add a Mixed inbound to the inbounds section of a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# tag: string, identifier for the inbound
|
|
# listen_address: string, IP address to listen on
|
|
# listen_port: number, port to listen on
|
|
# Outputs:
|
|
# Writes updated JSON configuration to stdout
|
|
# Example:
|
|
# CONFIG=$(sing_box_cm_add_mixed_inbound "$CONFIG" "tproxy-in" "192.168.1.1" 2080)
|
|
#######################################
|
|
sing_box_cm_add_mixed_inbound() {
|
|
local config="$1"
|
|
local tag="$2"
|
|
local listen_address="$3"
|
|
local listen_port="$4"
|
|
|
|
echo "$config" | jq \
|
|
--arg tag "$tag" \
|
|
--arg listen_address "$listen_address" \
|
|
--argjson listen_port "$listen_port" \
|
|
'.inbounds += [{
|
|
type: "mixed",
|
|
tag: $tag,
|
|
listen: $listen_address,
|
|
listen_port: $listen_port,
|
|
}]'
|
|
}
|
|
|
|
#######################################
|
|
# Add a Direct outbound to the outbounds section of a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# tag: string, identifier for the outbound
|
|
# Outputs:
|
|
# Writes updated JSON configuration to stdout
|
|
# Example:
|
|
# CONFIG=$(sing_box_cm_add_direct_outbound "$CONFIG" "direct-out")
|
|
#######################################
|
|
sing_box_cm_add_direct_outbound() {
|
|
local config="$1"
|
|
local tag="$2"
|
|
|
|
echo "$config" | jq \
|
|
--arg tag "$tag" \
|
|
'.outbounds += [{
|
|
type: "direct",
|
|
tag: $tag
|
|
}]'
|
|
}
|
|
|
|
#######################################
|
|
# Add a SOCKS5 outbound to the outbounds section of a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# tag: string, identifier for the outbound
|
|
# server_address: string, IP address or hostname of the SOCKS5 server
|
|
# server_port: number, port of the SOCKS5 server
|
|
# version: string, optional SOCKS version
|
|
# username: string, optional username for authentication
|
|
# password: string, optional password for authentication
|
|
# network: string, optional network type (e.g., "tcp")
|
|
# udp_over_tcp: number, optional version for UDP over TCP
|
|
# Outputs:
|
|
# Writes updated JSON configuration to stdout
|
|
# Example:
|
|
# CONFIG=$(sing_box_cm_add_socks5_outbound "$CONFIG" "socks5-out" "192.168.1.10" 1080)
|
|
#######################################
|
|
sing_box_cm_add_socks5_outbound() {
|
|
local config="$1"
|
|
local tag="$2"
|
|
local server_address="$3"
|
|
local server_port="$4"
|
|
local version="$5"
|
|
local username="$6"
|
|
local password="$7"
|
|
local network="$8"
|
|
local udp_over_tcp="$9"
|
|
|
|
echo "$config" | jq \
|
|
--arg tag "$tag" \
|
|
--arg server_address "$server_address" \
|
|
--arg server_port "$server_port" \
|
|
--arg version "$version" \
|
|
--arg username "$username" \
|
|
--arg password "$password" \
|
|
--arg network "$network" \
|
|
--arg udp_over_tcp "$udp_over_tcp" \
|
|
'.outbounds += [(
|
|
{
|
|
type: "socks",
|
|
tag: $tag,
|
|
server: $server_address,
|
|
server_port: ($server_port | tonumber)
|
|
}
|
|
+ (if $version != "" then {version: $version} else {} end)
|
|
+ (if $username != "" then {username: $username} else {} end)
|
|
+ (if $password != "" then {password: $password} else {} end)
|
|
+ (if $network != "" then {network: $network} else {} end)
|
|
+ (if $udp_over_tcp != "" then {
|
|
udp_over_tcp: {
|
|
enabled: true,
|
|
version: ($udp_over_tcp | tonumber)
|
|
}
|
|
} else {} end)
|
|
|
|
)]'
|
|
}
|
|
|
|
#######################################
|
|
# Add a Shadowsocks outbound to the outbounds section of a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# tag: string, identifier for the outbound
|
|
# server_address: string, IP address or hostname of the Shadowsocks server
|
|
# server_port: number, port of the Shadowsocks server
|
|
# method: string, encryption method
|
|
# password: string, password for encryption
|
|
# network: string, optional network type (e.g., "tcp")
|
|
# udp_over_tcp: number, optional version for UDP over TCP
|
|
# plugin: string, optional plugin name
|
|
# plugin_opts: string, optional plugin options
|
|
# Outputs:
|
|
# Writes updated JSON configuration to stdout
|
|
# Example:
|
|
# CONFIG=$(
|
|
# sing_box_cm_add_shadowsocks_outbound "$CONFIG" "ss-out" "127.0.0.1" 443 \
|
|
# "2022-blake3-aes-128-gcm" "8JCsPssfgS8tiRwiMlhARg=="
|
|
# )
|
|
#######################################
|
|
sing_box_cm_add_shadowsocks_outbound() {
|
|
local config="$1"
|
|
local tag="$2"
|
|
local server_address="$3"
|
|
local server_port="$4"
|
|
local method="$5"
|
|
local password="$6"
|
|
local network="$7"
|
|
local udp_over_tcp="$8"
|
|
local plugin="$9"
|
|
local plugin_opts="${10}"
|
|
|
|
echo "$config" | jq \
|
|
--arg tag "$tag" \
|
|
--arg server_address "$server_address" \
|
|
--arg server_port "$server_port" \
|
|
--arg method "$method" \
|
|
--arg password "$password" \
|
|
--arg plugin "$plugin" \
|
|
--arg plugin_opts "$plugin_opts" \
|
|
--arg network "$network" \
|
|
--arg udp_over_tcp "$udp_over_tcp" \
|
|
'.outbounds += [(
|
|
{
|
|
type: "shadowsocks",
|
|
tag: $tag,
|
|
server: $server_address,
|
|
server_port: ($server_port | tonumber),
|
|
method: $method,
|
|
password: $password
|
|
}
|
|
+ (if $plugin != "" then {plugin: $plugin} else {} end)
|
|
+ (if $plugin_opts != "" then {plugin_opts: $plugin_opts} else {} end)
|
|
+ (if $network != "" then {network: $network} else {} end)
|
|
+ (if $udp_over_tcp != "" then {
|
|
udp_over_tcp: {
|
|
enabled: true,
|
|
version: ($udp_over_tcp | tonumber)
|
|
}
|
|
} else {} end)
|
|
)]'
|
|
}
|
|
|
|
#######################################
|
|
# Add a VLESS outbound to the outbounds section of a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# tag: string, identifier for the outbound
|
|
# server_address: string, IP address or hostname of the VLESS server
|
|
# server_port: number, port of the VLESS server
|
|
# uuid: string, user UUID
|
|
# flow: string, optional flow setting
|
|
# network: string, optional network type (e.g., "tcp")
|
|
# packet_encoding: string, optional packet encoding method
|
|
# Outputs:
|
|
# Writes updated JSON configuration to stdout
|
|
# Example:
|
|
# CONFIG=$(
|
|
# sing_box_cm_add_vless_outbound "$CONFIG" "vless-reality-out" "example.com" 443 \
|
|
# "bf000d23-0752-40b4-affe-68f7707a9661" "xtls-rprx-vision"
|
|
# )
|
|
#######################################
|
|
sing_box_cm_add_vless_outbound() {
|
|
local config="$1"
|
|
local tag="$2"
|
|
local server_address="$3"
|
|
local server_port="$4"
|
|
local uuid="$5"
|
|
local flow="$6"
|
|
local network="$7"
|
|
local packet_encoding="$8"
|
|
|
|
echo "$config" | jq \
|
|
--arg tag "$tag" \
|
|
--arg server_address "$server_address" \
|
|
--arg server_port "$server_port" \
|
|
--arg uuid "$uuid" \
|
|
--arg flow "$flow" \
|
|
--arg network "$network" \
|
|
--arg packet_encoding "$packet_encoding" \
|
|
'.outbounds += [(
|
|
{
|
|
type: "vless",
|
|
tag: $tag,
|
|
server: $server_address,
|
|
server_port: ($server_port | tonumber),
|
|
uuid: $uuid
|
|
}
|
|
+ (if $flow != "" then {flow: $flow} else {} end)
|
|
+ (if $network != "" then {network: $network} else {} end)
|
|
+ (if $packet_encoding != "" then {packet_encoding: $packet_encoding} else {} end)
|
|
)]'
|
|
}
|
|
|
|
#######################################
|
|
# Add a Trojan outbound to the outbounds section of a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: string, JSON configuration
|
|
# tag: string, identifier for the outbound
|
|
# server_address: string, IP address or hostname of the Trojan server
|
|
# server_port: number, port of the Trojan server
|
|
# password: string, password for authentication
|
|
# network: string, optional network type (e.g., "tcp")
|
|
# Outputs:
|
|
# Writes updated JSON configuration to stdout
|
|
# Example:
|
|
# CONFIG=$(sing_box_cm_add_trojan_outbound "$CONFIG" "trojan-out" "example.com" 443 "supersecretpassword" "tcp")
|
|
#######################################
|
|
sing_box_cm_add_trojan_outbound() {
|
|
local config="$1"
|
|
local tag="$2"
|
|
local server_address="$3"
|
|
local server_port="$4"
|
|
local password="$5"
|
|
local network="$6"
|
|
|
|
echo "$config" | jq \
|
|
--arg tag "$tag" \
|
|
--arg server_address "$server_address" \
|
|
--arg server_port "$server_port" \
|
|
--arg password "$password" \
|
|
--arg network "$network" \
|
|
'.outbounds += [(
|
|
{
|
|
type: "trojan",
|
|
tag: $tag,
|
|
server: $server_address,
|
|
server_port: ($server_port | tonumber),
|
|
password: $password
|
|
}
|
|
+ (if $network != "" then {network: $network} else {} end)
|
|
)]'
|
|
}
|
|
|
|
#######################################
|
|
# Set gRPC transport settings for an outbound in a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# tag: string, identifier of the outbound to modify
|
|
# service_name: string, optional gRPC service name
|
|
# idle_timeout: string or number, optional idle timeout
|
|
# ping_timeout: string or number, optional ping timeout
|
|
# permit_without_stream: boolean, optional flag for permitting without stream
|
|
# Outputs:
|
|
# Writes updated JSON configuration to stdout
|
|
# Example:
|
|
# CONFIG=$(sing_box_cm_set_grpc_transport_for_outbound "$CONFIG" "vless-tls-grpc-out")
|
|
#######################################
|
|
sing_box_cm_set_grpc_transport_for_outbound() {
|
|
local config="$1"
|
|
local tag="$2"
|
|
local service_name="$3"
|
|
local idle_timeout="$4"
|
|
local ping_timeout="$5"
|
|
local permit_without_stream="$6"
|
|
|
|
echo "$config" | jq \
|
|
--arg tag "$tag" \
|
|
--arg service_name "$service_name" \
|
|
--arg idle_timeout "$idle_timeout" \
|
|
--arg ping_timeout "$ping_timeout" \
|
|
--arg permit_without_stream "$permit_without_stream" \
|
|
'.outbounds |= map(
|
|
if .tag == $tag then
|
|
. + {
|
|
transport: (
|
|
{ type: "grpc" }
|
|
+ (if $service_name != "" then {service_name: $service_name} else {} end)
|
|
+ (if $idle_timeout != "" then {idle_timeout: $idle_timeout} else {} end)
|
|
+ (if $ping_timeout != "" then {ping_timeout: $ping_timeout} else {} end)
|
|
+ (if $permit_without_stream != "" then {permit_without_stream: $permit_without_stream} else {} end)
|
|
)
|
|
}
|
|
else
|
|
.
|
|
end
|
|
)'
|
|
}
|
|
|
|
#######################################
|
|
# Set WebSocket transport settings for an outbound in a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# tag: string, identifier of the outbound to modify
|
|
# path: string, WebSocket path
|
|
# host: string, optional Host header for WebSocket
|
|
# max_early_data: number, optional maximum early data
|
|
# early_data_header_name: string, optional header name for early data
|
|
# Outputs:
|
|
# Writes updated JSON configuration to stdout
|
|
# Example:
|
|
# CONFIG=$(sing_box_cm_set_ws_transport_for_outbound "$CONFIG" "vless-tls-ws-out" "/path" "example.com")
|
|
#######################################
|
|
sing_box_cm_set_ws_transport_for_outbound() {
|
|
local config="$1"
|
|
local tag="$2"
|
|
local path="$3"
|
|
local host="$4"
|
|
local max_early_data="$5"
|
|
local early_data_header_name="$6"
|
|
|
|
# Not sure if the "Host" parameter in headers is correct — needs verification
|
|
echo "$config" | jq \
|
|
--arg tag "$tag" \
|
|
--arg path "$path" \
|
|
--arg host "$host" \
|
|
--arg max_early_data "$max_early_data" \
|
|
--arg early_data_header_name "$early_data_header_name" \
|
|
'.outbounds |= map(
|
|
if .tag == $tag then
|
|
. + {
|
|
transport: (
|
|
{
|
|
type: "ws",
|
|
path: $path
|
|
}
|
|
+ (if $host != "" then {headers: {Host: $host}} else {} end)
|
|
+ (if $max_early_data != "" then {max_early_data: $max_early_data | tonumber} else {} end)
|
|
+ (if $early_data_header_name != "" then
|
|
{early_data_header_name: $early_data_header_name}
|
|
else {} end)
|
|
)
|
|
}
|
|
else
|
|
.
|
|
end
|
|
)'
|
|
}
|
|
|
|
#######################################
|
|
# Set TLS settings for an outbound in a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# tag: string, identifier of the outbound to modify
|
|
# server_name: string, optional, used to verify the hostname on the returned certificates
|
|
# insecure: boolean, accept any server certificate
|
|
# alpn: JSON value or null, optional supported application level protocols
|
|
# utls_fingerprint: string, optional uTLS fingerprint
|
|
# reality_public_key: string, optional Reality public key
|
|
# reality_short_id: string, optional Reality short ID
|
|
# Outputs:
|
|
# Writes updated JSON configuration to stdout
|
|
# Example:
|
|
# CONFIG=$(
|
|
# sing_box_cm_set_tls_for_outbound "$CONFIG" "vless-reality-out" "example.com" false null "chrome" \
|
|
# "jNXHt1yRo0vDuchQlIP6Z0ZvjT3KtzVI-T4E7RoLJS0" "0123456789abcdef"
|
|
# )
|
|
#######################################
|
|
sing_box_cm_set_tls_for_outbound() {
|
|
local config="$1"
|
|
local tag="$2"
|
|
local server_name="$3"
|
|
local insecure="$4"
|
|
local alpn="$5"
|
|
local utls_fingerprint="$6"
|
|
local reality_public_key="$7"
|
|
local reality_short_id="$8"
|
|
|
|
echo "$config" | jq \
|
|
--arg tag "$tag" \
|
|
--arg server_name "$server_name" \
|
|
--arg insecure "$insecure" \
|
|
--argjson alpn "$alpn" \
|
|
--arg utls_fingerprint "$utls_fingerprint" \
|
|
--arg reality_public_key "$reality_public_key" \
|
|
--arg reality_short_id "$reality_short_id" \
|
|
'.outbounds |= map(
|
|
if .tag == $tag then
|
|
. + {
|
|
tls: (
|
|
{ enabled: true }
|
|
+ (if $server_name != "" then {server_name: $server_name} else {} end)
|
|
+ (if $insecure == "true" then {insecure: true} else {} end)
|
|
+ (if $alpn != null then {alpn: $alpn} else {} end)
|
|
+ (if $utls_fingerprint != "" then {
|
|
utls: {
|
|
enabled: true,
|
|
fingerprint: $utls_fingerprint
|
|
}
|
|
} else {} end)
|
|
+ (if $reality_public_key != "" then {
|
|
reality: {
|
|
enabled: true,
|
|
public_key: $reality_public_key,
|
|
short_id: $reality_short_id
|
|
}
|
|
} else {} end)
|
|
)
|
|
}
|
|
else
|
|
.
|
|
end
|
|
)'
|
|
}
|
|
|
|
#######################################
|
|
# Add a Direct outbound with a specific network interface to a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# tag: string, identifier for the outbound
|
|
# interface: string, network interface to bind the outbound
|
|
# domain_resolver: string, tag of the domain resolver to be used for this outbound (optional)
|
|
# Outputs:
|
|
# Writes updated JSON configuration to stdout
|
|
# Example:
|
|
# CONFIG=$(sing_box_cm_add_interface_outbound "$CONFIG" "warp-out" "awg0")
|
|
#######################################
|
|
sing_box_cm_add_interface_outbound() {
|
|
local config="$1"
|
|
local tag="$2"
|
|
local interface="$3"
|
|
local domain_resolver="$4"
|
|
|
|
echo "$config" | jq \
|
|
--arg tag "$tag" \
|
|
--arg interface "$interface" \
|
|
--arg domain_resolver "$domain_resolver" \
|
|
'.outbounds += [
|
|
{
|
|
type: "direct",
|
|
tag: $tag,
|
|
bind_interface: $interface
|
|
}
|
|
+ (if $domain_resolver != "" then {domain_resolver: $domain_resolver} else {} end)
|
|
]'
|
|
}
|
|
|
|
#######################################
|
|
# Add a raw outbound JSON object to the outbounds section of a sing-box configuration.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# tag: string, identifier for the outbound
|
|
# raw_outbound: JSON object, the raw outbound configuration to add
|
|
# Outputs:
|
|
# Writes updated JSON configuration to stdout
|
|
# Example:
|
|
# CONFIG=$(sing_box_cm_add_raw_outbound "$CONFIG" "raw-out" '{"type":"trojan","tag":"trojan-out","server":"127.0.0.1","server_port":1080,"password":"8JCsPssfgS8tiRwiMlhARg==","network":"tcp"}')
|
|
#######################################
|
|
sing_box_cm_add_raw_outbound() {
|
|
local config="$1"
|
|
local tag="$2"
|
|
local raw_outbound="$3"
|
|
|
|
echo "$config" | jq \
|
|
--arg tag "$tag" \
|
|
--argjson raw_outbound "$raw_outbound" \
|
|
'.outbounds += [(
|
|
$raw_outbound + {tag: $tag}
|
|
)]'
|
|
}
|
|
|
|
#######################################
|
|
# Add a URLTest outbound to the outbounds section of a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration
|
|
# tag: string, identifier for the URLTest outbound
|
|
# outbounds: JSON array of outbound tags to test
|
|
# url: URL to probe (optional)
|
|
# interval: test interval (e.g., "10s") (optional)
|
|
# tolerance: max latency difference tolerated (optional)
|
|
# idle_timeout: idle timeout duration (optional)
|
|
# interrupt_exist_connections: flag to interrupt existing connections ("true"/"false") (optional)
|
|
# Outputs:
|
|
# Writes updated JSON configuration to stdout
|
|
# Example:
|
|
# CONFIG=$(sing_box_cm_add_urltest_outbound "$CONFIG" "auto-select" '["proxy1","proxy2"]')
|
|
#######################################
|
|
sing_box_cm_add_urltest_outbound() {
|
|
local config="$1"
|
|
local tag="$2"
|
|
local outbounds="$3"
|
|
local url="$4"
|
|
local interval="$5"
|
|
local tolerance="$6"
|
|
local idle_timeout="$7"
|
|
local interrupt_exist_connections="$8"
|
|
|
|
echo "$config" | jq \
|
|
--arg tag "$tag" \
|
|
--argjson outbounds "$outbounds" \
|
|
--arg url "$url" \
|
|
--arg interval "$interval" \
|
|
--arg tolerance "$tolerance" \
|
|
--arg idle_timeout "$idle_timeout" \
|
|
--arg interrupt_exist_connections "$interrupt_exist_connections" \
|
|
'.outbounds += [
|
|
{
|
|
type: "urltest",
|
|
tag: $tag,
|
|
outbounds: $outbounds
|
|
}
|
|
+ (if $url != "" then {url: $url} else {} end)
|
|
+ (if $interval != "" then {interval: $interval} else {} end)
|
|
+ (if $tolerance != "" then {tolerance: ($tolerance | tonumber)} else {} end)
|
|
+ (if $idle_timeout != "" then {idle_timeout: $idle_timeout} else {} end)
|
|
+ (if $interrupt_exist_connections == "true" then {interrupt_exist_connections: true} else {} end)
|
|
]'
|
|
}
|
|
|
|
#######################################
|
|
# Add a Selector outbound to the outbounds section of a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration
|
|
# tag: string, identifier for the Selector outbound
|
|
# outbounds: JSON array of outbound tags to choose from
|
|
# default: default outbound tag if none selected (optional)
|
|
# interrupt_exist_connections: flag to interrupt existing connections ("true"/"false") (optional)
|
|
# Outputs:
|
|
# Writes updated JSON configuration to stdout
|
|
# Example:
|
|
# CONFIG=$(sing_box_cm_add_selector_outbound "$CONFIG" "select-proxy" '["proxy1","proxy2"]')
|
|
#######################################
|
|
sing_box_cm_add_selector_outbound() {
|
|
local config="$1"
|
|
local tag="$2"
|
|
local outbounds="$3"
|
|
local default="$4"
|
|
local interrupt_exist_connections="$5"
|
|
|
|
echo "$config" | jq \
|
|
--arg tag "$tag" \
|
|
--argjson outbounds "$outbounds" \
|
|
--arg default "$default" \
|
|
--arg interrupt_exist_connections "$interrupt_exist_connections" \
|
|
'.outbounds += [
|
|
{
|
|
type: "selector",
|
|
tag: $tag,
|
|
outbounds: $outbounds,
|
|
default: $default
|
|
}
|
|
+ (if $interrupt_exist_connections == "true" then {interrupt_exist_connections: true} else {} end)
|
|
]'
|
|
}
|
|
|
|
#######################################
|
|
# Configure the route section of a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# final: string, final outbound tag for unmatched traffic
|
|
# auto_detect_interface: boolean, enable or disable automatic interface detection
|
|
# default_domain_resolver: string, default DNS resolver for domain-based routing
|
|
# Outputs:
|
|
# Writes updated JSON configuration to stdout
|
|
# Example:
|
|
# CONFIG=$(sing_box_cm_configure_route "$CONFIG" "direct-out" true "udp-server")
|
|
#######################################
|
|
sing_box_cm_configure_route() {
|
|
local config="$1"
|
|
local final="$2"
|
|
local auto_detect_interface="$3"
|
|
local default_domain_resolver="$4"
|
|
|
|
echo "$config" | jq \
|
|
--arg final "$final" \
|
|
--argjson auto_detect_interface "$auto_detect_interface" \
|
|
--arg default_domain_resolver "$default_domain_resolver" \
|
|
'.route = {
|
|
rules: (.route.rules // []),
|
|
rule_set: (.route.rule_set // []),
|
|
final: $final,
|
|
auto_detect_interface: $auto_detect_interface,
|
|
default_domain_resolver: $default_domain_resolver
|
|
}'
|
|
}
|
|
|
|
#######################################
|
|
# Add a routing rule to the route section of a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# tag: string, identifier for the route rule
|
|
# inbound: string, inbound tag to match
|
|
# outbound: string, outbound tag to route matched traffic to
|
|
# Outputs:
|
|
# Writes updated JSON configuration to stdout
|
|
# Example:
|
|
# CONFIG=$(sing_box_cm_add_route_rule "$CONFIG" "main-route-rule" "tproxy-in" "main")
|
|
#######################################
|
|
sing_box_cm_add_route_rule() {
|
|
local config="$1"
|
|
local tag="$2"
|
|
local inbound="$3"
|
|
local outbound="$4"
|
|
|
|
echo "$config" | jq \
|
|
--arg service_tag "$SERVICE_TAG" \
|
|
--arg tag "$tag" \
|
|
--arg inbound "$inbound" \
|
|
--arg outbound "$outbound" \
|
|
'.route.rules += [{
|
|
action: "route",
|
|
inbound: $inbound,
|
|
outbound: $outbound,
|
|
$service_tag: $tag
|
|
}]'
|
|
}
|
|
|
|
#######################################
|
|
# Patch a routing rule in the route section of a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# tag: string, identifier of the route rule to patch
|
|
# key: string, the key in the rule to update or add
|
|
# value: JSON value to assign to the key
|
|
# Outputs:
|
|
# Writes updated JSON configuration to stdout
|
|
# Example:
|
|
# CONFIG=$(sing_box_cm_patch_route_rule "$CONFIG" "main-route-rule" "rule_set" "inline-ruleset")
|
|
#######################################
|
|
sing_box_cm_patch_route_rule() {
|
|
local config="$1"
|
|
local tag="$2"
|
|
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 {"search": "/usr/lib/podkop"};
|
|
.route.rules |= map(
|
|
if .[$service_tag] == $tag then
|
|
if has($key) then
|
|
.[$key] |= h::extend_key_value(.; $value)
|
|
else
|
|
. + { ($key): $value }
|
|
end
|
|
else
|
|
.
|
|
end
|
|
)'
|
|
}
|
|
|
|
#######################################
|
|
# Add a reject rule to the route section of a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# key: string, the key to set for the reject rule
|
|
# value: JSON value to assign to the key
|
|
# Outputs:
|
|
# Writes updated JSON configuration to stdout
|
|
# Example:
|
|
# CONFIG=$(sing_box_cm_add_reject_route_rule "$CONFIG" "reject-rule-tag")
|
|
#######################################
|
|
sing_box_cm_add_reject_route_rule() {
|
|
local config="$1"
|
|
local tag="$2"
|
|
local inbound="$3"
|
|
|
|
echo "$config" | jq \
|
|
--arg service_tag "$SERVICE_TAG" \
|
|
--arg tag "$tag" \
|
|
--arg inbound "$inbound" \
|
|
'.route.rules += [{
|
|
action: "reject",
|
|
inbound: $inbound,
|
|
$service_tag: $tag
|
|
}]'
|
|
}
|
|
|
|
#######################################
|
|
# Add a hijack-dns rule to the route section of a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# key: string, the key to set for the hijack-dns rule
|
|
# value: JSON value to assign to the key
|
|
# Outputs:
|
|
# Writes updated JSON configuration to stdout
|
|
# Example:
|
|
# 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" \
|
|
'.route.rules += [{
|
|
action: "hijack-dns",
|
|
($key): $value
|
|
}]'
|
|
}
|
|
|
|
#######################################
|
|
# Add a route-options rule to the route section of a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# tag: string, identifier for the route-options rule
|
|
# Outputs:
|
|
# Writes updated JSON configuration to stdout
|
|
# Example:
|
|
# CONFIG=$(sing_box_cm_add_options_route_rule "$CONFIG" "override-fakeip-port")
|
|
#######################################
|
|
sing_box_cm_add_options_route_rule() {
|
|
local config="$1"
|
|
local tag="$2"
|
|
|
|
echo "$config" | jq \
|
|
--arg service_tag "$SERVICE_TAG" \
|
|
--arg tag "$tag" \
|
|
'.route.rules += [{
|
|
action: "route-options",
|
|
$service_tag: $tag
|
|
}]'
|
|
}
|
|
|
|
#######################################
|
|
# Add a sniff rule to the route section of a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# key: string, the key to set for the sniff rule
|
|
# value: JSON value to assign to the key
|
|
# 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","dns-in"]')
|
|
#######################################
|
|
sing_box_cm_sniff_route_rule() {
|
|
local config="$1"
|
|
local key="$2"
|
|
local value="$3"
|
|
|
|
value=$(_normalize_arg "$value")
|
|
|
|
echo "$config" | jq \
|
|
--arg key "$key" \
|
|
--argjson value "$value" \
|
|
'.route.rules += [{
|
|
action: "sniff",
|
|
($key): $value
|
|
}]'
|
|
}
|
|
|
|
#######################################
|
|
# Add an inline ruleset to the route.rule_set section of a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# tag: string, identifier for the inline ruleset
|
|
# Outputs:
|
|
# Writes updated JSON configuration to stdout
|
|
# Example:
|
|
# CONFIG=$(sing_box_cm_add_inline_ruleset "$CONFIG" "inline-ruleset")
|
|
#######################################
|
|
sing_box_cm_add_inline_ruleset() {
|
|
local config="$1"
|
|
local tag="$2"
|
|
|
|
echo "$config" | jq \
|
|
--arg tag "$tag" \
|
|
'.route.rule_set += [{
|
|
type: "inline",
|
|
tag: $tag
|
|
}]'
|
|
}
|
|
|
|
#######################################
|
|
# Add or update a rule in an inline ruleset within the route.rule_set section of a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# tag: string, identifier of the inline ruleset
|
|
# key: string, the key in the ruleset to update or add
|
|
# value: JSON value to assign to the key
|
|
# 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")
|
|
#######################################
|
|
sing_box_cm_add_inline_ruleset_rule() {
|
|
local config="$1"
|
|
local tag="$2"
|
|
local key="$3"
|
|
local value="$4"
|
|
|
|
value=$(_normalize_arg "$value")
|
|
|
|
echo "$config" | jq -L /usr/lib/podkop \
|
|
--arg tag "$tag" \
|
|
--arg key "$key" \
|
|
--argjson value "$value" \
|
|
'import "helpers" as h {"search": "/usr/lib/podkop"};
|
|
.route.rule_set |= map(
|
|
if .tag == $tag then
|
|
if has($key) then
|
|
.[$key] |= h::extend_key_value(.; $value)
|
|
else
|
|
. + { ($key): $value }
|
|
end
|
|
else
|
|
.
|
|
end
|
|
)'
|
|
}
|
|
|
|
#######################################
|
|
# Add a local ruleset to the route.rule_set section of a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# tag: string, identifier for the local ruleset
|
|
# format: string, format of the local ruleset ("source" or "binary")
|
|
# path: string, file path to the local ruleset
|
|
# Outputs:
|
|
# Writes updated JSON configuration to stdout
|
|
# Example:
|
|
# CONFIG=$(sing_box_cm_add_local_ruleset "$CONFIG" "local-source-ruleset" "source" "/tmp/local-ruleset.json")
|
|
# CONFIG=$(sing_box_cm_add_local_ruleset "$CONFIG" "local-binary-ruleset" "binary" "/tmp/local-ruleset.srs")
|
|
#######################################
|
|
sing_box_cm_add_local_ruleset() {
|
|
local config="$1"
|
|
local tag="$2"
|
|
local format="$3"
|
|
local path="$4"
|
|
|
|
echo "$config" | jq \
|
|
--arg tag "$tag" \
|
|
--arg format "$format" \
|
|
--arg path "$path" \
|
|
'.route.rule_set += [{
|
|
type: "local",
|
|
tag: $tag,
|
|
format: $format,
|
|
path: $path
|
|
}]'
|
|
}
|
|
|
|
#######################################
|
|
# Add a remote ruleset to the route.rule_set section of a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# tag: string, identifier for the remote ruleset
|
|
# format: string, format of the remote ruleset ("source" or "binary")
|
|
# url: string, URL to download the ruleset from
|
|
# download_detour: string, optional detour tag for downloading
|
|
# update_interval: string, optional update interval for the ruleset
|
|
# Outputs:
|
|
# Writes updated JSON configuration to stdout
|
|
# Example:
|
|
# CONFIG=$(sing_box_cm_add_remote_ruleset "$CONFIG" "remote-source-ruleset" "source" "https://example.com/telegram.json")
|
|
#######################################
|
|
sing_box_cm_add_remote_ruleset() {
|
|
local config="$1"
|
|
local tag="$2"
|
|
local format="$3"
|
|
local url="$4"
|
|
local download_detour="$5"
|
|
local update_interval="$6"
|
|
|
|
echo "$config" | jq \
|
|
--arg tag "$tag" \
|
|
--arg format "$format" \
|
|
--arg url "$url" \
|
|
--arg download_detour "$download_detour" \
|
|
--arg update_interval "$update_interval" \
|
|
'.route.rule_set += [(
|
|
{
|
|
type: "remote",
|
|
tag: $tag,
|
|
format: $format,
|
|
url: $url
|
|
}
|
|
+ (if $download_detour != "" then { download_detour: $download_detour } else {} end)
|
|
+ (if $update_interval != "" then { update_interval: $update_interval } else {} end)
|
|
)]'
|
|
|
|
}
|
|
|
|
#######################################
|
|
# Configure the experimental cache_file section of a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# enabled: boolean, enable or disable file caching
|
|
# path: string, file path for cache storage
|
|
# store_fakeip: boolean, whether to store fake IPs in the cache
|
|
# Outputs:
|
|
# Writes updated JSON configuration to stdout
|
|
# Example:
|
|
# CONFIG=$(sing_box_cm_configure_cache_file "$CONFIG" true "/tmp/cache.db" true)
|
|
#######################################
|
|
sing_box_cm_configure_cache_file() {
|
|
local config="$1"
|
|
local enabled="$2"
|
|
local path="$3"
|
|
local store_fakeip="$4"
|
|
|
|
echo "$config" | jq \
|
|
--argjson enabled "$enabled" \
|
|
--arg path "$path" \
|
|
--argjson store_fakeip "$store_fakeip" \
|
|
'.experimental.cache_file = {
|
|
enabled: $enabled,
|
|
path: $path,
|
|
store_fakeip: $store_fakeip
|
|
}'
|
|
}
|
|
|
|
#######################################
|
|
# Configure the experimental clash_api section of a sing-box JSON configuration.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# external_controller: string, URL or path for the external controller
|
|
# external_ui: string, URL or path for the external UI
|
|
# Outputs:
|
|
# Writes updated JSON configuration to stdout
|
|
# Example:
|
|
# CONFIG=$(sing_box_cm_configure_clash_api "$CONFIG" "192.168.1.1:9090" "ui")
|
|
#######################################
|
|
sing_box_cm_configure_clash_api() {
|
|
local config="$1"
|
|
local external_controller="$2"
|
|
local external_ui="$3"
|
|
|
|
echo "$config" | jq \
|
|
--arg external_controller "$external_controller" \
|
|
--arg external_ui "$external_ui" \
|
|
'.experimental.clash_api = {
|
|
external_controller: $external_controller,
|
|
external_ui: $external_ui
|
|
}'
|
|
}
|
|
|
|
#######################################
|
|
# Create a local source ruleset JSON file for sing-box.
|
|
# Arguments:
|
|
# filepath: path to the JSON file to create
|
|
# Example:
|
|
# sing_box_cm_create_local_source_ruleset "/tmp/sing-box/ruleset.json"
|
|
#######################################
|
|
sing_box_cm_create_local_source_ruleset() {
|
|
local filepath="$1"
|
|
|
|
jq -n '{version: 3, rules: []}' > "$filepath"
|
|
}
|
|
|
|
#######################################
|
|
# Patch a local source ruleset JSON file for sing-box by adding unique! values to a given key.
|
|
# Arguments:
|
|
# filepath: path to the JSON file to patch
|
|
# key: the ruleset key to update (e.g., "ip_cidr")
|
|
# value: a JSON array of values to add to the key
|
|
# Example:
|
|
# sing_box_cm_patch_local_source_ruleset_rules "/tmp/sing-box/ruleset.json" "ip_cidr" '["1.1.1.1","2.2.2.2"]'
|
|
#######################################
|
|
sing_box_cm_patch_local_source_ruleset_rules() {
|
|
local filepath="$1"
|
|
local key="$2"
|
|
local value="$3"
|
|
|
|
value=$(_normalize_arg "$value")
|
|
|
|
local content
|
|
content="$(cat "$filepath")"
|
|
|
|
echo "$content" | jq \
|
|
--arg key "$key" \
|
|
--argjson value "$value" '
|
|
([.rules[]?[$key][]] | unique) as $existing
|
|
| ($value - $existing) as $value
|
|
| if ($value | length) > 0 then
|
|
.rules += [{($key): $value}]
|
|
else
|
|
.
|
|
end
|
|
' > "$filepath"
|
|
}
|
|
|
|
#######################################
|
|
# Save a sing-box JSON configuration to a file, removing service-specific tags.
|
|
# Arguments:
|
|
# config: JSON configuration (string)
|
|
# file_path: string, path to save the configuration file
|
|
# Outputs:
|
|
# Writes the cleaned JSON configuration to the specified file
|
|
# Example:
|
|
# sing_box_cm_save_config_to_file "$CONFIG" "/tmp/sing-box-config.json"
|
|
#######################################
|
|
sing_box_cm_save_config_to_file() {
|
|
local config="$1"
|
|
local filepath="$2"
|
|
|
|
echo "$config" | jq \
|
|
--arg tag "$SERVICE_TAG" \
|
|
'walk(if type == "object" then del(.[$tag]) else . end)' \
|
|
> "$filepath"
|
|
}
|
|
|
|
_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
|
|
}
|