@ -16,6 +16,10 @@ TMP_DNSMASQ_PATH=/var/etc/dnsmasq-passwall.d
DNSMASQ_PATH = /etc/dnsmasq.d
RESOLVFILE = /tmp/resolv.conf.d/resolv.conf.auto
DNS_PORT = 7913
TUN_DNS = " 127.0.0.1# ${ DNS_PORT } "
IS_DEFAULT_DNS =
LOCAL_DNS =
DEFAULT_DNS =
NO_PROXY =
LUA_API_PATH = /usr/lib/lua/luci/model/cbi/$CONFIG /api
API_GEN_SS = $LUA_API_PATH /gen_shadowsocks.lua
@ -23,33 +27,22 @@ API_GEN_V2RAY=$LUA_API_PATH/gen_v2ray.lua
API_GEN_TROJAN = $LUA_API_PATH /gen_trojan.lua
echolog( ) {
local d = " $( date "+%Y-%m-%d %H:%M:%S" ) "
echo -e " $d : $@ " >>$LOG_FILE
}
find_bin( ) {
bin_name = $1
result = $( find /usr/*bin -iname " $bin_name " -type f)
if [ -z " $result " ] ; then
echo "null"
else
echo " $result "
fi
echo -e " $d : $* " >>$LOG_FILE
}
config_n_get( ) {
local ret = $( uci -q get $CONFIG .$1 .$2 2>/dev/null)
echo ${ ret : = $3 }
local ret = $( uci -q get " ${ CONFIG } . ${ 1 } . ${ 2 } " 2>/dev/null)
echo " ${ ret : = $3 } "
}
config_t_get( ) {
local index = 0
[ -n " $4 " ] && index = $4
local ret = $( uci -q get $CONFIG .@$1 [ $index ] .$2 2>/dev/null)
echo ${ ret : = $3 }
local index = ${ 4 :- 0 }
local ret = $( uci -q get " ${ CONFIG } .@ ${ 1 } [ ${ index } ]. ${ 2 } " 2>/dev/null)
echo " ${ ret : = ${ 3 } } "
}
get_enabled_anonymous_secs( ) {
uci -q show $CONFIG | grep " ${ 1 } \[.*\.enabled='1' " | cut -d'.' -sf2
uci -q show " ${ CONFIG } " | grep " ${ 1 } \[.*\.enabled='1' " | cut -d'.' -sf2
}
get_host_ip( ) {
@ -100,6 +93,24 @@ get_ip_port_from() {
eval " ${ __ipv } =\" $val1 \"; ${ __portv } =\" $val2 \" "
}
host_from_url( ) {
local f = ${ 1 }
## Remove protocol part of url ##
f = " ${ f ##http : // } "
f = " ${ f ##https : // } "
f = " ${ f ##ftp : // } "
f = " ${ f ##sftp : // } "
## Remove username and/or username:password part of URL ##
f = " ${ f ##* : *@ } "
f = " ${ f ##*@ } "
## Remove rest of urls ##
f = " ${ f %%/* } "
echo " ${ f %% : * } "
}
hosts_foreach( ) {
local __hosts
eval " __hosts=\$ ${ 1 } " ; shift 1
@ -139,6 +150,28 @@ get_last_dns() {
[ " ${ __first } " = = " ${ __last } " ] || echo " ${ __last } "
}
gen_dnsmasq_items( ) {
local ipsetlist = ${ 1 } ; shift 1
local fwd_dns = ${ 1 } ; shift 1
local outf = ${ 1 } ; shift 1
awk -v ipsetlist = " ${ ipsetlist } " -v fwd_dns = " ${ fwd_dns } " -v outf = " ${ outf } " '
BEGIN {
if ( outf = = "" ) outf = "/dev/stdout" ;
split( fwd_dns, dns, "," ) ; setdns = length( dns) >0; setlist = length( ipsetlist) >0;
if ( setdns) for ( i in dns) if ( length( dns[ i] ) = = 0) delete dns[ i] ;
fail = 1;
}
! /^$/&& !/^#/ {
fail = 0
if ( ! ( setdns || setlist) ) { printf( "server=%s\n" , $0 ) >>outf; next; }
if ( setdns) for ( i in dns) printf( "server=/.%s/%s\n" , $0 , dns[ i] ) >>outf;
if ( setlist) printf( "ipset=/.%s/%s\n" , $0 , ipsetlist) >>outf;
}
END { fflush( outf) ; close( outf) ; exit( fail) ; }
'
}
check_port_exists( ) {
port = $1
protocol = $2
@ -173,22 +206,26 @@ get_new_port() {
fi
}
first_type( ) {
local path_name = ${ 1 }
type -t -p " /bin/ ${ path_name } " -p " ${ TMP_BIN_PATH } / ${ path_name } " -p " ${ path_name } " -p "/usr/bin/v2ray/{path_name}" $@ | head -n1
}
ln_start_bin( ) {
local file = $1
[ " $file " != "null" ] && {
local bin = $2
shift 2
if [ -n " ${ TMP_BIN_PATH } / $bin " -a -f " ${ TMP_BIN_PATH } / $bin " ] ; then
${ TMP_BIN_PATH } /$bin $@ >/dev/null 2>& 1 &
else
if [ -n " $file " -a -f " $file " ] ; then
ln -s $file ${ TMP_BIN_PATH } /$bin
${ TMP_BIN_PATH } /$bin $@ >/dev/null 2>& 1 &
else
echolog " 找不到 $bin主程序 ,无法启动! "
fi
fi
}
local file_func = ${ 1 }
local ln_name = ${ 2 }
shift 2;
if [ " ${ file_func %%/* } " != " ${ file_func } " ] ; then
[ ! -L " ${ file_func } " ] && {
ln -s " ${ file_func } " " ${ TMP_BIN_PATH } / ${ ln_name } "
file_func = " ${ TMP_BIN_PATH } / ${ ln_name } "
}
[ -x " ${ file_func } " ] || echolog " - $( readlink ${ file_func } ) 没有执行权限,无法启动: ${ file_func } $@ "
fi
echo " ${ file_func } $@ " >& 2
[ -n " ${ file_func } " ] || echolog " - 找不到 ${ ln_name } ,无法启动... "
${ file_func :- echolog " - ${ ln_name } " } $@ >/dev/null 2>& 1 &
}
ENABLED = $( config_t_get global enabled 0)
@ -246,7 +283,7 @@ load_config() {
}
DNS_MODE = $( config_t_get global dns_mode pdnsd)
DNS_FORWARD = $( config_t_get global dns_forward 8.8.4.4:53)
DNS_FORWARD = $( config_t_get global dns_forward 8.8.4.4:53 | sed 's/:/#/g' )
DNS_CACHE = $( config_t_get global dns_cache 1)
use_tcp_node_resolve_dns = 0
use_udp_node_resolve_dns = 0
@ -256,25 +293,12 @@ load_config() {
else
process = $( config_t_get global_forwarding process)
fi
UP_CHINA_DNS = $( config_t_get global up_china_dns dnsbyisp)
[ " $UP_CHINA_DNS " = = "default" ] && IS_DEFAULT_CHINA_DNS = 1
[ ! -f " $RESOLVFILE " -o ! -s " $RESOLVFILE " ] && RESOLVFILE = /tmp/resolv.conf.auto
if [ " $UP_CHINA_DNS " = = "dnsbyisp" -o " $UP_CHINA_DNS " = = "default" ] ; then
UP_CHINA_DNS1 = $( cat $RESOLVFILE 2>/dev/null | grep -E -o "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" | grep -v 0.0.0.0 | grep -v 127.0.0.1 | sed -n '1P' )
DEFAULT_DNS1 = " $UP_CHINA_DNS1 "
[ -z " $UP_CHINA_DNS1 " ] && UP_CHINA_DNS1 = "119.29.29.29"
UP_CHINA_DNS = " $UP_CHINA_DNS1 "
UP_CHINA_DNS2 = $( cat $RESOLVFILE 2>/dev/null | grep -E -o "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" | grep -v 0.0.0.0 | grep -v 127.0.0.1 | sed -n '2P' )
[ -n " $UP_CHINA_DNS1 " -a -n " $UP_CHINA_DNS2 " ] && UP_CHINA_DNS = " $UP_CHINA_DNS1 , $UP_CHINA_DNS2 "
else
UP_CHINA_DNS1 = $( get_first_dns UP_CHINA_DNS 53)
if [ -n " $UP_CHINA_DNS1 " ] ; then
UP_CHINA_DNS2 = $( get_last_dns UP_CHINA_DNS 53)
[ -n " $UP_CHINA_DNS2 " ] && UP_CHINA_DNS = " ${ UP_CHINA_DNS1 } , ${ UP_CHINA_DNS2 } "
else
UP_CHINA_DNS1 = "119.29.29.29"
UP_CHINA_DNS = $UP_CHINA_DNS1
fi
LOCAL_DNS = $( config_t_get global up_china_dns dnsbyisp | sed 's/:/#/g' )
[ -f " ${ RESOLVFILE } " ] && [ -s " ${ RESOLVFILE } " ] || RESOLVFILE = /tmp/resolv.conf.auto
DEFAULT_DNS = $( cat " ${ RESOLVFILE } " 2>/dev/null | sed -n 's/^nameserver[ \t]*\([^ ]*\)$/\1/p' | grep -v "0.0.0.0" | grep -v "127.0.0.1" | grep -v " ^:: $" | sed 's/\n/,/g' )
if [ " ${ LOCAL_DNS } " = "default" ] ; then
IS_DEFAULT_DNS = 1
LOCAL_DNS = " ${ DEFAULT_DNS :- 119 .29.29.29 } "
fi
PROXY_IPV6 = $( config_t_get global_forwarding proxy_ipv6 0)
mkdir -p /var/etc $TMP_PATH $TMP_BIN_PATH $TMP_ID_PATH $TMP_PORT_PATH
@ -294,7 +318,7 @@ run_socks() {
echolog " - 启用 ${ bind } : ${ local_port } "
if [ -n " $server_host " ] && [ -n " $port " ] ; then
server_host = $( echo $server_host | sed 's/^\(https:\/\/\|http:\/\/\)//g' | awk -F '/' '{print $1}' )
server_host = $( host_from_url " $server_host " )
[ -n " $( echo -n $server_host | awk '{print gensub(/[!-~]/,"","g",$0)}' ) " ] && msg = " $remarks ,非法的代理服务器地址,无法启动 ! "
else
msg = "某种原因,此 Socks 服务的相关配置已失联,启动中止!"
@ -310,23 +334,26 @@ run_socks() {
echolog " - 不能使用 Socks 类型的代理节点"
elif [ " $type " = = "v2ray" ] ; then
lua $API_GEN_V2RAY $node nil nil $local_port > $config_file
ln_start_bin $( config_t_get global_app v2ray_file $( find_bin v2ray) ) /v2ray v2ray " -config= $config_file "
ln_start_bin " $( first_type $( config_t_get global_app v2ray_file notset) /v2ray v2ray) " v2ray " -config= $config_file "
elif [ " $type " = = "trojan" ] ; then
lua $API_GEN_TROJAN $node client $bind $local_port > $config_file
ln_start_bin $( find_bin trojan-plus) trojan-plus " -c $config_file "
ln_start_bin " $( first_type trojan) " trojan " -c $config_file "
elif [ " $type " = = "trojan-plus" ] ; then
lua $API_GEN_TROJAN $node client $bind $local_port > $config_file
ln_start_bin " $( first_type trojan-plus trojan) " trojan-plus " -c $config_file "
elif [ " $type " = = "trojan-go" ] ; then
lua $API_GEN_TROJAN $node client $bind $local_port > $config_file
ln_start_bin $( config_t_get global_app trojan_go_file $( find_bin trojan-go) ) trojan-go " -config $config_file "
ln_start_bin " $( first_type $( config_t_get global_app trojan_go_file notset) trojan-go) " trojan-go " -config $config_file "
elif [ " $type " = = "brook" ] ; then
local protocol = $( config_n_get $node brook_protocol client)
local brook_tls = $( config_n_get $node brook_tls 0)
[ " $protocol " = = "wsclient" ] && {
[ " $brook_tls " = = "1" ] && server_host = " wss:// ${ server_host } " || server_host = " ws:// ${ server_host } "
}
ln_start_bin $( config_t_get global_app brook_file $( find_bin brook) ) brook_socks_$5 " $protocol -l $bind : $local_port -i $ $ bind -s $server_host : $port -p $( config_n_get $node password) "
ln_start_bin " $( first_type $( config_t_get global_app brook_file notset) brook) " brook_socks_$5 " $protocol -l $bind : $local_port -i $ bind -s $server_host : $port -p $( config_n_get $node password) "
elif [ " $type " = = "ssr" ] || [ " $type " = = "ss" ] ; then
lua $API_GEN_SS $node $local_port > $config_file
ln_start_bin $( find_bin ${ type } -local) ${ type } -local " -c $config_file -b $bind -u "
ln_start_bin " $( first_type ${ type } -local) " ${ type } -local " -c $config_file -b $bind -u "
fi
}
@ -342,7 +369,7 @@ run_redir() {
local port = $( config_n_get $node port)
[ -n " $server_host " -a -n " $port " ] && {
# 判断节点服务器地址是否URL并去掉~
local server_host = $( echo $server_host | sed 's/^\(https:\/\/\|http:\/\/\)//g' | awk -F '/' '{print $1}' )
local server_host = $( host_from_url " $server_host " )
# 判断节点服务器地址是否包含汉字~
local tmp = $( echo -n $server_host | awk '{print gensub(/[!-~]/,"","g",$0)}' )
[ -n " $tmp " ] && {
@ -360,26 +387,29 @@ run_redir() {
local server_username = $( config_n_get $node username)
local server_password = $( config_n_get $node password)
eval port = \$ UDP_REDIR_PORT$6
ln_start_bin $( find_bin ipt2socks) ipt2socks_udp_$6 " -U -l $port -b 0.0.0.0 -s $node_address -p $node_port -R "
ln_start_bin " $( first_type ipt2socks) " ipt2socks_udp_$6 " -U -l $port -b 0.0.0.0 -s $node_address -p $node_port -R "
elif [ " $type " = = "v2ray" ] ; then
lua $API_GEN_V2RAY $node udp $local_port nil > $config_file
ln_start_bin $( config_t_get global_app v2ray_file $( find_bin v2ray) ) /v2ray v2ray " -config= $config_file "
ln_start_bin " $( first_type $( config_t_get global_app v2ray_file notset) /v2ray v2ray) " v2ray " -config= $config_file "
elif [ " $type " = = "trojan" ] ; then
lua $API_GEN_TROJAN $node nat "0.0.0.0" $local_port >$config_file
ln_start_bin $( find_bin trojan-plus) trojan-plus " -c $config_file "
ln_start_bin " $( first_type trojan) " trojan " -c $config_file "
elif [ " $type " = = "trojan-plus" ] ; then
lua $API_GEN_TROJAN $node nat "0.0.0.0" $local_port >$config_file
ln_start_bin " $( first_type trojan-plus trojan) " trojan-plus " -c $config_file "
elif [ " $type " = = "trojan-go" ] ; then
lua $API_GEN_TROJAN $node nat "0.0.0.0" $local_port >$config_file
ln_start_bin $( config_t_get global_app trojan_go_file $( find_bin trojan-go) ) trojan-go " -config $config_file "
ln_start_bin " $( first_type $( config_t_get global_app trojan_go_file notset) trojan-go) " trojan-go " -config $config_file "
elif [ " $type " = = "brook" ] ; then
local protocol = $( config_n_get $node brook_protocol client)
if [ " $protocol " = = "wsclient" ] ; then
echolog "Brook的WebSocket不支持UDP转发! "
else
ln_start_bin $( config_t_get global_app brook_file $( find_bin brook) ) brook_udp_$6 " tproxy -l 0.0.0.0: $local_port -s $server_host : $port -p $( config_n_get $node password) "
ln_start_bin " $( first_type $( config_t_get global_app brook_file notset) brook) " brook_udp_$6 " tproxy -l 0.0.0.0: $local_port -s $server_host : $port -p $( config_n_get $node password) "
fi
elif [ " $type " = = "ssr" ] || [ " $type " = = "ss" ] ; then
lua $API_GEN_SS $node $local_port > $config_file
ln_start_bin $( find_bin ${ type } -redir) ${ type } -redir " -c $config_file -U "
ln_start_bin " $( first_type ${ type } -redir) " ${ type } -redir " -c $config_file -U "
fi
fi
@ -392,20 +422,25 @@ run_redir() {
eval port = \$ TCP_REDIR_PORT$6
local extra_param = "-T"
[ " $6 " = = 1 ] && [ " $UDP_NODE1 " = = "tcp" ] && extra_param = ""
ln_start_bin $( find_bin ipt2socks) ipt2socks_tcp_$6 " -l $port -b 0.0.0.0 -s $node_address -p $node_port -R $extra_param "
ln_start_bin " $( first_type ipt2socks) " ipt2socks_tcp_$6 " -l $port -b 0.0.0.0 -s $node_address -p $node_port -R $extra_param "
elif [ " $type " = = "v2ray" ] ; then
local extra_param = "tcp"
[ " $6 " = = 1 ] && [ " $UDP_NODE1 " = = "tcp" ] && extra_param = "tcp,udp"
lua $API_GEN_V2RAY $node $extra_param $local_port nil > $config_file
ln_start_bin $( config_t_get global_app v2ray_file $( find_bin v2ray) ) /v2ray v2ray " -config= $config_file "
ln_start_bin " $( first_type $( config_t_get global_app v2ray_file notset) /v2ray v2ray) " v2ray " -config= $config_file "
elif [ " $type " = = "trojan" ] ; then
lua $API_GEN_TROJAN $node nat "0.0.0.0" $local_port > $config_file
for k in $( seq 1 $process ) ; do
ln_start_bin $( find_bin trojan-plus) trojan-plus " -c $config_file "
ln_start_bin " $( first_type trojan) " trojan " -c $config_file "
done
elif [ " $type " = = "trojan-plus" ] ; then
lua $API_GEN_TROJAN $node nat "0.0.0.0" $local_port > $config_file
for k in $( seq 1 $process ) ; do
ln_start_bin " $( first_type trojan-plus trojan) " trojan-plus " -c $config_file "
done
elif [ " $type " = = "trojan-go" ] ; then
lua $API_GEN_TROJAN $node nat "0.0.0.0" $local_port > $config_file
ln_start_bin $( config_t_get global_app trojan_go_file $( find_bin trojan-go) ) trojan-go " -config $config_file "
ln_start_bin " $( first_type $( config_t_get global_app trojan_go_file notset) trojan-go) " trojan-go " -config $config_file "
else
local kcptun_use = $( config_n_get $node use_kcp 0)
if [ " $kcptun_use " = = "1" ] ; then
@ -421,7 +456,7 @@ run_redir() {
local run_kcptun_ip = $server_host
[ -n " $kcptun_server_host " ] && run_kcptun_ip = $( get_host_ip $network_type $kcptun_server_host )
KCPTUN_REDIR_PORT = $( get_new_port $KCPTUN_REDIR_PORT tcp)
ln_start_bin $( config_t_get global_app kcptun_client_file $( find_bin kcptun-client) ) kcptun_tcp_$6 " -l 0.0.0.0: $KCPTUN_REDIR_PORT -r $run_kcptun_ip : $kcptun_port $kcptun_config "
ln_start_bin " $( first_type $( config_t_get global_app kcptun_client_file notset) kcptun-client) " kcptun_tcp_$6 " -l 0.0.0.0: $KCPTUN_REDIR_PORT -r $run_kcptun_ip : $kcptun_port $kcptun_config "
fi
fi
if [ " $type " = = "ssr" ] || [ " $type " = = "ss" ] ; then
@ -433,7 +468,7 @@ run_redir() {
[ " $6 " = = 1 ] && [ " $UDP_NODE1 " = = "tcp" ] && extra_param = "-u"
fi
for k in $( seq 1 $process ) ; do
ln_start_bin $( find_bin ${ type } -redir) ${ type } -redir " -c $config_file $extra_param "
ln_start_bin " $( first_type ${ type } -redir) " ${ type } -redir " -c $config_file $extra_param "
done
elif [ " $type " = = "brook" ] ; then
local server_ip = $server_host
@ -442,9 +477,9 @@ run_redir() {
if [ " $protocol " = = "wsclient" ] ; then
[ " $brook_tls " = = "1" ] && server_ip = " wss:// ${ server_ip } " || server_ip = " ws:// ${ server_ip } "
socks_port = $( get_new_port 2081 tcp)
ln_start_bin $( config_t_get global_app brook_file $( find_bin brook) ) brook_tcp_$6 " wsclient -l 127.0.0.1: $socks_port -i 127.0.0.1 -s $server_ip : $port -p $( config_n_get $node password) "
ln_start_bin " $( first_type $( config_t_get global_app brook_file notset) brook) " brook_tcp_$6 " wsclient -l 127.0.0.1: $socks_port -i 127.0.0.1 -s $server_ip : $port -p $( config_n_get $node password) "
eval port = \$ TCP_REDIR_PORT$6
ln_start_bin $( find_bin ipt2socks) ipt2socks_tcp_$6 " -T -l $port -b 0.0.0.0 -s 127.0.0.1 -p $socks_port -R "
ln_start_bin " $( first_type ipt2socks) " ipt2socks_tcp_$6 " -T -l $port -b 0.0.0.0 -s 127.0.0.1 -p $socks_port -R "
echolog "Brook的WebSocket不支持透明代理, 将使用ipt2socks转换透明代理! "
[ " $6 " = = 1 ] && [ " $UDP_NODE1 " = = "tcp" ] && echolog "Brook的WebSocket不支持UDP转发! "
else
@ -452,7 +487,7 @@ run_redir() {
server_ip = 127.0.0.1
port = $KCPTUN_REDIR_PORT
}
ln_start_bin $( config_t_get global_app brook_file $( find_bin brook) ) brook_tcp_$6 " tproxy -l 0.0.0.0: $local_port -s $server_ip : $port -p $( config_n_get $node password) "
ln_start_bin " $( first_type $( config_t_get global_app brook_file notset) brook) " brook_tcp_$6 " tproxy -l 0.0.0.0: $local_port -s $server_ip : $port -p $( config_n_get $node password) "
fi
fi
fi
@ -592,12 +627,9 @@ start_dns() {
nonuse)
echolog "DNS: 不使用, 将会直接使用上级DNS! "
; ;
local_7913)
echolog "DNS: 使用本机7913端口DNS服务器解析域名..."
; ;
dns2socks)
[ " $DNS_CACHE " = = "0" ] && local _cache = "/d"
ln_start_bin $( find_bin dns2socks) dns2socks " $DNS2SOCKS_SOCKS_SERVER $DNS2SOCKS_FORWARD 127.0.0.1: $DNS_PORT $_cache "
ln_start_bin " $( first_type dns2socks) " dns2socks " $DNS2SOCKS_SOCKS_SERVER $DNS2SOCKS_FORWARD 127.0.0.1: $DNS_PORT $_cache "
echolog " DNS: dns2socks, ${ DNS2SOCKS_FORWARD -D46.182.19.48 : 53 } "
; ;
pdnsd)
@ -606,13 +638,13 @@ start_dns() {
force_stop
else
gen_pdnsd_config $DNS_PORT
ln_start_bin $( find_bin pdnsd) pdnsd " --daemon -c $pdnsd_dir /pdnsd.conf -d "
ln_start_bin " $( first_type pdnsd) " pdnsd " --daemon -c $pdnsd_dir /pdnsd.conf -d "
echolog "DNS: pdnsd + 使用TCP节点解析DNS"
fi
; ;
chinadns-ng)
local china_ng_chn = $( echo $UP_CHINA_DNS | sed 's/:/#/g' )
local china_ng_gfw = $( echo $DNS_FORWARD | sed 's/:/#/g' )
local china_ng_chn = ${ LOCAL_DNS }
local china_ng_gfw = ${ DNS_FORWARD }
other_port = $( expr $DNS_PORT + 1)
[ -f " $RULES_PATH /gfwlist.conf " ] && cat $RULES_PATH /gfwlist.conf | sort | uniq | sed -e '/127.0.0.1/d' | sed 's/ipset=\/.//g' | sed 's/\/gfwlist//g' > $TMP_PATH /gfwlist.txt
[ -f " $TMP_PATH /gfwlist.txt " ] && {
@ -639,88 +671,86 @@ start_dns() {
force_stop
else
gen_pdnsd_config $other_port
ln_start_bin $( find_bin pdnsd) pdnsd " --daemon -c $pdnsd_dir /pdnsd.conf -d "
ln_start_bin $( find_bin chinadns-ng) chinadns-ng " -l $DNS_PORT -c $china_ng_chn -t 127.0.0.1# $other_port $gfwlist_param $chnlist_param $fair_mode "
ln_start_bin " $( first_type pdnsd) " pdnsd " --daemon -c $pdnsd_dir /pdnsd.conf -d "
ln_start_bin " $( first_type chinadns-ng) " chinadns-ng " -l $DNS_PORT -c $china_ng_chn -t 127.0.0.1# $other_port $gfwlist_param $chnlist_param $fair_mode "
echolog " DNS: ChinaDNS-NG + pdnsd, $china_ng_gfw , 国内DNS: $china_ng_chn "
fi
elif [ " $up_trust_chinadns_ng_dns " = = "dns2socks" ] ; then
[ " $DNS_CACHE " = = "0" ] && local _cache = "/d"
ln_start_bin $( find_bin dns2socks) dns2socks " $DNS2SOCKS_SOCKS_SERVER $DNS2SOCKS_FORWARD 127.0.0.1: $other_port $_cache "
ln_start_bin $( find_bin chinadns-ng) chinadns-ng " -l $DNS_PORT -c $china_ng_chn -t 127.0.0.1# $other_port $gfwlist_param $chnlist_param $fair_mode "
ln_start_bin " $( first_type dns2socks) " dns2socks " $DNS2SOCKS_SOCKS_SERVER $DNS2SOCKS_FORWARD 127.0.0.1: $other_port $_cache "
ln_start_bin " $( first_type chinadns-ng) " chinadns-ng " -l $DNS_PORT -c $china_ng_chn -t 127.0.0.1# $other_port $gfwlist_param $chnlist_param $fair_mode "
echolog " DNS: ChinaDNS-NG + dns2socks, ${ DNS2SOCKS_FORWARD :- D46 .182.19.48 : 53 } , 国内DNS: $china_ng_chn "
elif [ " $up_trust_chinadns_ng_dns " = = "udp" ] ; then
use_udp_node_resolve_dns = 1
ln_start_bin $( find_bin chinadns-ng) chinadns-ng " -l $DNS_PORT -c $china_ng_chn -t $china_ng_gfw $gfwlist_param $chnlist_param $fair_mode "
ln_start_bin " $( first_type chinadns-ng) " chinadns-ng " -l $DNS_PORT -c $china_ng_chn -t $china_ng_gfw $gfwlist_param $chnlist_param $fair_mode "
echolog " DNS: ChinaDNS-NG, 国内DNS: $china_ng_chn , 可信DNS: $up_trust_chinadns_ng_dns , $china_ng_gfw "
echolog " - 如非直连地址, 请确保UDP节点已打开并且支持UDP转发。"
fi
; ;
*)
TUN_DNS = " $( echo ${ DNS_MODE } | sed 's/:/#/g' ) "
DNS_MODE = "other_dns"
echolog " 可信DNS: 指定DNS服务器(支持UDP查询)解析域名: ${ TUN_DNS } "
; ;
esac
}
add_dnsmasq( ) {
local msg
local fwd_dns
echolog "准备 dnsmasq 配置文件..."
mkdir -p $TMP_DNSMASQ_PATH $DNSMASQ_PATH /var/dnsmasq.d
local adblock = $( config_t_get global_rules adblock 0)
local chinadns_mode = 0
[ " $DNS_MODE " = = "chinadns-ng" ] && [ " $IS_DEFAULT_ CHINA_ DNS" != 1 ] && chinadns_mode = 1 && msg = "chinadns-ng"
[ " $DNS_MODE " = = "chinadns-ng" ] && [ " $IS_DEFAULT_ DNS" != 1 ] && chinadns_mode = 1
[ " $adblock " = = "1" ] && {
msg = " ${ msg } , adblock"
[ -f " $RULES_PATH /adblock.conf " -a -s " $RULES_PATH /adblock.conf " ] && ln -s $RULES_PATH /adblock.conf $TMP_DNSMASQ_PATH /adblock.conf
}
[ " $DNS_MODE " != "nonuse" ] && {
msg = " ${ msg } : $UP_CHINA_DNS1 , $UP_CHINA_DNS2 "
[ -f " $RULES_PATH /direct_host " -a -s " $RULES_PATH /direct_host " ] && cat $RULES_PATH /direct_host | sed -e " /^ $/d " | sort -u | awk '{if (mode == 0 && dns1 != "") print "server=/."$1"/' $UP_CHINA_DNS1 '"; if (mode == 0 && dns2 != "") print "server=/."$1"/' $UP_CHINA_DNS2 '"; print "ipset=/."$1"/whitelist"}' mode = $chinadns_mode dns1 = $UP_CHINA_DNS1 dns2 = $UP_CHINA_DNS2 > $TMP_DNSMASQ_PATH /direct_host.conf
uci show $CONFIG | grep ".address=" | cut -d "'" -f 2 | sed 's/^\(https:\/\/\|http:\/\/\)//g' | awk -F '/' '{print $1}' | grep -v "google.c" | grep -E '.*\..*$' | grep '[a-zA-Z]$' | sort -u | awk '{if (dns1 != "") print "server=/."$1"/' $UP_CHINA_DNS1 '"; if (dns2 != "") print "server=/."$1"/' $UP_CHINA_DNS2 '"; print "ipset=/."$1"/vpsiplist"}' dns1 = $UP_CHINA_DNS1 dns2 = $UP_CHINA_DNS2 > $TMP_DNSMASQ_PATH /vpsiplist_host.conf
[ -f " $RULES_PATH /proxy_host " -a -s " $RULES_PATH /proxy_host " ] && cat $RULES_PATH /proxy_host | sed -e " /^ $/d " | sort -u | awk '{if (mode == 0) print "server=/."$1"/127.0.0.1#' $DNS_PORT '"; print "ipset=/."$1"/blacklist"}' mode = $chinadns_mode > $TMP_DNSMASQ_PATH /proxy_host.conf
[ " ${ chinadns_mode } " = "0" ] && fwd_dns = " ${ LOCAL_DNS } "
cat " ${ RULES_PATH } /direct_host " | sort -u | gen_dnsmasq_items "whitelist" " ${ fwd_dns } " " ${ TMP_DNSMASQ_PATH } /direct_host.conf "
echolog " - [ $? ]域名白名单(whitelist): ${ fwd_dns :- 默认 } "
fwd_dns = " ${ LOCAL_DNS } "
hosts_foreach "servers" host_from_url | grep -v "google.c" | grep '[a-zA-Z]$' | sort -u | gen_dnsmasq_items "vpsiplist" " ${ fwd_dns } " " ${ TMP_DNSMASQ_PATH } /vpsiplist_host.conf "
echolog " - [ $? ]节点列表中的域名(vpsiplist): ${ fwd_dns :- 默认 } "
unset fwd_dns
[ " ${ chinadns_mode } " = "0" ] && fwd_dns = " 127.0.0.1# ${ DNS_PORT } " && cat " ${ RULES_PATH } /proxy_host " | sort -u | gen_dnsmasq_items "blacklist" " ${ fwd_dns } " " ${ TMP_DNSMASQ_PATH } /proxy_host.conf "
echolog " - [ $? ]代理域名表(blacklist): ${ fwd_dns :- 默认 } "
if [ " $chinadns_mode " = = 0 ] ; then
[ -f " $RULES_PATH /gfwlist.conf " -a -s " $RULES_PATH /gfwlist.conf " ] && ln -s $RULES_PATH /gfwlist.conf $TMP_DNSMASQ_PATH /gfwlist.conf
else
cat $TMP_PATH /gfwlist.txt | sed -e " /^ $/d " | sort -u | awk '{print "ipset=/."$1"/gfwlist"}' > $TMP_DNSMASQ_PATH /gfwlist.conf
fi
subscribe_proxy = $( config_t_get global_subscribe subscribe_proxy 0)
[ " $subscribe_proxy " = = "1" ] && {
echolog " - [ $? ]防火墙域名表(gfwlist): ${ fwd_dns :- 默认 } "
[ " $( config_t_get global_subscribe subscribe_proxy 0) " = "1" ] && {
local items = $( get_enabled_anonymous_secs "@subscribe_list" )
[ -n " $items " ] && {
for item in ${ items } ; do
local url = $( config_n_get ${ item } url)
[ -n " $url " ] && [ " $url " != "" ] && {
if [ -n " $( echo -n " $url " | grep "//" ) " ] ; then
[ " $chinadns_mode " = = 0 ] && echo -n " $url " | awk -F '/' '{print $3}' | sed "s/^/server=&\/./g" | sed " s/ $/\/127.0.0.1# $DNS_PORT /g " >>$TMP_DNSMASQ_PATH /subscribe.conf
echo -n " $url " | awk -F '/' '{print $3}' | sed "s/^/ipset=&\/./g" | sed " s/ $/\/blacklist/g " >>$TMP_DNSMASQ_PATH /subscribe.conf
else
[ " $chinadns_mode " = = 0 ] && echo -n " $url " | awk -F '/' '{print $1}' | sed "s/^/server=&\/./g" | sed " s/ $/\/127.0.0.1# $DNS_PORT /g " >>$TMP_DNSMASQ_PATH /subscribe.conf
echo -n " $url " | awk -F '/' '{print $1}' | sed "s/^/ipset=&\/./g" | sed " s/ $/\/blacklist/g " >>$TMP_DNSMASQ_PATH /subscribe.conf
fi
}
done
}
for item in ${ items } ; do
host_from_url " $( config_n_get ${ item } url) " | gen_dnsmasq_items "blacklist" " ${ fwd_dns } " " ${ TMP_DNSMASQ_PATH } /subscribe.conf "
echolog " - [ $? ]节点订阅用域名, $( host_from_url $( config_n_get ${ item } url) ) : ${ fwd_dns :- 默认 } "
done
}
}
echolog " - ${ msg } "
if [ -z " $IS_DEFAULT_CHINA_DNS " ] || [ " $IS_DEFAULT_CHINA_DNS " = = 0 ] ; then
server = " server=127.0.0.1# $DNS_PORT "
[ " $DNS_MODE " != "chinadns-ng" ] && {
[ -n " $UP_CHINA_DNS1 " ] && server = " server= $UP_CHINA_DNS1 "
[ -n " $UP_CHINA_DNS2 " ] && server = " ${ server } \nserver= ${ UP_CHINA_DNS2 } "
}
cat <<-EOF > /var/dnsmasq.d/dnsmasq-$CONFIG .conf
$( echo -e $server )
if [ " ${ IS_DEFAULT_DNS } " != "1" ] ; then
servers = " ${ TUN_DNS } "
[ " $DNS_MODE " != "chinadns-ng" ] && servers = " ${ LOCAL_DNS } "
cat <<-EOF > " /var/dnsmasq.d/dnsmasq- ${ CONFIG } .conf "
$( echo " ${ servers } " | sed 's/,/\n/g' | gen_dnsmasq_items)
all-servers
no-poll
no-resolv
EOF
echolog " - 默认DNS: ${ server } "
echolog " - 默认DNS: ${ server s } "
else
[ -z " $DEFAULT_DNS1 " ] && {
[ -z " ${ DEFAULT_DNS } " ] && {
local tmp = $( get_host_ip ipv4 www.baidu.com 1)
[ -z " $tmp " ] && {
cat <<-EOF > /var/dnsmasq.d/dnsmasq-$CONFIG .conf
server = $UP_CHINA_DNS1
server = $( get_first_dns LOCAL_DNS 53)
no-poll
no-resolv
EOF
@ -763,10 +793,10 @@ gen_pdnsd_config() {
}
EOF
echolog " - [ $? ]监听: 127.0.0.1: ${ 1 } "
append_pdnsd_updns( ) {
[ -z " ${ 2 } " ] && echolog " - 略过错误 : ${ 1 } " && return 0
echolog " - 上游DNS: ${ 2 } : ${ 3 } "
cat >> $pdnsd_dir /pdnsd.conf <<-EOF
server {
label = " node- ${ 2 } _ ${ 3 } " ;
@ -781,6 +811,7 @@ gen_pdnsd_config() {
caching = $_cache ;
}
EOF
echolog " - [ $? ]上游DNS: ${ 2 } : ${ 3 } "
}
hosts_foreach DNS_FORWARD append_pdnsd_updns 53
@ -794,127 +825,124 @@ del_dnsmasq() {
}
start_haproxy( ) {
local haproxy_bin HAPROXY_PATH HAPROXY_FILE item lport sorted_items
[ " $( config_t_get global_haproxy balancing_enable 0) " = = "1" ] && {
echolog "HAPROXY 负载均衡..."
haproxy_bin = $( find_bin haproxy)
[ -f " $haproxy_bin " ] && {
HAPROXY_PATH = $TMP_PATH /haproxy
mkdir -p $HAPROXY_PATH
HAPROXY_FILE = $HAPROXY_PATH /config.cfg
cat <<-EOF > $HAPROXY_FILE
global
log 127.0.0.1 local2
chroot /usr/bin
maxconn 60000
stats socket $HAPROXY_PATH /haproxy.sock
user root
daemon
defaults
mode tcp
log global
option tcplog
option dontlognull
option http-server-close
#option forwardfor except 127.0.0.0/8
option redispatch
retries 2
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
local haproxy_path haproxy_file item items lport sort_items
[ " $( config_t_get global_haproxy balancing_enable 0) " != "1" ] && return
echolog "HAPROXY 负载均衡..."
haproxy_path = ${ TMP_PATH } /haproxy
mkdir -p " ${ haproxy_path } "
haproxy_file = ${ haproxy_path } /config.cfg
cat <<-EOF > " ${ haproxy_file } "
global
log 127.0.0.1 local2
chroot /usr/bin
maxconn 60000
stats socket ${ haproxy_path } /haproxy.sock
user root
daemon
defaults
mode tcp
log global
option tcplog
option dontlognull
option http-server-close
#option forwardfor except 127.0.0.0/8
option redispatch
retries 2
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
EOF
items = $( get_enabled_anonymous_secs "@haproxy_config" )
for item in $items ; do
lport = $( config_n_get ${ item } haproxy_port 0)
[ " ${ lport } " = "0" ] && echolog " - 丢弃1个明显无效的节点" && continue
sort_items = " ${ sort_items } ${ IFS } ${ lport } ${ item } "
done
items = $( echo " ${ sort_items } " | sort -n | cut -d' ' -sf 2)
unset lport
local haproxy_port lbss lbort lbweight export backup
local msg bip bport bline bbackup failcount interface
for item in ${ items } ; do
unset haproxy_port lbort bbackup
eval $( uci -q show " ${ CONFIG } . ${ item } " | cut -d'.' -sf 3-)
get_ip_port_from " $lbss " bip bport
[ " $lbort " = "default" ] && lbort = $bport || bport = $lbort
[ -z " $haproxy_port " ] || [ -z " $bip " ] || [ -z " $lbort " ] && echolog " - 丢弃1个明显无效的节点" && continue
[ " $backup " = "1" ] && bbackup = "backup"
[ " $lport " = " ${ haproxy_port } " ] || {
item = "hasvalid"
lport = ${ haproxy_port }
echolog " + 入口 0.0.0.0: ${ lport } ... "
cat <<-EOF >> " ${ haproxy_file } "
listen $lport
mode tcp
bind 0.0.0.0:$lport
EOF
items = $( get_enabled_anonymous_secs "@haproxy_config" )
for item in $items ; do
lport = $( config_n_get ${ item } haproxy_port 0)
[ " ${ lport } " = = "0" ] && echolog " - 丢弃1个明显无效的节点" && continue
sorted_items = " ${ sorted_items } ${ IFS } ${ lport } ${ item } "
done
items = $( echo " ${ sorted_items } " | sort -n | cut -d' ' -sf 2)
unset lport
[ -n " $items " ] && {
local haproxy_port lbss lbort lbweight export backup
local msg bip bport bline bbackup failcount interface
for item in ${ items } ; do
unset haproxy_port lbort bbackup
eval $( uci -q show $CONFIG .${ item } | cut -d'.' -sf 3- | grep -v '^$' )
get_ip_port_from " $lbss " bip bport
[ " $lbort " = = "default" ] && lbort = $bport || bport = $lbort
[ -z " $haproxy_port " ] || [ -z " $bip " ] || [ -z " $lbort " ] && echolog " - 丢弃1个明显无效的节点" && continue
[ " $backup " = "1" ] && bbackup = "backup"
[ " $lport " = = " ${ haproxy_port } " ] || {
lport = ${ haproxy_port }
echolog " - 入口 0.0.0.0: ${ lport } ... "
cat <<-EOF >> $HAPROXY_FILE
listen $lport
mode tcp
bind 0.0.0.0:$lport
EOF
}
cat <<-EOF >> $HAPROXY_FILE
server $bip :$bport $bip :$bport weight $lbweight check inter 1500 rise 1 fall 3 $bbackup
EOF
if [ " $export " != "0" ] ; then
unset msg
failcount = 0
while [ " $failcount " -lt "3" ] ; do
ubus list network.interface.${ export } >/dev/null 2>& 1
if [ $? -ne 0 ] ; then
echolog " - 找不到出口接口: $export , 1分钟后再重试(${ failcount } /3), ${ bip } "
let "failcount++"
[ " $failcount " -ge 3 ] && exit 0
sleep 1m
else
route add -host ${ bip } dev ${ export }
msg = " [ $? ] 从 ${ export } 接口路由, "
echo " $bip " >>/tmp/balancing_ip
break
fi
done
fi
echolog " - ${ msg } 出口节点: ${ bip } : ${ bport } ,权重: ${ lbweight } "
done
}
# 控制台配置
local console_port = $( config_t_get global_haproxy console_port)
local console_user = $( config_t_get global_haproxy console_user)
local console_password = $( config_t_get global_haproxy console_password)
local auth = ""
[ -n " $console_user " -a -n "console_password" ] && auth = " stats auth $console_user : $console_password "
cat <<-EOF >> $HAPROXY_FILE
listen console
bind 0.0.0.0:$console_port
mode http
stats refresh 30s
stats uri /
stats admin if TRUE
$auth
EOF
ln_start_bin $haproxy_bin haproxy " -f $HAPROXY_FILE "
echolog " - 控制台端口: ${ console_port } /, ${ auth :- 公开 } "
}
}
cat <<-EOF >> " ${ haproxy_file } "
server $bip :$bport $bip :$bport weight $lbweight check inter 1500 rise 1 fall 3 $bbackup
EOF
if [ " $export " != "0" ] ; then
unset msg
failcount = 0
while [ " $failcount " -lt "3" ] ; do
ubus list network.interface.${ export } >/dev/null 2>& 1
if [ $? -ne 0 ] ; then
let "failcount++"
echolog " - 找不到出口接口: $export , 1分钟后再重试(${ failcount } /3), ${ bip } "
[ " $failcount " -ge 3 ] && exit 0
sleep 1m
else
route add -host ${ bip } dev ${ export }
msg = " [ $? ] 从 ${ export } 接口路由, "
echo " $bip " >>/tmp/balancing_ip
break
fi
done
fi
echolog " | - ${ msg } 出口节点: ${ bip } : ${ bport } ,权重: ${ lbweight } "
done
# 控制台配置
local console_port = $( config_t_get global_haproxy console_port)
local console_user = $( config_t_get global_haproxy console_user)
local console_password = $( config_t_get global_haproxy console_password)
local auth = ""
[ -n " $console_user " ] && [ -n " $console_password " ] && auth = " stats auth $console_user : $console_password "
cat <<-EOF >> " ${ haproxy_file } "
listen console
bind 0.0.0.0:$console_port
mode http
stats refresh 30s
stats uri /
stats admin if TRUE
$auth
EOF
[ " ${ item } " = = "hasvalid" ] && echolog " - 没有发现任何有效节点信息..." && return 0
ln_start_bin " $( first_type haproxy) " haproxy -f " ${ haproxy_file } "
echolog " * 控制台端口: ${ console_port } /, ${ auth :- 公开 } "
}
kill_all( ) {
kill -9 $( pidof $@ ) >/dev/null 2>& 1 &
kill -9 $( pidof " $@ " ) >/dev/null 2>& 1 &
}
force_stop( ) {
@ -938,8 +966,8 @@ boot() {
start( ) {
load_config
start_socks
start_haproxy
[ " $NO_PROXY " = = 1 ] || {
start_haproxy
start_redir TCP tcp
start_redir UDP udp
start_dns
@ -991,4 +1019,4 @@ start)
boot)
boot
; ;
esac
esac