S50smartdns 8.7 KB

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