mirror of
https://github.com/mack-a/v2ray-agent.git
synced 2026-09-02 22:06:36 +00:00
feat(脚本): 完善黑名单机制
This commit is contained in:
+338
-40
@@ -3309,6 +3309,7 @@ addSingBoxRouteRule() {
|
|||||||
domainList="${domainList},$(jq -rc .route.rules[0].rule_set[] "${singBoxConfigPath}${routingName}.json" | awk -F "[_]" '{print $1}' | paste -sd ',')"
|
domainList="${domainList},$(jq -rc .route.rules[0].rule_set[] "${singBoxConfigPath}${routingName}.json" | awk -F "[_]" '{print $1}' | paste -sd ',')"
|
||||||
domainList="${domainList},$(jq -rc .route.rules[0].domain_regex[] "${singBoxConfigPath}${routingName}.json" | awk -F "[*]" '{print $2}' | paste -sd ',' | sed 's/\\//g')"
|
domainList="${domainList},$(jq -rc .route.rules[0].domain_regex[] "${singBoxConfigPath}${routingName}.json" | awk -F "[*]" '{print $2}' | paste -sd ',' | sed 's/\\//g')"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
fi
|
fi
|
||||||
local rules=
|
local rules=
|
||||||
rules=$(initSingBoxRules "${domainList}" "${routingName}")
|
rules=$(initSingBoxRules "${domainList}" "${routingName}")
|
||||||
@@ -3326,7 +3327,6 @@ addSingBoxRouteRule() {
|
|||||||
ruleSetTag=$(echo "${ruleSet}" | jq '.|map(.tag)')
|
ruleSetTag=$(echo "${ruleSet}" | jq '.|map(.tag)')
|
||||||
fi
|
fi
|
||||||
if [[ -n "${singBoxConfigPath}" ]]; then
|
if [[ -n "${singBoxConfigPath}" ]]; then
|
||||||
|
|
||||||
cat <<EOF >"${singBoxConfigPath}${routingName}.json"
|
cat <<EOF >"${singBoxConfigPath}${routingName}.json"
|
||||||
{
|
{
|
||||||
"route": {
|
"route": {
|
||||||
@@ -6637,8 +6637,10 @@ blacklist() {
|
|||||||
echoContent red "\n=============================================================="
|
echoContent red "\n=============================================================="
|
||||||
echoContent yellow "1.查看已屏蔽域名"
|
echoContent yellow "1.查看已屏蔽域名"
|
||||||
echoContent yellow "2.添加域名"
|
echoContent yellow "2.添加域名"
|
||||||
echoContent yellow "3.屏蔽大陆域名"
|
echoContent yellow "3.屏蔽大陆域名+IP"
|
||||||
echoContent yellow "4.卸载黑名单"
|
echoContent yellow "4.卸载黑/白名单"
|
||||||
|
echoContent yellow "5.添加IP"
|
||||||
|
echoContent yellow "6.添加域名白名单"
|
||||||
echoContent red "=============================================================="
|
echoContent red "=============================================================="
|
||||||
|
|
||||||
read -r -p "请选择:" blacklistStatus
|
read -r -p "请选择:" blacklistStatus
|
||||||
@@ -6667,54 +6669,231 @@ blacklist() {
|
|||||||
echoContent green " ---> 添加完毕"
|
echoContent green " ---> 添加完毕"
|
||||||
|
|
||||||
elif [[ "${blacklistStatus}" == "3" ]]; then
|
elif [[ "${blacklistStatus}" == "3" ]]; then
|
||||||
|
local allowDomainList="dl.google.com,apple.com,bing.com,microsoft.com,gstatic,xn--ngstr-lra8j.com,googleapis.com,googleapis.cn"
|
||||||
|
|
||||||
if [[ "${coreInstallType}" == "1" ]]; then
|
if [[ "${coreInstallType}" == "1" ]]; then
|
||||||
unInstallRouting blackhole_out outboundTag
|
unInstallRouting blackhole_out outboundTag
|
||||||
|
unInstallRouting blackhole_ip_out outboundTag
|
||||||
|
|
||||||
addXrayRouting blackhole_out outboundTag "cn"
|
addXrayRouting blackhole_out outboundTag "cn"
|
||||||
|
addXrayIPRouting blackhole_ip_out outboundTag "cn"
|
||||||
|
addXrayRouting allow_domain_direct_outbound outboundTag "${allowDomainList}" "top"
|
||||||
|
|
||||||
addXrayOutbound blackhole_out
|
addXrayOutbound blackhole_out
|
||||||
|
addXrayOutbound blackhole_ip_out
|
||||||
|
addXrayOutbound allow_domain_direct_outbound
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -n "${singBoxConfigPath}" ]]; then
|
if [[ -n "${singBoxConfigPath}" ]]; then
|
||||||
|
|
||||||
addSingBoxRouteRule "cn_block_outbound" "cn" "cn_block_route"
|
addSingBoxRouteRule "cn_block_outbound" "cn" "cn_block_route"
|
||||||
|
addSingBoxGeoIPRouteRule "block_ip_outbound" "cn" "cn_block_ip_route"
|
||||||
addSingBoxRouteRule "01_direct_outbound" "googleapis.com,googleapis.cn,xn--ngstr-lra8j.com,gstatic.com" "cn_01_google_play_route"
|
addSingBoxRouteRule "01_direct_outbound" "${allowDomainList}" "00_allow_domain_route"
|
||||||
|
|
||||||
addSingBoxOutbound "cn_block_outbound"
|
addSingBoxOutbound "cn_block_outbound"
|
||||||
|
addSingBoxOutbound "block_ip_outbound"
|
||||||
addSingBoxOutbound "01_direct_outbound"
|
addSingBoxOutbound "01_direct_outbound"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echoContent green " ---> 屏蔽大陆域名完毕"
|
echoContent green " ---> 屏蔽大陆域名+IP完毕"
|
||||||
|
|
||||||
elif [[ "${blacklistStatus}" == "4" ]]; then
|
elif [[ "${blacklistStatus}" == "4" ]]; then
|
||||||
if [[ "${coreInstallType}" == "1" ]]; then
|
if [[ "${coreInstallType}" == "1" ]]; then
|
||||||
unInstallRouting blackhole_out outboundTag
|
unInstallRouting blackhole_out outboundTag
|
||||||
|
unInstallRouting blackhole_ip_out outboundTag
|
||||||
|
unInstallRouting allow_domain_direct_outbound outboundTag
|
||||||
|
|
||||||
|
removeXrayOutbound blackhole_ip_out
|
||||||
|
removeXrayOutbound allow_domain_direct_outbound
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -n "${singBoxConfigPath}" ]]; then
|
if [[ -n "${singBoxConfigPath}" ]]; then
|
||||||
removeSingBoxConfig "cn_block_route"
|
removeSingBoxConfig "cn_block_route"
|
||||||
removeSingBoxConfig "cn_block_outbound"
|
removeSingBoxConfig "cn_block_outbound"
|
||||||
|
removeSingBoxConfig "cn_block_ip_route"
|
||||||
|
removeSingBoxConfig "block_ip_route"
|
||||||
|
removeSingBoxConfig "block_ip_outbound"
|
||||||
|
|
||||||
removeSingBoxConfig "cn_01_google_play_route"
|
removeSingBoxConfig "cn_01_google_play_route"
|
||||||
|
removeSingBoxConfig "00_allow_domain_route"
|
||||||
|
|
||||||
removeSingBoxConfig "block_domain_route"
|
removeSingBoxConfig "block_domain_route"
|
||||||
removeSingBoxConfig "block_domain_outbound"
|
removeSingBoxConfig "block_domain_outbound"
|
||||||
fi
|
fi
|
||||||
echoContent green " ---> 域名黑名单删除完毕"
|
echoContent green " ---> 域名黑名单/白名单删除完毕"
|
||||||
|
elif [[ "${blacklistStatus}" == "5" ]]; then
|
||||||
|
echoContent red "=============================================================="
|
||||||
|
echoContent yellow "录入示例:1.1.1.1,8.8.8.8,1.1.1.0/24,2400:3200::/32\n"
|
||||||
|
read -r -p "请按照上面示例录入IP:" ipList
|
||||||
|
if [[ -z "${ipList}" ]]; then
|
||||||
|
echoContent red " ---> IP不可为空"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${coreInstallType}" == "1" ]]; then
|
||||||
|
addXrayIPRouting blackhole_ip_out outboundTag "${ipList}"
|
||||||
|
addXrayOutbound blackhole_ip_out
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "${singBoxConfigPath}" ]]; then
|
||||||
|
addSingBoxIPRouteRule "block_ip_outbound" "${ipList}" "block_ip_route"
|
||||||
|
addSingBoxOutbound "block_ip_outbound"
|
||||||
|
fi
|
||||||
|
echoContent green " ---> 添加IP完毕"
|
||||||
|
elif [[ "${blacklistStatus}" == "6" ]]; then
|
||||||
|
echoContent red "=============================================================="
|
||||||
|
echoContent yellow "录入示例:speedtest,openai,google.com\n"
|
||||||
|
read -r -p "请按照上面示例录入域名:" allowDomainList
|
||||||
|
if [[ -z "${allowDomainList}" ]]; then
|
||||||
|
echoContent red " ---> 域名不可为空"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${coreInstallType}" == "1" ]]; then
|
||||||
|
addXrayRouting allow_domain_direct_outbound outboundTag "${allowDomainList}" "top"
|
||||||
|
addXrayOutbound allow_domain_direct_outbound
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "${singBoxConfigPath}" ]]; then
|
||||||
|
addSingBoxRouteRule "01_direct_outbound" "${allowDomainList}" "00_allow_domain_route"
|
||||||
|
addSingBoxOutbound "01_direct_outbound"
|
||||||
|
fi
|
||||||
|
echoContent green " ---> 添加域名白名单完毕"
|
||||||
else
|
else
|
||||||
echoContent red " ---> 选择错误"
|
echoContent red " ---> 选择错误"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
reloadCore
|
reloadCore
|
||||||
}
|
}
|
||||||
|
# 下载 dlc.dat_plain.yml 到核心目录
|
||||||
|
downloadDLCPlainYAML() {
|
||||||
|
local corePath=$1
|
||||||
|
local dlcFilePath="${corePath}/dlc.dat_plain.yml"
|
||||||
|
local tmpFilePath="${dlcFilePath}.tmp"
|
||||||
|
|
||||||
|
if [[ -z "${corePath}" ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "${corePath}" >/dev/null 2>&1
|
||||||
|
if [[ -s "${dlcFilePath}" ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
local dlcDownloadURL="https://github.com/v2fly/domain-list-community/releases/latest/download/dlc.dat_plain.yml"
|
||||||
|
if [[ "${release}" == "alpine" ]]; then
|
||||||
|
wget -c -O "${tmpFilePath}" "${dlcDownloadURL}" >/dev/null 2>&1
|
||||||
|
else
|
||||||
|
wget -c "${wgetShowProgressStatus}" -O "${tmpFilePath}" "${dlcDownloadURL}" >/dev/null 2>&1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# shellcheck disable=SC2181
|
||||||
|
if [[ "$?" -ne 0 || ! -s "${tmpFilePath}" ]]; then
|
||||||
|
rm -f "${tmpFilePath}" >/dev/null 2>&1
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mv "${tmpFilePath}" "${dlcFilePath}" >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
# 转义grep/regex匹配字符
|
||||||
|
escapeDLCRegexPattern() {
|
||||||
|
# shellcheck disable=SC2016
|
||||||
|
# shellcheck disable=SC2001
|
||||||
|
echo "$1" | sed -e 's/[.[\*^$()+?{|]/\\&/g'
|
||||||
|
}
|
||||||
|
|
||||||
|
# 根据规则行号向上回溯对应name
|
||||||
|
getDLCNameByRuleLine() {
|
||||||
|
local ruleLine=$1
|
||||||
|
local dlcFilePath=$2
|
||||||
|
awk -v targetLine="${ruleLine}" '
|
||||||
|
/^[[:space:]]*-[[:space:]]*name:[[:space:]]*/ {
|
||||||
|
line = $0
|
||||||
|
sub(/^[[:space:]]*-[[:space:]]*name:[[:space:]]*/, "", line)
|
||||||
|
currentName = line
|
||||||
|
}
|
||||||
|
NR == targetLine {
|
||||||
|
print currentName
|
||||||
|
exit
|
||||||
|
}' "${dlcFilePath}"
|
||||||
|
}
|
||||||
|
|
||||||
|
isDomainFormat() {
|
||||||
|
local target=$1
|
||||||
|
[[ "${target}" =~ ^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z0-9-]{2,63}$ ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
# 根据输入域名匹配 dlc.dat_plain.yml 对应 geosite name
|
||||||
|
getDLCGeositeName() {
|
||||||
|
local inputRule=$1
|
||||||
|
local corePath=$2
|
||||||
|
local dlcFilePath="${corePath}/dlc.dat_plain.yml"
|
||||||
|
|
||||||
|
if [[ -z "${inputRule}" || -z "${corePath}" ]]; then
|
||||||
|
echo ""
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
local normalizedInput
|
||||||
|
normalizedInput=$(echo "${inputRule}" | tr '[:upper:]' '[:lower:]' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
||||||
|
normalizedInput=${normalizedInput#domain:}
|
||||||
|
normalizedInput=${normalizedInput#full:}
|
||||||
|
normalizedInput=${normalizedInput#keyword:}
|
||||||
|
|
||||||
|
if [[ -z "${normalizedInput}" ]]; then
|
||||||
|
echo ""
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if isDomainFormat "${normalizedInput}"; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! downloadDLCPlainYAML "${corePath}"; then
|
||||||
|
echo ""
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
local escapedInput=
|
||||||
|
escapedInput=$(escapeDLCRegexPattern "${normalizedInput}")
|
||||||
|
|
||||||
|
local matchedLine=
|
||||||
|
matchedLine=$(grep -n -m1 -E "^[[:space:]]*-[[:space:]]*name:[[:space:]]*${escapedInput}[[:space:]]*$" "${dlcFilePath}")
|
||||||
|
if [[ -n "${matchedLine}" ]]; then
|
||||||
|
echo "${normalizedInput}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# 获取规则匹配结果,优先geosite,失败回退domain
|
||||||
|
getDLCMatchedRuleValue() {
|
||||||
|
local inputRule=$1
|
||||||
|
local corePath=$2
|
||||||
|
local normalizedInput=
|
||||||
|
normalizedInput=$(echo "${inputRule}" | tr '[:upper:]' '[:lower:]' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
||||||
|
|
||||||
|
if isDomainFormat "${normalizedInput}"; then
|
||||||
|
local escapedDomain=
|
||||||
|
escapedDomain=$(escapeDLCRegexPattern "${normalizedInput}")
|
||||||
|
echo "regexp:.*${escapedDomain}.*"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
local matchedRuleName=
|
||||||
|
matchedRuleName=$(getDLCGeositeName "${normalizedInput}" "${corePath}")
|
||||||
|
if [[ -n "${matchedRuleName}" ]]; then
|
||||||
|
echo "geosite:${matchedRuleName}"
|
||||||
|
else
|
||||||
|
echo "domain:${normalizedInput}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# 添加routing配置
|
# 添加routing配置
|
||||||
addXrayRouting() {
|
addXrayRouting() {
|
||||||
|
|
||||||
local tag=$1 # warp-socks
|
local tag=$1 # warp-socks
|
||||||
local type=$2 # outboundTag/inboundTag
|
local type=$2 # outboundTag/inboundTag
|
||||||
local domain=$3 # 域名
|
local domain=$3 # 域名
|
||||||
|
local rulePosition=$4
|
||||||
|
|
||||||
if [[ -z "${tag}" || -z "${type}" || -z "${domain}" ]]; then
|
if [[ -z "${tag}" || -z "${type}" || -z "${domain}" ]]; then
|
||||||
echoContent red " ---> 参数错误"
|
echoContent red " ---> 参数错误"
|
||||||
@@ -6750,27 +6929,146 @@ EOF
|
|||||||
if echo "${routingRule}" | grep -q "${line}"; then
|
if echo "${routingRule}" | grep -q "${line}"; then
|
||||||
echoContent yellow " ---> ${line}已存在,跳过"
|
echoContent yellow " ---> ${line}已存在,跳过"
|
||||||
else
|
else
|
||||||
local geositeStatus
|
local matchedRuleValue
|
||||||
geositeStatus=$(curl -s "https://api.github.com/repos/v2fly/domain-list-community/contents/data/${line}" | jq .message)
|
matchedRuleValue=$(getDLCMatchedRuleValue "${line}" "/etc/v2ray-agent/xray")
|
||||||
|
routingRule=$(echo "${routingRule}" | jq -r --arg rule "${matchedRuleValue}" '.domain += [$rule]')
|
||||||
if [[ "${geositeStatus}" == "null" ]]; then
|
|
||||||
routingRule=$(echo "${routingRule}" | jq -r '.domain += ["geosite:'"${line}"'"]')
|
|
||||||
else
|
|
||||||
routingRule=$(echo "${routingRule}" | jq -r '.domain += ["domain:'"${line}"'"]')
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
done < <(echo "${domain}" | tr ',' '\n')
|
done < <(echo "${domain}" | tr ',' '\n')
|
||||||
|
|
||||||
unInstallRouting "${tag}" "${type}"
|
unInstallRouting "${tag}" "${type}"
|
||||||
if ! grep -q "gstatic.com" ${configPath}09_routing.json && [[ "${tag}" == "blackhole_out" ]]; then
|
if ! grep -q "gstatic.com" ${configPath}09_routing.json && [[ "${tag}" == "blackhole_out" ]]; then
|
||||||
local routing=
|
local routing=
|
||||||
routing=$(jq -r ".routing.rules += [{\"type\": \"field\",\"domain\": [\"gstatic.com\"],\"outboundTag\": \"direct\"}]" ${configPath}09_routing.json)
|
routing=$(jq -r ".routing.rules += [{\"type\": \"field\",\"domain\": [\"domain:gstatic.com\"],\"outboundTag\": \"allow_domain_direct_outbound\"}]" ${configPath}09_routing.json)
|
||||||
echo "${routing}" | jq . >${configPath}09_routing.json
|
echo "${routing}" | jq . >${configPath}09_routing.json
|
||||||
|
addXrayOutbound allow_domain_direct_outbound
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ "${rulePosition}" == "top" ]]; then
|
||||||
|
routing=$(jq -r ".routing.rules = [${routingRule}] + .routing.rules" ${configPath}09_routing.json)
|
||||||
|
else
|
||||||
|
routing=$(jq -r ".routing.rules += [${routingRule}]" ${configPath}09_routing.json)
|
||||||
|
fi
|
||||||
|
echo "${routing}" | jq . >${configPath}09_routing.json
|
||||||
|
}
|
||||||
|
|
||||||
|
# 添加 Xray IP 屏蔽路由规则
|
||||||
|
# 支持 geoip:cn 与自定义 IPv4/IPv6/CIDR
|
||||||
|
addXrayIPRouting() {
|
||||||
|
|
||||||
|
local tag=$1
|
||||||
|
local type=$2
|
||||||
|
local ipList=$3
|
||||||
|
|
||||||
|
if [[ -z "${tag}" || -z "${type}" || -z "${ipList}" ]]; then
|
||||||
|
echoContent red " ---> 参数错误"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f "${configPath}09_routing.json" ]]; then
|
||||||
|
cat <<EOF >${configPath}09_routing.json
|
||||||
|
{
|
||||||
|
"routing":{
|
||||||
|
"type": "field",
|
||||||
|
"rules": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
local routingRule=
|
||||||
|
routingRule=$(jq -r ".routing.rules[]|select(.outboundTag==\"${tag}\" and (.protocol == null) and (.ip != null))" ${configPath}09_routing.json)
|
||||||
|
if [[ -z "${routingRule}" ]]; then
|
||||||
|
routingRule="{\"type\": \"field\",\"ip\": [],\"outboundTag\": \"${tag}\"}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
while read -r line; do
|
||||||
|
line=$(echo "${line}" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
||||||
|
if [[ -z "${line}" ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
local ipRuleValue=${line}
|
||||||
|
if [[ "${line}" == "cn" ]]; then
|
||||||
|
ipRuleValue="geoip:cn"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if echo "${routingRule}" | grep -q "${ipRuleValue}"; then
|
||||||
|
echoContent yellow " ---> ${ipRuleValue}已存在,跳过"
|
||||||
|
else
|
||||||
|
routingRule=$(echo "${routingRule}" | jq -r '.ip += ["'"${ipRuleValue}"'"]')
|
||||||
|
fi
|
||||||
|
done < <(echo "${ipList}" | tr ',' '\n')
|
||||||
|
|
||||||
|
unInstallRouting "${tag}" "${type}"
|
||||||
|
local routing=
|
||||||
routing=$(jq -r ".routing.rules += [${routingRule}]" ${configPath}09_routing.json)
|
routing=$(jq -r ".routing.rules += [${routingRule}]" ${configPath}09_routing.json)
|
||||||
echo "${routing}" | jq . >${configPath}09_routing.json
|
echo "${routing}" | jq . >${configPath}09_routing.json
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# 添加 sing-box IP 屏蔽路由规则
|
||||||
|
# 支持增量合并历史 ip_cidr
|
||||||
|
addSingBoxIPRouteRule() {
|
||||||
|
local outboundTag=$1
|
||||||
|
local ipList=$2
|
||||||
|
local routingName=$3
|
||||||
|
|
||||||
|
local historyIPs=
|
||||||
|
if [[ -f "${singBoxConfigPath}${routingName}.json" ]]; then
|
||||||
|
historyIPs=$(jq -r '.route.rules[0].ip_cidr[]?' "${singBoxConfigPath}${routingName}.json" | paste -sd ',')
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "${historyIPs}" ]]; then
|
||||||
|
ipList="${ipList},${historyIPs}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
local ipCIDR=[]
|
||||||
|
ipCIDR=$(echo "${ipList}" | tr ',' '\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | grep -v '^$' | sort -n | uniq | jq -R . | jq -s .)
|
||||||
|
|
||||||
|
cat <<EOF >"${singBoxConfigPath}${routingName}.json"
|
||||||
|
{
|
||||||
|
"route": {
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"ip_cidr": ${ipCIDR},
|
||||||
|
"outbound": "${outboundTag}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
# 添加 sing-box GeoIP 远程规则
|
||||||
|
# 用于大陆 IP 自动屏蔽场景
|
||||||
|
addSingBoxGeoIPRouteRule() {
|
||||||
|
local outboundTag=$1
|
||||||
|
local geoipCode=$2
|
||||||
|
local routingName=$3
|
||||||
|
|
||||||
|
cat <<EOF >"${singBoxConfigPath}${routingName}.json"
|
||||||
|
{
|
||||||
|
"route": {
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"rule_set": [
|
||||||
|
"geoip_${geoipCode}_${routingName}"
|
||||||
|
],
|
||||||
|
"outbound": "${outboundTag}"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"rule_set": [
|
||||||
|
{
|
||||||
|
"tag": "geoip_${geoipCode}_${routingName}",
|
||||||
|
"type": "remote",
|
||||||
|
"format": "binary",
|
||||||
|
"url": "https://raw.githubusercontent.com/SagerNet/sing-geoip/rule-set/geoip-${geoipCode}.srs",
|
||||||
|
"download_detour": "01_direct_outbound"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
}
|
||||||
# 根据tag卸载Routing
|
# 根据tag卸载Routing
|
||||||
unInstallRouting() {
|
unInstallRouting() {
|
||||||
local tag=$1
|
local tag=$1
|
||||||
@@ -7446,13 +7744,21 @@ initSingBoxRules() {
|
|||||||
local domainRules=[]
|
local domainRules=[]
|
||||||
local ruleSet=[]
|
local ruleSet=[]
|
||||||
while read -r line; do
|
while read -r line; do
|
||||||
local geositeStatus
|
local normalizedLine=
|
||||||
geositeStatus=$(curl -s "https://api.github.com/repos/SagerNet/sing-geosite/contents/geosite-${line}.srs?ref=rule-set" | jq .message)
|
normalizedLine=$(echo "${line}" | tr '[:upper:]' '[:lower:]' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
||||||
|
if isDomainFormat "${normalizedLine}"; then
|
||||||
if [[ "${geositeStatus}" == "null" ]]; then
|
local escapedDomain=
|
||||||
ruleSet=$(echo "${ruleSet}" | jq -r ". += [{\"tag\":\"${line}_$2\",\"type\":\"remote\",\"format\":\"binary\",\"url\":\"https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-${line}.srs\",\"download_detour\":\"01_direct_outbound\"}]")
|
escapedDomain=${normalizedLine//./\\.}
|
||||||
|
domainRules=$(echo "${domainRules}" | jq -r --arg reg ".*${escapedDomain}.*" '. += [$reg]')
|
||||||
else
|
else
|
||||||
domainRules=$(echo "${domainRules}" | jq -r ". += [\"^([a-zA-Z0-9_-]+\\\.)*${line//./\\\\.}\"]")
|
local matchedRuleName
|
||||||
|
matchedRuleName=$(getDLCGeositeName "${normalizedLine}" "/etc/v2ray-agent/sing-box")
|
||||||
|
|
||||||
|
if [[ -n "${matchedRuleName}" ]]; then
|
||||||
|
ruleSet=$(echo "${ruleSet}" | jq -r ". += [{\"tag\":\"${matchedRuleName}_$2\",\"type\":\"remote\",\"format\":\"binary\",\"url\":\"https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-${matchedRuleName}.srs\",\"download_detour\":\"01_direct_outbound\"}]")
|
||||||
|
else
|
||||||
|
domainRules=$(echo "${domainRules}" | jq -r --arg reg "^([a-zA-Z0-9_-]+\\.)*${normalizedLine//./\\.}" '. += [$reg]')
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
done < <(echo "$1" | tr ',' '\n' | grep -v '^$' | sort -n | uniq | paste -sd ',' | tr ',' '\n')
|
done < <(echo "$1" | tr ',' '\n' | grep -v '^$' | sort -n | uniq | paste -sd ',' | tr ',' '\n')
|
||||||
echo "{ \"domainRules\":${domainRules},\"ruleSet\":${ruleSet}}"
|
echo "{ \"domainRules\":${domainRules},\"ruleSet\":${ruleSet}}"
|
||||||
@@ -7635,14 +7941,9 @@ setSocks5OutboundRouting() {
|
|||||||
if echo "${routingRule}" | grep -q "${line}"; then
|
if echo "${routingRule}" | grep -q "${line}"; then
|
||||||
echoContent yellow " ---> ${line}已存在,跳过"
|
echoContent yellow " ---> ${line}已存在,跳过"
|
||||||
else
|
else
|
||||||
local geositeStatus
|
local matchedRuleValue
|
||||||
geositeStatus=$(curl -s "https://api.github.com/repos/v2fly/domain-list-community/contents/data/${line}" | jq .message)
|
matchedRuleValue=$(getDLCMatchedRuleValue "${line}" "/etc/v2ray-agent/xray")
|
||||||
|
domainRules=$(echo "${domainRules}" | jq -r --arg rule "${matchedRuleValue}" '. += [$rule]')
|
||||||
if [[ "${geositeStatus}" == "null" ]]; then
|
|
||||||
domainRules=$(echo "${domainRules}" | jq -r ". += [\"geosite:${line}\"]")
|
|
||||||
else
|
|
||||||
domainRules=$(echo "${domainRules}" | jq -r ". += [\"domain:${line}\"]")
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
done < <(echo "${socks5RoutingOutboundDomain}" | tr ',' '\n')
|
done < <(echo "${socks5RoutingOutboundDomain}" | tr ',' '\n')
|
||||||
if [[ ! -f "${configPath}09_routing.json" ]]; then
|
if [[ ! -f "${configPath}09_routing.json" ]]; then
|
||||||
@@ -7793,7 +8094,9 @@ setUnlockSNI() {
|
|||||||
read -r -p "请按照上面示例录入域名:" xrayDomainList
|
read -r -p "请按照上面示例录入域名:" xrayDomainList
|
||||||
local hosts={}
|
local hosts={}
|
||||||
while read -r domain; do
|
while read -r domain; do
|
||||||
hosts=$(echo "${hosts}" | jq -r ".\"geosite:${domain}\"=\"${setSNIP}\"")
|
local matchedRuleValue
|
||||||
|
matchedRuleValue=$(getDLCMatchedRuleValue "${domain}" "/etc/v2ray-agent/xray")
|
||||||
|
hosts=$(echo "${hosts}" | jq -r --arg key "${matchedRuleValue}" --arg value "${setSNIP}" '. + {($key):$value}')
|
||||||
done < <(echo "${xrayDomainList}" | tr ',' '\n')
|
done < <(echo "${xrayDomainList}" | tr ',' '\n')
|
||||||
cat <<EOF >${configPath}11_dns.json
|
cat <<EOF >${configPath}11_dns.json
|
||||||
{
|
{
|
||||||
@@ -7826,14 +8129,9 @@ addXrayDNSConfig() {
|
|||||||
local domainList=$2
|
local domainList=$2
|
||||||
local domains=[]
|
local domains=[]
|
||||||
while read -r line; do
|
while read -r line; do
|
||||||
local geositeStatus
|
local matchedRuleValue
|
||||||
geositeStatus=$(curl -s "https://api.github.com/repos/v2fly/domain-list-community/contents/data/${line}" | jq .message)
|
matchedRuleValue=$(getDLCMatchedRuleValue "${line}" "/etc/v2ray-agent/xray")
|
||||||
|
domains=$(echo "${domains}" | jq -r --arg rule "${matchedRuleValue}" '. += [$rule]')
|
||||||
if [[ "${geositeStatus}" == "null" ]]; then
|
|
||||||
domains=$(echo "${domains}" | jq -r '. += ["geosite:'"${line}"'"]')
|
|
||||||
else
|
|
||||||
domains=$(echo "${domains}" | jq -r '. += ["domain:'"${line}"'"]')
|
|
||||||
fi
|
|
||||||
done < <(echo "${domainList}" | tr ',' '\n')
|
done < <(echo "${domainList}" | tr ',' '\n')
|
||||||
|
|
||||||
if [[ "${coreInstallType}" == "1" ]]; then
|
if [[ "${coreInstallType}" == "1" ]]; then
|
||||||
@@ -9649,7 +9947,7 @@ menu() {
|
|||||||
cd "$HOME" || exit
|
cd "$HOME" || exit
|
||||||
echoContent red "\n=============================================================="
|
echoContent red "\n=============================================================="
|
||||||
echoContent green "作者:mack-a"
|
echoContent green "作者:mack-a"
|
||||||
echoContent green "当前版本:v3.5.12"
|
echoContent green "当前版本:v3.5.13"
|
||||||
echoContent green "Github:https://github.com/mack-a/v2ray-agent"
|
echoContent green "Github:https://github.com/mack-a/v2ray-agent"
|
||||||
echoContent green "描述:八合一共存脚本\c"
|
echoContent green "描述:八合一共存脚本\c"
|
||||||
showInstallStatus
|
showInstallStatus
|
||||||
|
|||||||
+254
-57
@@ -5545,8 +5545,10 @@ blacklist() {
|
|||||||
echoContent red "\n================================================ ================="
|
echoContent red "\n================================================ ================="
|
||||||
echoContent yellow "1.View blocked domain names"
|
echoContent yellow "1.View blocked domain names"
|
||||||
echoContent yellow "2.Add domain name"
|
echoContent yellow "2.Add domain name"
|
||||||
echoContent yellow "3.Block domestic domain names"
|
echoContent yellow "3.Block domestic domain names + IP"
|
||||||
echoContent yellow "4.Delete blacklist"
|
echoContent yellow "4.Delete blacklist/whitelist"
|
||||||
|
echoContent yellow "5.Add blocked IP"
|
||||||
|
echoContent yellow "6.Add domain whitelist"
|
||||||
echoContent red "================================================== ==============="
|
echoContent red "================================================== ==============="
|
||||||
|
|
||||||
read -r -p "Please select:" blacklistStatus
|
read -r -p "Please select:" blacklistStatus
|
||||||
@@ -5575,33 +5577,194 @@ blacklist() {
|
|||||||
echoContent green " ---> Added successfully"
|
echoContent green " ---> Added successfully"
|
||||||
|
|
||||||
elif [[ "${blacklistStatus}" == "3" ]]; then
|
elif [[ "${blacklistStatus}" == "3" ]]; then
|
||||||
|
local autoAllowDomainList="dl.google.com,apple.com,bing.com,microsoft.com,gstatic.cn"
|
||||||
|
unInstallRouting blackhole-out outboundTag
|
||||||
|
unInstallRouting blackhole-ip-out outboundTag
|
||||||
|
|
||||||
addInstallRouting blackhole-out outboundTag "cn"
|
addInstallRouting blackhole-out outboundTag "cn"
|
||||||
|
addInstallIPRouting blackhole-ip-out outboundTag "cn"
|
||||||
|
addInstallRouting allow-domain-direct-out outboundTag "${autoAllowDomainList}" "top"
|
||||||
|
|
||||||
unInstallOutbounds blackhole-out
|
unInstallOutbounds blackhole-out
|
||||||
|
unInstallOutbounds blackhole-ip-out
|
||||||
|
unInstallOutbounds allow-domain-direct-out
|
||||||
|
|
||||||
outbounds=$(jq -r '.outbounds += [{"protocol":"blackhole","tag":"blackhole-out"}]' ${configPath}10_ipv4_outbounds.json)
|
outbounds=$(jq -r '.outbounds += [{"protocol":"blackhole","tag":"blackhole-out"},{"protocol":"blackhole","tag":"blackhole-ip-out"},{"protocol":"freedom","tag":"allow-domain-direct-out","settings":{"domainStrategy":"UseIP"}}]' ${configPath}10_ipv4_outbounds.json)
|
||||||
|
|
||||||
echo "${outbounds}" | jq . >${configPath}10_ipv4_outbounds.json
|
echo "${outbounds}" | jq . >${configPath}10_ipv4_outbounds.json
|
||||||
|
|
||||||
echoContent green " ---> Domestic domain name blocked successfully"
|
echoContent green " ---> Domestic domain name + IP blocked successfully"
|
||||||
|
|
||||||
elif [[ "${blacklistStatus}" == "4" ]]; then
|
elif [[ "${blacklistStatus}" == "4" ]]; then
|
||||||
|
|
||||||
unInstallRouting blackhole-out outboundTag
|
unInstallRouting blackhole-out outboundTag
|
||||||
|
unInstallRouting blackhole-ip-out outboundTag
|
||||||
|
unInstallRouting allow-domain-direct-out outboundTag
|
||||||
|
|
||||||
echoContent green " ---> Domain name blacklist deleted successfully"
|
unInstallOutbounds blackhole-ip-out
|
||||||
|
unInstallOutbounds allow-domain-direct-out
|
||||||
|
|
||||||
|
echoContent green " ---> Domain blacklist/whitelist deleted successfully"
|
||||||
|
elif [[ "${blacklistStatus}" == "5" ]]; then
|
||||||
|
echoContent yellow "Input example:1.1.1.1,8.8.8.8,1.1.1.0/24,2400:3200::/32\n"
|
||||||
|
read -r -p "Please enter the blocked IP list:" ipList
|
||||||
|
if [[ -z "${ipList}" ]]; then
|
||||||
|
echoContent red " ---> ip cannot be empty"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
addInstallIPRouting blackhole-ip-out outboundTag "${ipList}"
|
||||||
|
unInstallOutbounds blackhole-ip-out
|
||||||
|
outbounds=$(jq -r '.outbounds += [{"protocol":"blackhole","tag":"blackhole-ip-out"}]' ${configPath}10_ipv4_outbounds.json)
|
||||||
|
echo "${outbounds}" | jq . >${configPath}10_ipv4_outbounds.json
|
||||||
|
echoContent green " ---> Blocked IP added successfully"
|
||||||
|
elif [[ "${blacklistStatus}" == "6" ]]; then
|
||||||
|
echoContent yellow "Input example:speedtest,openai,google.com\n"
|
||||||
|
read -r -p "Please enter whitelist domains:" allowDomainList
|
||||||
|
if [[ -z "${allowDomainList}" ]]; then
|
||||||
|
echoContent red " ---> domain cannot be empty"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
addInstallRouting allow-domain-direct-out outboundTag "${allowDomainList}" "top"
|
||||||
|
unInstallOutbounds allow-domain-direct-out
|
||||||
|
outbounds=$(jq -r '.outbounds += [{"protocol":"freedom","tag":"allow-domain-direct-out","settings":{"domainStrategy":"UseIP"}}]' ${configPath}10_ipv4_outbounds.json)
|
||||||
|
echo "${outbounds}" | jq . >${configPath}10_ipv4_outbounds.json
|
||||||
|
echoContent green " ---> Domain whitelist added successfully"
|
||||||
else
|
else
|
||||||
echoContent red " ---> Wrong selection"
|
echoContent red " ---> Wrong selection"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
reloadCore
|
reloadCore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Download dlc.dat_plain.yml into core directory
|
||||||
|
downloadDLCPlainYAML() {
|
||||||
|
local corePath=$1
|
||||||
|
local dlcFilePath="${corePath}/dlc.dat_plain.yml"
|
||||||
|
local tmpFilePath="${dlcFilePath}.tmp"
|
||||||
|
|
||||||
|
if [[ -z "${corePath}" ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "${corePath}" >/dev/null 2>&1
|
||||||
|
if [[ -s "${dlcFilePath}" ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
local dlcDownloadURL="https://github.com/v2fly/domain-list-community/releases/latest/download/dlc.dat_plain.yml"
|
||||||
|
if [[ "${release}" == "alpine" ]]; then
|
||||||
|
wget -c -q -O "${tmpFilePath}" "${dlcDownloadURL}" >/dev/null 2>&1
|
||||||
|
else
|
||||||
|
wget -c -q "${wgetShowProgressStatus}" -O "${tmpFilePath}" "${dlcDownloadURL}" >/dev/null 2>&1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $? -ne 0 || ! -s "${tmpFilePath}" ]]; then
|
||||||
|
rm -f "${tmpFilePath}" >/dev/null 2>&1
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mv "${tmpFilePath}" "${dlcFilePath}" >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Escape grep/regex pattern meta characters
|
||||||
|
escapeDLCRegexPattern() {
|
||||||
|
echo "$1" | sed -e 's/[.[\\*^$()+?{|]/\\\\&/g'
|
||||||
|
}
|
||||||
|
|
||||||
|
# Resolve nearest upper name by matched rule line
|
||||||
|
getDLCNameByRuleLine() {
|
||||||
|
local ruleLine=$1
|
||||||
|
local dlcFilePath=$2
|
||||||
|
awk -v targetLine="${ruleLine}" '
|
||||||
|
/^[[:space:]]*-[[:space:]]*name:[[:space:]]*/ {
|
||||||
|
line = $0
|
||||||
|
sub(/^[[:space:]]*-[[:space:]]*name:[[:space:]]*/, "", line)
|
||||||
|
currentName = line
|
||||||
|
}
|
||||||
|
NR == targetLine {
|
||||||
|
print currentName
|
||||||
|
exit
|
||||||
|
}' "${dlcFilePath}"
|
||||||
|
}
|
||||||
|
|
||||||
|
isDomainFormat() {
|
||||||
|
local target=$1
|
||||||
|
[[ "${target}" =~ ^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z0-9-]{2,63}$ ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Resolve geosite name from dlc.dat_plain.yml by input domain
|
||||||
|
getDLCGeositeName() {
|
||||||
|
local inputRule=$1
|
||||||
|
local corePath=$2
|
||||||
|
local dlcFilePath="${corePath}/dlc.dat_plain.yml"
|
||||||
|
|
||||||
|
if [[ -z "${inputRule}" || -z "${corePath}" ]]; then
|
||||||
|
echo ""
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
local normalizedInput
|
||||||
|
normalizedInput=$(echo "${inputRule}" | tr '[:upper:]' '[:lower:]' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
||||||
|
normalizedInput=${normalizedInput#domain:}
|
||||||
|
normalizedInput=${normalizedInput#full:}
|
||||||
|
normalizedInput=${normalizedInput#keyword:}
|
||||||
|
|
||||||
|
if [[ -z "${normalizedInput}" ]]; then
|
||||||
|
echo ""
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if isDomainFormat "${normalizedInput}"; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! downloadDLCPlainYAML "${corePath}"; then
|
||||||
|
echo ""
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
local escapedInput=
|
||||||
|
escapedInput=$(escapeDLCRegexPattern "${normalizedInput}")
|
||||||
|
|
||||||
|
local matchedLine=
|
||||||
|
matchedLine=$(grep -n -m1 -E "^[[:space:]]*-[[:space:]]*name:[[:space:]]*${escapedInput}[[:space:]]*$" "${dlcFilePath}")
|
||||||
|
if [[ -n "${matchedLine}" ]]; then
|
||||||
|
echo "${normalizedInput}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Build final rule value: prefer geosite, fallback to domain
|
||||||
|
getDLCMatchedRuleValue() {
|
||||||
|
local inputRule=$1
|
||||||
|
local corePath=$2
|
||||||
|
local normalizedInput=
|
||||||
|
normalizedInput=$(echo "${inputRule}" | tr '[:upper:]' '[:lower:]' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
||||||
|
|
||||||
|
if isDomainFormat "${normalizedInput}"; then
|
||||||
|
local escapedDomain=
|
||||||
|
escapedDomain=$(escapeDLCRegexPattern "${normalizedInput}")
|
||||||
|
echo "regexp:.*${escapedDomain}.*"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
local matchedRuleName=
|
||||||
|
matchedRuleName=$(getDLCGeositeName "${normalizedInput}" "${corePath}")
|
||||||
|
if [[ -n "${matchedRuleName}" ]]; then
|
||||||
|
echo "geosite:${matchedRuleName}"
|
||||||
|
else
|
||||||
|
echo "domain:${normalizedInput}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
#Add routing configuration
|
#Add routing configuration
|
||||||
addInstallRouting() {
|
addInstallRouting() {
|
||||||
|
|
||||||
local tag=$1 # warp-socks
|
local tag=$1 # warp-socks
|
||||||
local type=$2 # outboundTag/inboundTag
|
local type=$2 # outboundTag/inboundTag
|
||||||
local domain=$3 # Domain name
|
local domain=$3 # Domain name
|
||||||
|
local rulePosition=$4
|
||||||
|
|
||||||
if [[ -z "${tag}" || -z "${type}" || -z "${domain}" ]]; then
|
if [[ -z "${tag}" || -z "${type}" || -z "${domain}" ]]; then
|
||||||
echoContent red " ---> Parameter error"
|
echoContent red " ---> Parameter error"
|
||||||
@@ -5642,24 +5805,83 @@ EOF
|
|||||||
if echo "${routingRule}" | grep -q "${line}"; then
|
if echo "${routingRule}" | grep -q "${line}"; then
|
||||||
echoContent yellow " ---> ${line} already exists, skip"
|
echoContent yellow " ---> ${line} already exists, skip"
|
||||||
else
|
else
|
||||||
local geositeStatus
|
local matchedRuleValue
|
||||||
geositeStatus=$(curl -s "https://api.github.com/repos/v2fly/domain-list-community/contents/data/${line}" | jq .message)
|
matchedRuleValue=$(getDLCMatchedRuleValue "${line}" "/etc/v2ray-agent/xray")
|
||||||
|
routingRule=$(echo "${routingRule}" | jq -r --arg rule "${matchedRuleValue}" '.domain += [$rule]')
|
||||||
if [[ "${geositeStatus}" == "null" ]]; then
|
|
||||||
routingRule=$(echo "${routingRule}" | jq -r '.domain += ["geosite:'"${line}"'"]')
|
|
||||||
else
|
|
||||||
routingRule=$(echo "${routingRule}" | jq -r '.domain += ["domain:'"${line}"'"]')
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
done < <(echo "${domain}" | tr ',' '\n')
|
done < <(echo "${domain}" | tr ',' '\n')
|
||||||
|
|
||||||
unInstallRouting "${tag}" "${type}"
|
unInstallRouting "${tag}" "${type}"
|
||||||
if ! grep -q "gstatic.com" ${configPath}09_routing.json && [[ "${tag}" == "blackhole-out" ]]; then
|
if ! grep -q "gstatic.com" ${configPath}09_routing.json && [[ "${tag}" == "blackhole-out" ]]; then
|
||||||
local routing=
|
local routing=
|
||||||
routing=$(jq -r ".routing.rules += [{\"type\": \"field\",\"domain\": [\"gstatic.com\"],\"outboundTag\": \"direct\"}]" ${configPath}09_routing.json)
|
routing=$(jq -r ".routing.rules += [{\"type\": \"field\",\"domain\": [\"domain:gstatic.com\"],\"outboundTag\": \"allow-domain-direct-out\"}]" ${configPath}09_routing.json)
|
||||||
echo "${routing}" | jq . >${configPath}09_routing.json
|
echo "${routing}" | jq . >${configPath}09_routing.json
|
||||||
|
|
||||||
|
if [[ -f "${configPath}10_ipv4_outbounds.json" ]] && ! grep -q '"allow-domain-direct-out"' "${configPath}10_ipv4_outbounds.json"; then
|
||||||
|
local outbounds=
|
||||||
|
outbounds=$(jq -r '.outbounds += [{"protocol":"freedom","tag":"allow-domain-direct-out","settings":{"domainStrategy":"UseIP"}}]' ${configPath}10_ipv4_outbounds.json)
|
||||||
|
echo "${outbounds}" | jq . >${configPath}10_ipv4_outbounds.json
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ "${rulePosition}" == "top" ]]; then
|
||||||
|
routing=$(jq -r ".routing.rules = [${routingRule}] + .routing.rules" ${configPath}09_routing.json)
|
||||||
|
else
|
||||||
|
routing=$(jq -r ".routing.rules += [${routingRule}]" ${configPath}09_routing.json)
|
||||||
|
fi
|
||||||
|
echo "${routing}" | jq . >${configPath}09_routing.json
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add Xray IP block routing
|
||||||
|
# Supports geoip:cn and custom IPv4/IPv6/CIDR input
|
||||||
|
addInstallIPRouting() {
|
||||||
|
|
||||||
|
local tag=$1
|
||||||
|
local type=$2
|
||||||
|
local ipList=$3
|
||||||
|
|
||||||
|
if [[ -z "${tag}" || -z "${type}" || -z "${ipList}" ]]; then
|
||||||
|
echoContent red " ---> Parameter error"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f "${configPath}09_routing.json" ]]; then
|
||||||
|
cat <<EOF >${configPath}09_routing.json
|
||||||
|
{
|
||||||
|
"routing":{
|
||||||
|
"type": "field",
|
||||||
|
"rules": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
local routingRule=
|
||||||
|
routingRule=$(jq -r ".routing.rules[]|select(.outboundTag==\"${tag}\" and (.protocol == null) and (.ip != null))" ${configPath}09_routing.json)
|
||||||
|
if [[ -z "${routingRule}" ]]; then
|
||||||
|
routingRule="{\"type\": \"field\",\"ip\": [],\"outboundTag\": \"${tag}\"}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
while read -r line; do
|
||||||
|
line=$(echo "${line}" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
||||||
|
if [[ -z "${line}" ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
local ipRuleValue=${line}
|
||||||
|
if [[ "${line}" == "cn" ]]; then
|
||||||
|
ipRuleValue="geoip:cn"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if echo "${routingRule}" | grep -q "${ipRuleValue}"; then
|
||||||
|
echoContent yellow " ---> ${ipRuleValue} already exists, skip"
|
||||||
|
else
|
||||||
|
routingRule=$(echo "${routingRule}" | jq -r '.ip += ["'"${ipRuleValue}"'"]')
|
||||||
|
fi
|
||||||
|
done < <(echo "${ipList}" | tr ',' '\n')
|
||||||
|
|
||||||
|
unInstallRouting "${tag}" "${type}"
|
||||||
|
local routing=
|
||||||
routing=$(jq -r ".routing.rules += [${routingRule}]" ${configPath}09_routing.json)
|
routing=$(jq -r ".routing.rules += [${routingRule}]" ${configPath}09_routing.json)
|
||||||
echo "${routing}" | jq . >${configPath}09_routing.json
|
echo "${routing}" | jq . >${configPath}09_routing.json
|
||||||
}
|
}
|
||||||
@@ -6254,14 +6476,9 @@ EOF
|
|||||||
local domains=
|
local domains=
|
||||||
domains=[]
|
domains=[]
|
||||||
while read -r line; do
|
while read -r line; do
|
||||||
local geositeStatus
|
local matchedRuleValue
|
||||||
geositeStatus=$(curl -s "https://api.github.com/repos/v2fly/domain-list-community/contents/data/${line}" | jq .message)
|
matchedRuleValue=$(getDLCMatchedRuleValue "${line}" "/etc/v2ray-agent/xray")
|
||||||
|
domains=$(echo "${domains}" | jq -r --arg rule "${matchedRuleValue}" '. += [$rule]')
|
||||||
if [[ "${geositeStatus}" == "null" ]]; then
|
|
||||||
domains=$(echo "${domains}" | jq -r '. += ["geosite:'"${line}"'"]')
|
|
||||||
else
|
|
||||||
domains=$(echo "${domains}" | jq -r '. += ["domain:'"${line}"'"]')
|
|
||||||
fi
|
|
||||||
done < <(echo "${domainList}" | tr ',' '\n')
|
done < <(echo "${domainList}" | tr ',' '\n')
|
||||||
|
|
||||||
if [[ -f "${configPath}09_routing.json" ]]; then
|
if [[ -f "${configPath}09_routing.json" ]]; then
|
||||||
@@ -6427,7 +6644,9 @@ setUnlockSNI() {
|
|||||||
if [[ -n "${domainList}" ]]; then
|
if [[ -n "${domainList}" ]]; then
|
||||||
local hosts={}
|
local hosts={}
|
||||||
while read -r domain; do
|
while read -r domain; do
|
||||||
hosts=$(echo "${hosts}" | jq -r ".\"geosite:${domain}\"=\"${setSNIP}\"")
|
local matchedRuleValue
|
||||||
|
matchedRuleValue=$(getDLCMatchedRuleValue "${domain}" "/etc/v2ray-agent/xray")
|
||||||
|
hosts=$(echo "${hosts}" | jq -r --arg key "${matchedRuleValue}" --arg value "${setSNIP}" '. + {($key):$value}')
|
||||||
done < <(echo "${domainList}" | tr ',' '\n')
|
done < <(echo "${domainList}" | tr ',' '\n')
|
||||||
cat <<EOF >${configPath}11_dns.json
|
cat <<EOF >${configPath}11_dns.json
|
||||||
{
|
{
|
||||||
@@ -6462,6 +6681,16 @@ setUnlockDNS() {
|
|||||||
echoContent yellow "netflix,bahamut,hulu,hbo,disney,bbc,4chan,fox,abema,dmm,niconico,pixiv,bilibili,viu"
|
echoContent yellow "netflix,bahamut,hulu,hbo,disney,bbc,4chan,fox,abema,dmm,niconico,pixiv,bilibili,viu"
|
||||||
read -r -p "Please enter the domain name according to the above example:" domainList
|
read -r -p "Please enter the domain name according to the above example:" domainList
|
||||||
if [[ "${domainList}" == "1" ]]; then
|
if [[ "${domainList}" == "1" ]]; then
|
||||||
|
domainList="netflix,bahamut,hulu,hbo,disney,bbc,4chan,fox,abema,dmm,niconico,pixiv,bilibili,viu"
|
||||||
|
fi
|
||||||
|
if [[ -n "${domainList}" ]]; then
|
||||||
|
local domains=[]
|
||||||
|
while read -r line; do
|
||||||
|
local matchedRuleValue
|
||||||
|
matchedRuleValue=$(getDLCMatchedRuleValue "${line}" "/etc/v2ray-agent/xray")
|
||||||
|
domains=$(echo "${domains}" | jq -r --arg rule "${matchedRuleValue}" '. += [$rule]')
|
||||||
|
done < <(echo "${domainList}" | tr ',' '\n')
|
||||||
|
|
||||||
cat <<EOF >${configPath}11_dns.json
|
cat <<EOF >${configPath}11_dns.json
|
||||||
{
|
{
|
||||||
"dns": {
|
"dns": {
|
||||||
@@ -6469,39 +6698,7 @@ setUnlockDNS() {
|
|||||||
{
|
{
|
||||||
"address": "${setDNS}",
|
"address": "${setDNS}",
|
||||||
"port": 53,
|
"port": 53,
|
||||||
"domains": [
|
"domains": ${domains}
|
||||||
"geosite:netflix",
|
|
||||||
"geosite:bahamut",
|
|
||||||
"geosite:hulu",
|
|
||||||
"geosite:hbo",
|
|
||||||
"geosite:disney",
|
|
||||||
"geosite:bbc",
|
|
||||||
"geosite:4chan",
|
|
||||||
"geosite:fox",
|
|
||||||
"geosite:abema",
|
|
||||||
"geosite:dmm",
|
|
||||||
"geosite:niconico",
|
|
||||||
"geosite:pixiv",
|
|
||||||
"geosite:bilibili",
|
|
||||||
"geosite:viu"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"localhost"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
elif [[ -n "${domainList}" ]]; then
|
|
||||||
cat <<EOF >${configPath}11_dns.json
|
|
||||||
{
|
|
||||||
"dns": {
|
|
||||||
"servers": [
|
|
||||||
{
|
|
||||||
"address": "${setDNS}",
|
|
||||||
"port": 53,
|
|
||||||
"domains": [
|
|
||||||
"geosite:${domainList//,/\",\"geosite:}"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"localhost"
|
"localhost"
|
||||||
]
|
]
|
||||||
@@ -7896,7 +8093,7 @@ menu() {
|
|||||||
cd "$HOME" || exit
|
cd "$HOME" || exit
|
||||||
echoContent red "\n================================================ ================="
|
echoContent red "\n================================================ ================="
|
||||||
echoContent green "Author: mack-a"
|
echoContent green "Author: mack-a"
|
||||||
echoContent green "Current version: v2.10.20"
|
echoContent green "Current version: v3.5.13"
|
||||||
echoContent green "Github: https://github.com/mack-a/v2ray-agent"
|
echoContent green "Github: https://github.com/mack-a/v2ray-agent"
|
||||||
echoContent green "Description: 8-in-1 coexistence script\c"
|
echoContent green "Description: 8-in-1 coexistence script\c"
|
||||||
showInstallStatus
|
showInstallStatus
|
||||||
|
|||||||
Reference in New Issue
Block a user