smartdns-lite 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. #!/bin/sh /etc/rc.common
  2. #
  3. # Copyright (C) 2018-2025 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. START=19
  18. STOP=82
  19. NAME=smartdns-lite
  20. USE_PROCD=1
  21. SMARTDNS_CONF_DIR="/etc/smartdns"
  22. SMARTDNS_CONF_DOWNLOAD_DIR="$SMARTDNS_CONF_DIR/conf.d"
  23. SMARTDNS_VAR_CONF_DIR="/var/etc/smartdns"
  24. SMARTDNS_CONF="$SMARTDNS_VAR_CONF_DIR/smartdns-lite.conf"
  25. CUSTOM_CONF="$SMARTDNS_CONF_DIR/custom.conf"
  26. SMARTDNS_CONF_TMP="${SMARTDNS_CONF}.tmp"
  27. EXTRA_COMMANDS="clear_rules"
  28. EXTRA_HELP=" clear_rules clear all rules"
  29. conf_append()
  30. {
  31. echo "$1 $2" >> $SMARTDNS_CONF_TMP
  32. }
  33. client_rule_addr_append()
  34. {
  35. conf_append "client-rules" "$1"
  36. }
  37. servers_append()
  38. {
  39. conf_append "server" "$1 $server_options"
  40. }
  41. setup_tproxy_rules()
  42. {
  43. local tproxy_port="$1"
  44. local table_type="$2"
  45. ip rule add fwmark 1104 lookup 981
  46. ip route add local 0.0.0.0/0 dev lo table 981
  47. ip -6 route add local ::/0 dev lo table 981
  48. if [ "$table_type" = "iptable" ]; then
  49. iptables -t mangle -N SMARTDNS_LITE
  50. iptables -t mangle -A SMARTDNS_LITE -p tcp -m set --match-set smartdns dst -j TPROXY --on-ip 127.0.0.1 --on-port ${tproxy_port} --tproxy-mark 1104
  51. iptables -t mangle -A SMARTDNS_LITE -p udp -m set --match-set smartdns dst -j TPROXY --on-ip 127.0.0.1 --on-port ${tproxy_port} --tproxy-mark 1104
  52. iptables -t mangle -A SMARTDNS_LITE -j ACCEPT
  53. iptables -t mangle -A PREROUTING -j SMARTDNS_LITE
  54. ip6tables -t mangle -N SMARTDNS_LITE
  55. ip6tables -t mangle -A SMARTDNS_LITE -p tcp -m set --match-set smartdns6 dst -j TPROXY --on-ip ::1 --on-port ${tproxy_port} --tproxy-mark 1104
  56. ip6tables -t mangle -A SMARTDNS_LITE -p udp -m set --match-set smartdns6 dst -j TPROXY --on-ip ::1 --on-port ${tproxy_port} --tproxy-mark 1104
  57. ip6tables -t mangle -A SMARTDNS_LITE -j ACCEPT
  58. ip6tables -t mangle -A PREROUTING -j SMARTDNS_LITE
  59. elif [ "$table_type" = "nftable" ]; then
  60. nft add table ip smartdns_lite
  61. nft add set ip smartdns_lite ipv4 { type ipv4_addr\; flags interval\; auto-merge\; }
  62. nft add chain ip smartdns_lite prerouting { type filter hook prerouting priority 0\; }
  63. nft add rule ip smartdns_lite prerouting meta l4proto tcp ip daddr @ipv4 tproxy to 127.0.0.1:${tproxy_port} mark set 1104
  64. nft add rule ip smartdns_lite prerouting meta l4proto udp ip daddr @ipv4 tproxy to 127.0.0.1:${tproxy_port} mark set 1104
  65. nft add table ip6 smartdns_lite
  66. nft add set ip6 smartdns_lite ipv6 { type ipv6_addr\; flags interval\; auto-merge\; }
  67. nft add chain ip6 smartdns_lite prerouting6 { type filter hook prerouting priority 0\; }
  68. nft add rule ip6 smartdns_lite prerouting6 meta l4proto tcp ip6 daddr @ipv6 tproxy to ::1:${tproxy_port} mark set 1104
  69. nft add rule ip6 smartdns_lite prerouting6 meta l4proto udp ip6 daddr @ipv6 tproxy to ::1:${tproxy_port} mark set 1104
  70. else
  71. echo "table_type error"
  72. return 1
  73. fi
  74. }
  75. clear_tproxy_rules()
  76. {
  77. ip rule del fwmark 1104 > /dev/null 2>&1
  78. ip route flush table 981 > /dev/null 2>&1
  79. iptables -t mangle -D PREROUTING -j SMARTDNS_LITE > /dev/null 2>&1
  80. iptables -t mangle -F SMARTDNS_LITE > /dev/null 2>&1
  81. iptables -t mangle -X SMARTDNS_LITE > /dev/null 2>&1
  82. ip6tables -t mangle -D PREROUTING -j SMARTDNS_LITE > /dev/null 2>&1
  83. ip6tables -t mangle -F SMARTDNS_LITE > /dev/null 2>&1
  84. ip6tables -t mangle -X SMARTDNS_LITE > /dev/null 2>&1
  85. nft delete table ip smartdns_lite > /dev/null 2>&1
  86. nft delete table ip6 smartdns_lite > /dev/null 2>&1
  87. }
  88. clear_rules()
  89. {
  90. clear_tproxy_rules
  91. }
  92. load_parental_control_rules()
  93. {
  94. local section="$1"
  95. local adblock_set_name="$2"
  96. local block_domain_set_file=""
  97. local client_set_name="pc-client-address-$section"
  98. local block_set_name="pc-block-domain-$section"
  99. local server_options="-e"
  100. config_get_bool pc_enabled "$section" "pc_enabled" "0"
  101. [ "$pc_enabled" != "1" ] && return
  102. conf_append "group-begin" "parental-control-${section}"
  103. config_get pc_client_addr_file "$section" "pc_client_addr_file" ""
  104. [ -e "$pc_client_addr_file" ] && {
  105. conf_append "ip-set" "-name ${client_set_name} -file '$pc_client_addr_file'"
  106. conf_append "group-match" "-client-ip ip-set:${client_set_name}"
  107. }
  108. config_list_foreach "$section" "pc_client_addr" client_rule_addr_append
  109. config_list_foreach "$section" "pc_servers" servers_append
  110. config_get pc_block_file "$section" "pc_block_file" ""
  111. [ -e "$pc_block_file" ] && {
  112. conf_append "domain-set" "-name ${block_set_name} -file '$pc_block_file'"
  113. conf_append "domain-rules" "/domain-set:${block_set_name}/ -address #"
  114. }
  115. [ ! -z "$adblock_set_name" ] && {
  116. conf_append "domain-rules" "/domain-set:${adblock_set_name}/ -address #"
  117. }
  118. conf_append "group-end"
  119. }
  120. load_domain_rules()
  121. {
  122. local section="$1"
  123. local domain_set_args=""
  124. local domain_set_name="rules-domain-set-$section"
  125. local domain_rule_name="rules-domain-group-$section"
  126. local as_group=0;
  127. local qtype_soa_list=""
  128. local server_options=""
  129. clear_tproxy_rules
  130. config_get_bool rules_enabled "$section" "rules_enabled" "0"
  131. [ "$rules_enabled" != "1" ] && return
  132. config_list_foreach "$section" "rules_servers" servers_append
  133. config_get rules_domain_file "$section" "rules_domain_file" ""
  134. [ -e "$rules_domain_file" ] && {
  135. conf_append "group-begin" "${domain_rule_name}"
  136. conf_append "domain-set" "-name ${domain_set_name} -file '$rules_domain_file'"
  137. conf_append "group-match" "-domain domain-set:${domain_set_name}"
  138. conf_append "force-qtype-SOA" "-"
  139. server_options="-e"
  140. as_group="1"
  141. }
  142. config_get rules_speed_check_mode "$section" "rules_speed_check_mode" ""
  143. [ ! -z "$rules_speed_check_mode" ] && conf_append "speed-check-mode" "$rules_speed_check_mode"
  144. config_get rules_force_aaaa_soa "$section" "rules_force_aaaa_soa" "0"
  145. [ "$rules_force_aaaa_soa" = "1" ] && qtype_soa_list="$qtype_soa_list 28"
  146. config_get rules_force_https_soa "$section" "rules_force_https_soa" "1"
  147. [ "$rules_force_https_soa" = "1" ] && qtype_soa_list="$qtype_soa_list 65"
  148. [ ! -z "$qtype_soa_list" ] && conf_append "force-qtype-SOA" "$qtype_soa_list"
  149. config_get_bool use_internal_rules "$section" "use_internal_rules" "0"
  150. [ "$use_internal_rules" = "1" ] && {
  151. config_get tproxy_server_port "$section" "tproxy_server_port" ""
  152. [ ! -z "$tproxy_server_port" ] && {
  153. which nft > /dev/null 2>&1
  154. if [ "$?" = "0" ]; then
  155. table_type="nftable"
  156. conf_append "nftset" "#4:ip#smartdns_lite#ipv4"
  157. conf_append "nftset" "#6:ip6#smartdns_lite#ipv6"
  158. else
  159. conf_append "ipset" "SMARTDNS_LITE"
  160. table_type="iptable"
  161. fi
  162. setup_tproxy_rules "$tproxy_server_port" "$table_type"
  163. }
  164. } || {
  165. config_get ipset_name "$section" "ipset_name" ""
  166. [ -z "$ipset_name" ] || conf_append "ipset" "$ipset_name"
  167. config_get nftset_name "$section" "nftset_name" ""
  168. [ -z "$nftset_name" ] || conf_append "nftset" "$nftset_name"
  169. }
  170. [ "$as_group" = "1" ] && {
  171. conf_append "group-end"
  172. }
  173. }
  174. cloudflare_cdn_alias()
  175. {
  176. conf_append "ip-alias" "$1 ip-set:$ipset_set_name"
  177. }
  178. load_cloudflare_cdn_accelerate()
  179. {
  180. local section="$1"
  181. local ipset_set_name="cloudflare-ip-set-$section"
  182. config_get_bool cloudflare_enabled "$section" "cloudflare_enabled" "0"
  183. [ "$cloudflare_enabled" != "1" ] && return
  184. config_get cloudflare_cdn_ip_file "$section" "cloudflare_cdn_ip_file" ""
  185. [ ! -e "$cloudflare_cdn_ip_file" ] && return
  186. conf_append "ip-set" "-name ${ipset_set_name} -file '$cloudflare_cdn_ip_file'"
  187. config_list_foreach "$section" "cloudflare_ip_alias" cloudflare_cdn_alias
  188. }
  189. unload_service()
  190. {
  191. :
  192. }
  193. load_service()
  194. {
  195. local section="$1"
  196. args=""
  197. local device=""
  198. local adblock_set_name=""
  199. local auto_set_dnsmasq="0"
  200. mkdir -p $SMARTDNS_VAR_CONF_DIR
  201. rm -f $SMARTDNS_CONF_TMP
  202. config_get_bool enabled "$section" "enabled" '0'
  203. [ "$enabled" != "1" ] && {
  204. uci -q set smartdns.@smartdns[0].enabled="0"
  205. uci -q del_list smartdns.@smartdns[0].conf_files="$SMARTDNS_CONF"
  206. uci commit smartdns
  207. clear_tproxy_rules
  208. /etc/init.d/smartdns reload
  209. return
  210. }
  211. config_get port "$section" "port" "53"
  212. config_get server_mode "$section" "server_mode" "main"
  213. [ "$server_mode" = "main" ] && {
  214. port="53"
  215. }
  216. [ "$server_mode" = "dnsmasq_upstream" ] && {
  217. auto_set_dnsmasq="1"
  218. }
  219. config_list_foreach "$section" "servers" servers_append
  220. config_get ad_block_file "$section" "ad_block_file" ""
  221. [ -e "$ad_block_file" ] && {
  222. adblock_set_name="adblock-block-$section"
  223. conf_append "domain-set" "-name ${adblock_set_name} -file '$ad_block_file'"
  224. conf_append "domain-rules" "/domain-set:${adblock_set_name}/ -address #"
  225. }
  226. load_cloudflare_cdn_accelerate "$section"
  227. load_parental_control_rules "$section" "$adblock_set_name"
  228. load_domain_rules "$section"
  229. uci -q set smartdns.@smartdns[0].enabled="1"
  230. uci -q set smartdns.@smartdns[0].port="$port"
  231. uci -q set smartdns.@smartdns[0].auto_set_dnsmasq="$auto_set_dnsmasq"
  232. uci -q del_list smartdns.@smartdns[0].conf_files="$SMARTDNS_CONF"
  233. uci -q add_list smartdns.@smartdns[0].conf_files="$SMARTDNS_CONF"
  234. touch $SMARTDNS_CONF_TMP
  235. mv $SMARTDNS_CONF_TMP $SMARTDNS_CONF
  236. uci commit smartdns
  237. /etc/init.d/smartdns reload
  238. }
  239. service_triggers() {
  240. procd_add_reload_trigger smartdns-lite
  241. }
  242. service_stopped()
  243. {
  244. config_load "smartdns-lite"
  245. config_foreach unload_service "smartdns-lite"
  246. }
  247. start_service()
  248. {
  249. config_load "smartdns-lite"
  250. config_foreach load_service "smartdns-lite"
  251. }
  252. reload_service()
  253. {
  254. stop
  255. start
  256. }