S50smartdns 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  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=/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. echo "find multiple dnsmasq, but not started by the same process"
  106. return 1
  107. fi
  108. PID=$PID1
  109. else
  110. echo "find multiple dnsmasq, but not started by the same process"
  111. return 1
  112. fi
  113. if [ ! -d "/proc/$PID" ]; then
  114. echo "dnsmasq is not running"
  115. return 1
  116. fi
  117. kill -9 "$PID"
  118. # get dnsmasq command
  119. CMD="$(echo "$CMD" | head -n 1)"
  120. DNSMASQ_CMD="$(echo "$CMD" | awk '{for(i=5; i<=NF;i++)printf $i " "}')"
  121. $DNSMASQ_CMD
  122. }
  123. add_dhcp_options6()
  124. {
  125. CONF_FILE=$1
  126. IPS="$(ifconfig | grep "inet addr" | grep -v ":127" | grep "Bcast" | awk '{print $2}' | awk -F: '{print $2}')"
  127. for IP in $IPS
  128. do
  129. DHCP_OPTION="$(grep "dhcp-option=" "$CONF_FILE" | grep "$IP" | head -n 1)"
  130. if [ -z "$DHCP_OPTION" ]; then
  131. continue
  132. fi
  133. SERVER_TAG="$(echo "$DHCP_OPTION" | awk -F= '{print $2}' | awk -F, '{print $1}')"
  134. LOCAL_SERVER_IP="$IP"
  135. grep "dhcp-option *= *$SERVER_TAG, *6 *, *$LOCAL_SERVER_IP" "$CONF_FILE" 1>/dev/null 2>&1
  136. if [ $? -eq 0 ]; then
  137. continue
  138. fi
  139. DHCP_OPTION="dhcp-option=$SERVER_TAG,6,$LOCAL_SERVER_IP"
  140. echo "$DHCP_OPTION" >> "$CONF_FILE"
  141. RESTART_DNSMASQ=1
  142. done
  143. return 1
  144. }
  145. clear_dhcp_options6()
  146. {
  147. CONF_FILE=$1
  148. IPS="$(ifconfig | grep "inet addr" | grep -v ":127" | grep "Bcast" | awk '{print $2}' | awk -F: '{print $2}')"
  149. for IP in $IPS
  150. do
  151. DHCP_OPTION="$(grep "dhcp-option=" "$CONF_FILE" | grep "$IP" | head -n 1)"
  152. if [ -z "$DHCP_OPTION" ]; then
  153. continue
  154. fi
  155. SERVER_TAG="$(echo "$DHCP_OPTION" | awk -F= '{print $2}' | awk -F, '{print $1}')"
  156. LOCAL_SERVER_IP="$IP"
  157. grep "dhcp-option *= *$SERVER_TAG, *6 *, *$LOCAL_SERVER_IP" "$CONF_FILE" 1>/dev/null 2>&1
  158. if [ $? -ne 0 ]; then
  159. continue
  160. fi
  161. sed -i "/^dhcp-option *=$SERVER_TAG,6,/d" "$CONF_FILE"
  162. RESTART_DNSMASQ=1
  163. done
  164. return 1
  165. }
  166. set_dnsmasq_conf()
  167. {
  168. local LOCAL_SERVER_IP=""
  169. local SERVER_TAG=""
  170. local CONF_FILE=$1
  171. local DHCP_OPTIONS=""
  172. add_dhcp_options6 "$CONF_FILE"
  173. grep "^port *=0" "$CONF_FILE" > /dev/null 2>&1
  174. if [ $? -ne 0 ]; then
  175. sed -i "/^port *=/d" "$CONF_FILE"
  176. echo "port=0" >> "$CONF_FILE"
  177. RESTART_DNSMASQ=1
  178. fi
  179. }
  180. set_dnsmasq()
  181. {
  182. local RESTART_DNSMASQ=0
  183. for conf in $DNSMASQ_CONF
  184. do
  185. if [ ! -e "$conf" ]; then
  186. continue
  187. fi
  188. set_dnsmasq_conf "$conf"
  189. done
  190. if [ $RESTART_DNSMASQ -ne 0 ]; then
  191. restart_dnsmasq
  192. fi
  193. }
  194. clear_dnsmasq_conf()
  195. {
  196. local LOCAL_SERVER_IP=""
  197. local SERVER_TAG=""
  198. local CONF_FILE=$1
  199. clear_dhcp_options6 "$CONF_FILE"
  200. grep "^port *=" "$CONF_FILE" > /dev/null 2>&1
  201. if [ $? -eq 0 ]; then
  202. sed -i "/^port *=/d" "$CONF_FILE"
  203. RESTART_DNSMASQ=1
  204. fi
  205. }
  206. clear_dnsmasq()
  207. {
  208. local RESTART_DNSMASQ=0
  209. for conf in $DNSMASQ_CONF
  210. do
  211. if [ ! -e "$conf" ]; then
  212. continue
  213. fi
  214. clear_dnsmasq_conf "$conf"
  215. done
  216. if [ $RESTART_DNSMASQ -ne 0 ]; then
  217. restart_dnsmasq
  218. fi
  219. }
  220. set_smartdns_port()
  221. {
  222. if [ "$SMARTDNS_WORKMODE" = "0" ]; then
  223. return 0
  224. elif [ "$SMARTDNS_WORKMODE" = "1" ]; then
  225. sed -i "s/^\(bind .*\):53\( .*\)\?$/\1:$SMARTDNS_PORT \2/g" $SMARTDNS_CONF
  226. sed -i "s/^\(bind-tcp .*\):53\( .*\)\?$/\1:$SMARTDNS_PORT \2/g" $SMARTDNS_CONF
  227. elif [ "$SMARTDNS_WORKMODE" = "2" ]; then
  228. sed -i "s/^\(bind .*\):$SMARTDNS_PORT\( .*\)\?$/\1:53 \2/g" $SMARTDNS_CONF
  229. sed -i "s/^\(bind-tcp .*\):$SMARTDNS_PORT\( .*\)\?$/\1:53 \2/g" $SMARTDNS_CONF
  230. else
  231. return 1
  232. fi
  233. return 0
  234. }
  235. set_rule()
  236. {
  237. if [ "$SMARTDNS_WORKMODE" = "0" ]; then
  238. return 0
  239. elif [ "$SMARTDNS_WORKMODE" = "1" ]; then
  240. set_iptable
  241. return $?
  242. elif [ "$SMARTDNS_WORKMODE" = "2" ]; then
  243. set_dnsmasq
  244. return $?
  245. else
  246. return 1
  247. fi
  248. }
  249. clear_rule()
  250. {
  251. if [ "$SMARTDNS_WORKMODE" = "0" ]; then
  252. return 0
  253. elif [ "$SMARTDNS_WORKMODE" = "1" ]; then
  254. clear_iptable
  255. return $?
  256. elif [ "$SMARTDNS_WORKMODE" = "2" ]; then
  257. clear_dnsmasq
  258. return $?
  259. else
  260. return 1
  261. fi
  262. }
  263. get_tz()
  264. {
  265. if [ -e "/etc/localtime" ]; then
  266. return
  267. fi
  268. for tzfile in /etc/TZ /var/etc/TZ
  269. do
  270. if [ ! -e "$tzfile" ]; then
  271. continue
  272. fi
  273. tz="$(cat $tzfile 2>/dev/null)"
  274. done
  275. if [ -z "$tz" ]; then
  276. return
  277. fi
  278. export TZ=$tz
  279. }
  280. case "$1" in
  281. start)
  282. set_rule
  283. if [ $? -ne 0 ]; then
  284. exit 1
  285. fi
  286. set_smartdns_port
  287. get_tz
  288. $SMARTDNS_BIN -c "$SMARTDNS_CONF" -p $SMARTDNS_PID
  289. if [ $? -ne 0 ]; then
  290. clear_rule
  291. exit 1
  292. fi
  293. ;;
  294. status)
  295. pid="$(cat $SMARTDNS_PID |head -n 1 2>/dev/null)"
  296. if [ -z "$pid" ]; then
  297. echo "smartdns not running."
  298. exit 0
  299. fi
  300. if [ -d "/proc/$pid" ]; then
  301. echo "smartdns is running"
  302. exit 0
  303. fi
  304. echo "smartdns not running."
  305. exit 0
  306. ;;
  307. stop)
  308. pid="$(cat "$SMARTDNS_PID" | head -n 1 2>/dev/null)"
  309. if [ -z "$pid" ]; then
  310. echo "smartdns not running."
  311. exit 0
  312. fi
  313. kill -15 "$pid" 2>/dev/null
  314. SLEEP=$(which usleep 2>/dev/null)
  315. SLEEPTIME=200000
  316. if [ -z "$SLEEP" ]; then
  317. SLEEP="sleep"
  318. SLEEPTIME=0.2
  319. fi
  320. N=300
  321. while [ $N -gt 0 ]
  322. do
  323. pid="$(cat "$SMARTDNS_PID" | head -n 1 2>/dev/null)"
  324. if [ -z "$pid" ]; then
  325. break
  326. fi
  327. if [ ! -d "/proc/$pid" ]; then
  328. break
  329. fi
  330. stat="$(cat /proc/${pid}/stat | awk '{print $3}' 2>/dev/null)"
  331. if [ "$stat" = "Z" ]; then
  332. $SLEEP $SLEEPTIME
  333. break
  334. fi
  335. $SLEEP $SLEEPTIME 2>/dev/null
  336. N=$((N-1))
  337. done
  338. kill -9 "$pid" 2>/dev/null
  339. clear_rule
  340. exit 0
  341. ;;
  342. restart)
  343. $0 stop
  344. $0 start
  345. ;;
  346. reload)
  347. ;;
  348. enable)
  349. nvram set apps_state_enable=2
  350. nvram set apps_state_error=0
  351. nvram set apps_state_install=5
  352. nvram set apps_state_action=install
  353. nvram set apps_u2ec_ex=2
  354. ;;
  355. firewall-start|reload|force-reload|reconfigure)
  356. $0 restart
  357. ;;
  358. *)
  359. ;;
  360. esac