S50smartdns 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. #!/bin/sh
  2. #
  3. # Copyright (C) 2018-2023 Ruilin Peng (Nick) <[email protected]>.
  4. #
  5. # smartdns is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation, either version 3 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # smartdns is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. SMARTDNS_BIN=/opt/usr/sbin/smartdns
  18. SMARTDNS_CONF=/opt/etc/smartdns/smartdns.conf
  19. DNSMASQ_CONF="/etc/dnsmasq.conf /var/etc/dnsmasq.conf /etc/storage/dnsmasq/dnsmasq.conf"
  20. SMARTDNS_PID=/var/run/smartdns.pid
  21. SMARTDNS_PORT=535
  22. SMARTDNS_OPT=/opt/etc/smartdns/smartdns-opt.conf
  23. # workmode
  24. # DO NOT CHANGE THIS, CHANGE MODE IN smartdns-opt.conf
  25. # 0: run as port only
  26. # 1: redirect port
  27. # 2: replace
  28. SMARTDNS_WORKMODE="1"
  29. if [ -f "$SMARTDNS_OPT" ]; then
  30. . "$SMARTDNS_OPT"
  31. fi
  32. set_iptable()
  33. {
  34. local redirect_tcp
  35. redirect_tcp=0
  36. grep ^bind-tcp $SMARTDNS_CONF > /dev/null 2>&1
  37. if [ $? -eq 0 ]; then
  38. redirect_tcp=1;
  39. fi
  40. IPS="$(ifconfig | grep "inet addr" | grep -v ":127" | grep "Bcast" | awk '{print $2}' | awk -F: '{print $2}')"
  41. for IP in $IPS
  42. do
  43. if [ $redirect_tcp -eq 1 ]; then
  44. iptables -t nat -A PREROUTING -p tcp -d "$IP" --dport 53 -j REDIRECT --to-ports "$SMARTDNS_PORT" > /dev/null 2>&1
  45. fi
  46. iptables -t nat -A PREROUTING -p udp -d "$IP" --dport 53 -j REDIRECT --to-ports "$SMARTDNS_PORT" > /dev/null 2>&1
  47. done
  48. }
  49. clear_iptable()
  50. {
  51. IPS="$(ifconfig | grep "inet addr" | grep -v ":127" | grep "Bcast" | awk '{print $2}' | awk -F: '{print $2}')"
  52. for IP in $IPS
  53. do
  54. iptables -t nat -D PREROUTING -p tcp -d "$IP" --dport 53 -j REDIRECT --to-ports "$SMARTDNS_PORT" > /dev/null 2>&1
  55. iptables -t nat -D PREROUTING -p udp -d "$IP" --dport 53 -j REDIRECT --to-ports "$SMARTDNS_PORT" > /dev/null 2>&1
  56. done
  57. }
  58. get_dnsmasq_cmd()
  59. {
  60. CMD="$(ps 2>/dev/null | grep -e '[a-zA-Z]\{0,2\} \{1,\}dnsmasq' | grep -v grep 2>/dev/null)"
  61. if [ ! -z "$CMD" ]; then
  62. return
  63. fi
  64. CMD="$(ps 2>/dev/null | grep '/usr/sbin/dnsmasq' | grep -v grep 2>/dev/null)"
  65. if [ ! -z "$CMD" ]; then
  66. return
  67. fi
  68. CMD="$(ps 2>/dev/null | grep 'dnsmasq' | grep -v grep 2>/dev/null)"
  69. if [ ! -z "$CMD" ]; then
  70. return
  71. fi
  72. CMD="$(ps ax 2>/dev/null | grep -e '[a-zA-Z]\{0,2\} \{1,\}dnsmasq' | grep -v grep 2>/dev/null)"
  73. if [ ! -z "$CMD" ]; then
  74. return
  75. fi
  76. CMD="$(ps ax 2>/dev/null | grep /usr/sbin/dnsmasq | grep -v grep 2>/dev/null)"
  77. if [ ! -z "$CMD" ]; then
  78. return
  79. fi
  80. CMD="$(ps ax 2>/dev/null | grep 'dnsmasq' | grep -v grep 2>/dev/null)"
  81. if [ ! -z "$CMD" ]; then
  82. return
  83. fi
  84. }
  85. restart_dnsmasq()
  86. {
  87. local CMD=""
  88. get_dnsmasq_cmd
  89. if [ -z "$CMD" ]; then
  90. echo "cannot find dnsmasq"
  91. return 1
  92. fi
  93. # check multiple dnsmasq
  94. linecount="$(echo "$CMD" | wc -l)"
  95. if [ $linecount -eq 1 ]; then
  96. PID="$(echo "$CMD" | awk '{print $1}')"
  97. elif [ $linecount -gt 1 ]; then
  98. PID1="$(echo "$CMD" | awk 'NR==1{print $1}')"
  99. PID2="$(echo "$CMD" | awk 'NR==2{print $1}')"
  100. PID2_PPID="$(grep 'PPid:' /proc/$PID2/status | awk '{print $2}' 2>/dev/null)"
  101. if [ "$PID2_PPID" != "$PID1" ]; then
  102. echo "find multiple dnsmasq, but not started by the same process"
  103. return 1
  104. fi
  105. PID=$PID1
  106. else
  107. echo "find multiple dnsmasq, but not started by the same process"
  108. return 1
  109. fi
  110. if [ ! -d "/proc/$PID" ]; then
  111. echo "dnsmasq is not running"
  112. return 1
  113. fi
  114. kill -9 "$PID"
  115. # get dnsmasq command
  116. CMD="$(echo "$CMD" | head -n 1)"
  117. DNSMASQ_CMD="$(echo "$CMD" | awk '{for(i=5; i<=NF;i++)printf $i " "}')"
  118. $DNSMASQ_CMD
  119. }
  120. add_dhcp_options6()
  121. {
  122. CONF_FILE=$1
  123. IPS="$(ifconfig | grep "inet addr" | grep -v ":127" | grep "Bcast" | awk '{print $2}' | awk -F: '{print $2}')"
  124. for IP in $IPS
  125. do
  126. DHCP_OPTION="$(grep "dhcp-option=" "$CONF_FILE" | grep "$IP" | head -n 1)"
  127. if [ -z "$DHCP_OPTION" ]; then
  128. continue
  129. fi
  130. SERVER_TAG="$(echo "$DHCP_OPTION" | awk -F= '{print $2}' | awk -F, '{print $1}')"
  131. LOCAL_SERVER_IP="$IP"
  132. grep "dhcp-option *= *$SERVER_TAG, *6 *, *$LOCAL_SERVER_IP" "$CONF_FILE" 1>/dev/null 2>&1
  133. if [ $? -eq 0 ]; then
  134. continue
  135. fi
  136. DHCP_OPTION="dhcp-option=$SERVER_TAG,6,$LOCAL_SERVER_IP"
  137. echo "$DHCP_OPTION" >> "$CONF_FILE"
  138. RESTART_DNSMASQ=1
  139. done
  140. return 1
  141. }
  142. clear_dhcp_options6()
  143. {
  144. CONF_FILE=$1
  145. IPS="$(ifconfig | grep "inet addr" | grep -v ":127" | grep "Bcast" | awk '{print $2}' | awk -F: '{print $2}')"
  146. for IP in $IPS
  147. do
  148. DHCP_OPTION="$(grep "dhcp-option=" "$CONF_FILE" | grep "$IP" | head -n 1)"
  149. if [ -z "$DHCP_OPTION" ]; then
  150. continue
  151. fi
  152. SERVER_TAG="$(echo "$DHCP_OPTION" | awk -F= '{print $2}' | awk -F, '{print $1}')"
  153. LOCAL_SERVER_IP="$IP"
  154. grep "dhcp-option *= *$SERVER_TAG, *6 *, *$LOCAL_SERVER_IP" "$CONF_FILE" 1>/dev/null 2>&1
  155. if [ $? -ne 0 ]; then
  156. continue
  157. fi
  158. sed -i "/^dhcp-option *=$SERVER_TAG,6,/d" "$CONF_FILE"
  159. RESTART_DNSMASQ=1
  160. done
  161. return 1
  162. }
  163. set_dnsmasq_conf()
  164. {
  165. local LOCAL_SERVER_IP=""
  166. local SERVER_TAG=""
  167. local CONF_FILE=$1
  168. local DHCP_OPTIONS=""
  169. add_dhcp_options6 "$CONF_FILE"
  170. grep "^port *=0" "$CONF_FILE" > /dev/null 2>&1
  171. if [ $? -ne 0 ]; then
  172. sed -i "/^port *=/d" "$CONF_FILE"
  173. echo "port=0" >> "$CONF_FILE"
  174. RESTART_DNSMASQ=1
  175. fi
  176. }
  177. set_dnsmasq()
  178. {
  179. local RESTART_DNSMASQ=0
  180. for conf in $DNSMASQ_CONF
  181. do
  182. if [ ! -e "$conf" ]; then
  183. continue
  184. fi
  185. set_dnsmasq_conf "$conf"
  186. done
  187. if [ $RESTART_DNSMASQ -ne 0 ]; then
  188. restart_dnsmasq
  189. fi
  190. }
  191. clear_dnsmasq_conf()
  192. {
  193. local LOCAL_SERVER_IP=""
  194. local SERVER_TAG=""
  195. local CONF_FILE=$1
  196. clear_dhcp_options6 "$CONF_FILE"
  197. grep "^port *=" "$CONF_FILE" > /dev/null 2>&1
  198. if [ $? -eq 0 ]; then
  199. sed -i "/^port *=/d" "$CONF_FILE"
  200. RESTART_DNSMASQ=1
  201. fi
  202. }
  203. clear_dnsmasq()
  204. {
  205. local RESTART_DNSMASQ=0
  206. for conf in $DNSMASQ_CONF
  207. do
  208. if [ ! -e "$conf" ]; then
  209. continue
  210. fi
  211. clear_dnsmasq_conf "$conf"
  212. done
  213. if [ $RESTART_DNSMASQ -ne 0 ]; then
  214. restart_dnsmasq
  215. fi
  216. }
  217. set_smartdns_port()
  218. {
  219. if [ "$SMARTDNS_WORKMODE" = "0" ]; then
  220. return 0
  221. elif [ "$SMARTDNS_WORKMODE" = "1" ]; then
  222. sed -i "s/^\(bind .*\):53\( .*\)\?$/\1:$SMARTDNS_PORT \2/g" $SMARTDNS_CONF
  223. sed -i "s/^\(bind-tcp .*\):53\( .*\)\?$/\1:$SMARTDNS_PORT \2/g" $SMARTDNS_CONF
  224. elif [ "$SMARTDNS_WORKMODE" = "2" ]; then
  225. sed -i "s/^\(bind .*\):$SMARTDNS_PORT\( .*\)\?$/\1:53 \2/g" $SMARTDNS_CONF
  226. sed -i "s/^\(bind-tcp .*\):$SMARTDNS_PORT\( .*\)\?$/\1:53 \2/g" $SMARTDNS_CONF
  227. else
  228. return 1
  229. fi
  230. return 0
  231. }
  232. set_rule()
  233. {
  234. if [ "$SMARTDNS_WORKMODE" = "0" ]; then
  235. return 0
  236. elif [ "$SMARTDNS_WORKMODE" = "1" ]; then
  237. set_iptable
  238. return $?
  239. elif [ "$SMARTDNS_WORKMODE" = "2" ]; then
  240. set_dnsmasq
  241. return $?
  242. else
  243. return 1
  244. fi
  245. }
  246. clear_rule()
  247. {
  248. if [ "$SMARTDNS_WORKMODE" = "0" ]; then
  249. return 0
  250. elif [ "$SMARTDNS_WORKMODE" = "1" ]; then
  251. clear_iptable
  252. return $?
  253. elif [ "$SMARTDNS_WORKMODE" = "2" ]; then
  254. clear_dnsmasq
  255. return $?
  256. else
  257. return 1
  258. fi
  259. }
  260. get_tz()
  261. {
  262. if [ -e "/etc/localtime" ]; then
  263. return
  264. fi
  265. for tzfile in /etc/TZ /var/etc/TZ
  266. do
  267. if [ ! -e "$tzfile" ]; then
  268. continue
  269. fi
  270. tz="$(cat $tzfile 2>/dev/null)"
  271. done
  272. if [ -z "$tz" ]; then
  273. return
  274. fi
  275. export TZ=$tz
  276. }
  277. case "$1" in
  278. start)
  279. set_rule
  280. if [ $? -ne 0 ]; then
  281. exit 1
  282. fi
  283. set_smartdns_port
  284. get_tz
  285. $SMARTDNS_BIN -c "$SMARTDNS_CONF" -p $SMARTDNS_PID
  286. if [ $? -ne 0 ]; then
  287. clear_rule
  288. exit 1
  289. fi
  290. ;;
  291. status)
  292. pid="$(cat $SMARTDNS_PID |head -n 1 2>/dev/null)"
  293. if [ -z "$pid" ]; then
  294. echo "smartdns not running."
  295. exit 0
  296. fi
  297. if [ -d "/proc/$pid" ]; then
  298. echo "smartdns is running"
  299. exit 0
  300. fi
  301. echo "smartdns not running."
  302. exit 0
  303. ;;
  304. stop)
  305. pid="$(cat "$SMARTDNS_PID" | head -n 1 2>/dev/null)"
  306. if [ -z "$pid" ]; then
  307. echo "smartdns not running."
  308. exit 0
  309. fi
  310. kill -15 "$pid" 2>/dev/null
  311. SLEEP=$(which usleep 2>/dev/null)
  312. SLEEPTIME=200000
  313. if [ -z "$SLEEP" ]; then
  314. SLEEP="sleep"
  315. SLEEPTIME=0.2
  316. fi
  317. N=300
  318. while [ $N -gt 0 ]
  319. do
  320. pid="$(cat "$SMARTDNS_PID" | head -n 1 2>/dev/null)"
  321. if [ -z "$pid" ]; then
  322. break
  323. fi
  324. if [ ! -d "/proc/$pid" ]; then
  325. break
  326. fi
  327. stat="$(cat /proc/${pid}/stat | awk '{print $3}' 2>/dev/null)"
  328. if [ "$stat" = "Z" ]; then
  329. $SLEEP $SLEEPTIME
  330. break
  331. fi
  332. $SLEEP $SLEEPTIME 2>/dev/null
  333. N=$((N-1))
  334. done
  335. kill -9 "$pid" 2>/dev/null
  336. clear_rule
  337. exit 0
  338. ;;
  339. restart)
  340. $0 stop
  341. $0 start
  342. ;;
  343. reload)
  344. ;;
  345. enable)
  346. nvram set apps_state_enable=2
  347. nvram set apps_state_error=0
  348. nvram set apps_state_install=5
  349. nvram set apps_state_action=install
  350. nvram set apps_u2ec_ex=2
  351. ;;
  352. firewall-start|reload|force-reload|reconfigure)
  353. $0 restart
  354. ;;
  355. *)
  356. ;;
  357. esac