unblockneteasemusic 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. #!/bin/sh /etc/rc.common
  2. # SPDX-License-Identifier: GPL-3.0-only
  3. # Copyright (C) 2021 Tianling Shen <[email protected]>
  4. START=92
  5. STOP=10
  6. NAME="unblockneteasemusic"
  7. UPGRADE_CONF="/lib/upgrade/keep.d/$NAME"
  8. uci_get_by_type() {
  9. local "ret"
  10. ret="$(uci get "$NAME".@"$1"[0]."$2" 2>/dev/null)"
  11. echo "${ret:=$3}"
  12. }
  13. uci_get_by_name() {
  14. local "index"
  15. index=0
  16. if [ -n "$4" ]; then
  17. index="$4"
  18. fi
  19. ret="$(uci get "$NAME".@"$1"["${index}"]."$2" 2>/dev/null)"
  20. echo "${ret:=$3}"
  21. }
  22. lan_addr="$(uci get network.lan.ipaddr)"
  23. enable="$(uci_get_by_type "$NAME" "enable" "0")"
  24. music_source="$(uci_get_by_type "$NAME" "music_source" "default")"
  25. enable_flac="$(uci_get_by_type "$NAME" "enable_flac" "0")"
  26. [ "${enable_flac}" -eq "1" ] && export ENABLE_FLAC="true"
  27. replace_music_source="$(uci_get_by_type "$NAME" "replace_music_source" "dont_replace")"
  28. use_remote_qq_server="$(uci_get_by_type "$NAME" "use_remote_qq_server")"
  29. auto_update="$(uci_get_by_type "$NAME" "auto_update" "1")"
  30. update_time="$(uci_get_by_type "$NAME" "update_time" "3")"
  31. http_port="$(uci_get_by_type "$NAME" "http_port" "5200")"
  32. https_port="$(uci_get_by_type "$NAME" "https_port" "5201")"
  33. endpoint_url="$(uci_get_by_type "$NAME" "endpoint_url" "http://music.163.com")"
  34. hijack_ways="$(uci_get_by_type "$NAME" "hijack_ways" "use_ipset")"
  35. migu_cookie="$(uci_get_by_type "$NAME" "migu_cookie")"
  36. [ -n "${migu_cookie}" ] && export MIGU_COOKIE="${migu_cookie}"
  37. qq_cookie="$(uci_get_by_type "$NAME" "qq_cookie")"
  38. [ -n "${qq_cookie}" ] && export QQ_COOKIE="${qq_cookie}"
  39. youtube_key="$(uci_get_by_type "$NAME" "youtube_key")"
  40. [ -n "${youtube_key}" ] && export YOUTUBE_KEY="${youtube_key}"
  41. keep_core_when_upgrade="$(uci_get_by_type "$NAME" "keep_core_when_upgrade")"
  42. [ "$(uci_get_by_type "$NAME" "pub_access")" = "1" ] && addr="0.0.0.0" || addr="${lan_addr}"
  43. [ "$(uci_get_by_type "$NAME" "strict_mode")" = "1" ] && strict_mode="-s"
  44. netease_server_ip="$(uci_get_by_type "$NAME" "netease_server_ip")"
  45. [ -n "${netease_server_ip}" ] && netease_server_ip="-f ${netease_server_ip}"
  46. proxy_server_ip="$(uci_get_by_type "$NAME" "proxy_server_ip")"
  47. [ -n "${proxy_server_ip}" ] && proxy_server_ip="-u ${proxy_server_ip}"
  48. self_issue_cert_crt="$(uci_get_by_type "$NAME" "self_issue_cert_crt")"
  49. self_issue_cert_key="$(uci_get_by_type "$NAME" "self_issue_cert_key")"
  50. { [ -n "{$self_issue_cert_crt}" ] && [ -n "${self_issue_cert_key}" ]; } && {
  51. export SIGN_CERT="${self_issue_cert_crt}"
  52. export SIGN_KEY="${self_issue_cert_key}"
  53. }
  54. set_ipset()
  55. {
  56. if [ "${set_type}" = "start" ]; then
  57. mkdir -p "/tmp/dnsmasq.d"
  58. rm -f "/tmp/dnsmasq.d/dnsmasq-$NAME.conf"
  59. cat <<-EOF > "/tmp/dnsmasq.d/dnsmasq-$NAME.conf"
  60. dhcp-option=252,http://${lan_addr}:${http_port}/proxy.pac
  61. ipset=/.music.163.com/neteasemusic
  62. ipset=/interface.music.163.com/neteasemusic
  63. ipset=/interface3.music.163.com/neteasemusic
  64. ipset=/apm.music.163.com/neteasemusic
  65. ipset=/apm3.music.163.com/neteasemusic
  66. ipset=/clientlog.music.163.com/neteasemusic
  67. ipset=/clientlog3.music.163.com/neteasemusic
  68. EOF
  69. /etc/init.d/dnsmasq reload > "/dev/null" 2>&1
  70. if ! ipset list "acl_neteasemusic_http" > "/dev/null"; then ipset create "acl_neteasemusic_http" hash:ip; fi
  71. if ! ipset list "acl_neteasemusic_https" > "/dev/null"; then ipset create "acl_neteasemusic_https" hash:ip; fi
  72. ip_addr_num="$(uci show "$NAME" | grep -c "filter_mode")"
  73. let ip_addr_num="ip_addr_num-1"
  74. [ "${ip_addr_num}" -ge "0" ] && for i in $(seq 0 "${ip_addr_num}")
  75. do
  76. ip_addr="$(uci_get_by_name "acl_rule" "ip_addr" "" "$i")"
  77. filter_mode="$(uci_get_by_name "acl_rule" "filter_mode" "" "$i")"
  78. case "${filter_mode}" in
  79. "disable_http")
  80. ipset -! add "acl_neteasemusic_http" "${ip_addr}"
  81. ;;
  82. "disable_https")
  83. ipset -! add "acl_neteasemusic_https" "${ip_addr}"
  84. ;;
  85. "disable_all")
  86. ipset -! add "acl_neteasemusic_http" "${ip_addr}"
  87. ipset -! add "acl_neteasemusic_https" "${ip_addr}"
  88. ;;
  89. esac
  90. done
  91. if ! ipset list "neteasemusic" > "/dev/null"; then ipset create "neteasemusic" hash:ip; fi
  92. uclient-fetch -q -O- "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.*' |sort -u |awk '{print "ipset add neteasemusic "$1}' |sh > "/dev/null" 2>&1
  93. iptables -t "nat" -N "netease_cloud_music"
  94. iptables -t "nat" -A "netease_cloud_music" -d "0.0.0.0/8" -j "RETURN"
  95. iptables -t "nat" -A "netease_cloud_music" -d "10.0.0.0/8" -j "RETURN"
  96. iptables -t "nat" -A "netease_cloud_music" -d "127.0.0.0/8" -j "RETURN"
  97. iptables -t "nat" -A "netease_cloud_music" -d "169.254.0.0/16" -j "RETURN"
  98. iptables -t "nat" -A "netease_cloud_music" -d "172.16.0.0/12" -j "RETURN"
  99. iptables -t "nat" -A "netease_cloud_music" -d "192.168.0.0/16" -j "RETURN"
  100. iptables -t "nat" -A "netease_cloud_music" -d "224.0.0.0/4" -j "RETURN"
  101. iptables -t "nat" -A "netease_cloud_music" -d "240.0.0.0/4" -j "RETURN"
  102. iptables -t "nat" -A "netease_cloud_music" -p "tcp" -m "set" ! --match-set "acl_neteasemusic_http" "src" --dport "80" -j "REDIRECT" --to-ports "${http_port}"
  103. iptables -t "nat" -A "netease_cloud_music" -p "tcp" -m "set" ! --match-set "acl_neteasemusic_https" "src" --dport "443" -j "REDIRECT" --to-ports "${https_port}"
  104. iptables -t "nat" -I "PREROUTING" -p "tcp" -m "set" --match-set "neteasemusic" "dst" -j "netease_cloud_music"
  105. [ -z "$(iptables -t "nat" -L "KOOLPROXY" | grep "UnblockMusic" | sed 's/\/.*//')" ] && iptables -t "nat" -I "KOOLPROXY" -m "set" --match-set "neteasemusic" "dst" -j "RETURN" -m "comment" --comment "KP for UnblockMusic"
  106. mkdir -p "/var/etc/"
  107. echo "/etc/init.d/$NAME restart" > "/var/etc/$NAME.include"
  108. elif [ "${set_type}" = "stop" ]; then
  109. iptables -t "nat" -D "PREROUTING" -p "tcp" -m set --match-set "neteasemusic" "dst" -j "netease_cloud_music"
  110. iptables -t "nat" -D "KOOLPROXY" -m "set" --match-set "neteasemusic" "dst" -j "RETURN" -m "comment" --comment "KP for UnblockMusic"
  111. iptables -t "nat" -F "netease_cloud_music"
  112. iptables -t "nat" -X "netease_cloud_music"
  113. ipset destroy "neteasemusic"
  114. ipset destroy "acl_neteasemusic_http"
  115. ipset destroy "acl_neteasemusic_https"
  116. echo "" > "/var/etc/$NAME.include"
  117. rm -f "/tmp/dnsmasq.d/dnsmasq-$NAME.conf"
  118. /etc/init.d/dnsmasq reload > "/dev/null" 2>&1
  119. fi
  120. }
  121. set_hosts()
  122. {
  123. if [ "${set_type}" = "start" ]; then
  124. mkdir -p "/tmp/dnsmasq.d"
  125. rm -f "/tmp/dnsmasq.d/dnsmasq-$NAME.conf"
  126. cat <<-EOF > "/tmp/dnsmasq.d/dnsmasq-$NAME.conf"
  127. dhcp-option=252,http://${lan_addr}:${http_port}/proxy.pac
  128. address=/music.163.com/${lan_addr}
  129. address=/interface.music.163.com/${lan_addr}
  130. address=/interface3.music.163.com/${lan_addr}
  131. address=/apm.music.163.com/${lan_addr}
  132. address=/apm3.music.163.com/${lan_addr}
  133. address=/clientlog.music.163.com/${lan_addr}
  134. address=/clientlog3.music.163.com/${lan_addr}
  135. address=/music.httpdns.c.163.com/0.0.0.0
  136. EOF
  137. /etc/init.d/dnsmasq reload > "/dev/null" 2>&1
  138. ip route add "223.252.199.10" dev lo
  139. elif [ "${set_type}" = "stop" ]; then
  140. rm -f "/tmp/dnsmasq.d/dnsmasq-$NAME.conf"
  141. /etc/init.d/dnsmasq reload > "/dev/null" 2>&1
  142. ip route del "223.252.199.10"
  143. fi
  144. }
  145. set_ports()
  146. {
  147. if [ "${set_type}" = "start" ]; then
  148. iptables -I "INPUT" -p "tcp" --dport "${http_port}" -j "ACCEPT"
  149. iptables -I "INPUT" -p "tcp" --dport "${https_port}" -j "ACCEPT"
  150. mkdir -p "/var/etc/"
  151. echo "/etc/init.d/$NAME restart" > "/var/etc/$NAME.include"
  152. elif [ "${set_type}" = "stop" ]; then
  153. iptables -D "INPUT" -p "tcp" --dport "${http_port}" -j "ACCEPT"
  154. iptables -D "INPUT" -p "tcp" --dport "${https_port}" -j "ACCEPT"
  155. echo "" > "/var/etc/$NAME.include"
  156. fi
  157. }
  158. start()
  159. {
  160. stop
  161. [ "${enable}" -ne "1" ] && exit 0
  162. sed -i "/$NAME/d" /etc/crontabs/root
  163. [ "${auto_update}" -eq "1" ] && echo "0 ${update_time} * * * /usr/share/$NAME/update.sh update_core" >> "/etc/crontabs/root"
  164. echo "*/5 * * * * /usr/share/$NAME/log_check.sh" >> "/etc/crontabs/root"
  165. /etc/init.d/cron restart > "/dev/null" 2>&1
  166. [ ! -e "/usr/share/$NAME/core/app.js" ] && { rm -f "/usr/share/$NAME/local_ver"; sh "/usr/share/$NAME/update.sh" "update_core_non_restart"; }
  167. [ ! -e "/usr/share/$NAME/core/app.js" ] && { echo "Core Not Found, please download it before starting." >> "/tmp/$NAME.log"; exit 1; }
  168. quality_check_line="$(awk "/target == 0 \|\| item.id == target/{print NR}" "/usr/share/$NAME/core/src/hook.js")"
  169. sed -i "${quality_check_line}d" "/usr/share/$NAME/core/src/hook.js"
  170. if [ "${replace_music_source}" = "dont_replace" ]; then
  171. sed -i -e "${quality_check_line}i \\\t\\tif ((item.code != 200 || item.freeTrialInfo) && (target == 0 || item.id == target)) {" "/usr/share/$NAME/core/src/hook.js"
  172. elif [ "${replace_music_source}" = "lower_than_192kbps" ]; then
  173. sed -i -e "${quality_check_line}i \\\t\\tif ((item.code != 200 || item.freeTrialInfo || item.br < 192000) && (target == 0 || item.id == target)) {" "/usr/share/$NAME/core/src/hook.js"
  174. elif [ "${replace_music_source}" = "lower_than_320kbps" ]; then
  175. sed -i -e "${quality_check_line}i \\\t\\tif ((item.code != 200 || item.freeTrialInfo || item.br < 320000) && (target == 0 || item.id == target)) {" "/usr/share/$NAME/core/src/hook.js"
  176. elif [ "${replace_music_source}" = "lower_than_999kbps" ]; then
  177. sed -i -e "${quality_check_line}i \\\t\\tif ((item.code != 200 || item.freeTrialInfo || item.br < 999000) && (target == 0 || item.id == target)) {" "/usr/share/$NAME/core/src/hook.js"
  178. elif [ "${replace_music_source}" = "replace_all" ]; then
  179. sed -i -e "${quality_check_line}i \\\t\\tif (target == 0 || item.id == target) {" "/usr/share/$NAME/core/src/hook.js"
  180. fi
  181. [ "${hijack_ways}" = "use_hosts" ] && { http_port="80"; https_port="443"; }
  182. [ "${music_source}" = "default" ] && music_source="" || music_source="-o ${music_source}"
  183. node "/usr/share/$NAME/core/app.js" -a "${addr}" -p "${http_port}":"${https_port}" ${music_source} -e "${endpoint_url}" ${netease_server_ip} ${proxy_server_ip} ${strict_mode} >> "/tmp/$NAME.log" 2>&1 &
  184. set_type="start"
  185. if [ "${hijack_ways}" = "use_ipset" ]; then
  186. set_ipset > "/dev/null" 2>&1
  187. elif [ "${hijack_ways}" = "use_hosts" ]; then
  188. set_hosts > "/dev/null" 2>&1
  189. fi
  190. [ "$(uci_get_by_type "$NAME" pub_access)" = "1" ] && set_ports > "/dev/null" 2>&1
  191. }
  192. stop()
  193. {
  194. { ps |grep "$NAME" |grep "app.js" |grep -v "grep" |awk '{print $1}' |xargs kill -9; } > "/dev/null" 2>&1
  195. sed -i "/$NAME/d" "/etc/crontabs/root"
  196. /etc/init.d/cron restart > "/dev/null" 2>&1
  197. [ ! -f "${UPGRADE_CONF}" ] && touch "${UPGRADE_CONF}"
  198. sed -i "/$NAME\/core/d;/$NAME\/local_ver/d" "${UPGRADE_CONF}"
  199. [ "${keep_core_when_upgrade}" -eq "1" ] && { echo "/usr/share/$NAME/core/" >> "${UPGRADE_CONF}"; echo "/usr/share/$NAME/local_ver" >> "${UPGRADE_CONF}"; }
  200. { [ -f "${self_issue_cert_crt}" ] && [ -f "${self_issue_cert_key}" ]; } && {
  201. sed -i "/${self_issue_cert_crt//\//\\/}/d" "${UPGRADE_CONF}"
  202. sed -i "/${self_issue_cert_key//\//\\/}/d" "${UPGRADE_CONF}"
  203. echo "${self_issue_cert_crt}" >> "${UPGRADE_CONF}"
  204. echo "${self_issue_cert_key}" >> "${UPGRADE_CONF}"
  205. }
  206. rm -f "/tmp/$NAME.log"
  207. set_type="stop"
  208. set_ipset > "/dev/null" 2>&1
  209. set_hosts > "/dev/null" 2>&1
  210. set_ports > "/dev/null" 2>&1
  211. }