smartdns 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. #!/bin/sh /etc/rc.common
  2. # Copyright (C) 2018 Nick Peng ([email protected])
  3. START=99
  4. NAME=smartdns
  5. USE_PROCD=1
  6. SERVICE_USE_PID=1
  7. SERVICE_WRITE_PID=1
  8. SERVICE_DAEMONIZE=1
  9. SERVICE_PID_FILE="/var/run/smartdns.pid"
  10. BASECONFIGFILE="/etc/smartdns/smartdns.conf"
  11. SMARTDNS_CONF_DIR="/etc/smartdns"
  12. SMARTDNS_VAR_CONF_DIR="/var/etc/smartdns"
  13. SMARTDNS_CONF="$SMARTDNS_VAR_CONF_DIR/smartdns.conf"
  14. ADDRESS_CONF="$SMARTDNS_CONF_DIR/address.conf"
  15. BLACKLIST_IP_CONF="$SMARTDNS_CONF_DIR/blacklist-ip.conf"
  16. CUSTOM_CONF="$SMARTDNS_CONF_DIR/custom.conf"
  17. SMARTDNS_CONF_TMP="${SMARTDNS_CONF}.tmp"
  18. COREDUMP="0"
  19. RESPAWN="1"
  20. set_forward_dnsmasq()
  21. {
  22. local PORT="$1"
  23. addr="127.0.0.1#$PORT"
  24. OLD_SERVER="`uci get dhcp.@dnsmasq[0].server 2>/dev/null`"
  25. echo $OLD_SERVER | grep "^$addr" >/dev/null 2>&1
  26. if [ $? -eq 0 ]; then
  27. return
  28. fi
  29. uci delete dhcp.@dnsmasq[0].server 2>/dev/null
  30. uci add_list dhcp.@dnsmasq[0].server=$addr
  31. for server in $OLD_SERVER; do
  32. if [ "$server" = "$addr" ]; then
  33. continue
  34. fi
  35. uci add_list dhcp.@dnsmasq[0].server=$server
  36. done
  37. uci delete dhcp.@dnsmasq[0].resolvfile 2>/dev/null
  38. uci set dhcp.@dnsmasq[0].noresolv=1
  39. uci commit dhcp
  40. /etc/init.d/dnsmasq restart
  41. }
  42. stop_forward_dnsmasq()
  43. {
  44. local OLD_PORT="$1"
  45. addr="127.0.0.1#$OLD_PORT"
  46. OLD_SERVER="`uci get dhcp.@dnsmasq[0].server 2>/dev/null`"
  47. echo $OLD_SERVER | grep "^$addr" >/dev/null 2>&1
  48. if [ $? -ne 0 ]; then
  49. return
  50. fi
  51. uci del_list dhcp.@dnsmasq[0].server=$addr 2>/dev/null
  52. addrlist="`uci get dhcp.@dnsmasq[0].server 2>/dev/null`"
  53. if [ -z "$addrlist" ] ; then
  54. uci set dhcp.@dnsmasq[0].resolvfile=/tmp/resolv.conf.auto 2>/dev/null
  55. uci delete dhcp.@dnsmasq[0].noresolv 2>/dev/null
  56. fi
  57. uci commit dhcp
  58. /etc/init.d/dnsmasq restart
  59. }
  60. set_iptable()
  61. {
  62. local ipv6_server=$1
  63. local tcp_server=$2
  64. IPS="`ifconfig | grep "inet addr" | grep -v ":127" | grep "Bcast" | awk '{print $2}' | awk -F : '{print $2}'`"
  65. for IP in $IPS
  66. do
  67. if [ "$tcp_server" == "1" ]; then
  68. iptables -t nat -A PREROUTING -p tcp -d $IP --dport 53 -j REDIRECT --to-ports $SMARTDNS_PORT >/dev/null 2>&1
  69. fi
  70. iptables -t nat -A PREROUTING -p udp -d $IP --dport 53 -j REDIRECT --to-ports $SMARTDNS_PORT >/dev/null 2>&1
  71. done
  72. if [ "$ipv6_server" == 0 ]; then
  73. return
  74. fi
  75. IPS="`ifconfig | grep "inet6 addr" | grep -v " fe80::" | grep -v " ::1" | grep "Global" | awk '{print $3}'`"
  76. for IP in $IPS
  77. do
  78. if [ "$tcp_server" == "1" ]; then
  79. ip6tables -t nat -A PREROUTING -p tcp -d $IP --dport 53 -j REDIRECT --to-ports $SMARTDNS_PORT >/dev/null 2>&1
  80. fi
  81. ip6tables -t nat -A PREROUTING -p udp -d $IP --dport 53 -j REDIRECT --to-ports $SMARTDNS_PORT >/dev/null 2>&1
  82. done
  83. }
  84. clear_iptable()
  85. {
  86. local OLD_PORT="$1"
  87. local ipv6_server=$2
  88. IPS="`ifconfig | grep "inet addr" | grep -v ":127" | grep "Bcast" | awk '{print $2}' | awk -F : '{print $2}'`"
  89. for IP in $IPS
  90. do
  91. iptables -t nat -D PREROUTING -p udp -d $IP --dport 53 -j REDIRECT --to-ports $OLD_PORT >/dev/null 2>&1
  92. iptables -t nat -D PREROUTING -p tcp -d $IP --dport 53 -j REDIRECT --to-ports $OLD_PORT >/dev/null 2>&1
  93. done
  94. if [ "$ipv6_server" == 0 ]; then
  95. return
  96. fi
  97. IPS="`ifconfig | grep "inet6 addr" | grep -v " fe80::" | grep -v " ::1" | grep "Global" | awk '{print $3}'`"
  98. for IP in $IPS
  99. do
  100. ip6tables -t nat -D PREROUTING -p udp -d $IP --dport 53 -j REDIRECT --to-ports $OLD_PORT >/dev/null 2>&1
  101. ip6tables -t nat -D PREROUTING -p tcp -d $IP --dport 53 -j REDIRECT --to-ports $OLD_PORT >/dev/null 2>&1
  102. done
  103. }
  104. service_triggers() {
  105. procd_add_reload_trigger firewall
  106. procd_add_reload_trigger smartdns
  107. }
  108. conf_append()
  109. {
  110. echo "$1 $2" >> $SMARTDNS_CONF_TMP
  111. }
  112. load_server()
  113. {
  114. local section="$1"
  115. local ADDITIONAL_ARGS=""
  116. local DNS_ADDRESS=""
  117. config_get_bool "enabled" "$section" "enabled" "1"
  118. config_get "port" "$section" "port" ""
  119. config_get "type" "$section" "type" "udp"
  120. config_get "ip" "$section" "ip" ""
  121. config_get "server_group" "$section" "server_group" ""
  122. config_get "blacklist_ip" "$section" "blacklist_ip" "0"
  123. config_get "check_edns" "$section" "check_edns" "0"
  124. config_get "spki_pin" "$section" "spki_pin" ""
  125. config_get "addition_arg" "$section" "addition_arg" ""
  126. if [ "$enabled" = "0" ]; then
  127. return
  128. fi
  129. if [ -z "$ip" ] || [ -z "$type" ]; then
  130. return
  131. fi
  132. SERVER="server"
  133. if [ "$type" = "tcp" ]; then
  134. SERVER="server-tcp"
  135. elif [ "$type" = "tls" ]; then
  136. SERVER="server-tls"
  137. elif [ "$type" = "https" ]; then
  138. SERVER="server-https"
  139. fi
  140. if [ ! -z "`echo $ip | grep ":" | grep -v "https://"`" ]; then
  141. if [ -z "`echo $ip | grep "\["`" ]; then
  142. ip="[$ip]"
  143. fi
  144. fi
  145. if [ ! -z "$server_group" ]; then
  146. ADDITIONAL_ARGS="$ADDITIONAL_ARGS -group $server_group"
  147. fi
  148. if [ "$blacklist_ip" != "0" ]; then
  149. ADDITIONAL_ARGS="$ADDITIONAL_ARGS -blacklist-ip"
  150. fi
  151. if [ "$check_edns" != "0" ]; then
  152. ADDITIONAL_ARGS="$ADDITIONAL_ARGS -check-edns"
  153. fi
  154. if [ ! -z "$spki_pin" ]; then
  155. ADDITIONAL_ARGS="$ADDITIONAL_ARGS -spki-pin $spki_pin"
  156. fi
  157. if [ ! -z "$port" ]; then
  158. DNS_ADDRESS="$ip:$port"
  159. else
  160. DNS_ADDRESS="$ip"
  161. fi
  162. if [ "$type" = "https" ]; then
  163. DNS_ADDRESS="$ip"
  164. fi
  165. conf_append "$SERVER" "$DNS_ADDRESS $ADDITIONAL_ARGS $addition_arg"
  166. }
  167. load_service() {
  168. local section="$1"
  169. args=""
  170. mkdir -p $SMARTDNS_VAR_CONF_DIR
  171. rm -f $SMARTDNS_CONF_TMP
  172. config_get_bool "enabled" "$section" "enabled" '0'
  173. config_get "server_name" "$section" "server_name" ""
  174. if [ ! -z "$server_name" ]; then
  175. conf_append "server-name" "$server_name"
  176. fi
  177. config_get "coredump" "$section" "coredump" "0"
  178. if [ "$coredump" = "1" ]; then
  179. COREDUMP="1"
  180. fi
  181. config_get "port" "$section" "port" "6053"
  182. config_get "ipv6_server" "$section" "ipv6_server" "1"
  183. config_get "tcp_server" "$section" "tcp_server" "1"
  184. if [ "$ipv6_server" = "1" ]; then
  185. conf_append "bind" "[::]:$port"
  186. else
  187. conf_append "bind" ":$port"
  188. fi
  189. if [ "$tcp_server" = "1" ]; then
  190. if [ "$ipv6_server" = "1" ]; then
  191. conf_append "bind-tcp" "[::]:$port"
  192. else
  193. conf_append "bind-tcp" ":$port"
  194. fi
  195. fi
  196. config_get "dualstack_ip_selection" "$section" "dualstack_ip_selection" "0"
  197. if [ "$dualstack_ip_selection" = "1" ]; then
  198. conf_append "dualstack-ip-selection" "yes"
  199. fi
  200. config_get "prefetch_domain" "$section" "prefetch_domain" "0"
  201. if [ "$prefetch_domain" = "1" ]; then
  202. conf_append "prefetch-domain" "yes"
  203. fi
  204. SMARTDNS_PORT="$port"
  205. config_get "cache_size" "$section" "cache_size" ""
  206. if [ ! -z "$cache_size" ]; then
  207. conf_append "cache-size" "$cache_size"
  208. fi
  209. config_get "rr_ttl" "$section" "rr_ttl" ""
  210. if [ ! -z "$rr_ttl" ]; then
  211. conf_append "rr-ttl" "$rr_ttl"
  212. fi
  213. config_get "rr_ttl_min" "$section" "rr_ttl_min" ""
  214. if [ ! -z "$rr_ttl_min" ]; then
  215. conf_append "rr-ttl-min" "$rr_ttl_min"
  216. fi
  217. config_get "rr_ttl_max" "$section" "rr_ttl_max" ""
  218. if [ ! -z "$rr_ttl_max" ]; then
  219. conf_append "rr-ttl-max" "$rr_ttl_max"
  220. fi
  221. config_get "log_size" "$section" "log_size" "64K"
  222. if [ ! -z "$log_size" ]; then
  223. conf_append "log-size" "$log_size"
  224. fi
  225. config_get "log_num" "$section" "log_num" "1"
  226. if [ ! -z "$log_num" ]; then
  227. conf_append "log-num" "$log_num"
  228. fi
  229. config_get "log_level" "$section" "log_level" "error"
  230. if [ ! -z "$log_level" ]; then
  231. conf_append "log-level" "$log_level"
  232. fi
  233. config_get "log_file" "$section" "log_file" ""
  234. if [ ! -z "$log_file" ]; then
  235. conf_append "log-file" "$log_file"
  236. fi
  237. config_get "redirect" "$section" "redirect" "none"
  238. config_get "old_redirect" "$section" "old_redirect" "none"
  239. config_get "old_port" "$section" "old_port" "0"
  240. config_get "old_enabled" "$section" "old_enabled" "0"
  241. if [ "$old_redirect" != "$redirect" ] || [ "$old_port" != "$SMARTDNS_PORT" ] || [ "$old_enabled" = "1" -a "$enabled" = "0" ]; then
  242. if [ "$old_redirect" != "none" ]; then
  243. if [ "$old_port" != "0" ]; then
  244. clear_iptable "$old_port" "$ipv6_server"
  245. fi
  246. if [ "$old_redirect" == "dnsmasq-upstream" ]; then
  247. stop_forward_dnsmasq "$old_port"
  248. fi
  249. fi
  250. fi
  251. uci delete smartdns.@smartdns[0].old_redirect 2>/dev/null
  252. uci delete smartdns.@smartdns[0].old_port 2>/dev/null
  253. uci delete smartdns.@smartdns[0].old_enabled 2>/dev/null
  254. uci add_list smartdns.@smartdns[0].old_redirect="$redirect" 2>/dev/null
  255. uci add_list smartdns.@smartdns[0].old_port="$SMARTDNS_PORT" 2>/dev/null
  256. uci add_list smartdns.@smartdns[0].old_enabled="$enabled" 2>/dev/null
  257. uci commit smartdns
  258. [ "$enabled" -gt 0 ] || return 1
  259. if [ "$redirect" = "redirect" ]; then
  260. set_iptable $ipv6_server $tcp_server
  261. elif [ "$redirect" = "dnsmasq-upstream" ]; then
  262. set_forward_dnsmasq "$SMARTDNS_PORT"
  263. fi
  264. config_foreach load_server "server"
  265. echo "conf-file $ADDRESS_CONF" >> $SMARTDNS_CONF_TMP
  266. echo "conf-file $BLACKLIST_IP_CONF" >> $SMARTDNS_CONF_TMP
  267. echo "conf-file $CUSTOM_CONF" >> $SMARTDNS_CONF_TMP
  268. mv $SMARTDNS_CONF_TMP $SMARTDNS_CONF
  269. procd_open_instance "smartdns"
  270. if [ "$COREDUMP" = "1" ]; then
  271. args="$args -S"
  272. procd_set_param limits core="unlimited"
  273. fi
  274. procd_set_param command /usr/sbin/smartdns -f -c $SMARTDNS_CONF $args
  275. if [ "$RESPAWN" = "1" ]; then
  276. procd_set_param respawn ${respawn_threshold:-3600} ${respawn_timeout:-5} ${respawn_retry:-5}
  277. fi
  278. procd_set_param file "$SMARTDNS_CONF"
  279. procd_close_instance
  280. }
  281. start_service() {
  282. config_load "smartdns"
  283. config_foreach load_service "smartdns"
  284. }
  285. reload_service(){
  286. stop
  287. start
  288. }