unblockneteasemusic 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. #!/bin/sh /etc/rc.common
  2. # SPDX-License-Identifier: GPL-3.0-only
  3. #
  4. # Copyright (C) 2019-2021 Tianling Shen <[email protected]>
  5. USE_PROCD=1
  6. START=99
  7. STOP=10
  8. NAME="unblockneteasemusic"
  9. UPGRADE_CONF="/lib/upgrade/keep.d/$NAME"
  10. IPT_N="iptables -t nat"
  11. RULES_UC="/usr/share/$NAME/rules/default.uc"
  12. RULES_NFT="/etc/nftables.d/90-$NAME-rules.nft"
  13. is_enabled() {
  14. local enabled
  15. config_get_bool enabled "$1" "$2" "${3:-0}"
  16. if [ "$enabled" -eq "1" ]; then
  17. return 0
  18. else
  19. return 1
  20. fi
  21. }
  22. append_param() {
  23. procd_append_param command "$1" $2
  24. }
  25. append_param_arg() {
  26. local value
  27. config_get value "$1" "$2" $4
  28. [ -n "$value" ] && append_param "$3" "$value"
  29. }
  30. append_param_env() {
  31. local value
  32. config_get value "$1" "$2" $4
  33. [ -n "$value" ] && procd_append_param env "$3"="$value"
  34. }
  35. uci_get_by_name() {
  36. local ret
  37. ret="$(uci -q get "$NAME".@"$1"["${4:-0}"]."$2")"
  38. echo "${ret:-$3}"
  39. }
  40. start_service()
  41. {
  42. config_load "$NAME"
  43. is_enabled "config" "enable" || exit 1
  44. local update_time
  45. config_get update_time "config" "update_time" "3"
  46. sed -i "/$NAME/d" /etc/crontabs/root
  47. is_enabled "config" "auto_update" && echo "0 ${update_time} * * * /usr/share/$NAME/update.sh update_core" >> "/etc/crontabs/root"
  48. echo "*/5 * * * * /usr/share/$NAME/log_check.sh" >> "/etc/crontabs/root"
  49. /etc/init.d/cron restart
  50. [ ! -s "/usr/share/$NAME/core/app.js" ] && { rm -f "/usr/share/$NAME/local_ver"; sh "/usr/share/$NAME/update.sh" "update_core_non_restart"; }
  51. [ ! -s "/usr/share/$NAME/core/app.js" ] && { echo "Core Not Found, please download it before starting." >> "/tmp/$NAME.log"; exit 1; }
  52. procd_open_instance "$NAME"
  53. procd_set_param command node "/usr/share/$NAME/core/app.js"
  54. append_param "-a" "0.0.0.0"
  55. local http_port https_port hijack_ways
  56. config_get http_port "config" "http_port" "5200"
  57. config_get https_port "config" "https_port" "5201"
  58. config_get hijack_ways "config" "hijack_ways" "use_ipset"
  59. [ "${hijack_ways}" = "use_hosts" ] && { http_port="80"; https_port="443"; }
  60. append_param "-p" "${http_port}":"${https_port}"
  61. if is_enabled "config" "pub_access"; then
  62. if [ -e "$(command -v fw4)" ]; then
  63. uci -q batch <<-EOF
  64. add firewall rule
  65. set firewall.@rule[-1].name='unblockneteasemusic_pub_access'
  66. set firewall.@rule[-1].proto='tcp'
  67. set firewall.@rule[-1].src='wan'
  68. set firewall.@rule[-1].dest_port='${http_port}-${https_port}'
  69. set firewall.@rule[-1].target='ACCEPT'
  70. commit firewall
  71. EOF
  72. fw4 reload
  73. else
  74. iptables -I "INPUT" -p "tcp" --dport "${http_port}" -j "ACCEPT"
  75. iptables -I "INPUT" -p "tcp" --dport "${https_port}" -j "ACCEPT"
  76. echo "${http_port}:${https_port}" > "/tmp/$NAME.ports"
  77. mkdir -p "/var/etc/"
  78. echo "/etc/init.d/$NAME restart" > "/var/etc/$NAME.include"
  79. fi
  80. fi
  81. local music_source
  82. config_get music_source "config" "music_source" "default"
  83. [ "${music_source}" != "default" ] && append_param -o "${music_source}"
  84. append_param_arg "config" "cnrelay" "-c"
  85. append_param_arg "config" "endpoint_url" "-e" "https://music.163.com"
  86. append_param_arg "config" "netease_server_ip" "-f"
  87. append_param_arg "config" "proxy_server_ip" "-u"
  88. is_enabled "config" "strict_mode" && append_param "-s"
  89. procd_set_param env LOG_FILE="/tmp/$NAME.log"
  90. append_param_env "config" "joox_cookie" "JOOX_COOKIE"
  91. append_param_env "config" "migu_cookie" "MIGU_COOKIE"
  92. append_param_env "config" "qq_cookie" "QQ_COOKIE"
  93. append_param_env "config" "youtube_key" "YOUTUBE_KEY"
  94. append_param_env "config" "self_issue_cert_crt" "SIGN_CERT" "/usr/share/$NAME/core/server.crt"
  95. append_param_env "config" "self_issue_cert_key" "SIGN_KEY" "/usr/share/$NAME/core/server.key"
  96. is_enabled "config" "enable_flac" && procd_append_param env ENABLE_FLAC="true"
  97. is_enabled "config" "local_vip" && procd_append_param env ENABLE_LOCAL_VIP="true"
  98. case "$(config_get "config" "replace_music_source")" in
  99. "lower_than_192kbps") procd_append_param env MIN_BR="192000" ;;
  100. "lower_than_320kbps") procd_append_param env MIN_BR="320000" ;;
  101. "lower_than_999kbps") procd_append_param env MIN_BR="600000" ;;
  102. "replace_all") procd_append_param env MIN_BR="9999999" ;;
  103. esac
  104. procd_append_param env JSON_LOG="true"
  105. procd_set_param stdout 1
  106. procd_set_param stderr 1
  107. procd_set_param respawn
  108. local lan_addr="$(uci -q get network.lan.ipaddr)"
  109. if [ "${hijack_ways}" = "use_ipset" ]; then
  110. # TODO: wating for dnsmasq support nftset
  111. mkdir -p "/tmp/dnsmasq.d"
  112. rm -f "/tmp/dnsmasq.d/dnsmasq-$NAME.conf"
  113. cat <<-EOF > "/tmp/dnsmasq.d/dnsmasq-$NAME.conf"
  114. dhcp-option=252,http://${lan_addr}:${http_port}/proxy.pac
  115. ipset=/.music.163.com/neteasemusic
  116. ipset=/interface.music.163.com/neteasemusic
  117. ipset=/interface3.music.163.com/neteasemusic
  118. ipset=/apm.music.163.com/neteasemusic
  119. ipset=/apm3.music.163.com/neteasemusic
  120. ipset=/clientlog.music.163.com/neteasemusic
  121. ipset=/clientlog3.music.163.com/neteasemusic
  122. EOF
  123. /etc/init.d/dnsmasq reload
  124. [ -e "$(command -v fw4)" ] || {
  125. ipset create "acl_neteasemusic_http" hash:ip
  126. ipset create "acl_neteasemusic_https" hash:ip
  127. ipset create "neteasemusic" hash:ip
  128. }
  129. local ip_addr_num="$(uci show "$NAME" | grep -c "filter_mode")"
  130. let ip_addr_num="ip_addr_num-1"
  131. local acl_http_addr acl_https_addr
  132. [ "${ip_addr_num}" -ge "0" ] && for i in $(seq 0 "${ip_addr_num}")
  133. do
  134. ip_addr="$(uci_get_by_name "acl_rule" "ip_addr" "" "$i")"
  135. filter_mode="$(uci_get_by_name "acl_rule" "filter_mode" "" "$i")"
  136. case "${filter_mode}" in
  137. "disable_http")
  138. if [ -e "$(command -v fw4)" ];then
  139. acl_http_addr="${acl_http_addr}${ip_addr}\n"
  140. else
  141. ipset -! add "acl_neteasemusic_http" "${ip_addr}"
  142. fi
  143. ;;
  144. "disable_https")
  145. if [ -e "$(command -v fw4)" ]; then
  146. acl_https_addr="${acl_https_addr}${ip_addr}\n"
  147. else
  148. ipset -! add "acl_neteasemusic_https" "${ip_addr}"
  149. fi
  150. ;;
  151. "disable_all")
  152. if [ -e "$(command -v fw4)" ]; then
  153. acl_http_addr="${acl_http_addr}${ip_addr}\n"
  154. acl_https_addr="${acl_https_addr}${ip_addr}\n"
  155. else
  156. ipset -! add "acl_neteasemusic_http" "${ip_addr}"
  157. ipset -! add "acl_neteasemusic_https" "${ip_addr}"
  158. fi
  159. ;;
  160. esac
  161. done
  162. local netease_music_ips="$(uclient-fetch -qO- "http://httpdns.n.netease.com/httpdns/v2/d?domain=music.163.com,interface.music.163.com,interface3.music.163.com,apm.music.163.com,apm3.music.163.com,clientlog.music.163.com,clientlog3.music.163.com" |jsonfilter -e '@.data.*.ip.*')"
  163. local netease_music_ips2="$(uclient-fetch -qO- "https://music.httpdns.c.163.com/d" --post-data="music.163.com,interface.music.163.com,interface3.music.163.com,apm.music.163.com,apm3.music.163.com,clientlog.music.163.com,clientlog3.music.163.com" |jsonfilter -e '@.dns.*["ips"].*')"
  164. if [ -e "$(command -v fw4)" ]; then
  165. local tmp="/tmp/$NAME"
  166. local neteasemusic_addr="$(echo -e "${netease_music_ips}\n${netease_music_ips2}" |sort -u |awk '{print $1}')"
  167. json_init
  168. json_add_int o_http_port "${http_port}"
  169. json_add_int o_https_port "${https_port}"
  170. json_add_string o_acl_http_addr "$acl_http_addr"
  171. json_add_string o_acl_https_addr "$acl_https_addr"
  172. json_add_string o_neteasemusic_addr "$neteasemusic_addr"
  173. json_dump -i >"$tmp.json"
  174. if ucode -S -i "$RULES_UC" -E "$tmp.json" >"$tmp.nft" \
  175. && ! cmp -s "$tmp.nft" "$RULES_NFT"; then
  176. echo "table inet chk {include \"$tmp.nft\";}" >"$tmp.nft.chk"
  177. if nft -f "$tmp.nft.chk" -c; then
  178. mv -f "$tmp.nft" "$RULES_NFT"
  179. fw4 reload
  180. fi
  181. rm -f "$tmp.nft.chk"
  182. fi
  183. rm -f "$tmp.json" "$tmp.nft"
  184. else
  185. echo -e "${netease_music_ips}\n${netease_music_ips2}" |sort -u |awk '{print "ipset add neteasemusic "$1}' |sh
  186. $IPT_N -N "netease_cloud_music"
  187. for local_addr in "0.0.0.0/8" "10.0.0.0/8" "127.0.0.0/8" "169.254.0.0/16" "172.16.0.0/12" "192.168.0.0/16" "224.0.0.0/4" "240.0.0.0/4"; do
  188. $IPT_N -A "netease_cloud_music" -d "${local_addr}" -j "RETURN"
  189. done
  190. $IPT_N -A "netease_cloud_music" -p "tcp" -m "set" ! --match-set "acl_neteasemusic_http" "src" --dport "80" -j "REDIRECT" --to-ports "${http_port}"
  191. $IPT_N -A "netease_cloud_music" -p "tcp" -m "set" ! --match-set "acl_neteasemusic_https" "src" --dport "443" -j "REDIRECT" --to-ports "${https_port}"
  192. $IPT_N -I "PREROUTING" -p "tcp" -m "set" --match-set "neteasemusic" "dst" -j "netease_cloud_music"
  193. mkdir -p "/var/etc/"
  194. echo "/etc/init.d/$NAME restart" > "/var/etc/$NAME.include"
  195. fi
  196. elif [ "${hijack_ways}" = "use_hosts" ]; then
  197. mkdir -p "/tmp/dnsmasq.d"
  198. rm -f "/tmp/dnsmasq.d/dnsmasq-$NAME.conf"
  199. cat <<-EOF > "/tmp/dnsmasq.d/dnsmasq-$NAME.conf"
  200. dhcp-option=252,http://${lan_addr}:${http_port}/proxy.pac
  201. address=/music.163.com/${lan_addr}
  202. address=/interface.music.163.com/${lan_addr}
  203. address=/interface3.music.163.com/${lan_addr}
  204. address=/apm.music.163.com/${lan_addr}
  205. address=/apm3.music.163.com/${lan_addr}
  206. address=/clientlog.music.163.com/${lan_addr}
  207. address=/clientlog3.music.163.com/${lan_addr}
  208. address=/music.httpdns.c.163.com/0.0.0.0
  209. EOF
  210. /etc/init.d/dnsmasq reload
  211. ip route add "223.252.199.10" dev lo
  212. fi
  213. procd_close_instance
  214. } >"/dev/null" 2>&1
  215. stop_service()
  216. {
  217. config_load "$NAME"
  218. sed -i "/$NAME/d" "/etc/crontabs/root"
  219. /etc/init.d/cron restart
  220. rm -f "${UPGRADE_CONF}"
  221. is_enabled "config" "keep_core_when_upgrade" && {
  222. echo "/usr/share/$NAME/core/" >> "${UPGRADE_CONF}"
  223. echo "/usr/share/$NAME/local_ver" >> "${UPGRADE_CONF}"
  224. }
  225. local self_issue_cert_crt self_issue_cert_key
  226. config_get "self_issue_cert_crt" "config" "self_issue_cert_crt"
  227. config_get "self_issue_cert_key" "config" "self_issue_cert_key"
  228. { [ -f "${self_issue_cert_crt}" ] && [ -f "${self_issue_cert_key}" ]; } && {
  229. echo "${self_issue_cert_crt}" >> "${UPGRADE_CONF}"
  230. echo "${self_issue_cert_key}" >> "${UPGRADE_CONF}"
  231. }
  232. if [ -e "$(command -v fw4)" ]; then
  233. local rule="$(uci show firewall | grep "name='unblockneteasemusic_pub_access'" | awk -F '.' '{ print $2}')"
  234. [ -n "${rule}" ] && {
  235. uci -q batch <<-EOF
  236. delete firewall.${rule}
  237. commit firewall
  238. EOF
  239. }
  240. [ ! -e "$RULES_NFT" ] || rm -f "$RULES_NFT"
  241. fw4 reload
  242. else
  243. [ ! -e "/tmp/$NAME.ports" ] || {
  244. iptables -D "INPUT" -p "tcp" --dport "$(awk -F ':' 'print $1' "/tmp/$NAME.ports")" -j "ACCEPT"
  245. iptables -D "INPUT" -p "tcp" --dport "$(awk -F ':' 'print $2' "/tmp/$NAME.ports")" -j "ACCEPT"
  246. }
  247. rm -f "/tmp/$NAME.ports"
  248. $IPT_N -D "PREROUTING" -p "tcp" -m set --match-set "neteasemusic" "dst" -j "netease_cloud_music"
  249. $IPT_N -F "netease_cloud_music"
  250. $IPT_N -X "netease_cloud_music"
  251. ipset destroy "neteasemusic"
  252. ipset destroy "acl_neteasemusic_http"
  253. ipset destroy "acl_neteasemusic_https"
  254. echo "" > "/var/etc/$NAME.include"
  255. fi
  256. rm -f "/tmp/dnsmasq.d/dnsmasq-$NAME.conf"
  257. /etc/init.d/dnsmasq reload
  258. ip route del "223.252.199.10"
  259. rm -f "/tmp/$NAME.log"
  260. } >"/dev/null" 2>&1
  261. reload_service() {
  262. stop
  263. start
  264. }
  265. service_triggers() {
  266. procd_add_reload_trigger "$NAME"
  267. }