OSDN Git Service

Merge Official Source
[immortalwrt/luci.git] / applications / luci-app-unblockneteasemusic / root / etc / init.d / unblockneteasemusic
1 #!/bin/sh /etc/rc.common
2 # Created By ImmortalWrt
3 # https://github.com/immortalwrt
4
5 START=92
6 STOP=10
7
8 NAME="unblockneteasemusic"
9 UPGRADE_CONF="/lib/upgrade/keep.d/$NAME"
10
11 uci_get_by_type() {
12         local "ret"
13         ret="$(uci get "$NAME".@"$1"[0]."$2" 2>/dev/null)"
14         echo "${ret:=$3}"
15 }
16
17 uci_get_by_name() {
18         local "index"
19         index=0
20         if [ -n "$4" ]; then
21                 index="$4"
22         fi
23         ret="$(uci get "$NAME".@"$1"["${index}"]."$2" 2>/dev/null)"
24         echo "${ret:=$3}"
25 }
26
27 lan_addr="$(uci get network.lan.ipaddr)"
28
29 enable="$(uci_get_by_type "$NAME" "enable" "0")"
30
31 music_source="$(uci_get_by_type "$NAME" "music_source" "default")"
32
33 enable_flac="$(uci_get_by_type "$NAME" "enable_flac" "0")"
34 [ "${enable_flac}" -eq "1" ] && export ENABLE_FLAC="true"
35 replace_music_source="$(uci_get_by_type "$NAME" "replace_music_source" "dont_replace")"
36
37 use_remote_qq_server="$(uci_get_by_type "$NAME" "use_remote_qq_server")"
38
39 auto_update="$(uci_get_by_type "$NAME" "auto_update" "1")"
40 update_time="$(uci_get_by_type "$NAME" "update_time" "3")"
41
42 http_port="$(uci_get_by_type "$NAME" "http_port" "5200")"
43 https_port="$(uci_get_by_type "$NAME" "https_port" "5201")"
44
45 endpoint_url="$(uci_get_by_type "$NAME" "endpoint_url" "http://music.163.com")"
46 hijack_ways="$(uci_get_by_type "$NAME" "hijack_ways" "use_ipset")"
47
48 migu_cookie="$(uci_get_by_type "$NAME" "migu_cookie")"
49 [ -n "${migu_cookie}" ] && export MIGU_COOKIE="${migu_cookie}"
50 neteasemusic_cookie="$(uci_get_by_type "$NAME" "neteasemusic_cookie")"
51 qq_cookie="$(uci_get_by_type "$NAME" "qq_cookie")"
52 [ -n "${qq_cookie}" ] && export QQ_COOKIE="${qq_cookie}"
53 youtube_key="$(uci_get_by_type "$NAME" "youtube_key")"
54 [ -n "${youtube_key}" ] && export YOUTUBE_KEY="${youtube_key}"
55
56 keep_core_when_upgrade="$(uci_get_by_type "$NAME" "keep_core_when_upgrade")"
57 [ "$(uci_get_by_type "$NAME" "pub_access")" = "1" ] && addr="0.0.0.0" || addr="${lan_addr}"
58 [ "$(uci_get_by_type "$NAME" "strict_mode")" = "1" ] && strict_mode="-s"
59
60 netease_server_ip="$(uci_get_by_type "$NAME" "netease_server_ip")"
61 [ -n "${netease_server_ip}" ] && netease_server_ip="-f ${netease_server_ip}"
62 proxy_server_ip="$(uci_get_by_type "$NAME" "proxy_server_ip")"
63 [ -n "${proxy_server_ip}" ] && proxy_server_ip="-u ${proxy_server_ip}"
64
65 self_issue_cert_crt="$(uci_get_by_type "$NAME" "self_issue_cert_crt")"
66 self_issue_cert_key="$(uci_get_by_type "$NAME" "self_issue_cert_key")"
67
68 set_ipset()
69 {
70         if [ "${set_type}" = "start" ]; then
71                 mkdir -p "/tmp/dnsmasq.d"
72                 rm -f "/tmp/dnsmasq.d/dnsmasq-$NAME.conf"
73                 cat <<-EOF > "/tmp/dnsmasq.d/dnsmasq-$NAME.conf"
74 dhcp-option=252,http://${lan_addr}:${http_port}/proxy.pac
75 ipset=/.music.163.com/neteasemusic
76 ipset=/interface.music.163.com/neteasemusic
77 ipset=/interface3.music.163.com/neteasemusic
78 ipset=/apm.music.163.com/neteasemusic
79 ipset=/apm3.music.163.com/neteasemusic
80 ipset=/clientlog.music.163.com/neteasemusic
81 ipset=/clientlog3.music.163.com/neteasemusic
82                 EOF
83                 /etc/init.d/dnsmasq reload > "/dev/null" 2>&1
84
85                 if ! ipset list "acl_neteasemusic_http" > "/dev/null"; then ipset create "acl_neteasemusic_http" hash:ip; fi
86                 if ! ipset list "acl_neteasemusic_https" > "/dev/null"; then ipset create "acl_neteasemusic_https" hash:ip; fi
87                 ip_addr_num="$(uci show "$NAME" | grep -c "filter_mode")"
88                 let ip_addr_num="ip_addr_num-1"
89                 [ "${ip_addr_num}" -ge "0" ] && for i in $(seq 0 "${ip_addr_num}")
90                 do
91                         ip_addr="$(uci_get_by_name "acl_rule" "ip_addr" "" "$i")"
92                         filter_mode="$(uci_get_by_name "acl_rule" "filter_mode" "" "$i")"
93                         case "${filter_mode}" in
94                         "disable_http")
95                                 ipset -! add "acl_neteasemusic_http" "${ip_addr}"
96                                 ;;
97                         "disable_https")
98                                 ipset -! add "acl_neteasemusic_https" "${ip_addr}"
99                                 ;;
100                         "disable_all")
101                                 ipset -! add "acl_neteasemusic_http" "${ip_addr}"
102                                 ipset -! add "acl_neteasemusic_https" "${ip_addr}"
103                                 ;;
104                         esac
105                 done
106
107                 if ! ipset list "neteasemusic" > "/dev/null"; then ipset create "neteasemusic" hash:ip; fi
108                 curl --retry "5" --retry-delay "3" -s "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" |grep -Eo '[0-9]+?\.[0-9]+?\.[0-9]+?\.[0-9]+?' |sort |uniq |awk '{print "ipset add neteasemusic "$1}' |bash > "/dev/null" 2>&1
109                 iptables -t "nat" -N "netease_cloud_music"
110                 iptables -t "nat" -A "netease_cloud_music" -d "0.0.0.0/8" -j "RETURN"
111                 iptables -t "nat" -A "netease_cloud_music" -d "10.0.0.0/8" -j "RETURN"
112                 iptables -t "nat" -A "netease_cloud_music" -d "127.0.0.0/8" -j "RETURN"
113                 iptables -t "nat" -A "netease_cloud_music" -d "169.254.0.0/16" -j "RETURN"
114                 iptables -t "nat" -A "netease_cloud_music" -d "172.16.0.0/12" -j "RETURN"
115                 iptables -t "nat" -A "netease_cloud_music" -d "192.168.0.0/16" -j "RETURN"
116                 iptables -t "nat" -A "netease_cloud_music" -d "224.0.0.0/4" -j "RETURN"
117                 iptables -t "nat" -A "netease_cloud_music" -d "240.0.0.0/4" -j "RETURN"
118                 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}"
119                 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}"
120                 iptables -t "nat" -I "PREROUTING" -p "tcp" -m "set" --match-set "neteasemusic" "dst" -j "netease_cloud_music"
121                 [ -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"
122
123                 mkdir -p "/var/etc/"
124                 echo "/etc/init.d/$NAME restart" > "/var/etc/$NAME.include"
125         elif [ "${set_type}" = "stop" ]; then
126                 iptables -t "nat" -D "PREROUTING" -p "tcp" -m set --match-set "neteasemusic" "dst" -j "netease_cloud_music"
127                 iptables -t "nat" -D "KOOLPROXY" -m "set" --match-set "neteasemusic" "dst" -j "RETURN" -m "comment" --comment "KP for UnblockMusic"
128                 iptables -t "nat" -F "netease_cloud_music"
129                 iptables -t "nat" -X "netease_cloud_music"
130                 ipset destroy "neteasemusic"
131                 ipset destroy "acl_neteasemusic_http"
132                 ipset destroy "acl_neteasemusic_https"
133
134                 echo "" > "/var/etc/$NAME.include"
135                 rm -f "/tmp/dnsmasq.d/dnsmasq-$NAME.conf"
136                 /etc/init.d/dnsmasq reload > "/dev/null" 2>&1
137         fi
138 }
139
140 set_hosts()
141 {
142         if [ "${set_type}" = "start" ]; then
143                 mkdir -p "/tmp/dnsmasq.d"
144                 rm -f "/tmp/dnsmasq.d/dnsmasq-$NAME.conf"
145                 cat <<-EOF > "/tmp/dnsmasq.d/dnsmasq-$NAME.conf"
146 dhcp-option=252,http://${lan_addr}:${http_port}/proxy.pac
147 address=/music.163.com/${lan_addr}
148 address=/interface.music.163.com/${lan_addr}
149 address=/interface3.music.163.com/${lan_addr}
150 address=/apm.music.163.com/${lan_addr}
151 address=/apm3.music.163.com/${lan_addr}
152 address=/clientlog.music.163.com/${lan_addr}
153 address=/clientlog3.music.163.com/${lan_addr}
154 address=/music.httpdns.c.163.com/0.0.0.0
155                 EOF
156                 /etc/init.d/dnsmasq reload > "/dev/null" 2>&1
157
158                 ip route add "223.252.199.10" dev lo
159         elif [ "${set_type}" = "stop" ]; then
160                 rm -f "/tmp/dnsmasq.d/dnsmasq-$NAME.conf"
161                 /etc/init.d/dnsmasq reload > "/dev/null" 2>&1
162
163                 ip route del "223.252.199.10"
164         fi
165 }
166
167 set_ports()
168 {
169         if [ "${set_type}" = "start" ]; then
170                 iptables -I "INPUT" -p "tcp" --dport "${http_port}" -j "ACCEPT"
171                 iptables -I "INPUT" -p "tcp" --dport "${https_port}" -j "ACCEPT"
172
173                 mkdir -p "/var/etc/"
174                 echo "/etc/init.d/$NAME restart" > "/var/etc/$NAME.include"
175         elif [ "${set_type}" = "stop" ]; then
176                 iptables -D "INPUT" -p "tcp" --dport "${http_port}" -j "ACCEPT"
177                 iptables -D "INPUT" -p "tcp" --dport "${https_port}" -j "ACCEPT"
178
179                 echo "" > "/var/etc/$NAME.include"
180         fi
181 }
182
183 start()
184 {
185         stop
186
187         [ "${enable}" -ne "1" ] && exit 0
188
189         sed -i "/$NAME/d" /etc/crontabs/root
190         [ "${auto_update}" -eq "1" ] && echo "0 ${update_time} * * * /usr/share/$NAME/update.sh update_core" >> "/etc/crontabs/root"
191         echo "*/5 * * * * /usr/share/$NAME/log_check.sh" >> "/etc/crontabs/root"
192         /etc/init.d/cron restart > "/dev/null" 2>&1
193
194         [ ! -e "/usr/share/$NAME/core/app.js" ] && { rm -f "/usr/share/$NAME/local_ver"; bash "/usr/share/$NAME/update.sh" "update_core_non_restart"; }
195         [ ! -e "/usr/share/$NAME/core/app.js" ] && { echo "Core Not Found, please download it before starting." >> "/tmp/$NAME.log"; exit 1; }
196
197         [ -n "${neteasemusic_cookie}" ] && {
198                 ub_cookie_line="$(sed -n -e "/netease.path.includes('song\/enhance')/=" "/usr/share/$NAME/core/src/hook.js")";
199                 [ -n "${ub_cookie_line}" ] && { let ub_cookie_endline="ub_cookie_line+6"; sed -i "${ub_cookie_line},${ub_cookie_endline}d" "/usr/share/$NAME/core/src/hook.js"; }
200                 sed -i "/netease.path == '\/api\/song\/enhance\/download\/url'/i\\\t\\t\\t\\tif (netease.path.includes('song\/enhance')) {" "/usr/share/$NAME/core/src/hook.js"
201                 sed -i "/if (netease.path.includes('song\/enhance')) {/a\\\t\\t\\t\\t\\treq.headers.cookie = [" "/usr/share/$NAME/core/src/hook.js"
202                 sed -i "/req.headers.cookie = \[/a\\\t\\t\\t\\t\\t\\t'MUSIC_U=${neteasemusic_cookie}'," "/usr/share/$NAME/core/src/hook.js"
203                 sed -i "/'MUSIC_U=${neteasemusic_cookie}',/a\\\t\\t\\t\\t\\t\\treq.headers.cookie.replace(\/\\\s*MUSIC_\\\w=[^\\\s;]+;*\/g, '')" "/usr/share/$NAME/core/src/hook.js"
204                 sed -i "/req.headers.cookie.replace(\/\\\s\\*MUSIC_\\\w=[^\\\s;]\\+/a\\\t\\t\\t\\t\\t].filter(line => line).join('; ')" "/usr/share/$NAME/core/src/hook.js"
205                 sed -i "/].filter(line => line).join('; ')/a\\\t\\t\\t\\t}\\n" "/usr/share/$NAME/core/src/hook.js"
206 }
207
208         quality_check_line="$(awk "/target == 0 \|\| item.id == target/{print NR}" "/usr/share/$NAME/core/src/hook.js")"
209         sed -i "${quality_check_line}d" "/usr/share/$NAME/core/src/hook.js"
210         if [ "${replace_music_source}" = "dont_replace" ]; then
211                 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"
212         elif [ "${replace_music_source}" = "lower_than_192kbps" ]; then
213                 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"
214         elif [ "${replace_music_source}" = "lower_than_320kbps" ]; then
215                 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"
216         elif [ "${replace_music_source}" = "lower_than_999kbps" ]; then
217                 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"
218         elif [ "${replace_music_source}" = "replace_all" ]; then
219                 sed -i -e "${quality_check_line}i \\\t\\tif (target == 0 || item.id == target) {" "/usr/share/$NAME/core/src/hook.js"
220         fi
221
222         { [ -f "${self_issue_cert_crt}" ] && [ -f "${self_issue_cert_key}" ]; } && {
223                 { [ "${self_issue_cert_crt}" != "/usr/share/$NAME/core/server.crt" ] && [ "${self_issue_cert_key}" != "/usr/share/$NAME/core/server.key" ]; } && {
224                         ln -sf "${self_issue_cert_crt}" "/usr/share/$NAME/core/server.crt"
225                         ln -sf "${self_issue_cert_key}" "/usr/share/$NAME/core/server.key"
226                 }
227         }
228
229         [ "${hijack_ways}" = "use_hosts" ] && { http_port="80"; https_port="443"; }
230         [ "${music_source}" = "default" ] && music_source="" || music_source="-o ${music_source}"
231         nohup 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 &
232
233         set_type="start"
234         if [ "${hijack_ways}" = "use_ipset" ]; then
235                 set_ipset > "/dev/null" 2>&1
236         elif [ "${hijack_ways}" = "use_hosts" ]; then
237                 set_hosts > "/dev/null" 2>&1
238         fi
239         [ "$(uci_get_by_type "$NAME" pub_access)" = "1" ] && set_ports > "/dev/null" 2>&1
240 }
241
242 stop()
243 {
244         { ps |grep "$NAME" |grep "app.js" |grep -v "grep" |awk '{print $1}' |xargs kill -9; } > "/dev/null" 2>&1
245
246         sed -i "/$NAME/d" "/etc/crontabs/root"
247         /etc/init.d/cron restart > "/dev/null" 2>&1
248
249         [ ! -f "${UPGRADE_CONF}" ] && touch "${UPGRADE_CONF}"
250         sed -i "/$NAME\/core/d;/$NAME\/local_ver/d" "${UPGRADE_CONF}"
251         [ "${keep_core_when_upgrade}" -eq "1" ] && { echo "/usr/share/$NAME/core/" >> "${UPGRADE_CONF}"; echo "/usr/share/$NAME/local_ver" >> "${UPGRADE_CONF}"; }
252
253         { [ -f "${self_issue_cert_crt}" ] && [ -f "${self_issue_cert_key}" ]; } && {
254                 { [ "${self_issue_cert_crt}" != "/usr/share/$NAME/core/server.crt" ] && [ "${self_issue_cert_key}" != "/usr/share/$NAME/core/server.key" ]; } && {
255                         sed -i "/${self_issue_cert_crt//\//\\/}/d" "${UPGRADE_CONF}"
256                         echo "${self_issue_cert_crt}" >> "${UPGRADE_CONF}"
257
258                         sed -i "/${self_issue_cert_key//\//\\/}/d" "${UPGRADE_CONF}"
259                         echo "${self_issue_cert_key}" >> "${UPGRADE_CONF}"
260                 }
261         }
262
263         rm -f "/tmp/$NAME.log"
264
265         set_type="stop"
266         set_ipset > "/dev/null" 2>&1
267         set_hosts > "/dev/null" 2>&1
268         set_ports > "/dev/null" 2>&1
269 }