mirror of
https://github.com/bolucat/Archive.git
synced 2026-04-23 00:17:16 +08:00
2112 lines
91 KiB
Bash
Executable File
2112 lines
91 KiB
Bash
Executable File
#!/bin/sh
|
||
# Copyright (C) 2018-2020 L-WRT Team
|
||
# Copyright (C) 2021-2025 xiaorouji
|
||
# Copyright (C) 2026 Openwrt-Passwall Organization
|
||
|
||
. /lib/functions.sh
|
||
. /lib/functions/service.sh
|
||
. /usr/share/libubox/jshn.sh
|
||
|
||
. /usr/share/passwall/utils.sh
|
||
GLOBAL_ACL_PATH=${TMP_ACL_PATH}/default
|
||
LUA_UTIL_PATH=/usr/lib/lua/luci/passwall
|
||
UTIL_SINGBOX=$LUA_UTIL_PATH/util_sing-box.lua
|
||
UTIL_SS=$LUA_UTIL_PATH/util_shadowsocks.lua
|
||
UTIL_XRAY=$LUA_UTIL_PATH/util_xray.lua
|
||
UTIL_TROJAN=$LUA_UTIL_PATH/util_trojan.lua
|
||
UTIL_NAIVE=$LUA_UTIL_PATH/util_naiveproxy.lua
|
||
UTIL_HYSTERIA2=$LUA_UTIL_PATH/util_hysteria2.lua
|
||
UTIL_TUIC=$LUA_UTIL_PATH/util_tuic.lua
|
||
SINGBOX_BIN=$(first_type $(config_t_get global_app sing_box_file) sing-box)
|
||
XRAY_BIN=$(first_type $(config_t_get global_app xray_file) xray)
|
||
|
||
check_run_environment() {
|
||
local prefer_nft=$(config_t_get global_forwarding prefer_nft 1)
|
||
local dnsmasq_info=$(dnsmasq -v 2>/dev/null)
|
||
local dnsmasq_ver=$(echo "$dnsmasq_info" | sed -n '1s/.*version \([0-9.]*\).*/\1/p')
|
||
# local dnsmasq_opts=$(echo "$dnsmasq_info" | grep -i "Compile time options")
|
||
local dnsmasq_ipset=0; echo "$dnsmasq_info" | grep -qw "ipset" && dnsmasq_ipset=1
|
||
local dnsmasq_nftset=0; echo "$dnsmasq_info" | grep -qw "nftset" && dnsmasq_nftset=1
|
||
local has_ipt=0; { command -v iptables-legacy || command -v iptables; } >/dev/null && has_ipt=1
|
||
local has_ipset=$(command -v ipset >/dev/null && echo 1 || echo 0)
|
||
local has_fw4=$(command -v fw4 >/dev/null && echo 1 || echo 0)
|
||
if [ "$prefer_nft" = "1" ]; then
|
||
if [ "$dnsmasq_nftset" -eq 1 ] && [ "$has_fw4" -eq 1 ]; then
|
||
USE_TABLES="nftables"
|
||
elif [ "$has_ipset" -eq 1 ] && [ "$has_ipt" -eq 1 ] && [ "$dnsmasq_ipset" -eq 1 ]; then
|
||
echolog "警告:nftables (fw4) 应用环境不完整,切换至 iptables。(has_fw4:$has_fw4/dnsmasq_nftset:$dnsmasq_nftset)"
|
||
USE_TABLES="iptables"
|
||
fi
|
||
else
|
||
if [ "$has_ipset" -eq 1 ] && [ "$has_ipt" -eq 1 ] && [ "$dnsmasq_ipset" -eq 1 ]; then
|
||
USE_TABLES="iptables"
|
||
elif [ "$dnsmasq_nftset" -eq 1 ] && [ "$has_fw4" -eq 1 ]; then
|
||
echolog "警告:iptables (fw3) 应用环境不完整,切换至 nftables。(has_ipt:$has_ipt/has_ipset:$has_ipset/dnsmasq_ipset:$dnsmasq_ipset)"
|
||
USE_TABLES="nftables"
|
||
fi
|
||
fi
|
||
|
||
if [ -n "$USE_TABLES" ]; then
|
||
local dep_list
|
||
local file_path="/usr/lib/opkg/info"
|
||
local file_ext=".control"
|
||
[ -d "/lib/apk/packages" ] && { file_path="/lib/apk/packages"; file_ext=".list"; }
|
||
|
||
if [ "$USE_TABLES" = "iptables" ]; then
|
||
dep_list="iptables-mod-tproxy iptables-mod-socket iptables-mod-iprange iptables-mod-conntrack-extra kmod-ipt-nat"
|
||
else
|
||
dep_list="kmod-nft-socket kmod-nft-tproxy kmod-nft-nat"
|
||
nftflag=1
|
||
local v_num=$(echo "$dnsmasq_ver" | tr -cd '0-9')
|
||
if [ "${v_num:-0}" -lt 290 ]; then
|
||
echolog "提示:Dnsmasq ($dnsmasq_ver) 低于 2.90,建议升级以增强稳定性。"
|
||
fi
|
||
fi
|
||
local pkg
|
||
for pkg in $dep_list; do
|
||
if [ ! -s "${file_path}/${pkg}${file_ext}" ]; then
|
||
echolog "警告:${USE_TABLES} 透明代理缺失基础依赖 ${pkg}!"
|
||
fi
|
||
done
|
||
else
|
||
echolog "警告:不满足任何透明代理系统环境。(has_fw4:$has_fw4/has_ipt:$has_ipt/has_ipset:$has_ipset/dnsmasq_nftset:$dnsmasq_nftset/dnsmasq_ipset:$dnsmasq_ipset)"
|
||
fi
|
||
}
|
||
|
||
run_ipt2socks() {
|
||
local flag proto tcp_tproxy local_port socks_address socks_port socks_username socks_password log_file
|
||
local _extra_param=""
|
||
eval_set_val $@
|
||
[ -n "$log_file" ] || log_file="/dev/null"
|
||
socks_address=$(get_host_ip "ipv4" ${socks_address})
|
||
[ -n "$socks_username" ] && [ -n "$socks_password" ] && _extra_param="${_extra_param} -a $socks_username -k $socks_password"
|
||
[ -n "$tcp_tproxy" ] || _extra_param="${_extra_param} -R"
|
||
case "$proto" in
|
||
UDP)
|
||
flag="${flag}_UDP"
|
||
_extra_param="${_extra_param} -U"
|
||
;;
|
||
TCP)
|
||
flag="${flag}_TCP"
|
||
_extra_param="${_extra_param} -T"
|
||
;;
|
||
*)
|
||
flag="${flag}_TCP_UDP"
|
||
;;
|
||
esac
|
||
_extra_param="${_extra_param} -o 60 -n 65535 -v"
|
||
ln_run "$(first_type ipt2socks)" "ipt2socks_${flag}" $log_file -l $local_port -b 0.0.0.0 -s $socks_address -p $socks_port ${_extra_param}
|
||
}
|
||
|
||
run_singbox() {
|
||
local flag type node tcp_redir_port tcp_proxy_way udp_redir_port socks_address socks_port socks_username socks_password http_address http_port http_username http_password
|
||
local dns_listen_port direct_dns_query_strategy direct_dns_port direct_dns_udp_server direct_dns_tcp_server remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh remote_dns_client_ip remote_fakedns remote_dns_query_strategy dns_cache dns_socks_address dns_socks_port
|
||
local loglevel log_file config_file server_host server_port no_run
|
||
eval_set_val $@
|
||
[ -z "$type" ] && {
|
||
type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
|
||
[ "$type" != "sing-box" ] && [ -n "$SINGBOX_BIN" ] && type="sing-box"
|
||
}
|
||
[ -z "$type" ] && return 1
|
||
[ -n "$log_file" ] || local log_file="/dev/null"
|
||
json_init
|
||
if [ "$log_file" = "/dev/null" ]; then
|
||
json_add_string "log" "0"
|
||
else
|
||
json_add_string "log" "1"
|
||
json_add_string "logfile" "${log_file}"
|
||
fi
|
||
[ -z "$loglevel" ] && local loglevel=$(config_t_get global loglevel "warn")
|
||
[ "$loglevel" = "warning" ] && loglevel="warn"
|
||
json_add_string "loglevel" "$loglevel"
|
||
|
||
[ -n "$flag" ] && json_add_string "flag" "$flag"
|
||
[ -n "$node" ] && json_add_string "node" "$node"
|
||
[ -n "$server_host" ] && json_add_string "server_host" "$server_host"
|
||
[ -n "$server_port" ] && json_add_string "server_port" "$server_port"
|
||
[ -n "$tcp_redir_port" ] && json_add_string "tcp_redir_port" "$tcp_redir_port"
|
||
[ -n "$tcp_proxy_way" ] && json_add_string "tcp_proxy_way" "$tcp_proxy_way"
|
||
[ -n "$udp_redir_port" ] && json_add_string "udp_redir_port" "$udp_redir_port"
|
||
[ -n "$socks_address" ] && json_add_string "local_socks_address" "$socks_address"
|
||
[ -n "$socks_port" ] && json_add_string "local_socks_port" "$socks_port"
|
||
[ -n "$socks_username" ] && [ -n "$socks_password" ] && {
|
||
json_add_string "local_socks_username" "$socks_username"
|
||
json_add_string "local_socks_password" "$socks_password"
|
||
}
|
||
[ -n "$http_address" ] && json_add_string "local_http_address" "$http_address"
|
||
[ -n "$http_port" ] && json_add_string "local_http_port" "$http_port"
|
||
[ -n "$http_username" ] && [ -n "$http_password" ] && {
|
||
json_add_string "local_http_username" "$http_username"
|
||
json_add_string "local_http_password" "$http_password"
|
||
}
|
||
[ -n "$dns_socks_address" ] && [ -n "$dns_socks_port" ] && {
|
||
json_add_string "dns_socks_address" "${dns_socks_address}"
|
||
json_add_string "dns_socks_port" "${dns_socks_port}"
|
||
}
|
||
[ -n "$dns_listen_port" ] && json_add_string "dns_listen_port" "${dns_listen_port}"
|
||
[ -n "$dns_cache" ] && json_add_string "dns_cache" "${dns_cache}"
|
||
|
||
if [ -n "$direct_dns_udp_server" ]; then
|
||
direct_dns_port=$(echo ${direct_dns_udp_server} | awk -F '#' '{print $2}')
|
||
json_add_string "direct_dns_udp_server" "$(echo ${direct_dns_udp_server} | awk -F '#' '{print $1}')"
|
||
elif [ -n "$direct_dns_tcp_server" ]; then
|
||
direct_dns_port=$(echo ${direct_dns_tcp_server} | awk -F '#' '{print $2}')
|
||
json_add_string "direct_dns_tcp_server" "$(echo ${direct_dns_tcp_server} | awk -F '#' '{print $1}')"
|
||
else
|
||
local local_dns=$(echo -n $(echo "${LOCAL_DNS}" | sed "s/,/\n/g" | head -n1) | tr " " ",")
|
||
json_add_string "direct_dns_udp_server" "$(echo ${local_dns} | awk -F '#' '{print $1}')"
|
||
direct_dns_port=$(echo ${local_dns} | awk -F '#' '{print $2}')
|
||
fi
|
||
json_add_string "direct_dns_port" "${direct_dns_port:-53}"
|
||
direct_dns_query_strategy=${direct_dns_query_strategy:-UseIP}
|
||
json_add_string "direct_dns_query_strategy" "${direct_dns_query_strategy}"
|
||
|
||
[ -n "$remote_dns_query_strategy" ] && json_add_string "remote_dns_query_strategy" "${remote_dns_query_strategy}"
|
||
case "$remote_dns_protocol" in
|
||
udp|tcp)
|
||
local _proto="$remote_dns_protocol"
|
||
local _dns=$(get_first_dns remote_dns_${_proto}_server 53 | sed 's/#/:/g')
|
||
local _dns_address=$(echo ${_dns} | awk -F ':' '{print $1}')
|
||
local _dns_port=$(echo ${_dns} | awk -F ':' '{print $2}')
|
||
json_add_string "remote_dns_${_proto}_server" "${_dns_address}"
|
||
json_add_string "remote_dns_${_proto}_port" "${_dns_port}"
|
||
;;
|
||
doh|http3)
|
||
local _doh_url _doh_host _doh_port _doh_bootstrap
|
||
parse_doh "$remote_dns_doh" _doh_url _doh_host _doh_port _doh_bootstrap
|
||
[ -n "$_doh_bootstrap" ] && json_add_string "remote_dns_doh_ip" "${_doh_bootstrap}"
|
||
json_add_string "remote_dns_doh_port" "${_doh_port}"
|
||
json_add_string "remote_dns_doh_url" "${_doh_url}"
|
||
json_add_string "remote_dns_doh_host" "${_doh_host}"
|
||
[ "$remote_dns_protocol" = "http3" ] && json_add_string "remote_dns_http3" "1"
|
||
;;
|
||
esac
|
||
[ -n "$remote_dns_client_ip" ] && json_add_string "remote_dns_client_ip" "${remote_dns_client_ip}"
|
||
[ "$remote_fakedns" = "1" ] && json_add_string "remote_dns_fake" "1"
|
||
[ -n "$no_run" ] && json_add_string "no_run" "1"
|
||
local _json_arg="$(json_dump)"
|
||
lua $UTIL_SINGBOX gen_config "${_json_arg}" > $config_file
|
||
[ -n "$no_run" ] && return
|
||
|
||
local test_log_file=$log_file
|
||
[ "$test_log_file" = "/dev/null" ] && test_log_file="${TMP_PATH}/${config_file##*/}_test.log"
|
||
$SINGBOX_BIN check -c "$config_file" > $test_log_file 2>&1; local status=$?
|
||
if [ "${status}" = 0 ]; then
|
||
ln_run "$SINGBOX_BIN" "sing-box" "${log_file}" run -c "$config_file"
|
||
else
|
||
echolog "Sing-box 配置文件 $config_file 校验有误,进程启动失败,错误信息:"
|
||
cat ${test_log_file} >> ${LOG_FILE}
|
||
fi
|
||
[ "$test_log_file" != "$log_file" ] && rm -f "${test_log_file}"
|
||
}
|
||
|
||
run_xray() {
|
||
local flag type node tcp_redir_port tcp_proxy_way udp_redir_port socks_address socks_port socks_username socks_password http_address http_port http_username http_password
|
||
local dns_listen_port direct_dns_query_strategy direct_dns_port direct_dns_udp_server direct_dns_tcp_server remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh remote_dns_client_ip remote_fakedns remote_dns_query_strategy dns_cache dns_socks_address dns_socks_port
|
||
local loglevel log_file config_file server_host server_port no_run
|
||
eval_set_val $@
|
||
[ -z "$type" ] && {
|
||
type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
|
||
[ "$type" != "xray" ] && [ -n "$XRAY_BIN" ] && type="xray"
|
||
}
|
||
[ -z "$type" ] && return 1
|
||
json_init
|
||
[ -n "$log_file" ] || local log_file="/dev/null"
|
||
[ -z "$loglevel" ] && local loglevel=$(config_t_get global loglevel "warning")
|
||
[ -n "$flag" ] && json_add_string "flag" "$flag"
|
||
[ -n "$node" ] && json_add_string "node" "$node"
|
||
[ -n "$server_host" ] && json_add_string "server_host" "$server_host"
|
||
[ -n "$server_port" ] && json_add_string "server_port" "$server_port"
|
||
[ -n "$tcp_redir_port" ] && json_add_string "tcp_redir_port" "$tcp_redir_port"
|
||
[ -n "$tcp_proxy_way" ] && json_add_string "tcp_proxy_way" "$tcp_proxy_way"
|
||
[ -n "$udp_redir_port" ] && json_add_string "udp_redir_port" "$udp_redir_port"
|
||
[ -n "$socks_address" ] && json_add_string "local_socks_address" "$socks_address"
|
||
[ -n "$socks_port" ] && json_add_string "local_socks_port" "$socks_port"
|
||
[ -n "$socks_username" ] && [ -n "$socks_password" ] && {
|
||
json_add_string "local_socks_username" "$socks_username"
|
||
json_add_string "local_socks_password" "$socks_password"
|
||
}
|
||
[ -n "$http_address" ] && json_add_string "local_http_address" "$http_address"
|
||
[ -n "$http_port" ] && json_add_string "local_http_port" "$http_port"
|
||
[ -n "$http_username" ] && [ -n "$http_password" ] && {
|
||
json_add_string "local_http_username" "$http_username"
|
||
json_add_string "local_http_password" "$http_password"
|
||
}
|
||
[ -n "$dns_socks_address" ] && [ -n "$dns_socks_port" ] && {
|
||
json_add_string "dns_socks_address" "${dns_socks_address}"
|
||
json_add_string "dns_socks_port" "${dns_socks_port}"
|
||
}
|
||
[ -n "$dns_listen_port" ] && json_add_string "dns_listen_port" "${dns_listen_port}"
|
||
|
||
if [ -n "$direct_dns_udp_server" ]; then
|
||
direct_dns_port=$(echo ${direct_dns_udp_server} | awk -F '#' '{print $2}')
|
||
json_add_string "direct_dns_udp_server" "$(echo ${direct_dns_udp_server} | awk -F '#' '{print $1}')"
|
||
elif [ -n "$direct_dns_tcp_server" ]; then
|
||
direct_dns_port=$(echo ${direct_dns_tcp_server} | awk -F '#' '{print $2}')
|
||
json_add_string "direct_dns_tcp_server" "$(echo ${direct_dns_tcp_server} | awk -F '#' '{print $1}')"
|
||
else
|
||
local local_dns=$(echo -n $(echo "${LOCAL_DNS}" | sed "s/,/\n/g" | head -n1) | tr " " ",")
|
||
json_add_string "direct_dns_udp_server" "$(echo ${local_dns} | awk -F '#' '{print $1}')"
|
||
direct_dns_port=$(echo ${local_dns} | awk -F '#' '{print $2}')
|
||
fi
|
||
json_add_string "direct_dns_port" "${direct_dns_port:-53}"
|
||
|
||
direct_dns_query_strategy=${direct_dns_query_strategy:-UseIP}
|
||
json_add_string "direct_dns_query_strategy" "${direct_dns_query_strategy}"
|
||
[ -n "$remote_dns_query_strategy" ] && json_add_string "remote_dns_query_strategy" "${remote_dns_query_strategy}"
|
||
[ -n "$remote_dns_client_ip" ] && json_add_string "remote_dns_client_ip" "${remote_dns_client_ip}"
|
||
[ "$remote_fakedns" = "1" ] && json_add_string "remote_dns_fake" "1"
|
||
[ -n "$dns_cache" ] && json_add_string "dns_cache" "${dns_cache}"
|
||
|
||
case "$remote_dns_protocol" in
|
||
udp)
|
||
local _dns=$(get_first_dns remote_dns_udp_server 53 | sed 's/#/:/g')
|
||
local _dns_address=$(echo ${_dns} | awk -F ':' '{print $1}')
|
||
local _dns_port=$(echo ${_dns} | awk -F ':' '{print $2}')
|
||
json_add_string "remote_dns_udp_server" "${_dns_address}"
|
||
json_add_string "remote_dns_udp_port" "${_dns_port}"
|
||
;;
|
||
tcp|tcp+doh)
|
||
local _dns=$(get_first_dns remote_dns_tcp_server 53 | sed 's/#/:/g')
|
||
local _dns_address=$(echo ${_dns} | awk -F ':' '{print $1}')
|
||
local _dns_port=$(echo ${_dns} | awk -F ':' '{print $2}')
|
||
json_add_string "remote_dns_tcp_server" "${_dns_address}"
|
||
json_add_string "remote_dns_tcp_port" "${_dns_port}"
|
||
[ "$remote_dns_protocol" = "tcp+doh" ] && {
|
||
local _doh_url _doh_host _doh_port _doh_bootstrap
|
||
parse_doh "$remote_dns_doh" _doh_url _doh_host _doh_port _doh_bootstrap
|
||
[ -n "$_doh_bootstrap" ] && json_add_string "remote_dns_doh_ip" "${_doh_bootstrap}"
|
||
json_add_string "remote_dns_doh_port" "${_doh_port}"
|
||
json_add_string "remote_dns_doh_url" "${_doh_url}"
|
||
json_add_string "remote_dns_doh_host" "${_doh_host}"
|
||
}
|
||
;;
|
||
esac
|
||
json_add_string "loglevel" "$loglevel"
|
||
[ -n "$no_run" ] && json_add_string "no_run" "1"
|
||
local _json_arg="$(json_dump)"
|
||
lua $UTIL_XRAY gen_config "${_json_arg}" > $config_file
|
||
[ -n "$no_run" ] && return
|
||
|
||
local test_log_file=$log_file
|
||
[ "$test_log_file" = "/dev/null" ] && test_log_file="${TMP_PATH}/${config_file##*/}_test.log"
|
||
$XRAY_BIN run -test -c "$config_file" > $test_log_file; local status=$?
|
||
if [ "${status}" = 0 ]; then
|
||
ln_run "$XRAY_BIN" "xray" "${log_file}" run -c "$config_file"
|
||
else
|
||
echolog "Xray 配置文件 $config_file 校验有误,进程启动失败,错误信息:"
|
||
cat ${test_log_file} >> ${LOG_FILE}
|
||
fi
|
||
[ "$test_log_file" != "$log_file" ] && rm -f "${test_log_file}"
|
||
}
|
||
|
||
run_dns2socks() {
|
||
local flag socks socks_address socks_port socks_username socks_password listen_address listen_port dns cache log_file
|
||
local _extra_param=""
|
||
eval_set_val $@
|
||
[ -n "$flag" ] && flag="_${flag}"
|
||
[ -n "$log_file" ] || log_file="/dev/null"
|
||
dns=$(get_first_dns dns 53 | sed 's/#/:/g')
|
||
[ -n "$socks" ] && {
|
||
socks="${socks//#/:}"
|
||
socks_address=$(echo $socks | awk -F ':' '{print $1}')
|
||
socks_port=$(echo $socks | awk -F ':' '{print $2}')
|
||
}
|
||
[ -n "$socks_username" ] && [ -n "$socks_password" ] && _extra_param="${_extra_param} /u $socks_username /p $socks_password"
|
||
[ -z "$cache" ] && cache=1
|
||
[ "$cache" = "0" ] && _extra_param="${_extra_param} /d"
|
||
ln_run "$(first_type dns2socks)" "dns2socks${flag}" $log_file ${_extra_param} "${socks_address}:${socks_port}" "${dns}" "${listen_address}:${listen_port}"
|
||
}
|
||
|
||
run_chinadns_ng() {
|
||
local _flag _listen_port _dns_local _dns_trust _no_ipv6_trust _use_direct_list _use_proxy_list _gfwlist _chnlist _default_mode _default_tag _no_logic_log _tcp_node _remote_fakedns _filter_https
|
||
local _extra_param=""
|
||
eval_set_val $@
|
||
|
||
local _CONF_FILE=$TMP_ACL_PATH/$_flag/chinadns_ng.conf
|
||
local _LOG_FILE="/dev/null"
|
||
[ "$(config_t_get global log_chinadns_ng "0")" == "1" ] && _LOG_FILE=$TMP_ACL_PATH/$_flag/chinadns_ng.log
|
||
|
||
_extra_param="-FLAG ${_flag} -TCP_NODE ${_tcp_node} -LISTEN_PORT ${_listen_port} -DNS_LOCAL ${_dns_local} -DNS_TRUST ${_dns_trust}"
|
||
_extra_param="${_extra_param} -USE_DIRECT_LIST ${_use_direct_list} -USE_PROXY_LIST ${_use_proxy_list} -USE_BLOCK_LIST ${_use_block_list}"
|
||
_extra_param="${_extra_param} -GFWLIST ${_gfwlist} -CHNLIST ${_chnlist} -NO_IPV6_TRUST ${_no_ipv6_trust} -DEFAULT_MODE ${_default_mode}"
|
||
_extra_param="${_extra_param} -DEFAULT_TAG ${_default_tag} -NFTFLAG ${nftflag} -NO_LOGIC_LOG ${_no_logic_log} -REMOTE_FAKEDNS ${_remote_fakedns}"
|
||
_extra_param="${_extra_param} -FILTER_HTTPS ${_filter_https} -LOG_FILE ${_LOG_FILE}"
|
||
|
||
lua $APP_PATH/helper_chinadns_add.lua ${_extra_param} > ${_CONF_FILE}
|
||
ln_run "$(first_type chinadns-ng)" chinadns-ng "${_LOG_FILE}" -C ${_CONF_FILE}
|
||
}
|
||
|
||
run_socks() {
|
||
local flag node bind socks_port config_file http_port http_config_file relay_port log_file no_run
|
||
eval_set_val $@
|
||
[ -n "$config_file" ] && [ -z "$(echo ${config_file} | grep $TMP_PATH)" ] && config_file=$TMP_PATH/$config_file
|
||
[ -n "$http_port" ] || http_port=0
|
||
[ -n "$http_config_file" ] && [ -z "$(echo ${http_config_file} | grep $TMP_PATH)" ] && http_config_file=$TMP_PATH/$http_config_file
|
||
if [ -n "$log_file" ] && [ -z "$(echo ${log_file} | grep $TMP_PATH)" ]; then
|
||
log_file=$TMP_PATH/$log_file
|
||
else
|
||
log_file="/dev/null"
|
||
fi
|
||
|
||
local node2socks_port=0
|
||
local type remarks server_host server_port
|
||
if is_socks_wrap "$node"; then
|
||
node2socks_port=$(config_n_get ${node#Socks_} port 0)
|
||
fi
|
||
if [ "$node2socks_port" = "0" ]; then
|
||
type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
|
||
remarks=$(config_n_get $node remarks)
|
||
server_host=$(config_n_get $node address)
|
||
server_port=$(config_n_get $node port)
|
||
else
|
||
type="socks"
|
||
server_host="127.0.0.1"
|
||
server_port=$node2socks_port
|
||
remarks="Socks 配置($server_port 端口)"
|
||
fi
|
||
|
||
[ -n "$relay_port" ] && {
|
||
server_host="127.0.0.1"
|
||
server_port=$relay_port
|
||
}
|
||
local error_msg tmp
|
||
|
||
if [ -n "$server_host" ] && [ -n "$server_port" ]; then
|
||
check_host $server_host
|
||
[ $? != 0 ] && {
|
||
echolog " - Socks节点:[$remarks]${server_host} 是非法的服务器地址,无法启动!"
|
||
return 1
|
||
}
|
||
tmp="${server_host}:${server_port}"
|
||
else
|
||
error_msg="某种原因,此 Socks 服务的相关配置已失联,启动中止!"
|
||
fi
|
||
|
||
if [ "$type" == "sing-box" ] || [ "$type" == "xray" ]; then
|
||
local protocol=$(config_n_get $node protocol)
|
||
if [ "$protocol" == "_balancing" ] || [ "$protocol" == "_shunt" ] || [ "$protocol" == "_iface" ] || [ "$protocol" == "_urltest" ]; then
|
||
unset error_msg
|
||
fi
|
||
fi
|
||
|
||
[ -n "${error_msg}" ] && {
|
||
[ "$bind" != "127.0.0.1" ] && echolog " - Socks节点:[$remarks]${tmp},启动中止 ${bind}:${socks_port} ${error_msg}"
|
||
return 1
|
||
}
|
||
[ "$bind" != "127.0.0.1" ] && echolog " - Socks节点:[$remarks]${tmp},启动 ${bind}:${socks_port}"
|
||
|
||
json_init
|
||
json_add_string "node" "${node}"
|
||
json_add_string "server_host" "${server_host}"
|
||
json_add_string "server_port" "${server_port}"
|
||
case "$type" in
|
||
socks)
|
||
local _socks_address _socks_port _socks_username _socks_password
|
||
if [ "$node2socks_port" = "0" ]; then
|
||
_socks_address=$(config_n_get $node address)
|
||
_socks_port=$(config_n_get $node port)
|
||
_socks_username=$(config_n_get $node username)
|
||
_socks_password=$(config_n_get $node password)
|
||
else
|
||
_socks_address="127.0.0.1"
|
||
_socks_port=$node2socks_port
|
||
fi
|
||
[ "$http_port" != "0" ] && {
|
||
http_flag=1
|
||
config_file="${config_file//SOCKS/HTTP_SOCKS}"
|
||
json_add_string "local_http_address" "$bind"
|
||
json_add_string "local_http_port" "$http_port"
|
||
}
|
||
json_add_null "server_host"
|
||
json_add_null "server_port"
|
||
json_add_string "local_socks_address" "$bind"
|
||
json_add_string "local_socks_port" "$socks_port"
|
||
json_add_string "server_proto" "socks"
|
||
json_add_string "server_address" "${_socks_address}"
|
||
json_add_string "server_port" "${_socks_port}"
|
||
json_add_string "server_username" "${_socks_username}"
|
||
json_add_string "server_password" "${_socks_password}"
|
||
if [ -n "${SINGBOX_BIN}" ]; then
|
||
type="sing-box"
|
||
local bin="${SINGBOX_BIN}"
|
||
local util="${UTIL_SINGBOX}"
|
||
elif [ -n "${XRAY_BIN}" ]; then
|
||
type="xray"
|
||
local bin="${XRAY_BIN}"
|
||
local util="${UTIL_XRAY}"
|
||
fi
|
||
[ -n "${bin}" ] && [ -n "${util}" ] && {
|
||
lua ${util} gen_proto_config "$(json_dump)" > $config_file
|
||
[ -n "$no_run" ] || ln_run "$bin" $type $log_file run -c "$config_file"
|
||
}
|
||
unset bin util
|
||
;;
|
||
sing-box)
|
||
[ "$http_port" != "0" ] && {
|
||
http_flag=1
|
||
config_file="${config_file//SOCKS/HTTP_SOCKS}"
|
||
local _args="http_address=$bind http_port=$http_port"
|
||
}
|
||
[ -n "$relay_port" ] && _args="${_args} server_host=$server_host server_port=$server_port"
|
||
[ -n "$no_run" ] && _args="${_args} no_run=1"
|
||
run_singbox flag=$flag node=$node socks_address=$bind socks_port=$socks_port config_file=$config_file log_file=$log_file ${_args}
|
||
;;
|
||
xray)
|
||
[ "$http_port" != "0" ] && {
|
||
http_flag=1
|
||
config_file="${config_file//SOCKS/HTTP_SOCKS}"
|
||
local _args="http_address=$bind http_port=$http_port"
|
||
}
|
||
[ -n "$relay_port" ] && _args="${_args} server_host=$server_host server_port=$server_port"
|
||
[ -n "$no_run" ] && _args="${_args} no_run=1"
|
||
run_xray flag=$flag node=$node socks_address=$bind socks_port=$socks_port config_file=$config_file log_file=$log_file ${_args}
|
||
;;
|
||
trojan*)
|
||
json_add_string "run_type" "client"
|
||
json_add_string "local_addr" "$bind"
|
||
json_add_string "local_port" "$socks_port"
|
||
lua $UTIL_TROJAN gen_config "$(json_dump)" > $config_file
|
||
[ -n "$no_run" ] || ln_run "$(first_type ${type})" "${type}" $log_file -c "$config_file"
|
||
;;
|
||
naiveproxy)
|
||
json_add_string "run_type" "socks"
|
||
json_add_string "local_addr" "$bind"
|
||
json_add_string "local_port" "$socks_port"
|
||
lua $UTIL_NAIVE gen_config "$(json_dump)" > $config_file
|
||
[ -n "$no_run" ] || ln_run "$(first_type naive)" naive $log_file "$config_file"
|
||
;;
|
||
ssr)
|
||
json_add_string "local_addr" "$bind"
|
||
json_add_string "local_port" "$socks_port"
|
||
lua $UTIL_SS gen_config "$(json_dump)" > $config_file
|
||
[ -n "$no_run" ] || ln_run "$(first_type ssr-local)" "ssr-local" $log_file -c "$config_file" -v -u
|
||
;;
|
||
ss)
|
||
[ -n "$no_run" ] || {
|
||
local plugin_sh="${config_file%.json}_plugin.sh"
|
||
json_add_string "plugin_sh" "$plugin_sh"
|
||
}
|
||
json_add_string "local_addr" "$bind"
|
||
json_add_string "local_port" "$socks_port"
|
||
json_add_string "mode" "tcp_and_udp"
|
||
lua $UTIL_SS gen_config "$(json_dump)" > $config_file
|
||
[ -n "$no_run" ] || ln_run "$(first_type ss-local)" "ss-local" $log_file -c "$config_file" -v
|
||
;;
|
||
ss-rust)
|
||
[ "$http_port" != "0" ] && {
|
||
http_flag=1
|
||
config_file="${config_file//SOCKS/HTTP_SOCKS}"
|
||
json_add_string "local_http_address" "$bind"
|
||
json_add_string "local_http_port" "$http_port"
|
||
}
|
||
[ -n "$no_run" ] || {
|
||
local plugin_sh="${config_file%.json}_plugin.sh"
|
||
json_add_string "plugin_sh" "$plugin_sh"
|
||
}
|
||
json_add_string "local_socks_address" "$bind"
|
||
json_add_string "local_socks_port" "$socks_port"
|
||
lua $UTIL_SS gen_config "$(json_dump)" > $config_file
|
||
[ -n "$no_run" ] || ln_run "$(first_type sslocal)" "sslocal" $log_file -c "$config_file" -v
|
||
;;
|
||
hysteria2)
|
||
[ "$http_port" != "0" ] && {
|
||
http_flag=1
|
||
config_file="${config_file//SOCKS/HTTP_SOCKS}"
|
||
json_add_string "local_http_address" "$bind"
|
||
json_add_string "local_http_port" "$http_port"
|
||
}
|
||
json_add_string "local_socks_address" "$bind"
|
||
json_add_string "local_socks_port" "$socks_port"
|
||
lua $UTIL_HYSTERIA2 gen_config "$(json_dump)" > $config_file
|
||
[ -n "$no_run" ] || ln_run "$(first_type $(config_t_get global_app hysteria_file))" "hysteria" $log_file -c "$config_file" client
|
||
;;
|
||
tuic)
|
||
json_add_string "local_addr" "$bind"
|
||
json_add_string "local_port" "$socks_port"
|
||
lua $UTIL_TUIC gen_config "$(json_dump)" > $config_file
|
||
[ -n "$no_run" ] || ln_run "$(first_type tuic-client)" "tuic-client" $log_file -c "$config_file"
|
||
;;
|
||
esac
|
||
|
||
set_cache_var "node_${node}_socks_port" "${socks_port}"
|
||
|
||
# http to socks
|
||
[ -z "$http_flag" ] && [ "$http_port" != "0" ] && [ -n "$http_config_file" ] && [ "$type" != "sing-box" ] && [ "$type" != "xray" ] && [ "$type" != "socks" ] && {
|
||
json_init
|
||
json_add_string "local_http_address" "$bind"
|
||
json_add_string "local_http_port" "$http_port"
|
||
json_add_string "server_proto" "socks"
|
||
json_add_string "server_address" "127.0.0.1"
|
||
json_add_string "server_port" "$socks_port"
|
||
json_add_string "server_username" "$_username"
|
||
json_add_string "server_password" "$_password"
|
||
if [ -n "${SINGBOX_BIN}" ]; then
|
||
type="sing-box"
|
||
local bin="${SINGBOX_BIN}"
|
||
local util="${UTIL_SINGBOX}"
|
||
elif [ -n "${XRAY_BIN}" ]; then
|
||
type="xray"
|
||
local bin="${XRAY_BIN}"
|
||
local util="${UTIL_XRAY}"
|
||
fi
|
||
[ -n "${bin}" ] && [ -n "${util}" ] && {
|
||
lua ${util} gen_proto_config "$(json_dump)" > $http_config_file
|
||
[ -n "$no_run" ] || ln_run "$bin" $type /dev/null run -c "$http_config_file"
|
||
}
|
||
unset bin util
|
||
}
|
||
unset http_flag
|
||
|
||
[ -z "$no_run" ] && [ "${server_host}" != "127.0.0.1" ] && [ "$type" != "sing-box" ] && [ "$type" != "xray" ] && echo "${node}" >> $TMP_PATH/direct_node_list
|
||
}
|
||
|
||
run_redir() {
|
||
local node proto bind local_port config_file log_file
|
||
eval_set_val $@
|
||
local tcp_node_socks_flag tcp_node_http_flag
|
||
[ -n "$config_file" ] && [ -z "$(echo ${config_file} | grep $TMP_PATH)" ] && config_file=${GLOBAL_ACL_PATH}/${config_file}
|
||
if [ -n "$log_file" ] && [ -z "$(echo ${log_file} | grep $TMP_PATH)" ]; then
|
||
log_file=${GLOBAL_ACL_PATH}/${log_file}
|
||
else
|
||
log_file="/dev/null"
|
||
fi
|
||
local proto=$(echo $proto | tr 'A-Z' 'a-z')
|
||
local PROTO=$(echo $proto | tr 'a-z' 'A-Z')
|
||
|
||
local node2socks_port=0
|
||
local type remarks server_host port
|
||
if is_socks_wrap "$node"; then
|
||
node2socks_port=$(config_n_get ${node#Socks_} port 0)
|
||
fi
|
||
if [ "$node2socks_port" = "0" ]; then
|
||
type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
|
||
remarks=$(config_n_get $node remarks)
|
||
server_host=$(config_n_get $node address)
|
||
port=$(config_n_get $node port)
|
||
else
|
||
type="socks"
|
||
server_host="127.0.0.1"
|
||
port=$node2socks_port
|
||
remarks="Socks 配置($port 端口)"
|
||
fi
|
||
|
||
local enable_log=$(config_t_get global log_${proto} 1)
|
||
[ "$enable_log" != "1" ] && log_file="/dev/null"
|
||
[ -n "$server_host" ] && [ -n "$port" ] && {
|
||
check_host $server_host
|
||
[ $? != 0 ] && {
|
||
echolog "${PROTO}节点:[$remarks]${server_host} 是非法的服务器地址,无法启动!"
|
||
return 1
|
||
}
|
||
}
|
||
[ "$bind" != "127.0.0.1" ] && echolog "${PROTO}节点:[$remarks],监听端口:$local_port"
|
||
|
||
json_init
|
||
json_add_string "node" "${node}"
|
||
case "$PROTO" in
|
||
UDP)
|
||
case "$type" in
|
||
socks)
|
||
local _socks_address _socks_port _socks_username _socks_password
|
||
if [ "$node2socks_port" = "0" ]; then
|
||
_socks_address=$(config_n_get $node address)
|
||
_socks_port=$(config_n_get $node port)
|
||
_socks_username=$(config_n_get $node username)
|
||
_socks_password=$(config_n_get $node password)
|
||
else
|
||
_socks_address="127.0.0.1"
|
||
_socks_port=$node2socks_port
|
||
fi
|
||
run_ipt2socks flag=default proto=UDP local_port=${local_port} socks_address=${_socks_address} socks_port=${_socks_port} socks_username=${_socks_username} socks_password=${_socks_password} log_file=${log_file}
|
||
;;
|
||
sing-box)
|
||
local protocol=$(config_n_get $node protocol)
|
||
[ "$protocol" = "_shunt" ] && {
|
||
local geoip_path="${V2RAY_LOCATION_ASSET%*/}/geoip.dat"
|
||
local geosite_path="${V2RAY_LOCATION_ASSET%*/}/geosite.dat"
|
||
if [ ! -s "$geoip_path" ] || [ ! -s "$geosite_path" ]; then
|
||
echolog "* 缺少Geo规则文件,UDP Sing-Box分流节点无法正常使用!"
|
||
fi
|
||
}
|
||
run_singbox flag=UDP node=$node udp_redir_port=$local_port config_file=$config_file log_file=$log_file
|
||
;;
|
||
xray)
|
||
local protocol=$(config_n_get $node protocol)
|
||
[ "$protocol" = "_shunt" ] && {
|
||
local geoip_path="${V2RAY_LOCATION_ASSET%*/}/geoip.dat"
|
||
local geosite_path="${V2RAY_LOCATION_ASSET%*/}/geosite.dat"
|
||
if [ ! -s "$geoip_path" ] || [ ! -s "$geosite_path" ]; then
|
||
echolog "* 缺少Geo规则文件,UDP Xray分流节点无法正常使用!"
|
||
fi
|
||
}
|
||
run_xray flag=UDP node=$node udp_redir_port=$local_port config_file=$config_file log_file=$log_file
|
||
;;
|
||
trojan*)
|
||
local loglevel=$(config_t_get global trojan_loglevel "2")
|
||
json_add_string "run_type" "nat"
|
||
json_add_string "local_addr" "0.0.0.0"
|
||
json_add_string "local_port" "$local_port"
|
||
json_add_string "loglevel" "$loglevel"
|
||
lua $UTIL_TROJAN gen_config "$(json_dump)" > $config_file
|
||
ln_run "$(first_type ${type})" "${type}" $log_file -c "$config_file"
|
||
;;
|
||
naiveproxy)
|
||
echolog "Naiveproxy不支持UDP转发!"
|
||
;;
|
||
ssr)
|
||
json_add_string "local_addr" "0.0.0.0"
|
||
json_add_string "local_port" "$local_port"
|
||
lua $UTIL_SS gen_config "$(json_dump)" > $config_file
|
||
ln_run "$(first_type ssr-redir)" "ssr-redir" $log_file -c "$config_file" -v -U
|
||
;;
|
||
ss)
|
||
local plugin_sh="${config_file%.json}_plugin.sh"
|
||
json_add_string "plugin_sh" "$plugin_sh"
|
||
json_add_string "local_addr" "0.0.0.0"
|
||
json_add_string "local_port" "$local_port"
|
||
json_add_string "mode" "udp_only"
|
||
lua $UTIL_SS gen_config "$(json_dump)" > $config_file
|
||
ln_run "$(first_type ss-redir)" "ss-redir" $log_file -c "$config_file" -v
|
||
;;
|
||
ss-rust)
|
||
local plugin_sh="${config_file%.json}_plugin.sh"
|
||
json_add_string "plugin_sh" "$plugin_sh"
|
||
json_add_string "local_udp_redir_port" "$local_port"
|
||
lua $UTIL_SS gen_config "$(json_dump)" > $config_file
|
||
ln_run "$(first_type sslocal)" "sslocal" $log_file -c "$config_file" -v
|
||
;;
|
||
hysteria2)
|
||
json_add_string "local_udp_redir_port" "$local_port"
|
||
lua $UTIL_HYSTERIA2 gen_config "$(json_dump)" > $config_file
|
||
ln_run "$(first_type $(config_t_get global_app hysteria_file))" "hysteria" $log_file -c "$config_file" client
|
||
;;
|
||
tuic)
|
||
echolog "TUIC不支持UDP转发!"
|
||
;;
|
||
esac
|
||
;;
|
||
TCP)
|
||
[ "$TCP_UDP" = "1" ] && echolog "UDP节点:与TCP节点相同"
|
||
tcp_node_socks=1
|
||
tcp_node_socks_bind_local=$(config_t_get global tcp_node_socks_bind_local 1)
|
||
tcp_node_socks_bind="127.0.0.1"
|
||
[ "${tcp_node_socks_bind_local}" != "1" ] && tcp_node_socks_bind="0.0.0.0"
|
||
tcp_node_socks_port=$(get_new_port $(config_t_get global tcp_node_socks_port 1070))
|
||
tcp_node_http_port=$(config_t_get global tcp_node_http_port 0)
|
||
[ "$tcp_node_http_port" != "0" ] && tcp_node_http=1
|
||
if [ $PROXY_IPV6 == "1" ]; then
|
||
echolog "开启实验性IPv6透明代理(TProxy),请确认您的节点及类型支持IPv6!"
|
||
fi
|
||
|
||
if [ "${TCP_PROXY_WAY}" = "redirect" ]; then
|
||
can_ipt=$(echo "$REDIRECT_LIST" | grep "$type")
|
||
elif [ "${TCP_PROXY_WAY}" = "tproxy" ]; then
|
||
can_ipt=$(echo "$TPROXY_LIST" | grep "$type")
|
||
fi
|
||
[ -z "$can_ipt" ] && type="socks"
|
||
|
||
case "$type" in
|
||
socks)
|
||
_socks_flag=1
|
||
if [ "$node2socks_port" = "0" ]; then
|
||
_socks_address=$(config_n_get $node address)
|
||
_socks_port=$(config_n_get $node port)
|
||
_socks_username=$(config_n_get $node username)
|
||
_socks_password=$(config_n_get $node password)
|
||
else
|
||
_socks_address="127.0.0.1"
|
||
_socks_port=$node2socks_port
|
||
fi
|
||
[ -z "$can_ipt" ] && {
|
||
local _config_file=$config_file
|
||
_config_file="TCP_SOCKS_${node}.json"
|
||
local _port=$(get_new_port 3001)
|
||
run_socks flag="TCP" node=$node bind=127.0.0.1 socks_port=${_port} config_file=${_config_file}
|
||
_socks_address=127.0.0.1
|
||
_socks_port=${_port}
|
||
unset _socks_username
|
||
unset _socks_password
|
||
}
|
||
;;
|
||
sing-box)
|
||
local _flag="TCP"
|
||
local _args=""
|
||
[ "$tcp_node_socks" = "1" ] && {
|
||
tcp_node_socks_flag=1
|
||
_args="${_args} socks_address=${tcp_node_socks_bind} socks_port=${tcp_node_socks_port}"
|
||
config_file="${config_file//TCP/TCP_SOCKS}"
|
||
}
|
||
[ "$tcp_node_http" = "1" ] && {
|
||
tcp_node_http_flag=1
|
||
_args="${_args} http_port=${tcp_node_http_port}"
|
||
config_file="${config_file//TCP/TCP_HTTP}"
|
||
}
|
||
[ "$TCP_UDP" = "1" ] && {
|
||
UDP_REDIR_PORT=$local_port
|
||
unset UDP_NODE
|
||
_flag="TCP_UDP"
|
||
_args="${_args} udp_redir_port=${UDP_REDIR_PORT}"
|
||
config_file="${config_file//TCP/TCP_UDP}"
|
||
}
|
||
|
||
local protocol=$(config_n_get $node protocol)
|
||
local default_node=$(config_n_get $node default_node)
|
||
local v2ray_dns_mode=$(config_t_get global v2ray_dns_mode tcp)
|
||
[ "${DNS_MODE}" != "sing-box" ] && [ "${DNS_MODE}" != "udp" ] && [ "$protocol" = "_shunt" ] && [ "$default_node" = "_direct" ] && {
|
||
DNS_MODE="sing-box"
|
||
v2ray_dns_mode="tcp"
|
||
echolog "* 当前TCP节点采用Sing-Box分流且默认节点为直连,远程DNS过滤模式将默认使用Sing-Box(TCP),防止环回!"
|
||
}
|
||
|
||
[ "$protocol" = "_shunt" ] && {
|
||
local geoip_path="${V2RAY_LOCATION_ASSET%*/}/geoip.dat"
|
||
local geosite_path="${V2RAY_LOCATION_ASSET%*/}/geosite.dat"
|
||
if [ ! -s "$geoip_path" ] || [ ! -s "$geosite_path" ]; then
|
||
echolog "* 缺少Geo规则文件,TCP Sing-Box分流节点无法正常使用!"
|
||
fi
|
||
}
|
||
|
||
[ "${DNS_MODE}" = "sing-box" ] && {
|
||
NO_PLUGIN_DNS=1
|
||
config_file="${config_file//.json/_DNS.json}"
|
||
_args="${_args} remote_dns_query_strategy=${REMOTE_DNS_QUERY_STRATEGY}"
|
||
DNSMASQ_FILTER_PROXY_IPV6=0
|
||
local _remote_dns_client_ip=$(config_t_get global remote_dns_client_ip)
|
||
[ -n "${_remote_dns_client_ip}" ] && _args="${_args} remote_dns_client_ip=${_remote_dns_client_ip}"
|
||
[ "${DNS_CACHE}" == "0" ] && _args="${_args} dns_cache=0"
|
||
resolve_dns_port=${NEXT_DNS_LISTEN_PORT}
|
||
_args="${_args} dns_listen_port=${resolve_dns_port}"
|
||
|
||
case "$(config_t_get global direct_dns_mode "auto")" in
|
||
udp)
|
||
_args="${_args} direct_dns_udp_server=$(config_t_get global direct_dns 223.5.5.5 | sed -E 's/^\[([^]]+)\]:(.*)$/\1#\2/; t; s/^([^:]+):([0-9]+)$/\1#\2/')"
|
||
;;
|
||
tcp)
|
||
_args="${_args} direct_dns_tcp_server=$(config_t_get global direct_dns 223.5.5.5 | sed -E 's/^\[([^]]+)\]:(.*)$/\1#\2/; t; s/^([^:]+):([0-9]+)$/\1#\2/')"
|
||
;;
|
||
esac
|
||
|
||
_args="${_args} remote_dns_protocol=${v2ray_dns_mode}"
|
||
case "$v2ray_dns_mode" in
|
||
udp|tcp)
|
||
local _proto="$v2ray_dns_mode"
|
||
_args="${_args} remote_dns_${_proto}_server=${REMOTE_DNS}"
|
||
resolve_dns_log="Sing-Box DNS(127.0.0.1#${resolve_dns_port}) -> ${_proto}://${REMOTE_DNS}"
|
||
;;
|
||
doh|http3)
|
||
remote_dns_doh=$(config_t_get global remote_dns_doh "https://1.1.1.1/dns-query")
|
||
_args="${_args} remote_dns_doh=${remote_dns_doh}"
|
||
resolve_dns_log="Sing-Box DNS(127.0.0.1#${resolve_dns_port}) -> ${remote_dns_doh}"
|
||
;;
|
||
esac
|
||
local remote_fakedns=$(config_t_get global remote_fakedns 0)
|
||
[ "${remote_fakedns}" = "1" ] && {
|
||
fakedns=1
|
||
_args="${_args} remote_fakedns=1"
|
||
resolve_dns_log="${resolve_dns_log} + FakeDNS"
|
||
}
|
||
NEXT_DNS_LISTEN_PORT=$(expr $NEXT_DNS_LISTEN_PORT + 1)
|
||
}
|
||
run_singbox flag=$_flag node=$node tcp_redir_port=$local_port tcp_proxy_way=$TCP_PROXY_WAY config_file=$config_file log_file=$log_file ${_args}
|
||
;;
|
||
xray)
|
||
local _flag="TCP"
|
||
local _args=""
|
||
[ "$tcp_node_socks" = "1" ] && {
|
||
tcp_node_socks_flag=1
|
||
_args="${_args} socks_address=${tcp_node_socks_bind} socks_port=${tcp_node_socks_port}"
|
||
config_file="${config_file//TCP/TCP_SOCKS}"
|
||
}
|
||
[ "$tcp_node_http" = "1" ] && {
|
||
tcp_node_http_flag=1
|
||
_args="${_args} http_port=${tcp_node_http_port}"
|
||
config_file="${config_file//TCP/TCP_HTTP}"
|
||
}
|
||
[ "$TCP_UDP" = "1" ] && {
|
||
UDP_REDIR_PORT=$local_port
|
||
unset UDP_NODE
|
||
_flag="TCP_UDP"
|
||
_args="${_args} udp_redir_port=${UDP_REDIR_PORT}"
|
||
config_file="${config_file//TCP/TCP_UDP}"
|
||
}
|
||
|
||
local protocol=$(config_n_get $node protocol)
|
||
local default_node=$(config_n_get $node default_node)
|
||
local v2ray_dns_mode=$(config_t_get global v2ray_dns_mode tcp)
|
||
[ "${DNS_MODE}" != "xray" ] && [ "${DNS_MODE}" != "udp" ] && [ "$protocol" = "_shunt" ] && [ "$default_node" = "_direct" ] && {
|
||
DNS_MODE="xray"
|
||
v2ray_dns_mode="tcp"
|
||
echolog "* 当前TCP节点采用Xray分流且默认节点为直连,远程DNS过滤模式将默认使用Xray(TCP),防止环回!"
|
||
}
|
||
|
||
[ "$protocol" = "_shunt" ] && {
|
||
local geoip_path="${V2RAY_LOCATION_ASSET%*/}/geoip.dat"
|
||
local geosite_path="${V2RAY_LOCATION_ASSET%*/}/geosite.dat"
|
||
if [ ! -s "$geoip_path" ] || [ ! -s "$geosite_path" ]; then
|
||
echolog "* 缺少Geo规则文件,TCP Xray分流节点无法正常使用!"
|
||
fi
|
||
}
|
||
|
||
[ "${DNS_MODE}" = "xray" ] && {
|
||
NO_PLUGIN_DNS=1
|
||
config_file="${config_file//.json/_DNS.json}"
|
||
_args="${_args} remote_dns_query_strategy=${REMOTE_DNS_QUERY_STRATEGY}"
|
||
DNSMASQ_FILTER_PROXY_IPV6=0
|
||
local _remote_dns_client_ip=$(config_t_get global remote_dns_client_ip)
|
||
[ -n "${_remote_dns_client_ip}" ] && _args="${_args} remote_dns_client_ip=${_remote_dns_client_ip}"
|
||
[ "${DNS_CACHE}" == "0" ] && _args="${_args} dns_cache=0"
|
||
resolve_dns_port=${NEXT_DNS_LISTEN_PORT}
|
||
_args="${_args} dns_listen_port=${resolve_dns_port}"
|
||
|
||
case "$(config_t_get global direct_dns_mode "auto")" in
|
||
udp)
|
||
_args="${_args} direct_dns_udp_server=$(config_t_get global direct_dns 223.5.5.5 | sed -E 's/^\[([^]]+)\]:(.*)$/\1#\2/; t; s/^([^:]+):([0-9]+)$/\1#\2/')"
|
||
;;
|
||
tcp)
|
||
_args="${_args} direct_dns_tcp_server=$(config_t_get global direct_dns 223.5.5.5 | sed -E 's/^\[([^]]+)\]:(.*)$/\1#\2/; t; s/^([^:]+):([0-9]+)$/\1#\2/')"
|
||
;;
|
||
esac
|
||
|
||
_args="${_args} remote_dns_protocol=${v2ray_dns_mode}"
|
||
case "$v2ray_dns_mode" in
|
||
udp)
|
||
_args="${_args} remote_dns_udp_server=${REMOTE_DNS}"
|
||
resolve_dns_log="Xray DNS(127.0.0.1#${resolve_dns_port}) -> udp://${REMOTE_DNS}"
|
||
;;
|
||
tcp|tcp+doh)
|
||
_args="${_args} remote_dns_tcp_server=${REMOTE_DNS}"
|
||
if [ "$v2ray_dns_mode" = "tcp+doh" ]; then
|
||
remote_dns_doh=$(config_t_get global remote_dns_doh "https://1.1.1.1/dns-query")
|
||
_args="${_args} remote_dns_doh=${remote_dns_doh}"
|
||
resolve_dns_log="Xray DNS(127.0.0.1#${resolve_dns_port}) -> (${remote_dns_doh})(A/AAAA) + tcp://${REMOTE_DNS}"
|
||
else
|
||
resolve_dns_log="Xray DNS(127.0.0.1#${resolve_dns_port}) -> tcp://${REMOTE_DNS}"
|
||
fi
|
||
;;
|
||
esac
|
||
local remote_fakedns=$(config_t_get global remote_fakedns 0)
|
||
[ "${remote_fakedns}" = "1" ] && {
|
||
fakedns=1
|
||
_args="${_args} remote_fakedns=1"
|
||
resolve_dns_log="${resolve_dns_log} + FakeDNS"
|
||
}
|
||
NEXT_DNS_LISTEN_PORT=$(expr $NEXT_DNS_LISTEN_PORT + 1)
|
||
}
|
||
run_xray flag=$_flag node=$node tcp_redir_port=$local_port tcp_proxy_way=$TCP_PROXY_WAY config_file=$config_file log_file=$log_file ${_args}
|
||
;;
|
||
trojan*)
|
||
[ "${TCP_PROXY_WAY}" = "tproxy" ] && json_add_string "use_tproxy" "true"
|
||
[ "$TCP_UDP" = "1" ] && {
|
||
config_file="${config_file//TCP/TCP_UDP}"
|
||
UDP_REDIR_PORT=$TCP_REDIR_PORT
|
||
unset UDP_NODE
|
||
}
|
||
local loglevel=$(config_t_get global trojan_loglevel "2")
|
||
json_add_string "run_type" "nat"
|
||
json_add_string "local_addr" "0.0.0.0"
|
||
json_add_string "local_port" "$local_port"
|
||
json_add_string "loglevel" "$loglevel"
|
||
lua $UTIL_TROJAN gen_config "$(json_dump)" > $config_file
|
||
ln_run "$(first_type ${type})" "${type}" $log_file -c "$config_file"
|
||
;;
|
||
naiveproxy)
|
||
json_add_string "run_type" "redir"
|
||
json_add_string "local_addr" "0.0.0.0"
|
||
json_add_string "local_port" "$local_port"
|
||
lua $UTIL_NAIVE gen_config "$(json_dump)" > $config_file
|
||
ln_run "$(first_type naive)" naive $log_file "$config_file"
|
||
;;
|
||
ssr)
|
||
[ "${TCP_PROXY_WAY}" = "tproxy" ] && json_add_string "tcp_tproxy" "true"
|
||
local _extra_param
|
||
[ "$TCP_UDP" = "1" ] && {
|
||
config_file="${config_file//TCP/TCP_UDP}"
|
||
UDP_REDIR_PORT=$TCP_REDIR_PORT
|
||
unset UDP_NODE
|
||
_extra_param="-u"
|
||
}
|
||
json_add_string "local_addr" "0.0.0.0"
|
||
json_add_string "local_port" "$local_port"
|
||
lua $UTIL_SS gen_config "$(json_dump)" > $config_file
|
||
ln_run "$(first_type ssr-redir)" "ssr-redir" $log_file -c "$config_file" -v ${_extra_param}
|
||
;;
|
||
ss)
|
||
[ "${TCP_PROXY_WAY}" = "tproxy" ] && json_add_string "tcp_tproxy" "true"
|
||
if [ "$TCP_UDP" = "1" ]; then
|
||
config_file="${config_file//TCP/TCP_UDP}"
|
||
UDP_REDIR_PORT=$TCP_REDIR_PORT
|
||
unset UDP_NODE
|
||
json_add_string "mode" "tcp_and_udp"
|
||
else
|
||
json_add_string "mode" "tcp_only"
|
||
fi
|
||
local plugin_sh="${config_file%.json}_plugin.sh"
|
||
json_add_string "plugin_sh" "$plugin_sh"
|
||
json_add_string "local_addr" "0.0.0.0"
|
||
json_add_string "local_port" "$local_port"
|
||
lua $UTIL_SS gen_config "$(json_dump)" > $config_file
|
||
ln_run "$(first_type ss-redir)" "ss-redir" $log_file -c "$config_file" -v
|
||
;;
|
||
ss-rust)
|
||
json_add_string "local_tcp_redir_port" "$local_port"
|
||
[ "${TCP_PROXY_WAY}" = "tproxy" ] && json_add_string "tcp_tproxy" "true"
|
||
[ "$tcp_node_socks" = "1" ] && {
|
||
tcp_node_socks_flag=1
|
||
config_file="${config_file//TCP/TCP_SOCKS}"
|
||
json_add_string "local_socks_address" "${tcp_node_socks_bind}"
|
||
json_add_string "local_socks_port" "${tcp_node_socks_port}"
|
||
}
|
||
[ "$tcp_node_http" = "1" ] && {
|
||
tcp_node_http_flag=1
|
||
config_file="${config_file//TCP/TCP_HTTP}"
|
||
json_add_string "local_http_port" "${tcp_node_http_port}"
|
||
}
|
||
[ "$TCP_UDP" = "1" ] && {
|
||
config_file="${config_file//TCP/TCP_UDP}"
|
||
UDP_REDIR_PORT=$TCP_REDIR_PORT
|
||
unset UDP_NODE
|
||
json_add_string "local_udp_redir_port" "$local_port"
|
||
}
|
||
local plugin_sh="${config_file%.json}_plugin.sh"
|
||
json_add_string "plugin_sh" "$plugin_sh"
|
||
lua $UTIL_SS gen_config "$(json_dump)" > $config_file
|
||
ln_run "$(first_type sslocal)" "sslocal" $log_file -c "$config_file" -v
|
||
;;
|
||
hysteria2)
|
||
json_add_string "local_tcp_redir_port" "$local_port"
|
||
[ "$tcp_node_socks" = "1" ] && {
|
||
tcp_node_socks_flag=1
|
||
config_file="${config_file//TCP/TCP_SOCKS}"
|
||
json_add_string "local_socks_address" "${tcp_node_socks_bind}"
|
||
json_add_string "local_socks_port" "${tcp_node_socks_port}"
|
||
}
|
||
[ "$tcp_node_http" = "1" ] && {
|
||
tcp_node_http_flag=1
|
||
config_file="${config_file//TCP/TCP_HTTP}"
|
||
json_add_string "local_http_port" "${tcp_node_http_port}"
|
||
}
|
||
[ "$TCP_UDP" = "1" ] && {
|
||
config_file="${config_file//TCP/TCP_UDP}"
|
||
UDP_REDIR_PORT=$TCP_REDIR_PORT
|
||
unset UDP_NODE
|
||
json_add_string "local_udp_redir_port" "$local_port"
|
||
}
|
||
json_add_string "tcp_proxy_way" "${TCP_PROXY_WAY}"
|
||
lua $UTIL_HYSTERIA2 gen_config "$(json_dump)" > $config_file
|
||
ln_run "$(first_type $(config_t_get global_app hysteria_file))" "hysteria" $log_file -c "$config_file" client
|
||
;;
|
||
esac
|
||
if [ -n "${_socks_flag}" ]; then
|
||
local _flag="TCP"
|
||
[ "$TCP_UDP" = "1" ] && {
|
||
_flag="TCP_UDP"
|
||
UDP_REDIR_PORT=$TCP_REDIR_PORT
|
||
unset UDP_NODE
|
||
}
|
||
local _socks_tproxy=""
|
||
[ "${TCP_PROXY_WAY}" = "tproxy" ] && _socks_tproxy="1"
|
||
run_ipt2socks flag=default proto=${_flag} tcp_tproxy=${_socks_tproxy} local_port=${local_port} socks_address=${_socks_address} socks_port=${_socks_port} socks_username=${_socks_username} socks_password=${_socks_password} log_file=${log_file}
|
||
fi
|
||
|
||
[ -z "$tcp_node_socks_flag" ] && {
|
||
[ "$tcp_node_socks" = "1" ] && {
|
||
local config_file="SOCKS_TCP.json"
|
||
local log_file="SOCKS_TCP.log"
|
||
local http_port=0
|
||
local http_config_file="HTTP2SOCKS_TCP.json"
|
||
[ "$tcp_node_http" = "1" ] && [ -z "$tcp_node_http_flag" ] && {
|
||
http_port=$tcp_node_http_port
|
||
}
|
||
run_socks flag=TCP node=$node bind=$tcp_node_socks_bind socks_port=$tcp_node_socks_port config_file=$config_file http_port=$http_port http_config_file=$http_config_file
|
||
}
|
||
}
|
||
|
||
[ "$tcp_node_socks" = "1" ] && {
|
||
TCP_SOCKS_server="127.0.0.1:$tcp_node_socks_port"
|
||
set_cache_var "GLOBAL_TCP_SOCKS_server" "${TCP_SOCKS_server}"
|
||
}
|
||
;;
|
||
esac
|
||
unset tcp_node_socks_flag tcp_node_http_flag
|
||
[ "$type" != "sing-box" ] && [ "$type" != "xray" ] && echo "${node}" >> $TMP_PATH/direct_node_list
|
||
[ -n "${redir_port}" ] && set_cache_var "node_${node}_${PROTO}_redir_port" "${local_port}"
|
||
}
|
||
|
||
start_redir() {
|
||
local proto=${1}
|
||
eval node=\$${proto}_NODE
|
||
if [ -n "$node" ]; then
|
||
TYPE=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
|
||
local config_file="${proto}.json"
|
||
local log_file="${proto}.log"
|
||
eval current_port=\$${proto}_REDIR_PORT
|
||
local port=$(echo $(get_new_port $current_port $proto))
|
||
eval ${proto}_REDIR_PORT=$port
|
||
run_redir node=$node proto=${proto} bind=0.0.0.0 local_port=$port config_file=$config_file log_file=$log_file
|
||
set_cache_var "ACL_GLOBAL_${proto}_node" "${node}"
|
||
set_cache_var "ACL_GLOBAL_${proto}_redir_port" "${port}"
|
||
[ "$TCP_UDP" = "1" ] && {
|
||
set_cache_var "ACL_GLOBAL_UDP_node" "${node}"
|
||
set_cache_var "ACL_GLOBAL_UDP_redir_port" "${port}"
|
||
}
|
||
else
|
||
[ "${proto}" = "UDP" ] && [ "$TCP_UDP" = "1" ] && return
|
||
echolog "${proto}节点没有选择或为空,不代理${proto}。"
|
||
fi
|
||
}
|
||
|
||
start_socks() {
|
||
[ "$SOCKS_ENABLED" = "1" ] && {
|
||
local ids=$(uci show $CONFIG | grep "=socks" | awk -F '.' '{print $2}' | awk -F '=' '{print $1}')
|
||
[ -n "$ids" ] && {
|
||
echolog "分析 Socks 服务的节点配置..."
|
||
for id in $ids; do
|
||
local enabled=$(config_n_get $id enabled 0)
|
||
[ "$enabled" == "0" ] && continue
|
||
local node=$(config_n_get $id node)
|
||
[ -z "$node" ] && continue
|
||
local bind_local=$(config_n_get $id bind_local 0)
|
||
local bind="0.0.0.0"
|
||
[ "$bind_local" = "1" ] && bind="127.0.0.1"
|
||
local port=$(config_n_get $id port)
|
||
local config_file="SOCKS_${id}.json"
|
||
local log_file="SOCKS_${id}.log"
|
||
local log=$(config_n_get $id log 1)
|
||
[ "$log" == "0" ] && log_file=""
|
||
local http_port=$(config_n_get $id http_port 0)
|
||
local http_config_file="HTTP2SOCKS_${id}.json"
|
||
run_socks flag=$id node=$node bind=$bind socks_port=$port config_file=$config_file http_port=$http_port http_config_file=$http_config_file log_file=$log_file
|
||
set_cache_var "socks_${id}" "$node"
|
||
|
||
#自动切换逻辑
|
||
local enable_autoswitch=$(config_n_get $id enable_autoswitch 0)
|
||
[ "$enable_autoswitch" = "1" ] && $APP_PATH/socks_auto_switch.sh ${id} > /dev/null 2>&1 &
|
||
done
|
||
}
|
||
}
|
||
}
|
||
|
||
socks_node_switch() {
|
||
local flag new_node
|
||
eval_set_val $@
|
||
[ -n "$flag" ] && [ -n "$new_node" ] && {
|
||
local prefix pf filename
|
||
# 结束 SS 插件进程
|
||
for prefix in "" "HTTP_"; do
|
||
pf="$TMP_PATH/${prefix}SOCKS_${flag}_plugin.pid"
|
||
[ -s "$pf" ] && kill -9 "$(head -n1 "$pf")" >/dev/null 2>&1
|
||
done
|
||
|
||
pgrep -af "$TMP_BIN_PATH" | awk -v P1="${flag}" 'BEGIN{IGNORECASE=1}$0~P1 && !/acl\/|acl_/{print $1}' | xargs kill -9 >/dev/null 2>&1
|
||
for prefix in "" "HTTP_" "HTTP2"; do
|
||
rm -rf "$TMP_PATH/${prefix}SOCKS_${flag}"*
|
||
done
|
||
|
||
for filename in $(ls ${TMP_SCRIPT_FUNC_PATH}); do
|
||
grep -q "${flag}" "${TMP_SCRIPT_FUNC_PATH}/${filename}" && \
|
||
rm -f "${TMP_SCRIPT_FUNC_PATH}/${filename}" "${TMP_PATH}/script_rstats/${filename}.count"
|
||
done
|
||
local bind_local=$(config_n_get $flag bind_local 0)
|
||
local bind="0.0.0.0"
|
||
[ "$bind_local" = "1" ] && bind="127.0.0.1"
|
||
local port=$(config_n_get $flag port)
|
||
local config_file="SOCKS_${flag}.json"
|
||
local log_file="SOCKS_${flag}.log"
|
||
local log=$(config_n_get $flag log 1)
|
||
[ "$log" == "0" ] && log_file=""
|
||
local http_port=$(config_n_get $flag http_port 0)
|
||
local http_config_file="HTTP2SOCKS_${flag}.json"
|
||
LOG_FILE="/dev/null"
|
||
run_socks flag=$flag node=$new_node bind=$bind socks_port=$port config_file=$config_file http_port=$http_port http_config_file=$http_config_file log_file=$log_file
|
||
set_cache_var "socks_${flag}" "$new_node"
|
||
local ENABLED_DEFAULT_ACL=$(get_cache_var "ENABLED_DEFAULT_ACL")
|
||
local ENABLED_ACLS=$(get_cache_var "ENABLED_ACLS")
|
||
[ "$ENABLED_DEFAULT_ACL" != "1" -a "$ENABLED_ACLS" != "1" ] && return
|
||
local USE_TABLES=$(get_cache_var "USE_TABLES")
|
||
[ -n "$USE_TABLES" ] && source $APP_PATH/${USE_TABLES}.sh filter_direct_node_list
|
||
}
|
||
}
|
||
|
||
clean_crontab() {
|
||
[ -f "${LOCK_PATH}/${CONFIG}_cron.lock" ] && return
|
||
touch /etc/crontabs/root
|
||
#sed -i "/${CONFIG}/d" /etc/crontabs/root >/dev/null 2>&1
|
||
sed -i "/$(echo "/etc/init.d/${CONFIG}" | sed 's#\/#\\\/#g')/d" /etc/crontabs/root >/dev/null 2>&1
|
||
sed -i "/$(echo "lua ${APP_PATH}/rule_update.lua log" | sed 's#\/#\\\/#g')/d" /etc/crontabs/root >/dev/null 2>&1
|
||
sed -i "/$(echo "lua ${APP_PATH}/subscribe.lua start" | sed 's#\/#\\\/#g')/d" /etc/crontabs/root >/dev/null 2>&1
|
||
|
||
pgrep -af "${CONFIG}/" | awk '/tasks\.sh/{print $1}' | xargs kill -9 >/dev/null 2>&1
|
||
rm -f ${LOCK_PATH}/${CONFIG}_tasks.lock
|
||
}
|
||
|
||
start_crontab() {
|
||
if [ "$ENABLED_DEFAULT_ACL" == 1 ] || [ "$ENABLED_ACLS" == 1 ]; then
|
||
start_daemon=$(config_t_get global_delay start_daemon 0)
|
||
[ "$start_daemon" = "1" ] && $APP_PATH/monitor.sh > /dev/null 2>&1 &
|
||
fi
|
||
|
||
[ -f "${LOCK_PATH}/${CONFIG}_cron.lock" ] && {
|
||
rm -f "${LOCK_PATH}/${CONFIG}_cron.lock"
|
||
echolog "当前为计划任务自动运行,不重新配置定时任务。"
|
||
return
|
||
}
|
||
|
||
clean_crontab
|
||
|
||
[ "$ENABLED" != 1 ] && {
|
||
/etc/init.d/cron restart
|
||
return
|
||
}
|
||
|
||
stop_week_mode=$(config_t_get global_delay stop_week_mode)
|
||
stop_time_mode=$(config_t_get global_delay stop_time_mode)
|
||
if [ -n "$stop_week_mode" ]; then
|
||
local t="0 $stop_time_mode * * $stop_week_mode"
|
||
[ "$stop_week_mode" = "7" ] && t="0 $stop_time_mode * * *"
|
||
if [ "$stop_week_mode" = "8" ]; then
|
||
update_loop=1
|
||
else
|
||
echo "$t /etc/init.d/$CONFIG stop > /dev/null 2>&1 &" >>/etc/crontabs/root
|
||
fi
|
||
echolog "配置定时任务:自动关闭服务。"
|
||
fi
|
||
start_week_mode=$(config_t_get global_delay start_week_mode)
|
||
start_time_mode=$(config_t_get global_delay start_time_mode)
|
||
if [ -n "$start_week_mode" ]; then
|
||
local t="0 $start_time_mode * * $start_week_mode"
|
||
[ "$start_week_mode" = "7" ] && t="0 $start_time_mode * * *"
|
||
if [ "$start_week_mode" = "8" ]; then
|
||
update_loop=1
|
||
else
|
||
echo "$t /etc/init.d/$CONFIG start > /dev/null 2>&1 &" >>/etc/crontabs/root
|
||
fi
|
||
echolog "配置定时任务:自动开启服务。"
|
||
fi
|
||
restart_week_mode=$(config_t_get global_delay restart_week_mode)
|
||
restart_time_mode=$(config_t_get global_delay restart_time_mode)
|
||
if [ -n "$restart_week_mode" ]; then
|
||
local t="0 $restart_time_mode * * $restart_week_mode"
|
||
[ "$restart_week_mode" = "7" ] && t="0 $restart_time_mode * * *"
|
||
if [ "$restart_week_mode" = "8" ]; then
|
||
update_loop=1
|
||
else
|
||
echo "$t /etc/init.d/$CONFIG restart > /dev/null 2>&1 &" >>/etc/crontabs/root
|
||
fi
|
||
echolog "配置定时任务:自动重启服务。"
|
||
fi
|
||
|
||
autoupdate=$(config_t_get global_rules auto_update)
|
||
weekupdate=$(config_t_get global_rules week_update)
|
||
dayupdate=$(config_t_get global_rules time_update)
|
||
if [ "$autoupdate" = "1" ]; then
|
||
local t="0 $dayupdate * * $weekupdate"
|
||
[ "$weekupdate" = "7" ] && t="0 $dayupdate * * *"
|
||
if [ "$weekupdate" = "8" ]; then
|
||
update_loop=1
|
||
else
|
||
echo "$t lua $APP_PATH/rule_update.lua log all cron > /dev/null 2>&1 &" >>/etc/crontabs/root
|
||
fi
|
||
echolog "配置定时任务:自动更新规则。"
|
||
fi
|
||
|
||
TMP_SUB_PATH=$TMP_PATH/sub_crontabs
|
||
mkdir -p $TMP_SUB_PATH
|
||
for item in $(uci show ${CONFIG} | grep "=subscribe_list" | cut -d '.' -sf 2 | cut -d '=' -sf 1); do
|
||
if [ "$(config_n_get $item auto_update 0)" = "1" ]; then
|
||
cfgid=$(uci show ${CONFIG}.$item | head -n 1 | cut -d '.' -sf 2 | cut -d '=' -sf 1)
|
||
remark=$(config_n_get $item remark)
|
||
week_update=$(config_n_get $item week_update)
|
||
time_update=$(config_n_get $item time_update)
|
||
echo "$cfgid" >> $TMP_SUB_PATH/${week_update}_${time_update}
|
||
echolog "配置定时任务:自动更新【$remark】订阅。"
|
||
fi
|
||
done
|
||
|
||
[ -d "${TMP_SUB_PATH}" ] && {
|
||
for name in $(ls ${TMP_SUB_PATH}); do
|
||
week_update=$(echo $name | awk -F '_' '{print $1}')
|
||
time_update=$(echo $name | awk -F '_' '{print $2}')
|
||
cfgids=$(echo -n $(cat ${TMP_SUB_PATH}/${name}) | sed 's# #,#g')
|
||
local t="0 $time_update * * $week_update"
|
||
[ "$week_update" = "7" ] && t="0 $time_update * * *"
|
||
if [ "$week_update" = "8" ]; then
|
||
update_loop=1
|
||
else
|
||
echo "$t lua $APP_PATH/subscribe.lua start $cfgids cron > /dev/null 2>&1 &" >>/etc/crontabs/root
|
||
fi
|
||
done
|
||
rm -rf $TMP_SUB_PATH
|
||
}
|
||
|
||
if [ "$ENABLED_DEFAULT_ACL" == 1 ] || [ "$ENABLED_ACLS" == 1 ]; then
|
||
[ "$update_loop" = "1" ] && {
|
||
$APP_PATH/tasks.sh > /dev/null 2>&1 &
|
||
echolog "自动更新:启动循环更新进程。"
|
||
}
|
||
else
|
||
echolog "运行于非代理模式,仅允许服务启停的定时任务。"
|
||
fi
|
||
|
||
/etc/init.d/cron restart
|
||
}
|
||
|
||
stop_crontab() {
|
||
[ -f "${LOCK_PATH}/${CONFIG}_cron.lock" ] && return
|
||
clean_crontab
|
||
/etc/init.d/cron restart
|
||
#echolog "清除定时执行命令。"
|
||
}
|
||
|
||
start_dns() {
|
||
echolog "DNS域名解析:"
|
||
|
||
local china_ng_local_dns=$(IFS=','; set -- $LOCAL_DNS; [ "${1%%[#:]*}" = "127.0.0.1" ] && echo "$1" || ([ -n "$2" ] && echo "$*" || echo "$1"))
|
||
local sing_box_local_dns=
|
||
local direct_dns_mode=$(config_t_get global direct_dns_mode "auto")
|
||
|
||
#获取访问控制节点所使用的DNS分流模式
|
||
local ACL_RULE_DNSMASQ=0
|
||
for acl_section in $(uci show ${CONFIG} | grep "=acl_rule" | cut -d '.' -sf 2 | cut -d '=' -sf 1); do
|
||
if [ "$(config_n_get $acl_section enabled)" = "1" ] && \
|
||
[ "$(config_n_get $acl_section dns_shunt)" = "dnsmasq" ]; then
|
||
ACL_RULE_DNSMASQ=1
|
||
break
|
||
fi
|
||
done
|
||
|
||
case "$direct_dns_mode" in
|
||
udp)
|
||
LOCAL_DNS=$(config_t_get global direct_dns 223.5.5.5 | sed -E 's/^\[([^]]+)\]:(.*)$/\1#\2/; t; s/^([^:]+):([0-9]+)$/\1#\2/')
|
||
china_ng_local_dns=${LOCAL_DNS}
|
||
sing_box_local_dns="direct_dns_udp_server=${LOCAL_DNS}"
|
||
;;
|
||
tcp)
|
||
local DIRECT_DNS=$(config_t_get global direct_dns 223.5.5.5 | sed -E 's/^\[([^]]+)\]:(.*)$/\1#\2/; t; s/^([^:]+):([0-9]+)$/\1#\2/')
|
||
china_ng_local_dns="tcp://${DIRECT_DNS}"
|
||
sing_box_local_dns="direct_dns_tcp_server=${DIRECT_DNS}"
|
||
|
||
#当全局(包括访问控制节点)开启chinadns-ng时,不启动新进程。
|
||
[ "$DNS_SHUNT" != "chinadns-ng" ] || [ "$ACL_RULE_DNSMASQ" = "1" ] && {
|
||
LOCAL_DNS="127.0.0.1#${NEXT_DNS_LISTEN_PORT}"
|
||
local china_ng_c_dns="tcp://$(get_first_dns DIRECT_DNS 53 | sed -E 's/^\[([^]]+)\]:(.*)$/\1#\2/; t; s/^([^:]+):([0-9]+)$/\1#\2/')"
|
||
ln_run "$(first_type chinadns-ng)" chinadns-ng "/dev/null" -b :: -l ${NEXT_DNS_LISTEN_PORT} -c ${china_ng_c_dns} -d chn
|
||
echolog " - ChinaDNS-NG(${LOCAL_DNS}) -> ${china_ng_c_dns}"
|
||
echolog " * 请确保上游直连 DNS 支持 TCP 查询。"
|
||
NEXT_DNS_LISTEN_PORT=$(expr $NEXT_DNS_LISTEN_PORT + 1)
|
||
}
|
||
;;
|
||
auto)
|
||
#Automatic logic is already done by default
|
||
:
|
||
;;
|
||
esac
|
||
|
||
# 追加直连DNS到iptables/nftables
|
||
[ "$(config_t_get global_haproxy balancing_enable 0)" != "1" ] && IPT_APPEND_DNS=
|
||
add_default_port() {
|
||
[ -z "$1" ] && echo "" || echo "$1" | awk -F',' '{for(i=1;i<=NF;i++){if($i !~ /#/) $i=$i"#53";} print $0;}' OFS=','
|
||
}
|
||
LOCAL_DNS=$(add_default_port "$LOCAL_DNS")
|
||
IPT_APPEND_DNS=$(add_default_port "${IPT_APPEND_DNS:-$LOCAL_DNS}")
|
||
echo "$IPT_APPEND_DNS" | grep -q -E "(^|,)$LOCAL_DNS(,|$)" || IPT_APPEND_DNS="${IPT_APPEND_DNS:+$IPT_APPEND_DNS,}$LOCAL_DNS"
|
||
[ -n "$DIRECT_DNS" ] && {
|
||
DIRECT_DNS=$(add_default_port "$DIRECT_DNS")
|
||
echo "$IPT_APPEND_DNS" | grep -q -E "(^|,)$DIRECT_DNS(,|$)" || IPT_APPEND_DNS="${IPT_APPEND_DNS:+$IPT_APPEND_DNS,}$DIRECT_DNS"
|
||
}
|
||
# 排除127.0.0.1的条目
|
||
IPT_APPEND_DNS=$(echo "$IPT_APPEND_DNS" | awk -F',' '{for(i=1;i<=NF;i++) if($i !~ /^127\.0\.0\.1/) printf (i>1?",":"") $i; print ""}' | sed 's/^,\|,$//g')
|
||
|
||
TUN_DNS="127.0.0.1#${NEXT_DNS_LISTEN_PORT}"
|
||
[ -n "${NO_PLUGIN_DNS}" ] && TUN_DNS="127.0.0.1#${resolve_dns_port}"
|
||
|
||
case "$DNS_MODE" in
|
||
dns2socks)
|
||
local dns2socks_socks_server=$(echo $(config_t_get global socks_server 127.0.0.1:1080) | sed "s/#/:/g")
|
||
local dns2socks_forward=$(get_first_dns REMOTE_DNS 53 | sed 's/#/:/g')
|
||
run_dns2socks socks=$dns2socks_socks_server listen_address=127.0.0.1 listen_port=${NEXT_DNS_LISTEN_PORT} dns=$dns2socks_forward cache=$DNS_CACHE
|
||
echolog " - dns2socks(${TUN_DNS}),${dns2socks_socks_server} -> tcp://${dns2socks_forward}"
|
||
;;
|
||
sing-box)
|
||
[ -z "${NO_PLUGIN_DNS}" ] && {
|
||
local config_file=$TMP_PATH/DNS.json
|
||
local log_file=$TMP_PATH/DNS.log
|
||
local log_file=/dev/null
|
||
local _args="type=$DNS_MODE config_file=$config_file log_file=$log_file"
|
||
[ "${DNS_CACHE}" == "0" ] && _args="${_args} dns_cache=0"
|
||
_args="${_args} direct_dns_query_strategy=${DIRECT_DNS_QUERY_STRATEGY}"
|
||
_args="${_args} remote_dns_query_strategy=${REMOTE_DNS_QUERY_STRATEGY}"
|
||
DNSMASQ_FILTER_PROXY_IPV6=0
|
||
local _remote_dns_client_ip=$(config_t_get global remote_dns_client_ip)
|
||
[ -n "${_remote_dns_client_ip}" ] && _args="${_args} remote_dns_client_ip=${_remote_dns_client_ip}"
|
||
TCP_PROXY_DNS=1
|
||
local v2ray_dns_mode=$(config_t_get global v2ray_dns_mode tcp)
|
||
_args="${_args} dns_listen_port=${NEXT_DNS_LISTEN_PORT}"
|
||
_args="${_args} remote_dns_protocol=${v2ray_dns_mode}"
|
||
case "$v2ray_dns_mode" in
|
||
udp|tcp)
|
||
local _proto="$v2ray_dns_mode"
|
||
_args="${_args} remote_dns_${_proto}_server=${REMOTE_DNS}"
|
||
echolog " - Sing-Box DNS(${TUN_DNS}) -> ${_proto}://${REMOTE_DNS}"
|
||
;;
|
||
doh|http3)
|
||
remote_dns_doh=$(config_t_get global remote_dns_doh "https://1.1.1.1/dns-query")
|
||
_args="${_args} remote_dns_doh=${remote_dns_doh}"
|
||
echolog " - Sing-Box DNS(${TUN_DNS}) -> ${remote_dns_doh}"
|
||
|
||
local _doh_url _doh_host _doh_port _doh_bootstrap
|
||
parse_doh "$remote_dns_doh" _doh_url _doh_host _doh_port _doh_bootstrap
|
||
[ -n "${_doh_bootstrap}" ] && REMOTE_DNS="${_doh_bootstrap}#${_doh_port}"
|
||
;;
|
||
esac
|
||
_args="${_args} dns_socks_address=127.0.0.1 dns_socks_port=${tcp_node_socks_port}"
|
||
[ -n "${sing_box_local_dns}" ] && _args="${_args} ${sing_box_local_dns}"
|
||
run_singbox ${_args}
|
||
}
|
||
;;
|
||
xray)
|
||
[ -z "${NO_PLUGIN_DNS}" ] && {
|
||
local config_file=$TMP_PATH/DNS.json
|
||
local log_file=$TMP_PATH/DNS.log
|
||
local log_file=/dev/null
|
||
local _args="type=$DNS_MODE config_file=$config_file log_file=$log_file"
|
||
[ "${DNS_CACHE}" == "0" ] && _args="${_args} dns_cache=0"
|
||
_args="${_args} direct_dns_query_strategy=${DIRECT_DNS_QUERY_STRATEGY}"
|
||
_args="${_args} remote_dns_query_strategy=${REMOTE_DNS_QUERY_STRATEGY}"
|
||
DNSMASQ_FILTER_PROXY_IPV6=0
|
||
local _remote_dns_client_ip=$(config_t_get global remote_dns_client_ip)
|
||
[ -n "${_remote_dns_client_ip}" ] && _args="${_args} remote_dns_client_ip=${_remote_dns_client_ip}"
|
||
TCP_PROXY_DNS=1
|
||
local v2ray_dns_mode=$(config_t_get global v2ray_dns_mode tcp)
|
||
_args="${_args} dns_listen_port=${NEXT_DNS_LISTEN_PORT}"
|
||
_args="${_args} remote_dns_protocol=${v2ray_dns_mode}"
|
||
case "$v2ray_dns_mode" in
|
||
udp)
|
||
_args="${_args} remote_dns_udp_server=${REMOTE_DNS}"
|
||
echolog " - Xray DNS(${TUN_DNS}) -> udp://${REMOTE_DNS}"
|
||
;;
|
||
tcp|tcp+doh)
|
||
_args="${_args} remote_dns_tcp_server=${REMOTE_DNS}"
|
||
if [ "$v2ray_dns_mode" = "tcp+doh" ]; then
|
||
remote_dns_doh=$(config_t_get global remote_dns_doh "https://1.1.1.1/dns-query")
|
||
_args="${_args} remote_dns_doh=${remote_dns_doh}"
|
||
echolog " - Xray DNS(${TUN_DNS}) -> (${remote_dns_doh})(A/AAAA) + tcp://${REMOTE_DNS}"
|
||
|
||
local _doh_url _doh_host _doh_port _doh_bootstrap
|
||
parse_doh "$remote_dns_doh" _doh_url _doh_host _doh_port _doh_bootstrap
|
||
[ -n "${_doh_bootstrap}" ] && REMOTE_DNS="${REMOTE_DNS},${_doh_bootstrap}#${_doh_port}"
|
||
else
|
||
echolog " - Xray DNS(${TUN_DNS}) -> tcp://${REMOTE_DNS}"
|
||
fi
|
||
;;
|
||
esac
|
||
_args="${_args} dns_socks_address=127.0.0.1 dns_socks_port=${tcp_node_socks_port}"
|
||
run_xray ${_args}
|
||
}
|
||
;;
|
||
udp)
|
||
UDP_PROXY_DNS=1
|
||
local china_ng_listen_port=${NEXT_DNS_LISTEN_PORT}
|
||
local china_ng_trust_dns="udp://$(get_first_dns REMOTE_DNS 53 | sed -E 's/^\[([^]]+)\]:(.*)$/\1#\2/; t; s/^([^:]+):([0-9]+)$/\1#\2/')"
|
||
if [ "$DNS_SHUNT" != "chinadns-ng" ] && [ "$FILTER_PROXY_IPV6" = "1" ]; then
|
||
DNSMASQ_FILTER_PROXY_IPV6=0
|
||
local no_ipv6_trust="-N"
|
||
ln_run "$(first_type chinadns-ng)" chinadns-ng "/dev/null" -b :: -l ${china_ng_listen_port} -t ${china_ng_trust_dns} -d gfw ${no_ipv6_trust}
|
||
echolog " - ChinaDNS-NG(${TUN_DNS}) -> ${china_ng_trust_dns}"
|
||
else
|
||
TUN_DNS="$(echo ${REMOTE_DNS} | sed 's/#/:/g' | sed -E 's/\:([^:]+)$/#\1/g')"
|
||
echolog " - udp://${TUN_DNS}"
|
||
fi
|
||
;;
|
||
tcp)
|
||
TCP_PROXY_DNS=1
|
||
local china_ng_listen_port=${NEXT_DNS_LISTEN_PORT}
|
||
local china_ng_trust_dns="tcp://$(get_first_dns REMOTE_DNS 53 | sed -E 's/^\[([^]]+)\]:(.*)$/\1#\2/; t; s/^([^:]+):([0-9]+)$/\1#\2/')"
|
||
[ "$DNS_SHUNT" != "chinadns-ng" ] && {
|
||
[ "$FILTER_PROXY_IPV6" = "1" ] && DNSMASQ_FILTER_PROXY_IPV6=0 && local no_ipv6_trust="-N"
|
||
ln_run "$(first_type chinadns-ng)" chinadns-ng "/dev/null" -b :: -l ${china_ng_listen_port} -t ${china_ng_trust_dns} -d gfw ${no_ipv6_trust}
|
||
echolog " - ChinaDNS-NG(${TUN_DNS}) -> ${china_ng_trust_dns}"
|
||
}
|
||
;;
|
||
esac
|
||
|
||
[ -n "${resolve_dns_log}" ] && echolog " - ${resolve_dns_log}"
|
||
|
||
[ -n "${TCP_PROXY_DNS}" ] && echolog " * 请确认上游 DNS 支持 TCP/DoH 查询,如非直连地址,确保 TCP 代理打开,并且已经正确转发!"
|
||
[ -n "${UDP_PROXY_DNS}" ] && echolog " * 请确认上游 DNS 支持 UDP 查询并已使用 UDP 节点,如上游 DNS 非直连地址,确保 UDP 代理打开,并且已经正确转发!"
|
||
|
||
local china_ng_listen=0
|
||
[ "${DNS_SHUNT}" = "smartdns" ] && {
|
||
if command -v smartdns > /dev/null 2>&1; then
|
||
rm -rf $TMP_PATH2/dnsmasq_default*
|
||
local group_domestic=$(config_t_get global group_domestic)
|
||
local smartdns_remote_dns=$(config_t_get global smartdns_remote_dns)
|
||
if [ -n "${smartdns_remote_dns}" -a "${smartdns_remote_dns}" != "nil" ]; then
|
||
smartdns_remote_dns=$(echo ${smartdns_remote_dns} | tr -s ' ' '|')
|
||
else
|
||
smartdns_remote_dns="tcp://1.1.1.1"
|
||
fi
|
||
|
||
echolog " - 域名解析:使用SmartDNS,请确保配置正常。"
|
||
china_ng_listen="127.0.0.1#${SMARTDNS_LISTEN_PORT}"
|
||
echolog " - SmartDNS(127.0.0.1#${SMARTDNS_LOCAL_PORT}) -> 国内分组(${group_domestic:-null}),SmartDNS(${china_ng_listen}) -> Dnsmasq"
|
||
china_ng_listen="${china_ng_listen},::1#${SMARTDNS_LISTEN_PORT}"
|
||
|
||
local subnet_ip=$(config_t_get global remote_dns_client_ip)
|
||
lua $APP_PATH/helper_smartdns_add.lua -FLAG "default" -SMARTDNS_CONF "/tmp/etc/smartdns/$CONFIG.conf" \
|
||
-LISTEN_PORT ${SMARTDNS_LISTEN_PORT} -LOCAL_PORT ${SMARTDNS_LOCAL_PORT} \
|
||
-LOCAL_GROUP ${group_domestic:-null} -REMOTE_GROUP "passwall_proxy" -REMOTE_PROXY_SERVER ${TCP_SOCKS_server} -USE_DEFAULT_DNS "${USE_DEFAULT_DNS:-direct}" \
|
||
-REMOTE_DNS ${smartdns_remote_dns} -DNS_MODE ${DNS_MODE:-socks} -TUN_DNS ${TUN_DNS} -REMOTE_FAKEDNS ${fakedns:-0} \
|
||
-USE_DIRECT_LIST "${USE_DIRECT_LIST}" -USE_PROXY_LIST "${USE_PROXY_LIST}" -USE_BLOCK_LIST "${USE_BLOCK_LIST}" -USE_GFW_LIST "${USE_GFW_LIST}" -CHN_LIST "${CHN_LIST}" \
|
||
-TCP_NODE ${TCP_NODE} -DEFAULT_PROXY_MODE "${TCP_PROXY_MODE}" -NO_PROXY_IPV6 ${FILTER_PROXY_IPV6:-0} -NFTFLAG ${nftflag:-0} \
|
||
-SUBNET ${subnet_ip:-0} -NO_LOGIC_LOG ${NO_LOGIC_LOG:-0}
|
||
source $APP_PATH/helper_smartdns.sh restart
|
||
|
||
USE_DEFAULT_DNS="chinadns_ng"
|
||
else
|
||
DNS_SHUNT="dnsmasq"
|
||
echolog " * 未安装SmartDNS,默认使用Dnsmasq进行域名解析!"
|
||
fi
|
||
}
|
||
|
||
[ "${DNS_SHUNT}" = "chinadns-ng" ] && [ -n "$(first_type chinadns-ng)" ] && {
|
||
chinadns_ng_min=2024.04.13
|
||
chinadns_ng_now=$($(first_type chinadns-ng) -V | grep -i "ChinaDNS-NG " | awk '{print $2}')
|
||
if [ $(check_ver "$chinadns_ng_now" "$chinadns_ng_min") = 1 ]; then
|
||
echolog " * 注意:当前 ChinaDNS-NG 版本为[ $chinadns_ng_now ],请更新到[ $chinadns_ng_min ]或以上版本,否则 DNS 有可能无法正常工作!"
|
||
fi
|
||
|
||
[ "$FILTER_PROXY_IPV6" = "1" ] && DNSMASQ_FILTER_PROXY_IPV6=0
|
||
[ -z "${china_ng_listen_port}" ] && local china_ng_listen_port=$(expr $NEXT_DNS_LISTEN_PORT + 1)
|
||
china_ng_listen="127.0.0.1#${china_ng_listen_port}"
|
||
[ -z "${china_ng_trust_dns}" ] && local china_ng_trust_dns=${TUN_DNS}
|
||
|
||
echolog " - ChinaDNS-NG(${china_ng_listen}):直连DNS:${china_ng_local_dns},可信DNS:${china_ng_trust_dns}"
|
||
|
||
china_ng_listen="${china_ng_listen},::1#${china_ng_listen_port}"
|
||
|
||
run_chinadns_ng \
|
||
_flag="default" \
|
||
_listen_port=${china_ng_listen_port} \
|
||
_dns_local=${china_ng_local_dns} \
|
||
_dns_trust=${china_ng_trust_dns} \
|
||
_no_ipv6_trust=${FILTER_PROXY_IPV6} \
|
||
_use_direct_list=${USE_DIRECT_LIST} \
|
||
_use_proxy_list=${USE_PROXY_LIST} \
|
||
_use_block_list=${USE_BLOCK_LIST} \
|
||
_gfwlist=${USE_GFW_LIST} \
|
||
_chnlist=${CHN_LIST} \
|
||
_default_mode=${TCP_PROXY_MODE} \
|
||
_default_tag=$(config_t_get global chinadns_ng_default_tag smart) \
|
||
_no_logic_log=0 \
|
||
_tcp_node=${TCP_NODE} \
|
||
_remote_fakedns=${fakedns:-0} \
|
||
_filter_https=$(config_t_get global force_https_soa 0)
|
||
|
||
USE_DEFAULT_DNS="chinadns_ng"
|
||
}
|
||
|
||
[ "$USE_DEFAULT_DNS" = "remote" ] && {
|
||
dnsmasq_version=$(dnsmasq -v | grep -i "Dnsmasq version " | awk '{print $3}')
|
||
[ "$(expr $dnsmasq_version \>= 2.87)" == 0 ] && echolog "Dnsmasq版本低于2.87,有可能无法正常使用!!!"
|
||
}
|
||
|
||
local DNSMASQ_TUN_DNS=$(get_first_dns TUN_DNS 53 | sed -E 's/^\[([^]]+)\]:(.*)$/\1#\2/; t; s/^([^:]+):([0-9]+)$/\1#\2/')
|
||
local RUN_NEW_DNSMASQ=1
|
||
RUN_NEW_DNSMASQ=${DNS_REDIRECT}
|
||
if [ "${RUN_NEW_DNSMASQ}" == "0" ]; then
|
||
#The old logic will be removed in the future.
|
||
#Run a copy dnsmasq instance, DNS hijack that don't need a proxy devices.
|
||
[ "1" = "0" ] && {
|
||
DIRECT_DNSMASQ_PORT=$(get_new_port 11400)
|
||
DIRECT_DNSMASQ_CONF=${GLOBAL_ACL_PATH}/direct_dnsmasq.conf
|
||
DIRECT_DNSMASQ_CONF_PATH=${GLOBAL_ACL_PATH}/direct_dnsmasq.d
|
||
mkdir -p ${DIRECT_DNSMASQ_CONF_PATH}
|
||
lua $APP_PATH/helper_dnsmasq.lua copy_instance -LISTEN_PORT ${DIRECT_DNSMASQ_PORT} -DNSMASQ_CONF ${DIRECT_DNSMASQ_CONF} -TMP_DNSMASQ_PATH ${DIRECT_DNSMASQ_CONF_PATH}
|
||
ln_run "$(first_type dnsmasq)" "dnsmasq_direct" "/dev/null" -C ${DIRECT_DNSMASQ_CONF} -x ${GLOBAL_ACL_PATH}/direct_dnsmasq.pid
|
||
echo "${DIRECT_DNSMASQ_PORT}" > ${GLOBAL_ACL_PATH}/direct_dnsmasq_port
|
||
}
|
||
|
||
#Rewrite the default DNS service configuration
|
||
#Modify the default dnsmasq service
|
||
lua $APP_PATH/helper_dnsmasq.lua stretch
|
||
lua $APP_PATH/helper_dnsmasq.lua add_rule -FLAG "default" -TMP_DNSMASQ_PATH ${GLOBAL_DNSMASQ_CONF_PATH} -DNSMASQ_CONF_FILE ${GLOBAL_DNSMASQ_CONF} \
|
||
-DEFAULT_DNS ${DEFAULT_DNS} -LOCAL_DNS ${LOCAL_DNS} -TUN_DNS ${DNSMASQ_TUN_DNS} \
|
||
-REMOTE_FAKEDNS ${fakedns:-0} -USE_DEFAULT_DNS "${USE_DEFAULT_DNS:-direct}" -CHINADNS_DNS ${china_ng_listen:-0} \
|
||
-USE_DIRECT_LIST "${USE_DIRECT_LIST}" -USE_PROXY_LIST "${USE_PROXY_LIST}" -USE_BLOCK_LIST "${USE_BLOCK_LIST}" -USE_GFW_LIST "${USE_GFW_LIST}" -CHN_LIST "${CHN_LIST}" \
|
||
-TCP_NODE ${TCP_NODE} -DEFAULT_PROXY_MODE ${TCP_PROXY_MODE} -NO_PROXY_IPV6 ${DNSMASQ_FILTER_PROXY_IPV6:-0} -NFTFLAG ${nftflag:-0} \
|
||
-NO_LOGIC_LOG ${NO_LOGIC_LOG:-0}
|
||
uci -q add_list dhcp.@dnsmasq[0].addnmount=${GLOBAL_DNSMASQ_CONF_PATH}
|
||
uci -q commit dhcp
|
||
lua $APP_PATH/helper_dnsmasq.lua logic_restart -LOG 1
|
||
else
|
||
#Run a copy dnsmasq instance, DNS hijack for that need proxy devices.
|
||
GLOBAL_DNSMASQ_PORT=$(get_new_port 11400)
|
||
GLOBAL_DNSMASQ_CONF=${GLOBAL_ACL_PATH}/dnsmasq.conf
|
||
GLOBAL_DNSMASQ_CONF_PATH=${GLOBAL_ACL_PATH}/dnsmasq.d
|
||
lua $APP_PATH/helper_dnsmasq.lua add_rule -FLAG "default" -TMP_DNSMASQ_PATH ${GLOBAL_DNSMASQ_CONF_PATH} -DNSMASQ_CONF_FILE ${GLOBAL_DNSMASQ_CONF} \
|
||
-LISTEN_PORT ${GLOBAL_DNSMASQ_PORT} -DEFAULT_DNS ${DEFAULT_DNS} -LOCAL_DNS ${LOCAL_DNS} -TUN_DNS ${DNSMASQ_TUN_DNS} \
|
||
-REMOTE_FAKEDNS ${fakedns:-0} -USE_DEFAULT_DNS "${USE_DEFAULT_DNS:-direct}" -CHINADNS_DNS ${china_ng_listen:-0} \
|
||
-USE_DIRECT_LIST "${USE_DIRECT_LIST}" -USE_PROXY_LIST "${USE_PROXY_LIST}" -USE_BLOCK_LIST "${USE_BLOCK_LIST}" -USE_GFW_LIST "${USE_GFW_LIST}" -CHN_LIST "${CHN_LIST}" \
|
||
-TCP_NODE ${TCP_NODE} -DEFAULT_PROXY_MODE ${TCP_PROXY_MODE} -NO_PROXY_IPV6 ${DNSMASQ_FILTER_PROXY_IPV6:-0} -NFTFLAG ${nftflag:-0} \
|
||
-NO_LOGIC_LOG ${NO_LOGIC_LOG:-0}
|
||
ln_run "$(first_type dnsmasq)" "dnsmasq_default" "/dev/null" -C ${GLOBAL_DNSMASQ_CONF} -x ${GLOBAL_ACL_PATH}/dnsmasq.pid
|
||
set_cache_var "ACL_default_dns_port" "${GLOBAL_DNSMASQ_PORT}"
|
||
DNS_REDIRECT_PORT=${GLOBAL_DNSMASQ_PORT}
|
||
#dhcp.leases to hosts
|
||
$APP_PATH/lease2hosts.sh > /dev/null 2>&1 &
|
||
fi
|
||
}
|
||
|
||
start_haproxy() {
|
||
[ "$(config_t_get global_haproxy balancing_enable 0)" != "1" ] && return
|
||
haproxy_path=$TMP_PATH/haproxy
|
||
haproxy_conf="config.cfg"
|
||
lua $APP_PATH/haproxy.lua -path ${haproxy_path} -conf ${haproxy_conf} -dns ${LOCAL_DNS}
|
||
ln_run "$(first_type haproxy)" haproxy "/dev/null" -f "${haproxy_path}/${haproxy_conf}"
|
||
}
|
||
|
||
acl_app() {
|
||
local items=$(uci show ${CONFIG} | grep "=acl_rule" | cut -d '.' -sf 2 | cut -d '=' -sf 1)
|
||
[ -n "$items" ] && {
|
||
local item
|
||
local socks_port redir_port dns_port dnsmasq_port chinadns_port
|
||
local msg msg2
|
||
socks_port=11100
|
||
redir_port=11200
|
||
dns_port=11300
|
||
dnsmasq_port=${GLOBAL_DNSMASQ_PORT:-11400}
|
||
chinadns_port=11500
|
||
for item in $items; do
|
||
local sid=$(uci -q show "${CONFIG}.${item}" | grep "=acl_rule" | awk -F '=' '{print $1}' | awk -F '.' '{print $2}')
|
||
[ "$(config_n_get $sid enabled)" = "1" ] || continue
|
||
eval $(uci -q show "${CONFIG}.${item}" | cut -d'.' -sf 3-)
|
||
|
||
if [ -n "${sources}" ]; then
|
||
for s in $sources; do
|
||
local s2
|
||
is_iprange=$(lua_api "iprange(\"${s}\")")
|
||
if [ "${is_iprange}" = "true" ]; then
|
||
s2="iprange:${s}"
|
||
elif [ -n "$(echo ${s} | grep '^ipset:')" ]; then
|
||
s2="ipset:${s}"
|
||
else
|
||
_ip_or_mac=$(lua_api "ip_or_mac(\"${s}\")")
|
||
if [ "${_ip_or_mac}" = "ip" ]; then
|
||
s2="ip:${s}"
|
||
elif [ "${_ip_or_mac}" = "mac" ]; then
|
||
s2="mac:${s}"
|
||
fi
|
||
fi
|
||
[ -n "${s2}" ] && source_list="${source_list}\n${s2}"
|
||
unset s2
|
||
done
|
||
else
|
||
source_list="any"
|
||
fi
|
||
|
||
local acl_path=${TMP_ACL_PATH}/$sid
|
||
mkdir -p ${acl_path}
|
||
[ -n "${source_list}" ] && echo -e "${source_list}" | sed '/^$/d' > ${acl_path}/source_list
|
||
|
||
use_global_config=${use_global_config:-0}
|
||
[ "${use_global_config}" = "1" ] && {
|
||
tcp_node="default"
|
||
udp_node="default"
|
||
}
|
||
tcp_no_redir_ports=${tcp_no_redir_ports:-${TCP_NO_REDIR_PORTS}}
|
||
udp_no_redir_ports=${udp_no_redir_ports:-${UDP_NO_REDIR_PORTS}}
|
||
if has_1_65535 "$tcp_no_redir_ports" && has_1_65535 "$udp_no_redir_ports"; then
|
||
unset use_global_config
|
||
unset tcp_node
|
||
unset udp_node
|
||
else
|
||
use_direct_list=${use_direct_list:-1}
|
||
use_proxy_list=${use_proxy_list:-1}
|
||
use_block_list=${use_block_list:-1}
|
||
use_gfw_list=${use_gfw_list:-1}
|
||
chn_list=${chn_list:-direct}
|
||
tcp_proxy_mode=${tcp_proxy_mode:-proxy}
|
||
udp_proxy_mode=${udp_proxy_mode:-proxy}
|
||
filter_proxy_ipv6=${filter_proxy_ipv6:-0}
|
||
dnsmasq_filter_proxy_ipv6=${filter_proxy_ipv6}
|
||
dns_shunt=${dns_shunt:-dnsmasq}
|
||
dns_mode=${dns_mode:-dns2socks}
|
||
remote_dns=${remote_dns:-1.1.1.1}
|
||
use_default_dns=${use_default_dns:-direct}
|
||
[ "$dns_mode" = "sing-box" ] && {
|
||
[ "$v2ray_dns_mode" = "doh" ] && remote_dns=${remote_dns_doh:-https://1.1.1.1/dns-query}
|
||
}
|
||
fi
|
||
|
||
[ -n "$tcp_node" ] && {
|
||
local GLOBAL_TCP_NODE=$(get_cache_var "ACL_GLOBAL_TCP_node")
|
||
[ -n "${GLOBAL_TCP_NODE}" ] && GLOBAL_TCP_redir_port=$(get_cache_var "ACL_GLOBAL_TCP_redir_port")
|
||
if [ "$tcp_node" = "default" ]; then
|
||
if [ -n "${GLOBAL_TCP_NODE}" ]; then
|
||
set_cache_var "ACL_${sid}_tcp_node" "${GLOBAL_TCP_NODE}"
|
||
set_cache_var "ACL_${sid}_tcp_redir_port" "${GLOBAL_TCP_redir_port}"
|
||
set_cache_var "ACL_${sid}_dns_port" "${GLOBAL_DNSMASQ_PORT}"
|
||
set_cache_var "ACL_${sid}_tcp_default" "1"
|
||
else
|
||
echolog " - 全局节点未启用,跳过【${remarks}】"
|
||
fi
|
||
else
|
||
[ "$(config_get_type $tcp_node)" = "nodes" ] || [ "$(config_get_type ${tcp_node#Socks_})" = "socks" ] && {
|
||
if [ -n "${GLOBAL_TCP_NODE}" ] && [ "$tcp_node" = "${GLOBAL_TCP_NODE}" ]; then
|
||
set_cache_var "ACL_${sid}_tcp_node" "${GLOBAL_TCP_NODE}"
|
||
set_cache_var "ACL_${sid}_tcp_redir_port" "${GLOBAL_TCP_redir_port}"
|
||
set_cache_var "ACL_${sid}_dns_port" "${GLOBAL_DNSMASQ_PORT}"
|
||
set_cache_var "ACL_${sid}_tcp_default" "1"
|
||
else
|
||
run_dns() {
|
||
local _dns_port
|
||
[ -n $1 ] && _dns_port=$1
|
||
[ -z ${_dns_port} ] && {
|
||
dns_port=$(get_new_port $(expr $dns_port + 1))
|
||
_dns_port=$dns_port
|
||
if [ "$dns_mode" = "dns2socks" ]; then
|
||
run_dns2socks flag=acl_${sid} socks_address=127.0.0.1 socks_port=$socks_port listen_address=0.0.0.0 listen_port=${_dns_port} dns=$remote_dns cache=1
|
||
elif [ "$dns_mode" = "sing-box" -o "$dns_mode" = "xray" ]; then
|
||
config_file=$TMP_ACL_PATH/${tcp_node}_SOCKS_${socks_port}_DNS.json
|
||
remote_dns_doh=${remote_dns_doh:-https://1.1.1.1/dns-query}
|
||
local type=${dns_mode}
|
||
[ "${dns_mode}" = "sing-box" ] && type="singbox"
|
||
dnsmasq_filter_proxy_ipv6=0
|
||
remote_dns_query_strategy="UseIP"
|
||
[ "$filter_proxy_ipv6" = "1" ] && remote_dns_query_strategy="UseIPv4"
|
||
run_${type} flag=acl_${sid} type=$dns_mode dns_socks_address=127.0.0.1 dns_socks_port=$socks_port dns_listen_port=${_dns_port} remote_dns_protocol=${v2ray_dns_mode} remote_dns_udp_server=${remote_dns} remote_dns_tcp_server=${remote_dns} remote_dns_doh="${remote_dns_doh}" remote_dns_query_strategy=${remote_dns_query_strategy} remote_dns_client_ip=${remote_dns_client_ip} config_file=$config_file
|
||
fi
|
||
set_cache_var "node_${tcp_node}_$(echo -n "${remote_dns}" | md5sum | cut -d " " -f1)" "${_dns_port}"
|
||
}
|
||
|
||
[ "$dns_shunt" = "chinadns-ng" ] && [ -n "$(first_type chinadns-ng)" ] && {
|
||
chinadns_ng_min=2024.04.13
|
||
chinadns_ng_now=$($(first_type chinadns-ng) -V | grep -i "ChinaDNS-NG " | awk '{print $2}')
|
||
if [ $(check_ver "$chinadns_ng_now" "$chinadns_ng_min") = 1 ]; then
|
||
echolog " * 注意:当前 ChinaDNS-NG 版本为[ $chinadns_ng_now ],请更新到[ $chinadns_ng_min ]或以上版本,否则 DNS 有可能无法正常工作!"
|
||
fi
|
||
|
||
[ "$filter_proxy_ipv6" = "1" ] && dnsmasq_filter_proxy_ipv6=0
|
||
chinadns_port=$(expr $chinadns_port + 1)
|
||
_china_ng_listen="127.0.0.1#${chinadns_port},::1#${chinadns_port}"
|
||
|
||
_chinadns_local_dns=$(IFS=','; set -- $LOCAL_DNS; [ "${1%%[#:]*}" = "127.0.0.1" ] && echo "$1" || ([ -n "$2" ] && echo "$1,$2" || echo "$1"))
|
||
_direct_dns_mode=$(config_t_get global direct_dns_mode "auto")
|
||
case "${_direct_dns_mode}" in
|
||
udp)
|
||
_chinadns_local_dns=$(config_t_get global direct_dns 223.5.5.5 | sed -E 's/^\[([^]]+)\]:(.*)$/\1#\2/; t; s/^([^:]+):([0-9]+)$/\1#\2/')
|
||
;;
|
||
tcp)
|
||
_chinadns_local_dns="tcp://$(config_t_get global direct_dns 223.5.5.5 | sed -E 's/^\[([^]]+)\]:(.*)$/\1#\2/; t; s/^([^:]+):([0-9]+)$/\1#\2/')"
|
||
;;
|
||
esac
|
||
|
||
run_chinadns_ng \
|
||
_flag="$sid" \
|
||
_listen_port=${chinadns_port} \
|
||
_dns_local=${_chinadns_local_dns} \
|
||
_dns_trust=127.0.0.1#${_dns_port} \
|
||
_no_ipv6_trust=${filter_proxy_ipv6} \
|
||
_use_direct_list=${use_direct_list} \
|
||
_use_proxy_list=${use_proxy_list} \
|
||
_use_block_list=${use_block_list} \
|
||
_gfwlist=${use_gfw_list} \
|
||
_chnlist=${chn_list} \
|
||
_default_mode=${tcp_proxy_mode} \
|
||
_default_tag=${chinadns_ng_default_tag:-smart} \
|
||
_no_logic_log=1 \
|
||
_tcp_node=${tcp_node} \
|
||
_remote_fakedns=${remote_fakedns:-0} \
|
||
_filter_https=${force_https_soa:-0}
|
||
|
||
use_default_dns="chinadns_ng"
|
||
}
|
||
|
||
dnsmasq_port=$(get_new_port $(expr $dnsmasq_port + 1))
|
||
local dnsmasq_conf=${acl_path}/dnsmasq.conf
|
||
local dnsmasq_conf_path=${acl_path}/dnsmasq.d
|
||
lua $APP_PATH/helper_dnsmasq.lua add_rule -FLAG ${sid} -TMP_DNSMASQ_PATH ${dnsmasq_conf_path} -DNSMASQ_CONF_FILE ${dnsmasq_conf} \
|
||
-LISTEN_PORT ${dnsmasq_port} -DEFAULT_DNS ${DEFAULT_DNS} -LOCAL_DNS $LOCAL_DNS \
|
||
-USE_DIRECT_LIST "${use_direct_list}" -USE_PROXY_LIST "${use_proxy_list}" -USE_BLOCK_LIST "${use_block_list}" -USE_GFW_LIST "${use_gfw_list}" -CHN_LIST "${chn_list}" \
|
||
-TUN_DNS "127.0.0.1#${_dns_port}" -REMOTE_FAKEDNS 0 -USE_DEFAULT_DNS "${use_default_dns:-direct}" -CHINADNS_DNS ${_china_ng_listen:-0} \
|
||
-TCP_NODE $tcp_node -DEFAULT_PROXY_MODE ${tcp_proxy_mode} -NO_PROXY_IPV6 ${dnsmasq_filter_proxy_ipv6:-0} -NFTFLAG ${nftflag:-0} \
|
||
-NO_LOGIC_LOG 1
|
||
ln_run "$(first_type dnsmasq)" "dnsmasq_${sid}" "/dev/null" -C ${dnsmasq_conf} -x ${acl_path}/dnsmasq.pid
|
||
set_cache_var "ACL_${sid}_dns_port" "${dnsmasq_port}"
|
||
set_cache_var "node_${tcp_node}_$(echo -n "${tcp_proxy_mode}${remote_dns}" | md5sum | cut -d " " -f1)" "${dnsmasq_port}"
|
||
#dhcp.leases to hosts
|
||
$APP_PATH/lease2hosts.sh > /dev/null 2>&1 &
|
||
}
|
||
_redir_port=$(get_cache_var "node_${tcp_node}_redir_port")
|
||
_socks_port=$(get_cache_var "node_${tcp_node}_socks_port")
|
||
if [ -n "${_socks_port}" ] && [ -n "${_redir_port}" ]; then
|
||
socks_port=${_socks_port}
|
||
tcp_port=${_redir_port}
|
||
_dnsmasq_port=$(get_cache_var "node_${tcp_node}_$(echo -n "${tcp_proxy_mode}${remote_dns}" | md5sum | cut -d " " -f1)")
|
||
if [ -z "${_dnsmasq_port}" ]; then
|
||
_dns_port=$(get_cache_var "node_${tcp_node}_$(echo -n "${remote_dns}" | md5sum | cut -d " " -f1)")
|
||
run_dns ${_dns_port}
|
||
else
|
||
[ -n "${_dnsmasq_port}" ] && set_cache_var "ACL_${sid}_dns_port" "${_dnsmasq_port}"
|
||
fi
|
||
else
|
||
socks_port=$(get_new_port $(expr $socks_port + 1))
|
||
set_cache_var "node_${tcp_node}_socks_port" "${socks_port}"
|
||
redir_port=$(get_new_port $(expr $redir_port + 1))
|
||
set_cache_var "node_${tcp_node}_redir_port" "${redir_port}"
|
||
tcp_port=$redir_port
|
||
|
||
local type=$(echo $(config_n_get $tcp_node type) | tr 'A-Z' 'a-z')
|
||
if [ -n "${type}" ] && ([ "${type}" = "sing-box" ] || [ "${type}" = "xray" ]); then
|
||
config_file="acl/${tcp_node}_TCP_${redir_port}.json"
|
||
_extra_param="socks_address=127.0.0.1 socks_port=$socks_port"
|
||
if ([ "$dns_mode" = "sing-box" ] || [ "$dns_mode" = "xray" ]) && [ "${type}" = "${dns_mode}" ]; then
|
||
dns_port=$(get_new_port $(expr $dns_port + 1))
|
||
_dns_port=$dns_port
|
||
config_file="${config_file//TCP_/DNS_${_dns_port}_TCP_}"
|
||
dnsmasq_filter_proxy_ipv6=0
|
||
remote_dns_query_strategy="UseIP"
|
||
[ "$filter_proxy_ipv6" = "1" ] && remote_dns_query_strategy="UseIPv4"
|
||
remote_dns_doh=${remote_dns_doh:-https://1.1.1.1/dns-query}
|
||
_extra_param="dns_listen_port=${_dns_port} remote_dns_protocol=${v2ray_dns_mode} remote_dns_udp_server=${remote_dns} remote_dns_tcp_server=${remote_dns} remote_dns_doh=${remote_dns_doh} remote_dns_query_strategy=${remote_dns_query_strategy} remote_dns_client_ip=${remote_dns_client_ip}"
|
||
fi
|
||
_extra_param="${_extra_param} tcp_proxy_way=$TCP_PROXY_WAY"
|
||
[ -n "$udp_node" ] && ([ "$udp_node" = "tcp" ] || [ "$udp_node" = "$tcp_node" ]) && {
|
||
config_file="${config_file//TCP_/TCP_UDP_}"
|
||
_extra_param="${_extra_param} udp_redir_port=$redir_port"
|
||
}
|
||
config_file="$TMP_PATH/$config_file"
|
||
[ "${type}" = "sing-box" ] && type="singbox"
|
||
run_${type} flag=$tcp_node node=$tcp_node tcp_redir_port=$redir_port ${_extra_param} config_file=$config_file
|
||
else
|
||
config_file="acl/${tcp_node}_SOCKS_${socks_port}.json"
|
||
run_socks flag=$tcp_node node=$tcp_node bind=127.0.0.1 socks_port=$socks_port config_file=$config_file
|
||
local log_file=$TMP_ACL_PATH/ipt2socks_${tcp_node}_${redir_port}.log
|
||
log_file="/dev/null"
|
||
run_ipt2socks flag=acl_${tcp_node} tcp_tproxy=${is_tproxy} local_port=$redir_port socks_address=127.0.0.1 socks_port=$socks_port log_file=$log_file
|
||
fi
|
||
run_dns ${_dns_port}
|
||
fi
|
||
set_cache_var "ACL_${sid}_tcp_node" "${tcp_node}"
|
||
set_cache_var "ACL_${sid}_tcp_redir_port" "${tcp_port}"
|
||
fi
|
||
}
|
||
fi
|
||
}
|
||
[ -n "$udp_node" ] && {
|
||
[ -n "$tcp_node" ] && {
|
||
local protocol=$(config_n_get $tcp_node protocol)
|
||
[ "$protocol" = "_shunt" ] && [ "$udp_node" != "default" ] && {
|
||
udp_node="tcp"
|
||
}
|
||
}
|
||
if [ "$udp_node" = "default" ]; then
|
||
local GLOBAL_UDP_NODE=$(get_cache_var "ACL_GLOBAL_UDP_node")
|
||
[ -n "${GLOBAL_UDP_NODE}" ] && GLOBAL_UDP_redir_port=$(get_cache_var "ACL_GLOBAL_UDP_redir_port")
|
||
if [ -n "${GLOBAL_UDP_NODE}" ]; then
|
||
set_cache_var "ACL_${sid}_udp_node" "${GLOBAL_UDP_NODE}"
|
||
set_cache_var "ACL_${sid}_udp_redir_port" "${GLOBAL_UDP_redir_port}"
|
||
set_cache_var "ACL_${sid}_udp_default" "1"
|
||
else
|
||
echolog " - 全局节点未启用,跳过【${remarks}】"
|
||
fi
|
||
elif [ "$udp_node" = "tcp" ] || [ "$udp_node" = "$tcp_node" ]; then
|
||
udp_node=$(get_cache_var "ACL_${sid}_tcp_node")
|
||
udp_port=$(get_cache_var "ACL_${sid}_tcp_redir_port")
|
||
set_cache_var "ACL_${sid}_udp_node" "${udp_node}"
|
||
set_cache_var "ACL_${sid}_udp_redir_port" "${udp_port}"
|
||
else
|
||
[ "$(config_get_type $udp_node)" = "nodes" ] || [ "$(config_get_type ${udp_node#Socks_})" = "socks" ] && {
|
||
if [ -n "${GLOBAL_UDP_NODE}" ] && [ "$udp_node" = "${GLOBAL_UDP_NODE}" ]; then
|
||
set_cache_var "ACL_${sid}_udp_node" "${GLOBAL_UDP_NODE}"
|
||
set_cache_var "ACL_${sid}_udp_redir_port" "${GLOBAL_UDP_redir_port}"
|
||
set_cache_var "ACL_${sid}_udp_default" "1"
|
||
else
|
||
_redir_port=$(get_cache_var "node_${udp_node}_redir_port")
|
||
_socks_port=$(get_cache_var "node_${udp_node}_socks_port")
|
||
if [ -n "${_socks_port}" ] && [ -n "${_redir_port}" ]; then
|
||
socks_port=${_socks_port}
|
||
udp_port=${_redir_port}
|
||
else
|
||
socks_port=$(get_new_port $(expr $socks_port + 1))
|
||
set_cache_var "node_${udp_node}_socks_port" "${socks_port}"
|
||
redir_port=$(get_new_port $(expr $redir_port + 1))
|
||
set_cache_var "node_${udp_node}_redir_port" "${redir_port}"
|
||
udp_port=$redir_port
|
||
|
||
local type=$(echo $(config_n_get $udp_node type) | tr 'A-Z' 'a-z')
|
||
if [ -n "${type}" ] && ([ "${type}" = "sing-box" ] || [ "${type}" = "xray" ]); then
|
||
config_file="acl/${udp_node}_UDP_${redir_port}.json"
|
||
config_file="$TMP_PATH/$config_file"
|
||
[ "${type}" = "sing-box" ] && type="singbox"
|
||
run_${type} flag=$udp_node node=$udp_node udp_redir_port=$redir_port config_file=$config_file
|
||
else
|
||
config_file="acl/${udp_node}_SOCKS_${socks_port}.json"
|
||
run_socks flag=$udp_node node=$udp_node bind=127.0.0.1 socks_port=$socks_port config_file=$config_file
|
||
local log_file=$TMP_ACL_PATH/ipt2socks_${udp_node}_${redir_port}.log
|
||
log_file="/dev/null"
|
||
run_ipt2socks flag=acl_${udp_node} local_port=$redir_port socks_address=127.0.0.1 socks_port=$socks_port log_file=$log_file
|
||
fi
|
||
fi
|
||
set_cache_var "ACL_${sid}_udp_node" "${udp_node}"
|
||
set_cache_var "ACL_${sid}_udp_redir_port" "${udp_port}"
|
||
fi
|
||
}
|
||
fi
|
||
}
|
||
unset enabled sid remarks sources interface tcp_no_redir_ports udp_no_redir_ports use_global_config tcp_node udp_node use_direct_list use_proxy_list use_block_list use_gfw_list chn_list tcp_proxy_mode udp_proxy_mode filter_proxy_ipv6 dns_mode remote_dns v2ray_dns_mode remote_dns_doh remote_dns_client_ip
|
||
unset _ip _mac _iprange _ipset _ip_or_mac source_list tcp_port udp_port config_file _extra_param
|
||
unset _china_ng_listen _chinadns_local_dns _direct_dns_mode chinadns_ng_default_tag dnsmasq_filter_proxy_ipv6 remote_fakedns force_https_soa
|
||
done
|
||
unset socks_port redir_port dns_port dnsmasq_port chinadns_port
|
||
}
|
||
}
|
||
|
||
start() {
|
||
mkdir -p /tmp/etc /tmp/log $TMP_PATH $TMP_BIN_PATH $TMP_SCRIPT_FUNC_PATH $TMP_ROUTE_PATH $TMP_ACL_PATH $TMP_PATH2
|
||
get_config
|
||
export V2RAY_LOCATION_ASSET=$(config_t_get global_rules v2ray_location_asset "/usr/share/v2ray/")
|
||
export XRAY_LOCATION_ASSET=$V2RAY_LOCATION_ASSET
|
||
export ENABLE_DEPRECATED_GEOSITE=true
|
||
export ENABLE_DEPRECATED_GEOIP=true
|
||
export SS_SYSTEM_DNS_RESOLVER_FORCE_BUILTIN=1
|
||
ulimit -n 65535
|
||
start_haproxy
|
||
start_socks
|
||
nftflag=0
|
||
USE_TABLES=""
|
||
check_run_environment
|
||
if [ "$ENABLED_DEFAULT_ACL" == 1 ] || [ "$ENABLED_ACLS" == 1 ]; then
|
||
[ "$(uci -q get dhcp.@dnsmasq[0].dns_redirect)" == "1" ] && {
|
||
uci -q set ${CONFIG}.@global[0].dnsmasq_dns_redirect='1'
|
||
uci -q commit ${CONFIG}
|
||
uci -q set dhcp.@dnsmasq[0].dns_redirect='0'
|
||
uci -q commit dhcp
|
||
lua $APP_PATH/helper_dnsmasq.lua restart -LOG 0
|
||
}
|
||
fi
|
||
[ "$ENABLED_DEFAULT_ACL" == 1 ] && {
|
||
mkdir -p ${GLOBAL_ACL_PATH}
|
||
start_redir TCP
|
||
start_redir UDP
|
||
start_dns
|
||
}
|
||
[ -n "$USE_TABLES" ] && source $APP_PATH/${USE_TABLES}.sh start
|
||
set_cache_var "USE_TABLES" "$USE_TABLES"
|
||
if [ "$ENABLED_DEFAULT_ACL" == 1 ] || [ "$ENABLED_ACLS" == 1 ]; then
|
||
bridge_nf_ipt=$(sysctl -e -n net.bridge.bridge-nf-call-iptables)
|
||
set_cache_var "bak_bridge_nf_ipt" "$bridge_nf_ipt"
|
||
sysctl -w net.bridge.bridge-nf-call-iptables=0 >/dev/null 2>&1
|
||
[ "$PROXY_IPV6" == "1" ] && {
|
||
bridge_nf_ip6t=$(sysctl -e -n net.bridge.bridge-nf-call-ip6tables)
|
||
set_cache_var "bak_bridge_nf_ip6t" "$bridge_nf_ip6t"
|
||
sysctl -w net.bridge.bridge-nf-call-ip6tables=0 >/dev/null 2>&1
|
||
}
|
||
fi
|
||
|
||
start_crontab
|
||
echolog "运行完成!\n"
|
||
|
||
[ "$ENABLED" = 1 ] && [ "$1" = "boot" ] && {
|
||
local cfgids item
|
||
for item in $(uci show ${CONFIG} | grep "=subscribe_list" | cut -d '.' -sf 2 | cut -d '=' -sf 1); do
|
||
if [ "$(config_n_get "$item" boot_update 0)" = "1" ]; then
|
||
local cfgid=$(uci show ${CONFIG}.$item | head -n 1 | cut -d '.' -sf 2 | cut -d '=' -sf 1)
|
||
cfgids="${cfgids:+$cfgids,}$cfgid"
|
||
fi
|
||
done
|
||
[ -n "$cfgids" ] && {
|
||
sleep 5
|
||
lua $APP_PATH/subscribe.lua start $cfgids cron > /dev/null 2>&1 &
|
||
}
|
||
}
|
||
}
|
||
|
||
stop() {
|
||
clean_log
|
||
eval_cache_var
|
||
[ -n "$USE_TABLES" ] && source $APP_PATH/${USE_TABLES}.sh stop
|
||
delete_ip2route
|
||
# 结束 SS 插件进程
|
||
# kill_all xray-plugin v2ray-plugin obfs-local shadow-tls
|
||
local pid_file pid
|
||
find "$TMP_PATH" -type f -name '*_plugin.pid' 2>/dev/null | while read -r pid_file; do
|
||
read -r pid < "$pid_file"
|
||
if [ -n "$pid" ]; then
|
||
kill -9 "$pid" >/dev/null 2>&1
|
||
fi
|
||
done
|
||
pgrep -f "sleep.*(6s|9s|58s)" | xargs kill -9 >/dev/null 2>&1
|
||
pgrep -af "${CONFIG}/" | awk '! /app\.sh|subscribe\.lua|rule_update\.lua|tasks\.sh|server_app\.lua|ujail/{print $1}' | xargs kill -9 >/dev/null 2>&1
|
||
unset V2RAY_LOCATION_ASSET
|
||
unset XRAY_LOCATION_ASSET
|
||
unset SS_SYSTEM_DNS_RESOLVER_FORCE_BUILTIN
|
||
stop_crontab
|
||
source $APP_PATH/helper_smartdns.sh del
|
||
rm -rf $GLOBAL_DNSMASQ_CONF
|
||
rm -rf $GLOBAL_DNSMASQ_CONF_PATH
|
||
[ "1" = "1" ] && {
|
||
#restore logic
|
||
bak_dnsmasq_dns_redirect=$(config_t_get global dnsmasq_dns_redirect)
|
||
[ -n "${bak_dnsmasq_dns_redirect}" ] && {
|
||
uci -q set dhcp.@dnsmasq[0].dns_redirect="${bak_dnsmasq_dns_redirect}"
|
||
uci -q commit dhcp
|
||
uci -q delete ${CONFIG}.@global[0].dnsmasq_dns_redirect
|
||
uci -q commit ${CONFIG}
|
||
}
|
||
if [ -z "${ACL_default_dns_port}" ] || [ -n "${bak_dnsmasq_dns_redirect}" ]; then
|
||
uci -q del_list dhcp.@dnsmasq[0].addnmount="${GLOBAL_DNSMASQ_CONF_PATH}"
|
||
uci -q commit dhcp
|
||
lua $APP_PATH/helper_dnsmasq.lua restart -LOG 0
|
||
fi
|
||
[ -n "${bak_bridge_nf_ipt}" ] && sysctl -w net.bridge.bridge-nf-call-iptables=${bak_bridge_nf_ipt} >/dev/null 2>&1
|
||
[ -n "${bak_bridge_nf_ip6t}" ] && sysctl -w net.bridge.bridge-nf-call-ip6tables=${bak_bridge_nf_ip6t} >/dev/null 2>&1
|
||
}
|
||
rm -rf $TMP_PATH
|
||
rm -f ${LOCK_PATH}/${CONFIG}_socks_auto_switch*
|
||
rm -f ${LOCK_PATH}/${CONFIG}_lease2hosts*
|
||
rm -f ${LOCK_PATH}/${CONFIG}_monitor*
|
||
echolog "清空并关闭相关程序和缓存完成。"
|
||
exit 0
|
||
}
|
||
|
||
get_config() {
|
||
ENABLED_DEFAULT_ACL=0
|
||
TCP_REDIR_PORT=1041
|
||
UDP_REDIR_PORT=1051
|
||
ENABLED=$(config_t_get global enabled 0)
|
||
SOCKS_ENABLED=$(config_t_get global socks_enabled 0)
|
||
TCP_NODE=$(config_t_get global tcp_node)
|
||
UDP_NODE=$(config_t_get global udp_node)
|
||
TCP_UDP=0
|
||
if [ "$UDP_NODE" = "tcp" ]; then
|
||
UDP_NODE=$TCP_NODE
|
||
TCP_UDP=1
|
||
elif [ "$UDP_NODE" = "$TCP_NODE" ]; then
|
||
TCP_UDP=1
|
||
fi
|
||
[ -n "$TCP_NODE" ] && {
|
||
local protocol=$(config_n_get $TCP_NODE protocol)
|
||
[ "$protocol" = "_shunt" ] && [ -n "$UDP_NODE" ] && {
|
||
UDP_NODE=$TCP_NODE
|
||
TCP_UDP=1
|
||
}
|
||
}
|
||
[ "$ENABLED" = 1 ] && {
|
||
local _node
|
||
for _node in "$TCP_NODE" "$UDP_NODE"; do
|
||
[ -n "$_node" ] && case "$_node" in
|
||
Socks_*) [ "$(config_get_type "${_node#Socks_}")" = "socks" ] && ENABLED_DEFAULT_ACL=1 ;;
|
||
*) [ "$(config_get_type "$_node")" = "nodes" ] && ENABLED_DEFAULT_ACL=1 ;;
|
||
esac
|
||
done
|
||
}
|
||
ENABLED_ACLS=$(config_t_get global acl_enable 0)
|
||
[ "$ENABLED_ACLS" = 1 ] && {
|
||
[ "$(uci show ${CONFIG} | grep "@acl_rule" | grep "enabled='1'" | wc -l)" == 0 ] && ENABLED_ACLS=0
|
||
}
|
||
set_cache_var ENABLED_DEFAULT_ACL $ENABLED_DEFAULT_ACL
|
||
set_cache_var ENABLED_ACLS $ENABLED_ACLS
|
||
|
||
TCP_PROXY_WAY=$(config_t_get global_forwarding tcp_proxy_way redirect)
|
||
PROXY_IPV6=$(config_t_get global_forwarding ipv6_tproxy 0)
|
||
TCP_REDIR_PORTS=$(config_t_get global_forwarding tcp_redir_ports '80,443')
|
||
UDP_REDIR_PORTS=$(config_t_get global_forwarding udp_redir_ports '1:65535')
|
||
TCP_NO_REDIR_PORTS=$(config_t_get global_forwarding tcp_no_redir_ports 'disable')
|
||
UDP_NO_REDIR_PORTS=$(config_t_get global_forwarding udp_no_redir_ports 'disable')
|
||
TCP_PROXY_DROP_PORTS=$(config_t_get global_forwarding tcp_proxy_drop_ports 'disable')
|
||
UDP_PROXY_DROP_PORTS=$(config_t_get global_forwarding udp_proxy_drop_ports '80,443')
|
||
USE_DIRECT_LIST=$(config_t_get global use_direct_list 1)
|
||
USE_PROXY_LIST=$(config_t_get global use_proxy_list 1)
|
||
USE_BLOCK_LIST=$(config_t_get global use_block_list 1)
|
||
USE_GFW_LIST=$(config_t_get global use_gfw_list 1)
|
||
CHN_LIST=$(config_t_get global chn_list direct)
|
||
TCP_PROXY_MODE=$(config_t_get global tcp_proxy_mode proxy)
|
||
UDP_PROXY_MODE=$(config_t_get global udp_proxy_mode proxy)
|
||
[ "${TCP_PROXY_MODE}" != "disable" ] && TCP_PROXY_MODE="proxy"
|
||
[ "${UDP_PROXY_MODE}" != "disable" ] && UDP_PROXY_MODE="proxy"
|
||
LOCALHOST_PROXY=$(config_t_get global localhost_proxy 1)
|
||
[ "${LOCALHOST_PROXY}" == 1 ] && {
|
||
LOCALHOST_TCP_PROXY_MODE=$TCP_PROXY_MODE
|
||
LOCALHOST_UDP_PROXY_MODE=$UDP_PROXY_MODE
|
||
}
|
||
CLIENT_PROXY=$(config_t_get global client_proxy 1)
|
||
DNS_SHUNT=$(config_t_get global dns_shunt dnsmasq)
|
||
[ -z "$(first_type $DNS_SHUNT)" ] && DNS_SHUNT="dnsmasq"
|
||
DNS_MODE=$(config_t_get global dns_mode tcp)
|
||
[ "$DNS_SHUNT" = "smartdns" ] && DNS_MODE=$(config_t_get global smartdns_dns_mode socks)
|
||
REMOTE_DNS=$(config_t_get global remote_dns 1.1.1.1:53 | sed 's/#/:/g' | sed -E 's/\:([^:]+)$/#\1/g')
|
||
USE_DEFAULT_DNS=$(config_t_get global use_default_dns direct)
|
||
FILTER_PROXY_IPV6=$(config_t_get global filter_proxy_ipv6 0)
|
||
DNS_REDIRECT=$(config_t_get global dns_redirect 1)
|
||
|
||
REDIRECT_LIST="socks ss ss-rust ssr sing-box xray trojan-plus naiveproxy hysteria2"
|
||
TPROXY_LIST="socks ss ss-rust ssr sing-box xray trojan-plus hysteria2"
|
||
|
||
NEXT_DNS_LISTEN_PORT=15353
|
||
TUN_DNS="127.0.0.1#${NEXT_DNS_LISTEN_PORT}"
|
||
DNS_CACHE=0
|
||
DIRECT_DNS_QUERY_STRATEGY="UseIP"
|
||
REMOTE_DNS_QUERY_STRATEGY="UseIP"
|
||
[ "$FILTER_PROXY_IPV6" = "1" ] && REMOTE_DNS_QUERY_STRATEGY="UseIPv4"
|
||
DNSMASQ_FILTER_PROXY_IPV6=${FILTER_PROXY_IPV6}
|
||
|
||
IPT_APPEND_DNS=${LOCAL_DNS}
|
||
|
||
DNSMASQ_CONF_DIR=/tmp/dnsmasq.d
|
||
DEFAULT_DNSMASQ_CFGID="$(uci -q show "dhcp.@dnsmasq[0]" | awk 'NR==1 {split($0, conf, /[.=]/); print conf[2]}')"
|
||
if [ -f "/tmp/etc/dnsmasq.conf.$DEFAULT_DNSMASQ_CFGID" ]; then
|
||
DNSMASQ_CONF_DIR="$(awk -F '=' '/^conf-dir=/ {print $2}' "/tmp/etc/dnsmasq.conf.$DEFAULT_DNSMASQ_CFGID")"
|
||
if [ -n "$DNSMASQ_CONF_DIR" ]; then
|
||
DNSMASQ_CONF_DIR=${DNSMASQ_CONF_DIR%*/}
|
||
else
|
||
DNSMASQ_CONF_DIR="/tmp/dnsmasq.d"
|
||
fi
|
||
fi
|
||
set_cache_var GLOBAL_DNSMASQ_CONF ${DNSMASQ_CONF_DIR}/dnsmasq-${CONFIG}.conf
|
||
set_cache_var GLOBAL_DNSMASQ_CONF_PATH ${GLOBAL_ACL_PATH}/dnsmasq.d
|
||
|
||
SMARTDNS_LOCAL_PORT=0
|
||
SMARTDNS_LISTEN_PORT=0
|
||
[ "${DNS_SHUNT}" = "smartdns" ] && {
|
||
NEXT_DNS_LISTEN_PORT=$(expr $NEXT_DNS_LISTEN_PORT + 1)
|
||
SMARTDNS_LOCAL_PORT=${NEXT_DNS_LISTEN_PORT}
|
||
NEXT_DNS_LISTEN_PORT=$(expr $NEXT_DNS_LISTEN_PORT + 1)
|
||
SMARTDNS_LISTEN_PORT=${NEXT_DNS_LISTEN_PORT}
|
||
NEXT_DNS_LISTEN_PORT=$(expr $NEXT_DNS_LISTEN_PORT + 1)
|
||
LOCAL_DNS="127.0.0.1#${SMARTDNS_LOCAL_PORT}"
|
||
}
|
||
}
|
||
|
||
get_local_dns() {
|
||
RESOLVFILE=/tmp/resolv.conf.d/resolv.conf.auto
|
||
[ -f "${RESOLVFILE}" ] && [ -s "${RESOLVFILE}" ] || RESOLVFILE=/tmp/resolv.conf.auto
|
||
|
||
ISP_DNS=$(cat $RESOLVFILE 2>/dev/null | grep -E -o "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" | grep -v -E '^(0\.0\.0\.0|127\.0\.0\.1)$' | awk '!seen[$0]++')
|
||
ISP_DNS6=$(cat $RESOLVFILE 2>/dev/null | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | awk -F % '{print $1}' | awk -F " " '{print $2}' | grep -v -Fx ::1 | grep -v -Fx :: | awk '!seen[$0]++')
|
||
|
||
DEFAULT_DNS=$(uci show dhcp.@dnsmasq[0] | grep "\.server=" | awk -F '=' '{print $2}' | sed "s/'//g" | tr ' ' '\n' | grep -v "\/" | sed ':label;N;s/\n/,/;b label')
|
||
[ -z "${DEFAULT_DNS}" ] && [ "$(echo $ISP_DNS | tr ' ' '\n' | wc -l)" -ge 1 ] && DEFAULT_DNS=$(echo -n $ISP_DNS | tr ' ' '\n' | tr '\n' ',' | sed 's/,$//')
|
||
LOCAL_DNS="${DEFAULT_DNS:-119.29.29.29,223.5.5.5}"
|
||
}
|
||
|
||
get_local_dns
|
||
|
||
arg1=$1
|
||
shift
|
||
case $arg1 in
|
||
run_socks)
|
||
run_socks $@
|
||
;;
|
||
socks_node_switch)
|
||
socks_node_switch $@
|
||
;;
|
||
start)
|
||
start $@
|
||
;;
|
||
stop)
|
||
stop
|
||
;;
|
||
esac
|