Files
Archive/openwrt-passwall2/luci-app-passwall2/root/usr/share/passwall2/app.sh
T
2026-04-19 21:03:22 +02:00

1370 lines
55 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/sh
# Copyright (C) 2022-2025 xiaorouji
# Copyright (C) 2026 Openwrt-Passwall Organization
. /lib/functions.sh
. /lib/functions/service.sh
. /usr/share/libubox/jshn.sh
. /usr/share/passwall2/utils.sh
GLOBAL_ACL_PATH=${TMP_ACL_PATH}/default
LUA_UTIL_PATH=/usr/lib/lua/luci/passwall2
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_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
log_i18n 0 "Warning: The %s application environment is incomplete. Switch to %s. (%s)" "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
log_i18n 0 "Warning: The %s application environment is incomplete. Switch to %s. (%s)" "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
log_i18n 0 "Note: Dnsmasq (%s) is below 2.90. Upgrading is recommended to improve stability." "${dnsmasq_ver}"
fi
fi
local pkg
for pkg in $dep_list; do
if [ ! -s "${file_path}/${pkg}${file_ext}" ]; then
log_i18n 0 "Warning: %s transparent proxy is missing basic dependency %s!" "${USE_TABLES}" "${pkg}"
fi
done
else
log 0 "$(i18n "Warning: Not compatible with any transparent proxy system environment.") (has_fw4:$has_fw4/has_ipt:$has_ipt/has_ipset:$has_ipset/dnsmasq_nftset:$dnsmasq_nftset/dnsmasq_ipset:$dnsmasq_ipset)"
fi
}
run_xray() {
local flag node redir_port tcp_proxy_way socks_address socks_port socks_username socks_password http_address http_port http_username http_password
local dns_listen_port direct_dns_query_strategy remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh remote_dns_client_ip remote_dns_detour remote_fakedns remote_dns_query_strategy dns_cache
local loglevel log_file config_file
eval_set_val $@
node_protocol=$(config_n_get $node protocol)
[ -n "$log_file" ] || local log_file="/dev/null"
[ -z "$loglevel" ] && local loglevel=$(config_t_get global loglevel "warning")
json_init
json_add_string "loglevel" "${loglevel}"
[ -n "$flag" ] && {
pgrep -af "$TMP_BIN_PATH" | awk -v P1="${flag}" 'BEGIN{IGNORECASE=1}$0~P1{print $1}' | xargs kill -9 >/dev/null 2>&1
json_add_string "flag" "${flag}"
}
[ -n "$socks_address" ] && [ -n "$socks_port" ] && {
json_add_string "local_socks_address" "${socks_address}"
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" ] && [ -n "$http_port" ] && {
json_add_string "local_http_address" "${http_address}"
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_listen_port" ] && {
json_add_string "dns_listen_port" "${dns_listen_port}"
[ -n "$dns_cache" ] && json_add_string "dns_cache" "${dns_cache}"
[ "${node_protocol}" = "_shunt" ] && local write_ipset_direct=$(config_n_get $node write_ipset_direct 0)
[ "${write_ipset_direct}" = "1" ] && {
direct_dnsmasq_listen_port=$(get_new_port $(expr $dns_listen_port + 1) udp)
local direct_ipset_conf=${GLOBAL_ACL_PATH}/dns_${flag}_direct.conf
[ -n "$(echo ${flag} | grep '^acl')" ] && direct_ipset_conf=${TMP_ACL_PATH}/${sid}/dns_${flag}_direct.conf
if [ "${nftflag}" = "1" ]; then
local direct_nftset4="passwall2_${node}_white"
local direct_nftset6="passwall2_${node}_white6"
local direct_nftset="4#inet#passwall2#${direct_nftset4},6#inet#passwall2#${direct_nftset6}"
else
local direct_ipset4="passwall2_${node}_white"
local direct_ipset6="passwall2_${node}_white6"
local direct_ipset="${direct_ipset4},${direct_ipset6}"
fi
run_ipset_dns_server listen_port=${direct_dnsmasq_listen_port} server_dns=${AUTO_DNS} ipset="${direct_ipset}" nftset="${direct_nftset}" config_file=${direct_ipset_conf}
DIRECT_DNS_UDP_PORT=${direct_dnsmasq_listen_port}
DIRECT_DNS_UDP_SERVER="127.0.0.1"
[ -n "${direct_ipset}" ] && {
json_add_string "direct_ipset" "${direct_ipset}"
set_cache_var "node_${node}_direct_ipset4" "${direct_ipset4}"
set_cache_var "node_${node}_direct_ipset6" "${direct_ipset6}"
}
[ -n "${direct_nftset}" ] && {
json_add_string "direct_nftset" "${direct_nftset}"
set_cache_var "node_${node}_direct_nftset4" "${direct_nftset4}"
set_cache_var "node_${node}_direct_nftset6" "${direct_nftset6}"
}
}
[ "$remote_fakedns" = "1" ] && {
json_add_string "remote_dns_fake" "1"
json_add_string "remote_dns_fake_strategy" "${remote_dns_query_strategy}"
}
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_port" "${_dns_port}"
json_add_string "remote_dns_udp_server" "${_dns_address}"
;;
tcp)
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_port" "${_dns_port}"
json_add_string "remote_dns_tcp_server" "${_dns_address}"
;;
doh)
local _doh_url=$(echo $remote_dns_doh | awk -F ',' '{print $1}')
local _doh_host_port=$(lua_api "get_domain_from_url(\"${_doh_url}\")")
#local _doh_host_port=$(echo $_doh_url | sed "s/https:\/\///g" | awk -F '/' '{print $1}')
local _doh_host=$(echo $_doh_host_port | awk -F ':' '{print $1}')
local is_ip=$(lua_api "is_ip(\"${_doh_host}\")")
local _doh_port=$(echo $_doh_host_port | awk -F ':' '{print $2}')
[ -z "${_doh_port}" ] && _doh_port=443
local _doh_bootstrap=$(echo $remote_dns_doh | cut -d ',' -sf 2-)
[ "${is_ip}" = "true" ] && _doh_bootstrap=${_doh_host}
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}"
[ -n "$_doh_bootstrap" ] && json_add_string "remote_dns_doh_ip" "${_doh_bootstrap}"
;;
esac
[ -n "$remote_dns_detour" ] && json_add_string "remote_dns_detour" "${remote_dns_detour}"
[ -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}"
}
json_add_string "direct_dns_udp_port" "${DIRECT_DNS_UDP_PORT}"
json_add_string "direct_dns_udp_server" "${DIRECT_DNS_UDP_SERVER}"
json_add_string "direct_dns_query_strategy" "${direct_dns_query_strategy}"
[ -n "${redir_port}" ] && {
json_add_string "redir_port" "${redir_port}"
set_cache_var "node_${node}_redir_port" "${redir_port}"
[ -n "${tcp_proxy_way}" ] && json_add_string "tcp_proxy_way" "${tcp_proxy_way}"
}
json_add_string "node" "${node}"
local _json_arg="$(json_dump)"
lua $UTIL_XRAY gen_config "${_json_arg}" > $config_file
test_log_file=$log_file
[ "$test_log_file" = "/dev/null" ] && test_log_file="${TMP_PATH}/test.log"
$XRAY_BIN run -test -c "$config_file" > $test_log_file; local status=$?
if [ "${status}" == 0 ]; then
ln_run ${QUEUE_RUN} "$XRAY_BIN" xray $log_file run -c "$config_file"
else
_error_log_file=$test_log_file
return ${status}
fi
}
run_singbox() {
local flag node redir_port tcp_proxy_way socks_address socks_port socks_username socks_password http_address http_port http_username http_password
local dns_listen_port direct_dns_query_strategy remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh remote_dns_client_ip remote_dns_detour remote_fakedns remote_dns_query_strategy dns_cache
local loglevel log_file config_file
eval_set_val $@
local type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
[ -z "$type" ] && return 1
node_protocol=$(config_n_get $node protocol)
[ -n "$log_file" ] || local log_file="/dev/null"
[ -z "$loglevel" ] && local loglevel=$(config_t_get global loglevel "warn")
[ "$loglevel" = "warning" ] && loglevel="warn"
local singbox_tag=$($SINGBOX_BIN version | grep 'Tags:' | awk '{print $2}')
json_init
json_add_string "tags" "${singbox_tag}"
if [ "$log_file" = "/dev/null" ]; then
json_add_string "log" "0"
else
json_add_string "log" "1"
json_add_string "logfile" "${log_file}"
fi
json_add_string "loglevel" "${loglevel}"
[ -n "$flag" ] && {
pgrep -af "$TMP_BIN_PATH" | awk -v P1="${flag}" 'BEGIN{IGNORECASE=1}$0~P1{print $1}' | xargs kill -9 >/dev/null 2>&1
json_add_string "flag" "${flag}"
}
[ -n "$socks_address" ] && [ -n "$socks_port" ] && {
json_add_string "local_socks_address" "${socks_address}"
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" ] && [ -n "$http_port" ] && {
json_add_string "local_http_address" "${http_address}"
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_listen_port" ] && {
[ "${node_protocol}" = "_shunt" ] && local write_ipset_direct=$(config_n_get $node write_ipset_direct 0)
[ "${write_ipset_direct}" = "1" ] && {
direct_dnsmasq_listen_port=$(get_new_port $(expr $dns_listen_port + 1) udp)
local direct_ipset_conf=${GLOBAL_ACL_PATH}/dns_${flag}_direct.conf
[ -n "$(echo ${flag} | grep '^acl')" ] && direct_ipset_conf=${TMP_ACL_PATH}/${sid}/dns_${flag}_direct.conf
if [ "${nftflag}" = "1" ]; then
local direct_nftset4="passwall2_${node}_white"
local direct_nftset6="passwall2_${node}_white6"
local direct_nftset="4#inet#passwall2#${direct_nftset4},6#inet#passwall2#${direct_nftset6}"
else
local direct_ipset4="passwall2_${node}_white"
local direct_ipset6="passwall2_${node}_white6"
local direct_ipset="${direct_ipset4},${direct_ipset6}"
fi
run_ipset_dns_server listen_port=${direct_dnsmasq_listen_port} server_dns=${AUTO_DNS} ipset="${direct_ipset}" nftset="${direct_nftset}" config_file=${direct_ipset_conf}
DIRECT_DNS_UDP_PORT=${direct_dnsmasq_listen_port}
DIRECT_DNS_UDP_SERVER="127.0.0.1"
[ -n "${direct_ipset}" ] && {
json_add_string "direct_ipset" "${direct_ipset}"
set_cache_var "node_${node}_direct_ipset4" "${direct_ipset4}"
set_cache_var "node_${node}_direct_ipset6" "${direct_ipset6}"
}
[ -n "${direct_nftset}" ] && {
json_add_string "direct_nftset" "${direct_nftset}"
set_cache_var "node_${node}_direct_nftset4" "${direct_nftset4}"
set_cache_var "node_${node}_direct_nftset6" "${direct_nftset6}"
}
}
case "$remote_dns_protocol" in
udp|\
quic)
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_port" "${_dns_port}"
json_add_string "remote_dns_udp_server" "${_dns_address}"
[ "$remote_dns_protocol" == "quic" ] && json_add_string "remote_dns_quic" "1"
;;
tcp|\
tls)
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_port" "${_dns_port}"
json_add_string "remote_dns_tcp_server" "${_dns_address}"
[ "$remote_dns_protocol" == "tls" ] && json_add_string "remote_dns_tls" "1"
;;
doh|\
http3)
local _doh_url=$(echo $remote_dns_doh | awk -F ',' '{print $1}')
local _doh_host_port=$(lua_api "get_domain_from_url(\"${_doh_url}\")")
#local _doh_host_port=$(echo $_doh_url | sed "s/https:\/\///g" | awk -F '/' '{print $1}')
local _doh_host=$(echo $_doh_host_port | awk -F ':' '{print $1}')
local is_ip=$(lua_api "is_ip(\"${_doh_host}\")")
local _doh_port=$(echo $_doh_host_port | awk -F ':' '{print $2}')
[ -z "${_doh_port}" ] && _doh_port=443
local _doh_bootstrap=$(echo $remote_dns_doh | cut -d ',' -sf 2-)
[ "${is_ip}" = "true" ] && _doh_bootstrap=${_doh_host}
[ -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_detour" ] && json_add_string "remote_dns_detour" "${remote_dns_detour}"
[ -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}"
[ -n "$dns_listen_port" ] && json_add_string "dns_listen_port" "${dns_listen_port}"
[ -n "$dns_cache" ] && json_add_string "dns_cache" "${dns_cache}"
[ "$remote_fakedns" = "1" ] && json_add_string "remote_dns_fake" "1"
}
json_add_string "direct_dns_udp_port" "${DIRECT_DNS_UDP_PORT}"
json_add_string "direct_dns_udp_server" "${DIRECT_DNS_UDP_SERVER}"
json_add_string "direct_dns_query_strategy" "${direct_dns_query_strategy}"
[ -n "${redir_port}" ] && {
json_add_string "redir_port" "${redir_port}"
set_cache_var "node_${node}_redir_port" "${redir_port}"
[ -n "${tcp_proxy_way}" ] && json_add_string "tcp_proxy_way" "${tcp_proxy_way}"
}
json_add_string "node" "${node}"
local _json_arg="$(json_dump)"
lua $UTIL_SINGBOX gen_config "${_json_arg}" > $config_file
test_log_file=$log_file
[ "$test_log_file" = "/dev/null" ] && test_log_file="${TMP_PATH}/test.log"
$SINGBOX_BIN check -c "$config_file" > $test_log_file 2>&1; local status=$?
if [ "${status}" == 0 ]; then
ln_run ${QUEUE_RUN} "$SINGBOX_BIN" "sing-box" "${log_file}" run -c "$config_file"
else
_error_log_file=$test_log_file
return ${status}
fi
}
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 type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
local remarks=$(config_n_get $node remarks)
local server_host=$(config_n_get $node address)
local server_port=$(config_n_get $node port)
[ -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 ] && {
log 1 "$(i18n "Socks node: [%s]%s is an invalid server address and cannot be started!" "${$remarks}" "${server_host}")"
return 1
}
tmp="${server_host}:${server_port}"
else
error_msg="$(i18n "For some reason, the configuration for this Socks service has been lost, and its startup has been aborted!")"
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" ] && log 1 "$(i18n "Socks node: [%s]%s, start failed %s:%s %s" "${remarks}" "${tmp}" "${bind}" "${socks_port}" "${error_msg}")"
return 1
}
[ "$bind" != "127.0.0.1" ] && log 1 "$(i18n "Socks node: [%s]%s, starting %s:%s" "${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
sing-box)
[ "$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}"
}
[ -z "$relay_port" ] && {
json_add_null "server_host"
json_add_null "server_port"
}
[ "${log_file}" != "/dev/null" ] && {
local loglevel=$(config_t_get global loglevel "warn")
[ "$loglevel" = "warning" ] && loglevel="warn"
json_add_string "log" "1"
json_add_string "loglevel" "${loglevel}"
json_add_string "logfile" "${log_file}"
}
[ -n "$no_run" ] && json_add_string "no_run" "1"
json_add_string "flag" "SOCKS_${flag}"
json_add_string "local_socks_address" "${bind}"
json_add_string "local_socks_port" "${socks_port}"
json_add_string "direct_dns_udp_port" "${DIRECT_DNS_UDP_PORT}"
json_add_string "direct_dns_udp_server" "${DIRECT_DNS_UDP_SERVER}"
json_add_string "direct_dns_query_strategy" "${DIRECT_DNS_QUERY_STRATEGY}"
local _json_arg="$(json_dump)"
lua $UTIL_SINGBOX gen_config "${_json_arg}" > $config_file
[ -z "$no_run" ] && ln_run ${QUEUE_RUN} "$SINGBOX_BIN" "sing-box" /dev/null run -c "$config_file"
;;
xray)
[ "$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}"
}
[ -z "$relay_port" ] && {
json_add_null "server_host"
json_add_null "server_port"
}
[ -n "$no_run" ] && json_add_string "no_run" "1"
json_add_string "flag" "SOCKS_${flag}"
json_add_string "local_socks_address" "${bind}"
json_add_string "local_socks_port" "${socks_port}"
json_add_string "direct_dns_udp_port" "${DIRECT_DNS_UDP_PORT}"
json_add_string "direct_dns_udp_server" "${DIRECT_DNS_UDP_SERVER}"
json_add_string "direct_dns_query_strategy" "${DIRECT_DNS_QUERY_STRATEGY}"
local _json_arg="$(json_dump)"
lua $UTIL_XRAY gen_config "${_json_arg}" > $config_file
[ -z "$no_run" ] && ln_run ${QUEUE_RUN} "$XRAY_BIN" "xray" $log_file run -c "$config_file"
;;
naiveproxy)
json_add_string "local_addr" "${bind}"
json_add_string "local_port" "${socks_port}"
json_add_string "run_type" "socks"
local _json_arg="$(json_dump)"
lua $UTIL_NAIVE gen_config "${_json_arg}" > $config_file
[ -z "$no_run" ] && ln_run ${QUEUE_RUN} "$(first_type naive)" naive $log_file "$config_file"
;;
ssr)
json_add_string "local_addr" "${bind}"
json_add_string "local_port" "${socks_port}"
local _json_arg="$(json_dump)"
lua $UTIL_SS gen_config "${_json_arg}" > $config_file
[ -z "$no_run" ] && ln_run ${QUEUE_RUN} "$(first_type ssr-local)" "ssr-local" $log_file -c "$config_file" -v -u
;;
ss)
json_add_string "local_addr" "${bind}"
json_add_string "local_port" "${socks_port}"
json_add_string "mode" "tcp_and_udp"
[ -z "$no_run" ] && {
local plugin_sh="${config_file%.json}_plugin.sh"
json_add_string "plugin_sh" "${plugin_sh}"
}
local _json_arg="$(json_dump)"
lua $UTIL_SS gen_config "${_json_arg}" > $config_file
[ -z "$no_run" ] && ln_run ${QUEUE_RUN} "$(first_type ss-local)" "ss-local" $log_file -c "$config_file" -v
;;
ss-rust)
json_add_string "local_socks_address" "${bind}"
json_add_string "local_socks_port" "${socks_port}"
[ "$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}"
}
[ -z "$no_run" ] && {
local plugin_sh="${config_file%.json}_plugin.sh"
json_add_string "plugin_sh" "${plugin_sh}"
}
local _json_arg="$(json_dump)"
lua $UTIL_SS gen_config "${_json_arg}" > $config_file
[ -z "$no_run" ] && ln_run ${QUEUE_RUN} "$(first_type sslocal)" "sslocal" $log_file -c "$config_file" -v
;;
hysteria2)
json_add_string "local_socks_address" "${bind}"
json_add_string "local_socks_port" "${socks_port}"
[ "$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}"
}
local _json_arg="$(json_dump)"
lua $UTIL_HYSTERIA2 gen_config "${_json_arg}" > $config_file
[ -z "$no_run" ] && ln_run ${QUEUE_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}"
local _json_arg="$(json_dump)"
lua $UTIL_TUIC gen_config "${_json_arg}" > $config_file
[ -z "$no_run" ] && ln_run ${QUEUE_RUN} "$(first_type tuic-client)" "tuic-client" $log_file -c "$config_file"
;;
esac
# 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_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}"
local _json_arg="$(json_dump)"
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_arg}" > ${http_config_file}
[ -z "$no_run" ] && ln_run ${QUEUE_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
}
socks_node_switch() {
local flag new_node
eval_set_val $@
[ -n "$flag" ] && [ -n "$new_node" ] && {
local prefix pf filename
# Kill the SS plugin process
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
cmd=$(cat ${TMP_SCRIPT_FUNC_PATH}/${filename})
[ -n "$(echo $cmd | grep "${flag}")" ] && rm -f ${TMP_SCRIPT_FUNC_PATH}/${filename}
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 USE_TABLES=$(get_cache_var "USE_TABLES")
[ -n "$USE_TABLES" ] && source $APP_PATH/${USE_TABLES}.sh filter_direct_node_list
}
}
run_global() {
[ -z "$NODE" ] && return 1
TYPE=$(echo $(config_n_get $NODE type) | tr 'A-Z' 'a-z')
[ -z "$TYPE" ] && return 1
if [ $PROXY_IPV6 == "1" ]; then
log_i18n 0 "To enable experimental IPv6 transparent proxy (TProxy), please ensure your node and type support IPv6!"
fi
TUN_DNS_PORT=15353
TUN_DNS="127.0.0.1#${TUN_DNS_PORT}"
V2RAY_ARGS="flag=global node=$NODE redir_port=$REDIR_PORT tcp_proxy_way=${TCP_PROXY_WAY}"
V2RAY_ARGS="${V2RAY_ARGS} dns_listen_port=${TUN_DNS_PORT} direct_dns_query_strategy=${DIRECT_DNS_QUERY_STRATEGY} remote_dns_query_strategy=${REMOTE_DNS_QUERY_STRATEGY} dns_cache=${DNS_CACHE}"
local dns_msg="DNS: ${TUN_DNS} $(i18n "Direct DNS: %s" "${AUTO_DNS}")"
[ -n "$REMOTE_DNS_PROTOCOL" ] && {
V2RAY_ARGS="${V2RAY_ARGS} remote_dns_protocol=${REMOTE_DNS_PROTOCOL} remote_dns_detour=${REMOTE_DNS_DETOUR}"
case "$REMOTE_DNS_PROTOCOL" in
udp|\
quic)
V2RAY_ARGS="${V2RAY_ARGS} remote_dns_udp_server=${REMOTE_DNS}"
dns_msg="${dns_msg} $(i18n "Remote DNS: %s" "${REMOTE_DNS}")"
;;
tcp|\
tls)
V2RAY_ARGS="${V2RAY_ARGS} remote_dns_tcp_server=${REMOTE_DNS}"
dns_msg="${dns_msg} $(i18n "Remote DNS: %s" "${REMOTE_DNS}")"
;;
doh|\
http3)
REMOTE_DNS_DOH=$(config_t_get global remote_dns_doh "https://1.1.1.1/dns-query")
V2RAY_ARGS="${V2RAY_ARGS} remote_dns_doh=${REMOTE_DNS_DOH}"
dns_msg="${dns_msg} $(i18n "Remote DNS: %s" "${REMOTE_DNS_DOH}")"
;;
esac
[ "$REMOTE_FAKEDNS" = "1" ] && {
V2RAY_ARGS="${V2RAY_ARGS} remote_fakedns=1"
dns_msg="${dns_msg} + FakeDNS "
}
local _remote_dns_client_ip=$(config_t_get global remote_dns_client_ip)
[ -n "${_remote_dns_client_ip}" ] && V2RAY_ARGS="${V2RAY_ARGS} remote_dns_client_ip=${_remote_dns_client_ip}"
}
dns_msg="${dns_msg}"
V2RAY_CONFIG=${GLOBAL_ACL_PATH}/global.json
V2RAY_LOG=${GLOBAL_ACL_PATH}/global.log
[ "$(config_t_get global log_node 1)" != "1" ] && V2RAY_LOG="/dev/null"
V2RAY_ARGS="${V2RAY_ARGS} log_file=${V2RAY_LOG} config_file=${V2RAY_CONFIG}"
node_socks_port=$(config_t_get global node_socks_port 1070)
node_socks_bind_local=$(config_t_get global node_socks_bind_local 1)
node_socks_bind="127.0.0.1"
[ "${node_socks_bind_local}" != "1" ] && node_socks_bind="0.0.0.0"
V2RAY_ARGS="${V2RAY_ARGS} socks_address=${node_socks_bind} socks_port=${node_socks_port}"
set_cache_var "GLOBAL_SOCKS_server" "127.0.0.1:$node_socks_port"
node_http_port=$(config_t_get global node_http_port 0)
[ "$node_http_port" != "0" ] && V2RAY_ARGS="${V2RAY_ARGS} http_port=${node_http_port}"
local run_func
[ -n "${XRAY_BIN}" ] && run_func="run_xray"
[ -n "${SINGBOX_BIN}" ] && run_func="run_singbox"
if [ "${TYPE}" = "xray" ] && [ -n "${XRAY_BIN}" ]; then
run_func="run_xray"
elif [ "${TYPE}" = "sing-box" ] && [ -n "${SINGBOX_BIN}" ]; then
run_func="run_singbox"
fi
${run_func} ${V2RAY_ARGS}; local status=$?
if [ "$status" == 0 ]; then
log 0 ${dns_msg}
else
log_i18n 0 "[%s] process %s error, skip this transparent proxy!" $(i18n "Global") "${V2RAY_CONFIG}"
cat ${_error_log_file} >> ${LOG_FILE}
unset _error_log_file
ENABLED_DEFAULT_ACL=0
return 1
fi
set_cache_var "ACL_GLOBAL_node" "$NODE"
set_cache_var "ACL_GLOBAL_redir_port" "$REDIR_PORT"
}
run_front_dns() {
local switch=0
direct_dns_shunt=$(config_t_get global direct_dns_shunt)
direct_dns_shunt=$(echo "${direct_dns_shunt}" | grep -v "^#")
[ -n "${direct_dns_shunt}" ] && switch=1
[ "${switch}" == "1" ] && {
local config_file="${TMP_PATH}/direct_dns.json"
local log_file="${TMP_PATH}/direct_dns.log"
log_file="/dev/null"
local listen_port=$(get_new_port 10553)
json_init
json_add_string "dns_listen_port" "${listen_port}"
json_add_string "direct_dns_udp_server" "${DIRECT_DNS_UDP_SERVER}"
json_add_string "direct_dns_udp_port" "${DIRECT_DNS_UDP_PORT}"
json_add_string "direct_dns_query_strategy" "${DIRECT_DNS_QUERY_STRATEGY}"
[ -n "${ACL_GLOBAL_node}" ] && [ -n "${TUN_DNS_PORT}" ] && {
json_add_string "default_dns_udp_server" "127.0.0.1"
json_add_string "default_dns_udp_port" "${TUN_DNS_PORT}"
}
local _json_arg="$(json_dump)"
local prefer_core=""
[ -n "${XRAY_BIN}" ] && prefer_core="xray"
[ -n "${SINGBOX_BIN}" ] && prefer_core="sing-box"
if [ "${prefer_core}" = "xray" ]; then
lua $UTIL_XRAY gen_front_dns_config "${_json_arg}" > $config_file
ln_run 0 "$XRAY_BIN" "xray" "${log_file}" run -c "$config_file"
elif [ "${prefer_core}" = "sing-box" ]; then
lua $UTIL_SINGBOX gen_front_dns_config "${_json_arg}" > $config_file
ln_run 0 "$SINGBOX_BIN" "sing-box" "${log_file}" run -c "$config_file"
else
return 1
fi
FRONT_DNS_SERVER="127.0.0.1"
FRONT_DNS_PORT="${listen_port}"
}
}
run_global_dnsmasq() {
[ -z "${ACL_GLOBAL_node}" ] && [ -z "${FRONT_DNS_PORT}" ] && return
local RUN_NEW_DNSMASQ=1
RUN_NEW_DNSMASQ=${DNS_REDIRECT}
DNSMASQ_DEFAULT_DNS="${AUTO_DNS}"
DNSMASQ_LOCAL_DNS="${LOCAL_DNS:-${AUTO_DNS}}"
DNSMASQ_TUN_DNS="${TUN_DNS}"
[ -n "${FRONT_DNS_PORT}" ] && {
DNSMASQ_DEFAULT_DNS="${FRONT_DNS_SERVER}#${FRONT_DNS_PORT}"
DNSMASQ_LOCAL_DNS="${DNSMASQ_DEFAULT_DNS}"
DNSMASQ_TUN_DNS="${DNSMASQ_DEFAULT_DNS}"
}
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}
json_init
json_add_string "LISTEN_PORT" "${DIRECT_DNSMASQ_PORT}"
json_add_string "DNSMASQ_CONF" "${DIRECT_DNSMASQ_CONF}"
json_add_string "TMP_DNSMASQ_PATH" "${DIRECT_DNSMASQ_CONF_PATH}"
lua $APP_PATH/helper_dnsmasq.lua copy_instance "$(json_dump)"
ln_run 0 "$(first_type dnsmasq)" "dnsmasq_direct" "/dev/null" -C ${DIRECT_DNSMASQ_CONF} -x ${GLOBAL_ACL_PATH}/direct_dnsmasq.pid
set_cache_var "DIRECT_DNSMASQ_PORT" "${DIRECT_DNSMASQ_PORT}"
}
#Rewrite the default DNS service configuration
#Modify the default dnsmasq service
lua $APP_PATH/helper_dnsmasq.lua stretch
json_init
json_add_string "FLAG" "default"
json_add_string "TMP_DNSMASQ_PATH" "${GLOBAL_DNSMASQ_CONF_PATH}"
json_add_string "DNSMASQ_CONF_FILE" "${GLOBAL_DNSMASQ_CONF}"
json_add_string "DEFAULT_DNS" "${DNSMASQ_DEFAULT_DNS}"
json_add_string "LOCAL_DNS" "${DNSMASQ_LOCAL_DNS}"
json_add_string "TUN_DNS" "${DNSMASQ_TUN_DNS}"
json_add_string "NFTFLAG" "${nftflag:-0}"
json_add_string "NO_LOGIC_LOG" "${NO_LOGIC_LOG:-0}"
lua $APP_PATH/helper_dnsmasq.lua add_rule "$(json_dump)"
uci -q add_list dhcp.@dnsmasq[0].addnmount=${GLOBAL_DNSMASQ_CONF_PATH}
uci -q commit dhcp
json_init
json_add_string "LOG" "1"
lua $APP_PATH/helper_dnsmasq.lua logic_restart "$(json_dump)"
else
#Run a copy dnsmasq instance, DNS hijack for that need proxy devices.
GLOBAL_DNSMASQ_PORT=$(get_new_port 11400)
run_copy_dnsmasq flag="default" listen_port=$GLOBAL_DNSMASQ_PORT local_dns="${DNSMASQ_LOCAL_DNS}" tun_dns="${DNSMASQ_TUN_DNS}" default_dns="${DNSMASQ_DEFAULT_DNS}"
DNS_REDIRECT_PORT=${GLOBAL_DNSMASQ_PORT}
#dhcp.leases to hosts
$APP_PATH/lease2hosts.sh > /dev/null 2>&1 &
fi
}
start_socks() {
[ "$SOCKS_ENABLED" = "1" ] && {
local ids=$(uci show $CONFIG | grep "=socks" | awk -F '.' '{print $2}' | awk -F '=' '{print $1}')
[ -n "$ids" ] && {
log_i18n 0 "Analyzing the node configuration of the Socks service..."
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"
# Auto switch logic
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
}
}
}
clean_crontab() {
[ -f "/tmp/lock/${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 -rf /tmp/lock/${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 "/tmp/lock/${CONFIG}_cron.lock" ] && {
rm -rf "/tmp/lock/${CONFIG}_cron.lock"
log_i18n 0 "The task is currently running automatically as a scheduled task; no reconfiguration of the scheduled task is required."
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
log_i18n 0 "Scheduled tasks: Auto stop service."
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
log_i18n 0 "Scheduled tasks: Auto start service."
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
log_i18n 0 "Scheduled tasks: Auto restart service."
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
log_i18n 0 "Scheduled tasks: Auto update rules."
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}
log_i18n 0 "Scheduled tasks: Auto update [%s] subscription." "${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 &
log_i18n 0 "Auto updates: Starts a cyclical update process."
}
else
log_i18n 0 "Running in no proxy mode, it only allows scheduled tasks for starting and stopping services."
fi
/etc/init.d/cron restart
}
stop_crontab() {
[ -f "/tmp/lock/${CONFIG}_cron.lock" ] && return
clean_crontab
/etc/init.d/cron restart
#log_i18n 0 "Clear scheduled commands."
}
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}
ln_run 0 "$(first_type haproxy)" haproxy "/dev/null" -f "${haproxy_path}/${haproxy_conf}"
}
run_copy_dnsmasq() {
local flag listen_port local_dns tun_dns default_dns
eval_set_val $@
local dnsmasq_conf=$TMP_ACL_PATH/$flag/dnsmasq.conf
local dnsmasq_conf_path=$TMP_ACL_PATH/$flag/dnsmasq.d
mkdir -p $dnsmasq_conf_path
json_init
json_add_string "LISTEN_PORT" "${listen_port}"
json_add_string "DNSMASQ_CONF" "${dnsmasq_conf}"
lua $APP_PATH/helper_dnsmasq.lua copy_instance "$(json_dump)"
json_init
json_add_string "FLAG" "${flag}"
json_add_string "TMP_DNSMASQ_PATH" "${dnsmasq_conf_path}"
json_add_string "DNSMASQ_CONF_FILE" "${dnsmasq_conf}"
json_add_string "DEFAULT_DNS" "${default_dns}"
json_add_string "LOCAL_DNS" "${local_dns}"
json_add_string "TUN_DNS" "${tun_dns}"
json_add_string "NFTFLAG" "${nftflag:-0}"
json_add_string "NO_LOGIC_LOG" "${NO_LOGIC_LOG:-0}"
lua $APP_PATH/helper_dnsmasq.lua add_rule "$(json_dump)"
ln_run 0 "$(first_type dnsmasq)" "dnsmasq_${flag}" "/dev/null" -C $dnsmasq_conf -x $TMP_ACL_PATH/$flag/dnsmasq.pid
set_cache_var "ACL_${flag}_dns_port" "${listen_port}"
}
run_ipset_dns_server() {
if [ -n "$(first_type chinadns-ng)" ]; then
run_ipset_chinadns_ng $@
else
run_ipset_dnsmasq $@
fi
}
run_ipset_chinadns_ng() {
local listen_port server_dns ipset nftset config_file
eval_set_val $@
[ ! -s "$TMP_ACL_PATH/vpslist" ] && {
node_servers=$(uci show "${CONFIG}" | grep -E "(.address=|.download_address=)" | cut -d "'" -f 2)
hosts_foreach "node_servers" host_from_url | grep '[a-zA-Z]$' | sort -u | grep -v "engage.cloudflareclient.com" > $TMP_ACL_PATH/vpslist
}
[ -n "${ipset}" ] && {
set_names=$ipset
vps_set_names="passwall2_vps,passwall2_vps6"
}
[ -n "${nftset}" ] && {
set_names=$(echo ${nftset} | awk -F, '{printf "%s,%s", substr($1,3), substr($2,3)}' | sed 's/#/@/g')
vps_set_names="inet@passwall2@passwall2_vps,inet@passwall2@passwall2_vps6"
}
cat <<-EOF > $config_file
bind-addr 127.0.0.1
bind-port ${listen_port}
china-dns ${server_dns}
trust-dns ${server_dns}
filter-qtype 65
add-tagchn-ip ${set_names}
default-tag chn
group vpslist
group-dnl $TMP_ACL_PATH/vpslist
group-upstream ${server_dns}
group-ipset ${vps_set_names}
EOF
ln_run 0 "$(first_type chinadns-ng)" "chinadns-ng" "/dev/null" -C $config_file -v
}
run_ipset_dnsmasq() {
local listen_port server_dns ipset nftset cache_size dns_forward_max config_file
eval_set_val $@
cat <<-EOF > $config_file
port=${listen_port}
no-poll
no-resolv
strict-order
cache-size=${cache_size:-0}
dns-forward-max=${dns_forward_max:-1000}
EOF
for i in $(echo ${server_dns} | sed "s#,# #g"); do
echo "server=${i}" >> $config_file
done
[ -n "${ipset}" ] && echo "ipset=${ipset}" >> $config_file
[ -n "${nftset}" ] && echo "nftset=${nftset}" >> $config_file
ln_run 0 "$(first_type dnsmasq)" "dnsmasq" "/dev/null" -C $config_file
}
acl_app() {
local items=$(uci show ${CONFIG} | grep "=acl_rule" | cut -d '.' -sf 2 | cut -d '=' -sf 1)
[ -n "$items" ] && {
local index=0
local item
local redir_port dns_port dnsmasq_port
local ipt_tmp msg msg2
redir_port=11200
dns_port=11300
dnsmasq_port=${GLOBAL_DNSMASQ_PORT:-11400}
for item in $items; do
index=$(expr $index + 1)
local enabled sid remarks sources interface tcp_no_redir_ports udp_no_redir_ports node direct_dns_query_strategy remote_dns_protocol remote_dns remote_dns_doh remote_dns_client_ip remote_dns_detour remote_fakedns remote_dns_query_strategy
local _ip _mac _iprange _ipset _ip_or_mac source_list config_file
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
node=${node:-default}
tcp_no_redir_ports=${tcp_no_redir_ports:-default}
udp_no_redir_ports=${udp_no_redir_ports:-default}
[ "$tcp_no_redir_ports" = "default" ] && tcp_no_redir_ports=$TCP_NO_REDIR_PORTS
[ "$udp_no_redir_ports" = "default" ] && 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 node
fi
[ -n "$node" ] && {
tcp_proxy_mode="global"
udp_proxy_mode="global"
direct_dns_query_strategy=${direct_dns_query_strategy:-UseIP}
remote_dns_protocol=${remote_dns_protocol:-tcp}
remote_dns=${remote_dns:-1.1.1.1}
case "$remote_dns_protocol" in
doh|\
http3)
remote_dns=${remote_dns_doh:-https://1.1.1.1/dns-query}
;;
esac
remote_dns_detour=${remote_dns_detour:-remote}
remote_fakedns=${remote_fakedns:-0}
remote_dns_query_strategy=${remote_dns_query_strategy:-UseIPv4}
local GLOBAL_node=$(get_cache_var "ACL_GLOBAL_node")
[ -n "${GLOBAL_node}" ] && GLOBAL_redir_port=$(get_cache_var "ACL_GLOBAL_redir_port")
if [ "$node" = "default" ]; then
if [ -n "${GLOBAL_node}" ]; then
set_cache_var "ACL_${sid}_node" "${GLOBAL_node}"
set_cache_var "ACL_${sid}_redir_port" "${GLOBAL_redir_port}"
set_cache_var "ACL_${sid}_dns_port" "${GLOBAL_DNSMASQ_PORT}"
set_cache_var "ACL_${sid}_default" "1"
else
log 1 "$(i18n "Global nodes are not enabled, skip [%s]." "${remarks}")"
fi
else
[ "$(config_get_type $node)" = "nodes" ] && {
if [ -n "${GLOBAL_node}" ] && [ "$node" = "${GLOBAL_node}" ]; then
set_cache_var "ACL_${sid}_node" "${GLOBAL_node}"
set_cache_var "ACL_${sid}_redir_port" "${GLOBAL_redir_port}"
set_cache_var "ACL_${sid}_dns_port" "${GLOBAL_DNSMASQ_PORT}"
set_cache_var "ACL_${sid}_default" "1"
else
redir_port=$(get_new_port $(expr $redir_port + 1))
local type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
if [ -n "${type}" ]; then
config_file=$TMP_ACL_PATH/${node}_TCP_UDP_DNS_${redir_port}.json
dns_port=$(get_new_port $(expr $dns_port + 1))
local acl_socks_port=$(get_new_port $(expr $redir_port + $index))
local run_func
[ -n "${XRAY_BIN}" ] && run_func="run_xray"
[ -n "${SINGBOX_BIN}" ] && run_func="run_singbox"
if [ "${type}" = "xray" ] && [ -n "${XRAY_BIN}" ]; then
run_func="run_xray"
elif [ "${type}" = "sing-box" ] && [ -n "${SINGBOX_BIN}" ]; then
run_func="run_singbox"
fi
${run_func} flag=acl_$sid node=$node redir_port=$redir_port tcp_proxy_way=${TCP_PROXY_WAY} \
socks_address=127.0.0.1 socks_port=$acl_socks_port \
dns_listen_port=${dns_port} \
direct_dns_query_strategy=${direct_dns_query_strategy} \
remote_dns_protocol=${remote_dns_protocol} remote_dns_tcp_server=${remote_dns} remote_dns_udp_server=${remote_dns} remote_dns_doh="${remote_dns}" \
remote_dns_client_ip=${remote_dns_client_ip} remote_dns_detour=${remote_dns_detour} remote_fakedns=${remote_fakedns} remote_dns_query_strategy=${remote_dns_query_strategy} \
config_file=${config_file}
local status=$?
if [ "$status" != 0 ]; then
log_i18n 2 "[%s] process %s error, skip this transparent proxy!" "${remarks}" "${config_file}"
cat ${_error_log_file} >> ${LOG_FILE}
unset _error_log_file
continue
fi
fi
dnsmasq_port=$(get_new_port $(expr $dnsmasq_port + 1))
run_copy_dnsmasq flag="$sid" listen_port=$dnsmasq_port local_dns="${LOCAL_DNS:-${AUTO_DNS}}" tun_dns="127.0.0.1#${dns_port}" default_dns="${AUTO_DNS}"
#dhcp.leases to hostsMore actions
$APP_PATH/lease2hosts.sh > /dev/null 2>&1 &
set_cache_var "ACL_${sid}_node" "$node"
set_cache_var "ACL_${sid}_redir_port" "$redir_port"
fi
}
fi
}
unset enabled sid remarks sources interface tcp_no_redir_ports udp_no_redir_ports node direct_dns_query_strategy remote_dns_protocol remote_dns remote_dns_doh remote_dns_client_ip remote_dns_detour remote_fakedns remote_dns_query_strategy
unset _ip _mac _iprange _ipset _ip_or_mac source_list config_file
done
unset redir_port dns_port dnsmasq_port
}
}
start() {
pgrep -f /tmp/etc/passwall2/bin > /dev/null 2>&1 && {
#log_i18n 0 "The program has started. Please stop it and then restart it!"
stop
}
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
json_init
json_add_string "LOG" "0"
lua $APP_PATH/helper_dnsmasq.lua restart "$(json_dump)"
}
fi
mkdir -p ${GLOBAL_ACL_PATH}
[ "$ENABLED_DEFAULT_ACL" == 1 ] && run_global
run_front_dns
run_global_dnsmasq
[ -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
run_process_queue
start_crontab
log_i18n 0 "Running complete!"
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
# Kill the SS plugin process
# 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
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
json_init
json_add_string "LOG" "0"
lua $APP_PATH/helper_dnsmasq.lua restart "$(json_dump)"
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 -rf /tmp/lock/${CONFIG}_socks_auto_switch*
rm -rf /tmp/lock/${CONFIG}_lease2hosts*
log_i18n 0 "Clearing and closing related programs and cache complete."
exit 0
}
get_direct_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]++')
DNSMASQ_UPSTREAM_DNS=$(uci show dhcp.@dnsmasq[0] | grep "\.server=" | awk -F '=' '{print $2}' | sed "s/'//g" | tr ' ' '\n' | grep -v "\/" | awk '{if($1 ~ /#/) {sub(/#/, "#", $1); print $1} else {print $1"#53"}}' | head -2 | sed ':label;N;s/\n/,/;b label')
DEFAULT_DNS="${DNSMASQ_UPSTREAM_DNS}"
[ -z "${DEFAULT_DNS}" ] && DEFAULT_DNS=$(echo -n $ISP_DNS | tr ' ' '\n' | head -2 | tr '\n' ',' | sed 's/,$//')
AUTO_DNS=${DEFAULT_DNS:-119.29.29.29}
local AUTO_DNS_1=$(echo ${AUTO_DNS} | awk -F ',' '{print $1}')
local AUTO_DNS_2=$(echo ${AUTO_DNS} | awk -F ',' '{print $2}')
local AUTO_DNS_ADDRESS=$(echo ${AUTO_DNS_1} | awk -F '#' '{print $1}')
local AUTO_DNS_PORT=$(echo ${AUTO_DNS_1} | awk -F '#' '{print $2}')
DIRECT_DNS_UDP_SERVER=${AUTO_DNS_ADDRESS}
DIRECT_DNS_UDP_PORT=${AUTO_DNS_PORT}
}
get_config() {
ENABLED_DEFAULT_ACL=0
ENABLED=$(config_t_get global enabled 0)
NODE=$(config_t_get global node)
[ "$ENABLED" == 1 ] && {
[ -n "$NODE" ] && [ "$(config_get_type $NODE)" == "nodes" ] && ENABLED_DEFAULT_ACL=1
}
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
}
SOCKS_ENABLED=$(config_t_get global socks_enabled 0)
REDIR_PORT=$(echo $(get_new_port 1041 tcp,udp))
TCP_PROXY_WAY=$(config_t_get global_forwarding tcp_proxy_way redirect)
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_REDIR_PORTS=$(config_t_get global_forwarding tcp_redir_ports '22,25,53,143,465,587,853,993,995,80,443')
UDP_REDIR_PORTS=$(config_t_get global_forwarding udp_redir_ports '1:65535')
PROXY_IPV6=$(config_t_get global_forwarding ipv6_tproxy 0)
TCP_PROXY_MODE="global"
UDP_PROXY_MODE="global"
LOCALHOST_PROXY=$(config_t_get global localhost_proxy '1')
CLIENT_PROXY=$(config_t_get global client_proxy '1')
DIRECT_DNS_QUERY_STRATEGY=$(config_t_get global direct_dns_query_strategy UseIP)
REMOTE_DNS_PROTOCOL=$(config_t_get global remote_dns_protocol tcp)
REMOTE_DNS_DETOUR=$(config_t_get global remote_dns_detour remote)
REMOTE_DNS=$(config_t_get global remote_dns 1.1.1.1:53 | sed 's/#/:/g' | sed -E 's/\:([^:]+)$/#\1/g')
REMOTE_FAKEDNS=$(config_t_get global remote_fakedns '0')
REMOTE_DNS_QUERY_STRATEGY=$(config_t_get global remote_dns_query_strategy UseIPv4)
DNS_CACHE=$(config_t_get global dns_cache 1)
DNS_REDIRECT=$(config_t_get global dns_redirect 1)
get_direct_dns
DEFAULT_DNSMASQ_CONF_DIR=/tmp/dnsmasq.d
DNSMASQ_CONF_DIR=${DEFAULT_DNSMASQ_CONF_DIR}
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=${DEFAULT_DNSMASQ_CONF_DIR}
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
QUEUE_RUN=1
}
arg1=$1
shift
case $arg1 in
run_socks)
get_direct_dns
QUEUE_RUN=0
run_socks $@
;;
socks_node_switch)
get_direct_dns
QUEUE_RUN=0
socks_node_switch $@
;;
start)
start $@
;;
stop)
stop
;;
esac