333 lines
11 KiB
Bash
Executable File
333 lines
11 KiB
Bash
Executable File
#!/bin/sh /etc/rc.common
|
|
# SPDX-License-Identifier: GPL-3.0-only
|
|
#
|
|
# Copyright (C) 2019-2023 Tianling Shen <cnsztl@immortalwrt.org>
|
|
|
|
USE_PROCD=1
|
|
|
|
START=99
|
|
STOP=10
|
|
|
|
NAME="unblockneteasemusic"
|
|
UNM_DIR="/usr/share/$NAME"
|
|
RUN_DIR="/var/run/$NAME"
|
|
|
|
IPT_N="iptables -t nat"
|
|
IPT_INPUT_RULE="unm_input_rule"
|
|
FW4="$(command -v fw4)"
|
|
|
|
# we don't know which is the default server, just take the first one
|
|
DNSMASQ_UCI_CONFIG="$(uci -q show "dhcp.@dnsmasq[0]" | awk 'NR==1 {split($0, conf, /[.=]/); print conf[2]}')"
|
|
if [ -f "/tmp/etc/dnsmasq.conf.$DNSMASQ_UCI_CONFIG" ]; then
|
|
DNSMASQ_DIR="$(awk -F '=' '/^conf-dir=/ {print $2}' "/tmp/etc/dnsmasq.conf.$DNSMASQ_UCI_CONFIG")"
|
|
else
|
|
DNSMASQ_DIR="/tmp/dnsmasq.d"
|
|
fi
|
|
|
|
is_enabled() {
|
|
local enabled
|
|
config_get_bool enabled "$1" "$2" "${3:-0}"
|
|
if [ "$enabled" -eq "1" ]; then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
append_param() {
|
|
procd_append_param command "$1" $2
|
|
}
|
|
|
|
append_param_arg() {
|
|
local value
|
|
config_get value "$1" "$2" "$4"
|
|
[ -n "$value" ] && append_param "$3" "$value"
|
|
}
|
|
|
|
append_param_env() {
|
|
local value
|
|
config_get value "$1" "$2" $4
|
|
[ -n "$value" ] && procd_append_param env "$3"="$value"
|
|
}
|
|
|
|
append_param_boolenv() {
|
|
is_enabled "$1" "$2" "$4" && procd_append_param env "$3"="true"
|
|
}
|
|
|
|
append_filter_client() {
|
|
local cfg="$1"
|
|
|
|
is_enabled "$cfg" "enable" || return 1
|
|
|
|
local mac_addr filter_mode
|
|
config_get mac_addr "$cfg" "mac_addr"
|
|
config_get filter_mode "$cfg" "filter_mode"
|
|
[ -n "$mac_addr" -a -n "$filter_mode" ] || return 1
|
|
|
|
case "${filter_mode}" in
|
|
"disable_http")
|
|
if [ -n "$FW4" ]; then
|
|
acl_http_addr="${acl_http_addr:+$acl_http_addr\n}${mac_addr}"
|
|
else
|
|
ipset -! add "acl_neteasemusic_http" "${mac_addr}"
|
|
fi
|
|
;;
|
|
"disable_https")
|
|
if [ -n "$FW4" ]; then
|
|
acl_https_addr="${acl_https_addr:+$acl_https_addr\n}${mac_addr}"
|
|
else
|
|
ipset -! add "acl_neteasemusic_https" "${mac_addr}"
|
|
fi
|
|
;;
|
|
"disable_all")
|
|
if [ -n "$FW4" ]; then
|
|
acl_http_addr="${acl_http_addr:+$acl_http_addr\n}${mac_addr}"
|
|
acl_https_addr="${acl_https_addr:+$acl_https_addr\n}${mac_addr}"
|
|
else
|
|
ipset -! add "acl_neteasemusic_http" "${mac_addr}"
|
|
ipset -! add "acl_neteasemusic_https" "${mac_addr}"
|
|
fi
|
|
;;
|
|
esac
|
|
}
|
|
|
|
start_service() {
|
|
config_load "$NAME"
|
|
is_enabled "config" "enable" || return 1
|
|
|
|
local update_time
|
|
config_get update_time "config" "update_time" "3"
|
|
sed -i "/$NAME/d" /etc/crontabs/root
|
|
! is_enabled "config" "auto_update" || echo -e "0 ${update_time} * * * $UNM_DIR/update.sh update_core" >> "/etc/crontabs/root"
|
|
/etc/init.d/cron restart
|
|
|
|
mkdir -p "$RUN_DIR"
|
|
[ -s "$UNM_DIR/core/app.js" ] || { rm -f "$UNM_DIR/local_ver"; sh "$UNM_DIR/update.sh" "update_core_non_restart"; }
|
|
[ -s "$UNM_DIR/core/app.js" ] || { echo "Core Not Found, please download it before starting." >> "$RUN_DIR/run.log"; return 1; }
|
|
|
|
procd_open_instance "$NAME"
|
|
procd_set_param command node "$UNM_DIR/core/app.js"
|
|
append_param "-a" "::"
|
|
|
|
local http_port https_port hijack_ways
|
|
config_get http_port "config" "http_port" "5200"
|
|
config_get https_port "config" "https_port" "5201"
|
|
config_get hijack_ways "config" "hijack_ways" "use_ipset"
|
|
[ "$hijack_ways" != "use_hosts" ] || { http_port="80"; https_port="443"; }
|
|
append_param "-p" "${http_port}":"${https_port}"
|
|
|
|
if [ -n "$FW4" ]; then
|
|
json_init
|
|
json_add_int http_port "${http_port}"
|
|
json_add_int https_port "${https_port}"
|
|
json_add_string hijack_ways "${hijack_ways}"
|
|
else
|
|
if is_enabled "config" "pub_access"; then
|
|
iptables -N "$IPT_INPUT_RULE"
|
|
iptables -t filter -I INPUT -j "$IPT_INPUT_RULE"
|
|
iptables -t filter -A "$IPT_INPUT_RULE" -p tcp --dport "${http_port}" -j ACCEPT
|
|
iptables -t filter -A "$IPT_INPUT_RULE" -p tcp --dport "${https_port}" -j ACCEPT
|
|
|
|
echo "/etc/init.d/$NAME restart" > "$RUN_DIR/fw3.include"
|
|
fi
|
|
fi
|
|
|
|
append_param_arg "config" "music_source" "-o" "kugou kuwo migu pyncmd"
|
|
append_param_arg "config" "cnrelay" "-c"
|
|
append_param_arg "config" "endpoint_url" "-e" "https://music.163.com"
|
|
append_param_arg "config" "netease_server_ip" "-f"
|
|
append_param_arg "config" "proxy_server_ip" "-u"
|
|
is_enabled "config" "strict_mode" && append_param "-s"
|
|
|
|
local log_level
|
|
config_get log_level "config" "log_level" "info"
|
|
procd_set_param env LOG_FILE="$RUN_DIR/run.log"
|
|
procd_append_param env LOG_LEVEL="$log_level"
|
|
|
|
append_param_env "config" "joox_cookie" "JOOX_COOKIE"
|
|
append_param_env "config" "migu_cookie" "MIGU_COOKIE"
|
|
append_param_env "config" "qq_cookie" "QQ_COOKIE"
|
|
append_param_env "config" "youtube_key" "YOUTUBE_KEY"
|
|
append_param_env "config" "self_issue_cert_crt" "SIGN_CERT" "$UNM_DIR/core/server.crt"
|
|
append_param_env "config" "self_issue_cert_key" "SIGN_KEY" "$UNM_DIR/core/server.key"
|
|
append_param_env "config" "local_vip" "ENABLE_LOCAL_VIP"
|
|
|
|
append_param_boolenv "config" "follow_source_order" "FOLLOW_SOURCE_ORDER"
|
|
append_param_boolenv "config" "search_album" "SEARCH_ALBUM"
|
|
append_param_boolenv "config" "enable_flac" "ENABLE_FLAC"
|
|
append_param_boolenv "config" "select_max_br" "SELECT_MAX_BR"
|
|
append_param_boolenv "config" "disable_upgrade_check" "DISABLE_UPGRADE_CHECK"
|
|
append_param_boolenv "config" "block_ads" "BLOCK_ADS"
|
|
case "$(config_get "config" "replace_music_source")" in
|
|
"lower_than_192kbps") procd_append_param env MIN_BR="192000" ;;
|
|
"lower_than_320kbps") procd_append_param env MIN_BR="320000" ;;
|
|
"lower_than_999kbps") procd_append_param env MIN_BR="600000" ;;
|
|
"replace_all") procd_append_param env MIN_BR="9999999" ;;
|
|
esac
|
|
|
|
procd_set_param stdout 1
|
|
procd_set_param stderr 1
|
|
procd_set_param respawn
|
|
|
|
local lan_addr="$(uci -q get network.lan.ipaddr)"
|
|
if [ "${hijack_ways}" = "use_ipset" ]; then
|
|
local settype setname
|
|
if [ -n "$FW4" ]; then
|
|
settype="nftset"
|
|
setname="inet#fw4#neteasemusic,6#inet#fw4#neteasemusic6"
|
|
else
|
|
settype="ipset"
|
|
setname="neteasemusic"
|
|
fi
|
|
mkdir -p "$DNSMASQ_DIR"
|
|
rm -f "$DNSMASQ_DIR/dnsmasq-$NAME.conf"
|
|
cat <<-EOF > "$DNSMASQ_DIR/dnsmasq-$NAME.conf"
|
|
dhcp-option=252,http://${lan_addr}:${http_port}/proxy.pac
|
|
${settype}=/.music.163.com/${setname}
|
|
${settype}=/interface.music.163.com/${setname}
|
|
${settype}=/interface3.music.163.com/${setname}
|
|
${settype}=/apm.music.163.com/${setname}
|
|
${settype}=/apm3.music.163.com/${setname}
|
|
${settype}=/clientlog.music.163.com/${setname}
|
|
${settype}=/clientlog3.music.163.com/${setname}
|
|
EOF
|
|
/etc/init.d/dnsmasq restart 2>"/dev/null"
|
|
|
|
if [ -z "$FW4" ]; then
|
|
ipset create "acl_neteasemusic_http" hash:mac
|
|
ipset create "acl_neteasemusic_https" hash:mac
|
|
ipset create "neteasemusic" hash:ip timeout 7200
|
|
fi
|
|
config_foreach append_filter_client "acl_rule"
|
|
|
|
local netease_music_ips="$(wget -T10 -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")"
|
|
if [ -n "$FW4" ]; then
|
|
json_add_string acl_http_addr "$(echo -e "${acl_http_addr}" | sort -u)"
|
|
json_add_string acl_https_addr "$(echo -e "${acl_https_addr}" | sort -u)"
|
|
json_add_string neteasemusic_addr "$(echo -e "${netease_music_ips}" | jsonfilter -e '@.data.*.ip.*' | sort -u)"
|
|
json_add_string neteasemusic_addr6 "$(echo -e "${netease_music_ips}" | jsonfilter -e '@.data.*.ipv6.*' | sort -u)"
|
|
|
|
json_dump > "$RUN_DIR/fw4.info"
|
|
json_cleanup
|
|
utpl -F "$RUN_DIR/fw4.info" -S "$UNM_DIR/nftables.ut" > "$RUN_DIR/fw4.nft"
|
|
|
|
if is_enabled "config" "pub_access"; then
|
|
procd_open_data
|
|
json_add_array firewall
|
|
json_add_object ""
|
|
json_add_string type rule
|
|
json_add_string name "Allow-access-UNM-http-$http_port"
|
|
json_add_string src "*"
|
|
json_add_string dest_port "$http_port"
|
|
json_add_string proto tcp
|
|
json_add_string target ACCEPT
|
|
json_close_object
|
|
|
|
json_add_object ""
|
|
json_add_string type rule
|
|
json_add_string name "Allow-access-UNM-https-$https_port"
|
|
json_add_string src "*"
|
|
json_add_string dest_port "$https_port"
|
|
json_add_string proto tcp
|
|
json_add_string target ACCEPT
|
|
json_close_object
|
|
json_close_array
|
|
procd_close_data
|
|
fi
|
|
else
|
|
echo -e "${netease_music_ips}" | jsonfilter -e '@.data.*.ip.*' | sort -u | awk '{print "ipset add neteasemusic "$1}' | sh
|
|
|
|
$IPT_N -N "netease_cloud_music"
|
|
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
|
|
$IPT_N -A "netease_cloud_music" -d "${local_addr}" -j "RETURN"
|
|
done
|
|
|
|
$IPT_N -A "netease_cloud_music" -p "tcp" -m "set" ! --match-set "acl_neteasemusic_http" "src" --dport "80" -j "REDIRECT" --to-ports "${http_port}"
|
|
$IPT_N -A "netease_cloud_music" -p "tcp" -m "set" ! --match-set "acl_neteasemusic_https" "src" --dport "443" -j "REDIRECT" --to-ports "${https_port}"
|
|
$IPT_N -I "PREROUTING" -p "tcp" -m "set" --match-set "neteasemusic" "dst" -j "netease_cloud_music"
|
|
|
|
echo "/etc/init.d/$NAME restart" > "$RUN_DIR/fw3.include"
|
|
fi
|
|
elif [ "${hijack_ways}" = "use_hosts" ]; then
|
|
mkdir -p "$DNSMASQ_DIR"
|
|
rm -f "$DNSMASQ_DIR/dnsmasq-$NAME.conf"
|
|
cat <<-EOF > "$DNSMASQ_DIR/dnsmasq-$NAME.conf"
|
|
dhcp-option=252,http://${lan_addr}:${http_port}/proxy.pac
|
|
address=/music.163.com/${lan_addr}
|
|
address=/interface.music.163.com/${lan_addr}
|
|
address=/interface3.music.163.com/${lan_addr}
|
|
address=/apm.music.163.com/${lan_addr}
|
|
address=/apm3.music.163.com/${lan_addr}
|
|
address=/clientlog.music.163.com/${lan_addr}
|
|
address=/clientlog3.music.163.com/${lan_addr}
|
|
address=/music.httpdns.c.163.com/0.0.0.0
|
|
EOF
|
|
/etc/init.d/dnsmasq restart 2>"/dev/null"
|
|
fi
|
|
|
|
procd_close_instance
|
|
|
|
procd_open_instance "log-check"
|
|
procd_set_param command "$UNM_DIR/log_check.sh"
|
|
procd_set_param respawn
|
|
procd_close_instance
|
|
}
|
|
|
|
service_started() {
|
|
[ -z "$FW4" ] || procd_set_config_changed firewall
|
|
}
|
|
|
|
stop_service() {
|
|
config_load "$NAME"
|
|
|
|
sed -i "/$NAME/d" "/etc/crontabs/root"
|
|
/etc/init.d/cron restart
|
|
|
|
local chain settable
|
|
if [ -n "$FW4" ]; then
|
|
for chain in "netease_cloud_music_redir" "netease_cloud_music"; do
|
|
nft flush chain inet fw4 "$chain" 2>"/dev/null"
|
|
nft delete chain inet fw4 "$chain" 2>"/dev/null"
|
|
done
|
|
for settable in "acl_neteasemusic_http" "acl_neteasemusic_https" "neteasemusic" "neteasemusic6"; do
|
|
nft flush set inet fw4 "$settable" 2>"/dev/null"
|
|
nft delete set inet fw4 "$settable" 2>"/dev/null"
|
|
done
|
|
|
|
rm -f "$RUN_DIR/fw4.info"
|
|
echo > "$RUN_DIR/fw4.nft"
|
|
else
|
|
iptables -t filter -D INPUT -j "$IPT_INPUT_RULE" 2>"/dev/null"
|
|
iptables -F "$IPT_INPUT_RULE" 2>"/dev/null"
|
|
iptables -X "$IPT_INPUT_RULE" 2>"/dev/null"
|
|
|
|
$IPT_N -D "PREROUTING" -p "tcp" -m set --match-set "neteasemusic" "dst" -j "netease_cloud_music" 2>"/dev/null"
|
|
$IPT_N -F "netease_cloud_music" 2>"/dev/null"
|
|
$IPT_N -X "netease_cloud_music" 2>"/dev/null"
|
|
|
|
for settable in "acl_neteasemusic_http" "acl_neteasemusic_https" "neteasemusic"; do
|
|
ipset destroy "$settable" 2>"/dev/null"
|
|
done
|
|
|
|
echo > "$RUN_DIR/fw3.include"
|
|
fi
|
|
|
|
rm -f "$DNSMASQ_DIR/dnsmasq-$NAME.conf"
|
|
/etc/init.d/dnsmasq restart 2>"/dev/null"
|
|
|
|
rm -f "$RUN_DIR/run.log"
|
|
}
|
|
|
|
service_stopped() {
|
|
[ -z "$FW4" ] || procd_set_config_changed firewall
|
|
}
|
|
|
|
reload_service() {
|
|
stop
|
|
start
|
|
}
|
|
|
|
service_triggers() {
|
|
procd_add_reload_trigger "$NAME"
|
|
}
|