immortalwrt/package/ctcgfw/luci-app-openclash/files/etc/init.d/openclash

1566 lines
63 KiB
Plaintext
Raw Normal View History

2020-06-18 12:39:01 +08:00
#!/bin/sh /etc/rc.common
2019-08-02 23:40:19 +08:00
# Copyright (c) 2019 vernesong
2019-07-19 18:18:45 +08:00
START=99
STOP=15
2020-04-30 20:22:10 +08:00
LOGTIME=$(date "+%Y-%m-%d %H:%M:%S")
2019-07-19 18:18:45 +08:00
CLASH="/etc/openclash/clash"
CLASH_CONFIG="/etc/openclash"
CRON_FILE="/etc/crontabs/root"
CONFIG_FILE=$(uci get openclash.config.config_path 2>/dev/null)
2019-07-19 18:18:45 +08:00
LOG_FILE="/tmp/openclash.log"
START_LOG="/tmp/openclash_start.log"
BACKUP_FILE="/etc/openclash/backup/$(uci get openclash.config.config_path 2>/dev/null |awk -F '/' '{print $5}' 2>/dev/null)"
2019-08-02 23:40:19 +08:00
START_BACKUP="/tmp/config.sbak"
2019-07-27 18:06:42 +08:00
CHANGE_FILE="/tmp/yaml_change.yaml"
2020-05-26 20:20:32 +08:00
SCRIPT_FILE="/tmp/yaml_script.yaml"
RULE_PROVIDER_FILE="/tmp/yaml_rule_provider.yaml"
2019-07-27 18:06:42 +08:00
RULE_FILE="/tmp/yaml_rules.yaml"
DNS_FILE="/tmp/yaml_dns.yaml"
PROXY_FILE="/tmp/yaml_proxy.yaml"
PROXY_PROVIDER_FILE="/tmp/yaml_proxy_provider.yaml"
GROUP_FILE="/tmp/yaml_group.yaml"
GAME_RULE_FILE="/tmp/yaml_game_rule_group.yaml"
HOSTS_FILE="/etc/openclash/custom/openclash_custom_hosts.list"
PROXY_FWMARK="0x162"
PROXY_ROUTE_TABLE="0x162"
2019-07-19 18:18:45 +08:00
add_cron()
{
2019-09-30 13:29:25 +08:00
[ -z "$(grep "openclash.sh" "$CRON_FILE" 2>/dev/null)" ] && {
2020-02-20 02:53:49 +08:00
[ "$(uci get openclash.config.auto_update 2>/dev/null)" -eq 1 ] && [ "$(uci get openclash.config.config_auto_update_mode 2>/dev/null)" -ne 1 ] && echo "0 $(uci get openclash.config.auto_update_time 2>/dev/null) * * $(uci get openclash.config.config_update_week_time 2>/dev/null) /usr/share/openclash/openclash.sh" >> $CRON_FILE
}
2019-09-30 13:29:25 +08:00
[ -z "$(grep "openclash_rule.sh" "$CRON_FILE" 2>/dev/null)" ] && {
2019-07-19 18:18:45 +08:00
[ "$(uci get openclash.config.other_rule_auto_update 2>/dev/null)" -eq 1 ] && echo "0 $(uci get openclash.config.other_rule_update_day_time 2>/dev/null) * * $(uci get openclash.config.other_rule_update_week_time 2>/dev/null) /usr/share/openclash/openclash_rule.sh" >> $CRON_FILE
}
2019-09-30 13:29:25 +08:00
[ -z "$(grep "openclash_ipdb.sh" "$CRON_FILE" 2>/dev/null)" ] && {
2019-07-27 18:06:42 +08:00
[ "$(uci get openclash.config.geo_auto_update 2>/dev/null)" -eq 1 ] && echo "0 $(uci get openclash.config.geo_update_day_time 2>/dev/null) * * $(uci get openclash.config.geo_update_week_time 2>/dev/null) /usr/share/openclash/openclash_ipdb.sh" >> $CRON_FILE
}
2019-07-19 18:18:45 +08:00
crontab $CRON_FILE
nohup /usr/share/openclash/openclash_watchdog.sh &
}
del_cron()
{
sed -i '/openclash.sh/d' $CRON_FILE 2>/dev/null
sed -i '/openclash_rule.sh/d' $CRON_FILE 2>/dev/null
2019-07-27 18:06:42 +08:00
sed -i '/openclash_ipdb.sh/d' $CRON_FILE 2>/dev/null
2019-07-19 18:18:45 +08:00
/etc/init.d/cron restart
}
change_dns() {
2020-07-16 21:07:14 +08:00
if [ "$1" -eq "1" ]; then
2019-10-01 09:11:06 +08:00
uci del dhcp.@dnsmasq[-1].server >/dev/null 2>&1
uci add_list dhcp.@dnsmasq[0].server=127.0.0.1#"$dns_port"
2020-07-16 21:07:14 +08:00
uci delete dhcp.@dnsmasq[0].resolvfile 2>/dev/null
uci set dhcp.@dnsmasq[0].noresolv=1 2>/dev/null
2019-10-30 23:36:56 +08:00
uci set openclash.config.redirect_dns=1
else
2020-07-16 21:07:14 +08:00
uci delete openclash.config.redirect_dns 2>/dev/null
2019-10-30 23:36:56 +08:00
fi
if [ "$2" -eq "1" ]; then
2020-07-16 21:07:14 +08:00
uci set dhcp.@dnsmasq[0].cachesize=0 2>/dev/null
2019-10-01 09:11:06 +08:00
fi
2019-10-30 23:36:56 +08:00
uci commit dhcp
uci commit openclash
}
revert_dns() {
2020-07-16 21:07:14 +08:00
[ "$1" -eq "0" ] && {
if [ "$(uci get openclash.config.dns_revert 2>/dev/null)" != "1" ]; then
uci del_list dhcp.@dnsmasq[0].server=127.0.0.1#"$3" >/dev/null 2>&1
uci set openclash.config.dns_revert=1 2>/dev/null
2020-05-10 11:26:20 +08:00
fi
2019-10-30 23:36:56 +08:00
}
2020-07-18 22:04:13 +08:00
2020-07-16 21:07:14 +08:00
[ "$1" -eq "1" ] && {
uci del_list dhcp.@dnsmasq[0].server=127.0.0.1#"$3" >/dev/null 2>&1
uci set openclash.config.dns_revert=0 2>/dev/null
2019-10-30 23:36:56 +08:00
}
2020-07-16 21:07:14 +08:00
2020-07-18 22:04:13 +08:00
[ "$(uci get dhcp.@dnsmasq[0].cachesize 2>/dev/null)" = "0" ] && {
2020-07-16 21:07:14 +08:00
uci delete dhcp.@dnsmasq[0].cachesize >/dev/null 2>&1
2020-07-18 22:04:13 +08:00
}
2020-07-16 21:07:14 +08:00
2020-07-18 22:04:13 +08:00
if [ -s "/tmp/resolv.conf.d/resolv.conf.auto" ]; then
uci set dhcp.@dnsmasq[0].resolvfile=/tmp/resolv.conf.d/resolv.conf.auto >/dev/null 2>&1
elif [ -s "/tmp/resolv.conf.auto" ]; then
uci set dhcp.@dnsmasq[0].resolvfile=/tmp/resolv.conf.auto >/dev/null 2>&1
fi
uci set dhcp.@dnsmasq[0].noresolv=0 >/dev/null 2>&1
uci commit dhcp
2020-07-16 21:07:14 +08:00
uci commit openclash
rm -rf /tmp/dnsmasq.d/dnsmasq_openclash.conf >/dev/null 2>&1
}
2020-05-26 20:20:32 +08:00
kill_clash()
{
clash_pids=$(pidof clash|sed 's/$//g')
for clash_pid in $clash_pids; do
kill -9 "$clash_pid" 2>/dev/null
done
sleep 1
}
field_cut()
{
local i lines end_len
proxy_len=$(sed -n '/^Proxy:/=' "$3" 2>/dev/null |sed -n 1p)
provider_len=$(sed -n '/^proxy-providers:/=' "$3" 2>/dev/null)
group_len=$(sed -n '/^proxy-groups:/=' "$3" 2>/dev/null)
rule_len=$(sed -n '/^rules:/=' "$3" 2>/dev/null)
rule_provider_len=$(sed -n '/^rule-providers:/=' "$3" 2>/dev/null)
script_len=$(sed -n '/^script:/=' "$3" 2>/dev/null)
lines="$proxy_len $provider_len $group_len $rule_len $rule_provider_len $script_len"
2020-06-18 12:39:01 +08:00
for i in $lines; do
2020-05-26 20:20:32 +08:00
if [ -z "$1" ]; then
break
fi
if [ "$1" -ge "$i" ]; then
continue
fi
if [ "$end_len" -gt "$i" ] || [ -z "$end_len" ]; then
end_len="$i"
fi
done 2>/dev/null
if [ -n "$1" ] && [ -z "$end_len" ]; then
end_len=$(sed -n '$=' "$3")
elif [ -n "$end_len" ]; then
end_len=$(expr "$end_len" - 1)
fi
sed -n "${1},${end_len}p" "$3" > "$2" 2>/dev/null
sed -i "${1},${end_len}d" "$3" 2>/dev/null
}
2019-07-19 18:18:45 +08:00
yml_check()
{
2020-04-16 03:17:11 +08:00
#格式替换
2019-09-30 13:29:25 +08:00
sed -i 's/\t/ /g' "$3" 2>/dev/null
2020-04-16 03:17:11 +08:00
sed -i "s/- \{2,\}/- /g" "$3" 2>/dev/null
2019-10-03 11:22:15 +08:00
#检查关键字避免后续操作出错
2020-04-30 20:22:10 +08:00
/usr/share/openclash/yml_field_name_ch.sh "$3" 2>/dev/null
2020-03-10 22:36:23 +08:00
#dns
2020-03-13 20:30:31 +08:00
[ -z "$(grep "^dns:" "$3")" ] && {
2020-04-23 03:09:15 +08:00
sed -i "s/^ \{1,\}dns:/dns:/g" "$3" 2>/dev/null
2020-03-10 22:36:23 +08:00
}
2019-07-27 18:06:42 +08:00
2020-03-09 03:58:10 +08:00
#创建启动备份
cp "$3" "$5"
2019-07-27 18:06:42 +08:00
2020-03-09 03:58:10 +08:00
#创建原始备份
if [ ! -f "$4" ]; then
cp "$3" "$4"
fi
2020-02-15 22:06:30 +08:00
2020-02-11 19:52:30 +08:00
#位置检查
2020-05-26 20:20:32 +08:00
proxy_len=$(sed -n '/^Proxy:/=' "$3" 2>/dev/null |sed -n 1p)
provider_len=$(sed -n '/^proxy-providers:/=' "$3" 2>/dev/null)
group_len=$(sed -n '/^proxy-groups:/=' "$3" 2>/dev/null)
2020-04-19 20:01:35 +08:00
dns_len=$(sed -n '/^dns:/=' "$3" 2>/dev/null)
2020-05-26 20:20:32 +08:00
rule_len=$(sed -n '/^rules:/=' "$3" 2>/dev/null)
2020-04-30 20:22:10 +08:00
2020-02-11 19:52:30 +08:00
if [ "$dns_len" -ge "$proxy_len" ] || [ "$dns_len" -ge "$rule_len" ] || [ "$dns_len" -ge "$group_len" ]; then
2020-05-26 20:20:32 +08:00
kill_clash
stop
2020-02-11 19:52:30 +08:00
echo "错误: 不支持的配置文件, General 设置部分应位于开头,请根据模板修改后重试!" > $START_LOG
echo "${LOGTIME} Unsupported Config, Please Check The General Setting's location And Try-again!" >> $LOG_FILE
mv "$START_BACKUP" "$CONFIG_FILE"
exit 0
2020-02-15 22:06:30 +08:00
fi 2>/dev/null
2020-02-11 19:52:30 +08:00
2020-05-26 20:20:32 +08:00
if [ "$proxy_len" -ge "$rule_len" ]; then
kill_clash
stop
2020-02-11 19:52:30 +08:00
echo "错误: 不支持的配置文件,服务器节点设置部分应位于规则之前,请根据模板修改后重试!" > $START_LOG
echo "${LOGTIME} Unsupported Config, Please Check The Proxy Setting's location And Try-again!" >> $LOG_FILE
mv "$START_BACKUP" "$CONFIG_FILE"
exit 0
2020-02-15 22:06:30 +08:00
fi 2>/dev/null
2020-02-11 19:52:30 +08:00
if [ "$group_len" -ge "$rule_len" ] || [ "$proxy_len" -ge "$group_len" ]; then
2020-05-26 20:20:32 +08:00
kill_clash
stop
2020-02-11 19:52:30 +08:00
echo "错误: 不支持的配置文件,策略组设置部分应位于规则之前、节点之后,请根据模板修改后重试!" > $START_LOG
echo "${LOGTIME} Unsupported Config, Please Check The Group Setting's location And Try-again!" >> $LOG_FILE
mv "$START_BACKUP" "$CONFIG_FILE"
exit 0
2020-02-15 22:06:30 +08:00
fi 2>/dev/null
2020-05-26 20:20:32 +08:00
#处理proxy_provider位置
if [ "$provider_len" -ge "$proxy_len" ] || [ "$provider_len" -ge "$group_len" ]; then
field_cut "$provider_len" "$PROXY_PROVIDER_FILE" "$3"
if [ -n "$proxy_len" ]; then
sed -i '/^Proxy:/i\proxy-provider-tag' "$3" 2>/dev/null
sed -i '/proxy-provider-tag/r/tmp/yaml_proxy_provider.yaml' "$3" 2>/dev/null
sed -i '/proxy-provider-tag/d' "$3" 2>/dev/null
elif [ -n "$group_len" ]; then
sed -i '/^proxy-groups:/i\proxy-provider-tag' "$3" 2>/dev/null
sed -i '/proxy-provider-tag/r/tmp/yaml_proxy_provider.yaml' "$3" 2>/dev/null
sed -i '/proxy-provider-tag/d' "$3" 2>/dev/null
fi
fi 2>/dev/null
2020-05-26 20:20:32 +08:00
#处理rule_provider位置
rule_provider_len=$(sed -n '/^rule-providers:/=' "$3" 2>/dev/null)
if [ -n "$rule_provider_len" ]; then
field_cut "$rule_provider_len" "$RULE_PROVIDER_FILE" "$3"
fi 2>/dev/null
#处理script位置
script_len=$(sed -n '/^script:/=' "$3" 2>/dev/null)
if [ -n "$script_len" ]; then
field_cut "$script_len" "$SCRIPT_FILE" "$3"
fi 2>/dev/null
if [ -n "$provider_len" ]; then
proxy_provider_mode=1
fi
#自定义DNS还原
if [ "$(grep -c '##Custom DNS##' "$3")" -gt 0 ] && [ "$2" = 0 ] && [ -f "$4" ]; then
if [ "$proxy_provider_mode" -eq 1 ]; then
2020-05-26 20:20:32 +08:00
awk '/^ {0,}nameserver:/,/proxy-providers:/{print}' "$4" | sed '/^proxy-providers:/d' >/tmp/backdns.config 2>/dev/null
else
awk '/^ {0,}nameserver:/,/Proxy:/{print}' "$4" | sed '/^Proxy:/d' >/tmp/backdns.config 2>/dev/null
fi
sed -i '/OpenClash-General-Settings/i\Custom DNS End' "$3" 2>/dev/null
sed -i '/^ \{0,\}nameserver:/,/^Custom DNS End$/d' "$3" 2>/dev/null
sed -i '/##Custom DNS##/r/tmp/bakdns.config' "$3" 2>/dev/null
rm -rf /tmp/backdns.config 2>/dev/null
2020-04-30 20:22:10 +08:00
fi 2>/dev/null
yml_dns_check
2020-04-30 20:22:10 +08:00
2020-05-26 20:20:32 +08:00
if [ -n "$(grep "^ \{1,\}port:" "$3")" ] || [ -n "$(grep "^ \{1,\}mode:" "$3")" ] || [ -n "$(grep "^ \{1,\}log-level:" "$3")" ]; then
2019-07-27 18:06:42 +08:00
cp "$3" /tmp/config.check 2>/dev/null
sed -i '/^dns:/,$d' /tmp/config.check 2>/dev/null
sed -i 's/^[ \t]*//' /tmp/config.check 2>/dev/null
sed -n '/^dns:/,$p' "$3" >> /tmp/config.check 2>/dev/null
mv /tmp/config.check "$3" 2>/dev/null
fi
#添加标识
2019-07-19 18:18:45 +08:00
sed -i '/OpenClash-General/d' "$3" 2>/dev/null
if [ "$proxy_provider_mode" -eq 1 ]; then
2020-05-26 20:20:32 +08:00
sed -i '/^proxy-providers:/i\#===================== OpenClash-General-Settings =====================#' "$3" 2>/dev/null
else
sed -i '/^Proxy:/i\#===================== OpenClash-General-Settings =====================#' "$3" 2>/dev/null
2020-05-26 20:20:32 +08:00
fi 2>/dev/null
2019-07-19 18:18:45 +08:00
}
2019-07-27 18:06:42 +08:00
#检查DNS设置
2019-07-19 18:18:45 +08:00
yml_dns_check()
{
2019-07-27 18:06:42 +08:00
2020-02-10 14:07:24 +08:00
if [ -z "$(grep '^dns:' "$CONFIG_FILE")" ]; then
if [ "$proxy_provider_mode" -eq 1 ]; then
2020-05-26 20:20:32 +08:00
sed -i '/^proxy-providers:/i\dns:' "$CONFIG_FILE" 2>/dev/null
else
sed -i '/^Proxy:/i\dns:' "$CONFIG_FILE" 2>/dev/null
2020-05-26 20:20:32 +08:00
fi 2>/dev/null
fi
2020-04-30 20:22:10 +08:00
2020-02-10 14:07:24 +08:00
if [ -z "$(grep '^ \{0,\}nameserver:' "$CONFIG_FILE")" ]; then
if [ "$proxy_provider_mode" -eq 1 ]; then
2020-05-26 20:20:32 +08:00
sed -i '/^proxy-providers:/i\ nameserver:' "$CONFIG_FILE" 2>/dev/null
else
sed -i '/^Proxy:/i\ nameserver:' "$CONFIG_FILE" 2>/dev/null
2020-05-26 20:20:32 +08:00
fi 2>/dev/null
2019-10-12 09:32:11 +08:00
sed -i "/^ \{0,\}nameserver:/a\ - tls://8.8.8.8:853" "$CONFIG_FILE" 2>/dev/null
sed -i "/^ \{0,\}nameserver:/a\ fallback:" "$CONFIG_FILE" 2>/dev/null
2019-10-12 09:32:11 +08:00
sed -i "/^ \{0,\}nameserver:/a\ - 114.114.114.114" "$CONFIG_FILE" 2>/dev/null
fi
2019-07-27 18:06:42 +08:00
2020-02-10 14:07:24 +08:00
dns_port=$(grep "^ \{0,\}listen:" "$CONFIG_FILE" |awk -F ':' '{print $3}' |awk -F '#' '{print $1}' |tr -cd "[0-9]" 2>/dev/null)
2019-07-27 18:06:42 +08:00
if [ -z "$dns_port" ] || [ "$dns_port" -eq 53 ]; then
2019-07-19 18:18:45 +08:00
dns_port=7874
fi
2020-04-30 20:22:10 +08:00
2020-05-26 20:20:32 +08:00
if [ -n "$(grep "^ \{0,\}listen:" "$CONFIG_FILE")" ]; then
2020-04-30 20:22:10 +08:00
if [ "$ipv6_enable" != "1" ]; then
2020-03-31 20:08:10 +08:00
sed -i "/^ \{0,\}listen:/c\ listen: 127.0.0.1:${dns_port}" "$CONFIG_FILE" 2>/dev/null
else
sed -i "/^ \{0,\}listen:/c\ listen: 0.0.0.0:${dns_port}" "$CONFIG_FILE" 2>/dev/null
fi
2019-07-27 18:06:42 +08:00
else
2020-04-30 20:22:10 +08:00
if [ "$ipv6_enable" != "1" ]; then
2020-03-31 20:08:10 +08:00
sed -i "/^dns:/a\ listen: 127.0.0.1:${dns_port}" "$CONFIG_FILE" 2>/dev/null
else
sed -i "/^dns:/a\ listen: 0.0.0.0:${dns_port}" "$CONFIG_FILE" 2>/dev/null
fi
2020-04-30 20:22:10 +08:00
fi 2>/dev/null
uci set openclash.config.dns_port="$dns_port" && uci commit openclash
2019-07-27 18:06:42 +08:00
2019-07-19 18:18:45 +08:00
}
2020-05-26 20:20:32 +08:00
#修改集路径
2020-04-23 03:09:15 +08:00
yml_provider_path()
{
2020-06-18 12:39:01 +08:00
provider_path_line=$(sed -n '/ \{0,\}path/=' "$1" 2>/dev/null)
2020-05-26 20:20:32 +08:00
if [ -n "$provider_path_line" ]; then
2020-06-18 12:39:01 +08:00
for n in $provider_path_line; do
if [ -n "$(sed -n "${n}p" "$1" |grep "^ \{0,\}#")" ]; then
continue
fi
provider_path=$(sed -n "${n}p" "$1" |sed "s/\'//g" |sed 's/\"//g' |awk -F 'path:' '{print $2}' 2>/dev/null |sed 's/,.*//' 2>/dev/null |sed 's/^ \{0,\}//g' 2>/dev/null |sed 's/ \{0,\}$//g' 2>/dev/null |sed 's/ \{0,\}\}\{0,\}$//g' 2>/dev/null)
2020-05-26 20:20:32 +08:00
if [ -z "$(echo "$provider_path" |grep "$2")" ]; then
2020-04-23 03:09:15 +08:00
provider_name=$(echo "$provider_path" |awk -F '/' '{print $NF}')
2020-06-18 12:39:01 +08:00
sed -i "s#path: ${provider_path}#path: ./${2}/${provider_name}#" "$1" 2>/dev/null
sed -i "s#\"${provider_path}#\"./${2}/${provider_name}#" "$1" 2>/dev/null
sed -i "s#\'${provider_path}#\'./${2}/${provider_name}#" "$1" 2>/dev/null
sed -i "s#\:${provider_path}#\:./${2}/${provider_name}#" "$1" 2>/dev/null
uci set openclash.config.config_reload=0 2>/dev/null
uci commit openclash
2020-04-23 03:09:15 +08:00
fi
done
2020-04-30 20:22:10 +08:00
fi 2>/dev/null
2020-04-23 03:09:15 +08:00
}
2020-05-26 20:20:32 +08:00
#检查集文件防止启动失败
yml_provider_check()
{
2020-06-18 12:39:01 +08:00
provider_path_line=$(sed -n '/ \{0,\}path/=' "$1" 2>/dev/null)
2020-05-26 20:20:32 +08:00
local provider_path_exist
if [ -n "$provider_path_line" ]; then
while ( [ -n "$(pidof clash)" ] && [ "$provider_path_exist" != 1 ] )
2020-04-23 03:09:15 +08:00
do
2020-05-26 20:20:32 +08:00
provider_path_exist=1
2020-06-18 12:39:01 +08:00
for n in $provider_path_line; do
if [ -n "$(sed -n "${n}p" "$1" |grep "^ \{0,\}#")" ]; then
continue
fi
provider_path=$(sed -n "${n}p" "$1" |sed "s/\'//g" |sed 's/\"//g' |awk -F 'path:' '{print $2}' 2>/dev/null |sed 's/,.*//' 2>/dev/null |sed 's/^ \{0,\}//g' 2>/dev/null |sed 's/ \{0,\}$//g' 2>/dev/null |sed 's/ \{0,\}\}\{0,\}$//g' 2>/dev/null)
if [ "$(echo "${provider_path:0:1}")" = "." ]; then
2020-05-26 20:20:32 +08:00
provider_path_check="/etc/openclash/$(echo ${provider_path:2})"
if [ -f "$provider_path_check" ] && [ "$2" = "proxy_provider" ]; then
2020-06-18 12:39:01 +08:00
if [ -z "$(grep "'proxies':" "$provider_path_check")" ] && [ -z "$(grep '"proxies":' "$provider_path_check")" ] && [ -z "$(grep 'proxies:' "$provider_path_check")" ]; then
2020-05-26 20:20:32 +08:00
provider_path_exist=0
fi
2020-05-26 20:20:32 +08:00
elif [ "$2" = "proxy_provider" ]; then
provider_path_exist=0
fi
if [ -f "$provider_path_check" ] && [ "$2" = "rule_provider" ]; then
2020-06-18 12:39:01 +08:00
if [ -z "$(grep "'payload':" "$provider_path_check")" ] && [ -z "$(grep '"payload":' "$provider_path_check")" ] && [ -z "$(grep 'payload:' "$provider_path_check")" ]; then
2020-05-26 20:20:32 +08:00
provider_path_exist=0
fi
2020-05-26 20:20:32 +08:00
elif [ "$2" = "rule_provider" ]; then
provider_path_exist=0
fi
2020-06-18 12:39:01 +08:00
elif [ "$(echo "${provider_path:0:1}")" = "/" ]; then
2020-05-26 20:20:32 +08:00
provider_path_check="$provider_path"
if [ -f "$provider_path_check" ] && [ "$2" = "proxy_provider" ]; then
2020-06-18 12:39:01 +08:00
if [ -z "$(grep "'proxies':" "$provider_path_check")" ] && [ -z "$(grep '"proxies":' "$provider_path_check")" ] && [ -z "$(grep 'proxies:' "$provider_path_check")" ]; then
2020-05-26 20:20:32 +08:00
provider_path_exist=0
fi
elif [ "$2" = "proxy_provider" ]; then
provider_path_exist=0
fi
if [ -f "$provider_path_check" ] && [ "$2" = "rule_provider" ]; then
2020-06-18 12:39:01 +08:00
if [ -z "$(grep "'payload':" "$provider_path_check")" ] && [ -z "$(grep '"payload":' "$provider_path_check")" ] && [ -z "$(grep 'payload:' "$provider_path_check")" ]; then
2020-05-26 20:20:32 +08:00
provider_path_exist=0
fi
elif [ "$2" = "rule_provider" ]; then
provider_path_exist=0
fi
fi
done
2020-04-23 03:09:15 +08:00
done
fi
2020-05-26 20:20:32 +08:00
if [ -z "$(pidof clash)" ] && [ "$provider_path_exist" = 0 ]; then
kill_clash
stop
if [ "$2" = "proxy_provider" ]; then
echo "错误: 代理集文件下载失败,请到日志页面查看详细错误信息!" >$START_LOG
echo "${LOGTIME} Faild to Download Proxy-Provider File, Please Check The Error Info And Try Again" >> $LOG_FILE
else
echo "错误: 规则集文件下载失败,请到日志页面查看详细错误信息!" >$START_LOG
echo "${LOGTIME} Faild to Download Rule-Provider File, Please Check The Error Info And Try Again" >> $LOG_FILE
fi
sleep 10
2020-05-26 20:20:32 +08:00
echo "" >$START_LOG
exit 0
fi
}
2019-07-27 18:06:42 +08:00
#切割配置文件以分开处理
2019-07-19 18:18:45 +08:00
yml_cut()
{
2019-07-27 18:06:42 +08:00
cp "$4" "$1"
2020-05-26 20:20:32 +08:00
sed -i '/^rules:/,$d' "$1" 2>/dev/null
sed -n '/^ \{0,\}nameserver:/,$p' "$1" >"$3" 2>/dev/null
if [ "$proxy_provider_mode" -eq 1 ]; then
2020-05-26 20:20:32 +08:00
sed -n '/^ \{0,\}proxy-groups:/,$p' "$3" >"$7" 2>/dev/null
sed -n '/^ \{0,\}Proxy:/,$p' "$3" >"$5" 2>/dev/null
2020-05-26 20:20:32 +08:00
sed -n '/^ \{0,\}proxy-providers:/,$p' "$3" >"$6" 2>/dev/null
sed -i '/^ \{0,\}proxy-groups:/,$d' "$5" 2>/dev/null
sed -i '/^ \{0,\}Proxy:/,$d' "$6" 2>/dev/null
2020-05-26 20:20:32 +08:00
sed -i '/^ \{0,\}proxy-groups:/,$d' "$6" 2>/dev/null
else
2020-05-26 20:20:32 +08:00
sed -n '/^ \{0,\}proxy-groups:/,$p' "$3" >"$7" 2>/dev/null
sed -n '/^ \{0,\}Proxy:/,$p' "$3" >"$5" 2>/dev/null
2020-05-26 20:20:32 +08:00
sed -i '/^ \{0,\}proxy-groups:/,$d' "$5" 2>/dev/null
fi 2>/dev/null
sed -i '/^ \{0,\}nameserver:/,$d' "$1" 2>/dev/null
if [ "$proxy_provider_mode" -eq 1 ]; then
2020-05-26 20:20:32 +08:00
sed -i '/^ \{0,\}proxy-providers:/,$d' "$3" 2>/dev/null
else
sed -i '/^ \{0,\}Proxy:/,$d' "$3" 2>/dev/null
2020-05-26 20:20:32 +08:00
fi 2>/dev/null
sed -n '/^rules:/,$p' "$4" >"$2" 2>/dev/null
2019-07-19 18:18:45 +08:00
}
2019-07-27 18:06:42 +08:00
#获取自定义DNS设置
2019-07-19 18:18:45 +08:00
yml_dns_get()
{
local section="$1"
2020-06-18 12:39:01 +08:00
local enabled port type ip group dns_type dns_address
2019-07-27 18:06:42 +08:00
config_get_bool "enabled" "$section" "enabled" "1"
2019-07-19 18:18:45 +08:00
config_get "port" "$section" "port" ""
config_get "type" "$section" "type" ""
config_get "ip" "$section" "ip" ""
config_get "group" "$section" "group" ""
2019-07-27 18:06:42 +08:00
if [ "$enabled" = "0" ]; then
return
fi
2019-07-19 18:18:45 +08:00
if [ -z "$ip" ]; then
return
fi
if [ "$type" = "tcp" ]; then
dns_type="- tcp://"
elif [ "$type" = "tls" ]; then
dns_type="- tls://"
elif [ "$type" = "udp" ]; then
dns_type="- "
2019-07-27 18:06:42 +08:00
elif [ "$type" = "https" ]; then
dns_type="- https://"
2019-07-19 18:18:45 +08:00
fi
2020-05-26 20:20:32 +08:00
if [ -n "$port" ] && [ -n "$ip" ]; then
2019-07-19 18:18:45 +08:00
dns_address="$ip:$port"
2020-05-26 20:20:32 +08:00
elif [ -z "$port" ] && [ -n "$ip" ]; then
2019-07-19 18:18:45 +08:00
dns_address="$ip"
else
return
fi
2020-05-26 20:20:32 +08:00
if [ -n "$group" ]; then
2019-07-19 18:18:45 +08:00
if [ "$group" = "nameserver" ]; then
echo " $dns_type$dns_address" >>/etc/openclash/config.namedns
else
2019-07-27 18:06:42 +08:00
if [ -z "$(grep "fallback:$" /etc/openclash/config.falldns 2>/dev/null)" ]; then
2019-07-19 18:18:45 +08:00
echo " fallback:" >/etc/openclash/config.falldns
fi
echo " $dns_type$dns_address" >>/etc/openclash/config.falldns
fi
else
return
fi
}
2019-07-27 18:06:42 +08:00
#添加自定义DNS设置
2019-07-19 18:18:45 +08:00
yml_dns_custom()
{
2019-07-27 18:06:42 +08:00
if [ "$1" = 1 ]; then
echo " nameserver:" >/etc/openclash/config.namedns
config_load "openclash"
config_foreach yml_dns_get "dns_servers"
sed -i '/^ \{0,\}nameserver:/i\##Custom DNS##' "$2" 2>/dev/null
sed -i '/OpenClash-General-Settings/i\Custom DNS End' "$2" 2>/dev/null
sed -i '/^ \{0,\}nameserver:/,/^Custom DNS End$/d' "$2" 2>/dev/null
sed -i '/##Custom DNS##/r/etc/openclash/config.falldns' "$2" 2>/dev/null
sed -i '/##Custom DNS##/r/etc/openclash/config.namedns' "$2" 2>/dev/null
rm -rf /etc/openclash/config.namedns 2>/dev/null
rm -rf /etc/openclash/config.falldns 2>/dev/null
else
sed -i "/^ \{0,\}nameserver:/c\ nameserver:" "$2" 2>/dev/null
sed -i "/^ \{0,\}fallback:/c\ fallback:" "$2" 2>/dev/null
2019-09-21 10:22:22 +08:00
fi
2019-09-30 13:29:25 +08:00
2019-09-21 10:22:22 +08:00
#fallback-filter
2020-06-18 12:39:01 +08:00
if [ -n "$(grep "^ \{0,\}fallback:" "$2")" ]; then
if [ -z "$(grep "^ \{0,\}fallback-filter:" "$2")" ]; then
2019-09-30 13:29:25 +08:00
awk '/^ {0,}fallback:/,/OpenClash-General-Settings/{print}' "$2" |sed '1d' |sed '$d' >/tmp/fallback.cache 2>/dev/null
2020-02-22 13:33:27 +08:00
sed -i '/cfw-bypass:/,$d' /tmp/fallback.cache 2>/dev/null
sed -i '/cfw-latency-timeout:/,$d' /tmp/fallback.cache 2>/dev/null
2019-09-30 13:29:25 +08:00
sed -i '/fallback:/,$d' "$2" 2>/dev/null
echo " fallback:" >>"$2"
sed -i '/ fallback:/a\ - 240.0.0.0/4' "$2" 2>/dev/null
sed -i '/ fallback:/a\ ipcidr:' "$2" 2>/dev/null
sed -i '/ fallback:/a\ geoip: true' "$2" 2>/dev/null
sed -i '/ fallback:/a\ fallback-filter:' "$2" 2>/dev/null
sed -i '/ fallback:/r/tmp/fallback.cache' "$2" 2>/dev/null
rm -rf /tmp/fallback.cache 2>/dev/null
echo "#===================== OpenClash-General-Settings =====================#" >>"$2"
2019-09-21 10:22:22 +08:00
else
2020-06-18 12:39:01 +08:00
if [ -z "$(grep "^ fallback-filter:" "$2")" ]; then
2019-09-21 10:22:22 +08:00
sed -i "/fallback-filter:/c\ fallback-filter:" "$2" 2>/dev/null
fi
2020-06-18 12:39:01 +08:00
if [ -z "$(grep "^ geoip: true" "$2")" ]; then
2019-09-21 10:22:22 +08:00
sed -i "/geoip: true/c\ geoip: true" "$2" 2>/dev/null
fi
2020-06-18 12:39:01 +08:00
if [ -z "$(grep "^ ipcidr:" "$2")" ]; then
2019-09-21 10:22:22 +08:00
sed -i "/ipcidr:/c\ ipcidr:" "$2" 2>/dev/null
fi
fi
2020-06-18 12:39:01 +08:00
if [ -z "$(grep "^ - " "$2")" ]; then
2019-09-21 10:22:22 +08:00
sed -i '/^ \{0,\}nameserver:/,/^ \{0,\}fallback-filter:/ {s/^ \{0,\}- / - /}' "$2" 2>/dev/null #修改参数空格
fi
2020-06-18 12:39:01 +08:00
if [ -z "$(grep "^ - " "$2")" ]; then
2019-09-21 10:22:22 +08:00
sed -i '/^ \{0,\}ipcidr:/,/OpenClash-General-Settings/ {s/^ \{0,\}- / - /}' "$2" 2>/dev/null #修改参数空格
fi
#删除fallback-filter
else
2020-06-18 12:39:01 +08:00
if [ -n "$(grep "^ \{0,\}fallback-filter:" "$2")" ]; then
2019-09-30 13:29:25 +08:00
sed -i '/fallback-filter:/,$d' "$2" 2>/dev/null
echo "#===================== OpenClash-General-Settings =====================#" >>"$2"
2019-09-21 10:22:22 +08:00
fi
2020-06-18 12:39:01 +08:00
if [ -n "$(grep "^ \{0,1\}- " "$2")" ]; then
#添加参数空格
sed -i "s/^ \{0,\}- / - /" "$2" 2>/dev/null
fi
2019-07-27 18:06:42 +08:00
fi
}
#获取认证信息
yml_auth_get()
{
local section="$1"
2020-06-18 12:39:01 +08:00
local enabled username password
2019-07-27 18:06:42 +08:00
config_get_bool "enabled" "$section" "enabled" "1"
config_get "username" "$section" "username" ""
config_get "password" "$section" "password" ""
if [ "$enabled" = "0" ]; then
return
fi
if [ -z "$username" ] || [ -z "$password" ]; then
return
else
echo " - $username:$password" >>/etc/openclash/config.auth
fi
}
#添加认证信息
yml_auth_custom()
{
2020-05-26 20:20:32 +08:00
if [ -n "$(grep "^authentication:" "$1")" ]; then
2019-07-27 18:06:42 +08:00
sed -i '/^dns:/i\#authentication' "$1" 2>/dev/null
sed -i '/^authentication:/,/^#authentication/d' "$1" 2>/dev/null
fi
2020-03-13 20:30:31 +08:00
if [ -f /etc/openclash/config.auth ]; then
2019-07-27 18:06:42 +08:00
sed -i '/^dns:/i\authentication:' "$1" 2>/dev/null
sed -i '/^authentication:/r/etc/openclash/config.auth' "$1" 2>/dev/null
2020-03-13 20:30:31 +08:00
mv /etc/openclash/config.auth /tmp/openclash.auth 2>/dev/null
else
rm -rf /tmp/openclash.auth 2>/dev/null
fi
2019-07-19 18:18:45 +08:00
}
2019-07-27 18:06:42 +08:00
get_rule_file()
{
if [ -z "$1" ]; then
return
fi
2020-06-18 12:39:01 +08:00
GAME_RULE_FILE_NAME=$(grep "^$1," /etc/openclash/game_rules.list |awk -F ',' '{print $3}' 2>/dev/null)
if [ -z "$GAME_RULE_FILE_NAME" ]; then
2020-06-18 12:39:01 +08:00
GAME_RULE_FILE_NAME=$(grep "^$1," /etc/openclash/game_rules.list |awk -F ',' '{print $2}' 2>/dev/null)
fi
GAME_RULE_PATH="/etc/openclash/game_rules/$GAME_RULE_FILE_NAME"
2020-06-18 12:39:01 +08:00
sed '/^#/d' "$GAME_RULE_PATH" 2>/dev/null |sed '/^ *$/d' |awk '{print "- IP-CIDR,"$0}' |awk -v tag="$2" '{print $0","'tag'""}' >> $GAME_RULE_FILE 2>/dev/null
set_rule_file=1
}
yml_game_rule_get()
{
local section="$1"
2020-06-18 12:39:01 +08:00
local enabled group config
config_get_bool "enabled" "$section" "enabled" "1"
config_get "group" "$section" "group" ""
2020-02-06 22:42:33 +08:00
config_get "config" "$section" "config" ""
if [ "$enabled" = "0" ]; then
return
fi
2020-05-26 20:20:32 +08:00
if [ -n "$config" ] && [ "$config" != "$CONFIG_NAME" ] && [ "$config" != "all" ]; then
2020-02-06 22:42:33 +08:00
return
fi
if [ -z "$group" ]; then
return
fi
config_list_foreach "$section" "rule_name" get_rule_file "$group"
}
2020-06-18 12:39:01 +08:00
yml_rule_group_get()
{
local section="$1"
2020-06-18 12:39:01 +08:00
local enabled group config
config_get_bool "enabled" "$section" "enabled" "1"
config_get "group" "$section" "group" ""
2020-02-06 22:42:33 +08:00
config_get "config" "$section" "config" ""
if [ "$enabled" = "0" ]; then
return
fi
2020-05-26 20:20:32 +08:00
if [ -n "$config" ] && [ "$config" != "$CONFIG_NAME" ] && [ "$config" != "all" ]; then
2020-02-06 22:42:33 +08:00
return
fi
if [ -z "$group" ]; then
return
fi
/usr/share/openclash/yml_groups_set.sh "$group"
}
yml_game_custom()
{
#处理游戏规则
rm -rf $GAME_RULE_FILE 2>/dev/null
config_load "openclash"
config_foreach yml_game_rule_get "game_config"
2020-05-26 20:20:32 +08:00
if [ -n "$(grep "OpenClash-Game-Rules" "$RULE_FILE")" ]; then
2020-01-21 13:57:40 +08:00
sed -i '/OpenClash-Game-Rules/,/OpenClash-Game-Rules-End/d' "$RULE_FILE" 2>/dev/null
fi
sed -i '/OpenClash-Game-Rules/d' "$RULE_FILE" 2>/dev/null
sed -i '/OpenClash-Game-Rules-End/d' "$RULE_FILE" 2>/dev/null
[ "$set_rule_file" = 1 ] && {
2020-06-18 12:39:01 +08:00
if [ -n "$(grep "##Custom Rules 2##" "$RULE_FILE")" ]; then
sed -i "/##Custom Rules 2##/i\#===================== OpenClash-Game-Rules =====================#" "$RULE_FILE" 2>/dev/null
elif [ -n "$(grep "^ \{0,\}- GEOIP" "$RULE_FILE")" ]; then
2020-01-21 13:57:40 +08:00
sed -i '1,/^ \{0,\}- GEOIP,/{/^ \{0,\}- GEOIP,/s/^ \{0,\}- GEOIP,/#===================== OpenClash-Game-Rules =====================#\n&/}' "$RULE_FILE" 2>/dev/null
2020-05-26 20:20:32 +08:00
elif [ -n "$(grep "^ \{0,\}- MATCH," "$RULE_FILE")" ]; then
2020-01-21 13:57:40 +08:00
sed -i '1,/^ \{0,\}- MATCH,/{/^ \{0,\}- MATCH,/s/^ \{0,\}- MATCH,/#===================== OpenClash-Game-Rules =====================#\n&/}' "$RULE_FILE" 2>/dev/null
2020-06-18 12:39:01 +08:00
elif [ -n "$(grep "^ \{0,\}- FINAL," "$RULE_FILE")" ]; then
sed -i '1,/^ \{0,\}- FINAL,/{/^ \{0,\}- FINAL,/s/^ \{0,\}- FINAL,/#===================== OpenClash-Game-Rules =====================#\n&/}' "$RULE_FILE" 2>/dev/null
2020-01-21 13:57:40 +08:00
else
echo "#===================== OpenClash-Game-Rules =====================#" >> "$RULE_FILE" 2>/dev/null
fi
echo "#===================== OpenClash-Game-Rules-End =====================#" >> $GAME_RULE_FILE
sed -i '/OpenClash-Game-Rules/r/tmp/yaml_game_rule_group.yaml' "$RULE_FILE" 2>/dev/null
}
#合并文件
2020-05-26 20:20:32 +08:00
cat "$CHANGE_FILE" "$DNS_FILE" "$PROXY_PROVIDER_FILE" "$PROXY_FILE" "$GROUP_FILE" "$RULE_PROVIDER_FILE" "$SCRIPT_FILE" "$RULE_FILE" > "$CONFIG_FILE" 2>/dev/null
#处理游戏节点与策略组
config_load "openclash"
2020-06-18 12:39:01 +08:00
config_foreach yml_rule_group_get "rule_provider_config"
config_foreach yml_rule_group_get "game_config"
2020-05-26 20:20:32 +08:00
sed -i '/^ \{0,\}proxy-groups:/r/tmp/yaml_groups.yaml' "$CONFIG_FILE" 2>/dev/null
sed -i '/^ \{0,\}Proxy:/d' /tmp/yaml_servers.yaml 2>/dev/null
2020-05-26 20:20:32 +08:00
sed -i '/^ \{0,\}proxy-providers:/d' /tmp/yaml_provider.yaml 2>/dev/null
2020-02-10 14:07:24 +08:00
if [ -z "$(grep "^ \{0,\}Proxy:" "$CONFIG_FILE" 2>/dev/null)" ] && [ -f "/tmp/yaml_servers.yaml" ]; then
2020-05-26 20:20:32 +08:00
sed -i '/^ \{0,\}proxy-groups:/i\Proxy:' "$CONFIG_FILE" 2>/dev/null
sed -i '/^ \{0,\}Proxy:/r/tmp/yaml_servers.yaml' "$CONFIG_FILE" 2>/dev/null
elif [ -f "/tmp/yaml_servers.yaml" ]; then
sed -i '/^ \{0,\}Proxy:/r/tmp/yaml_servers.yaml' "$CONFIG_FILE" 2>/dev/null
fi
2020-05-26 20:20:32 +08:00
if [ -z "$(grep "^ \{0,\}proxy-providers:" "$CONFIG_FILE" 2>/dev/null)" ] && [ -f "/tmp/yaml_provider.yaml" ]; then
sed -i '/OpenClash-General-Settings/a\proxy-providers:' "$CONFIG_FILE" 2>/dev/null
sed -i '/^ \{0,\}proxy-providers:/r/tmp/yaml_provider.yaml' "$CONFIG_FILE" 2>/dev/null
elif [ -f "/tmp/yaml_servers.yaml" ]; then
2020-05-26 20:20:32 +08:00
sed -i '/^ \{0,\}proxy-providers:r/tmp/yaml_provider.yaml' "$CONFIG_FILE" 2>/dev/null
fi
}
2020-06-18 12:39:01 +08:00
yml_rule_set_add()
{
if [ -z "$(grep "rules:" "$RULE_FILE" 2>/dev/null)" ]; then
echo "rules:" > "$RULE_FILE"
fi
if [ "$3" -eq 1 ]; then
if [ -z "$(grep "OpenClash-Rule-Set-Extended-End" "$RULE_FILE" 2>/dev/null)" ]; then
if [ -n "$(grep "##Custom Rules 2##" "$RULE_FILE")" ]; then
sed -i "/##Custom Rules 2##/i\#===================== OpenClash-Rule-Set-Extended-End =====================#" "$RULE_FILE" 2>/dev/null
sed -i "/OpenClash-Rule-Set-Extended-End/i\#===================== OpenClash-Rule-Set-Extended =====================#" "$RULE_FILE" 2>/dev/null
elif [ -n "$(grep "^ \{0,\}- GEOIP" "$RULE_FILE")" ]; then
sed -i '1,/^ \{0,\}- GEOIP,/{/^ \{0,\}- GEOIP,/s/^ \{0,\}- GEOIP,/#===================== OpenClash-Rule-Set-Extended-End =====================#\n&/}' "$RULE_FILE" 2>/dev/null
sed -i "/OpenClash-Rule-Set-Extended-End/i\#===================== OpenClash-Rule-Set-Extended =====================#" "$RULE_FILE" 2>/dev/null
elif [ -n "$(grep "^ \{0,\}- MATCH," "$RULE_FILE")" ]; then
sed -i '1,/^ \{0,\}- MATCH,/{/^ \{0,\}- MATCH,/s/^ \{0,\}- MATCH,/#===================== OpenClash-Rule-Set-Extended-End =====================#\n&/}' "$RULE_FILE" 2>/dev/null
sed -i "/OpenClash-Rule-Set-Extended-End/i\#===================== OpenClash-Rule-Set-Extended =====================#" "$RULE_FILE" 2>/dev/null
elif [ -n "$(grep "^ \{0,\}- FINAL," "$RULE_FILE")" ]; then
sed -i '1,/^ \{0,\}- FINAL,/{/^ \{0,\}- FINAL,/s/^ \{0,\}- FINAL,/#===================== OpenClash-Rule-Set-Extended-End =====================#\n&/}' "$RULE_FILE" 2>/dev/null
sed -i "/OpenClash-Rule-Set-Extended-End/i\#===================== OpenClash-Rule-Set-Extended =====================#" "$RULE_FILE" 2>/dev/null
else
echo "#===================== OpenClash-Rule-Set-Extended =====================#" >> "$RULE_FILE" 2>/dev/null
echo "#===================== OpenClash-Rule-Set-Extended-End =====================#" >> "$RULE_FILE" 2>/dev/null
fi
fi
sed -i "/OpenClash-Rule-Set-Extended-End/i\- RULE-SET,${1},${2}" "$RULE_FILE" 2>/dev/null
elif [ "$3" -eq 0 ]; then
if [ -z "$(grep "OpenClash-Rule-Set-Priority-End" "$RULE_FILE" 2>/dev/null)" ]; then
if [ -n "$(grep "##Custom Rules##" "$RULE_FILE" 2>/dev/null)" ]; then
sed -i "/##Custom Rules End##/a\#===================== OpenClash-Rule-Set-Priority-End =====================#" "$RULE_FILE" 2>/dev/null
sed -i "/##Custom Rules End##/a\#===================== OpenClash-Rule-Set-Priority =====================#" "$RULE_FILE" 2>/dev/null
else
sed -i "/^rules:/a\#===================== OpenClash-Rule-Set-Priority-End =====================#" "$RULE_FILE" 2>/dev/null
sed -i "/^rules:/a\#===================== OpenClash-Rule-Set-Priority =====================#" "$RULE_FILE" 2>/dev/null
fi
fi
sed -i "/OpenClash-Rule-Set-Priority-End/i\- RULE-SET,${1},${2}" "$RULE_FILE" 2>/dev/null
fi
}
yml_gen_rule_provider_file()
{
if [ -z "$1" ]; then
return
fi
RULE_PROVIDER_FILE_NAME=$(grep "^$1," /etc/openclash/rule_providers.list |awk -F ',' '{print $6}' 2>/dev/null)
if [ -z "$RULE_PROVIDER_FILE_NAME" ]; then
RULE_PROVIDER_FILE_NAME=$(grep "^$1," /etc/openclash/rule_providers.list |awk -F ',' '{print $5}' 2>/dev/null)
fi
RULE_PROVIDER_FILE_BEHAVIOR=$(grep -F "$RULE_PROVIDER_FILE_NAME" /etc/openclash/rule_providers.list |awk -F ',' '{print $3}' 2>/dev/null)
RULE_PROVIDER_FILE_PATH="/etc/openclash/rule_provider/$RULE_PROVIDER_FILE_NAME"
RULE_PROVIDER_FILE_URL="https://raw.githubusercontent.com/$(grep -F "$RULE_PROVIDER_FILE_NAME" /etc/openclash/rule_providers.list |awk -F ',' '{print $4$5}' 2>/dev/null)"
if [ -n "$(grep "$RULE_PROVIDER_FILE_URL" $RULE_PROVIDER_FILE)" ]; then
return
fi
if [ -z "$(grep "rule-providers:" $RULE_PROVIDER_FILE 2>/dev/null)" ]; then
echo "rule-providers:" > "$RULE_PROVIDER_FILE"
fi
if [ -z "$(grep "OpenClash-Rule-Providers-Set" $RULE_PROVIDER_FILE 2>/dev/null)" ]; then
echo "#===================== OpenClash-Rule-Providers-Set =====================#" >> "$RULE_PROVIDER_FILE"
fi
cat >> "$RULE_PROVIDER_FILE" <<-EOF
$1:
type: http
behavior: $RULE_PROVIDER_FILE_BEHAVIOR
path: $RULE_PROVIDER_FILE_PATH
url: $RULE_PROVIDER_FILE_URL
EOF
if [ -z "$3" ]; then
cat >> "$RULE_PROVIDER_FILE" <<-EOF
interval=86400
EOF
else
cat >> "$RULE_PROVIDER_FILE" <<-EOF
interval: $3
EOF
fi
yml_rule_set_add "$1" "$2" "$4"
}
yml_get_rule_provider()
{
local section="$1"
local enabled group config interval position
config_get_bool "enabled" "$section" "enabled" "1"
config_get "group" "$section" "group" ""
config_get "config" "$section" "config" ""
config_get "interval" "$section" "interval" ""
config_get "position" "$section" "position" ""
if [ "$enabled" = "0" ]; then
return
fi
if [ -n "$config" ] && [ "$config" != "$CONFIG_NAME" ] && [ "$config" != "all" ]; then
return
fi
if [ -z "$group" ]; then
return
fi
config_list_foreach "$section" "rule_name" yml_gen_rule_provider_file "$group" "$interval" "$position"
}
#处理自定义规则集
yml_set_custom_rule_provider()
{
local section="$1"
local enabled name config type behavior path url interval group position
config_get_bool "enabled" "$section" "enabled" "1"
config_get "name" "$section" "name" ""
config_get "config" "$section" "config" ""
config_get "type" "$section" "type" ""
config_get "behavior" "$section" "behavior" ""
config_get "path" "$section" "path" ""
config_get "url" "$section" "url" ""
config_get "interval" "$section" "interval" ""
config_get "group" "$section" "group" ""
config_get "position" "$section" "position" ""
if [ "$enabled" = "0" ]; then
return
fi
if [ -n "$(grep "$url" "$RULE_PROVIDER_FILE")" ] && [ -n "$url" ]; then
return
fi
if [ -n "$config" ] && [ "$config" != "$CONFIG_NAME" ] && [ "$config" != "all" ]; then
return
fi
if [ -z "$name" ] || [ -z "$type" ] || [ -z "$behavior" ]; then
return
fi
if [ "$type" = "http" ] && [ -z "$url" ]; then
return
fi
if [ "$path" != "./rule_provider/$name.yaml" ] && [ "$type" = "http" ]; then
path="./rule_provider/$name.yaml"
elif [ -z "$path" ]; then
return
fi
if [ -n "$(grep "$path" "$RULE_PROVIDER_FILE")" ]; then
return
fi
if [ -z "$interval" ] && [ "$type" = "http" ]; then
interval=86400
fi
if [ -z "$(grep "rule-providers:" "$RULE_PROVIDER_FILE" 2>/dev/null)" ]; then
echo "rule-providers:" > "$RULE_PROVIDER_FILE"
fi
if [ -z "$(grep "OpenClash-Rule-Providers-Set" "$RULE_PROVIDER_FILE" 2>/dev/null)" ]; then
echo "#===================== OpenClash-Rule-Providers-Set =====================#" >> "$RULE_PROVIDER_FILE"
fi
cat >> "$RULE_PROVIDER_FILE" <<-EOF
$name:
type: $type
behavior: $behavior
path: $path
EOF
if [ "$type" = "http" ]; then
cat >> "$RULE_PROVIDER_FILE" <<-EOF
url: $url
interval: $interval
EOF
fi
yml_rule_set_add "$name" "$group" "$position"
}
#处理规则集
yml_custom_rule_provider()
{
if [ -n "$(grep "OpenClash-Rule-Set-Extended-End" "$RULE_FILE")" ]; then
sed -i '/OpenClash-Rule-Set-Extended/,/OpenClash-Rule-Set-Extended-End/d' "$RULE_FILE" 2>/dev/null
fi
if [ -n "$(grep "OpenClash-Rule-Set-Priority-End" "$RULE_FILE")" ]; then
sed -i '/OpenClash-Rule-Set-Priority/,/OpenClash-Rule-Set-Priority-End/d' "$RULE_FILE" 2>/dev/null
fi
if [ -n "$(grep "OpenClash-Rule-Providers-Set" "$RULE_PROVIDER_FILE")" ]; then
sed -i '/OpenClash-Rule-Providers-Set/,/OpenClash-Rule-Providers-Set-End/d' "$RULE_PROVIDER_FILE" 2>/dev/null
fi
sed -i '/OpenClash-Rule-Set/d' "$RULE_FILE" 2>/dev/null
sed -i '/OpenClash-Rule-Providers/d' "$RULE_PROVIDER_FILE" 2>/dev/null
if [ -z "$(grep "^ type:" $RULE_PROVIDER_FILE 2>/dev/null)" ]; then
#处理缩进
sed -i '/^ *$/d' "$RULE_PROVIDER_FILE" 2>/dev/null
sed -i 's/\t/ /g' "$RULE_PROVIDER_FILE" 2>/dev/null
sed -i 's/^ \{1,\}/ /g' "$RULE_PROVIDER_FILE" 2>/dev/null
sed -i 's/^ \{1,\}type:/ type:/g' "$RULE_PROVIDER_FILE" 2>/dev/null
sed -i 's/^ \{1,\}behavior:/ behavior:/g' "$RULE_PROVIDER_FILE" 2>/dev/null
sed -i 's/^ \{1,\}path:/ path:/g' "$RULE_PROVIDER_FILE" 2>/dev/null
sed -i 's/^ \{1,\}url:/ url:/g' "$RULE_PROVIDER_FILE" 2>/dev/null
sed -i 's/^ \{1,\}interval:/ interval:/g' "$RULE_PROVIDER_FILE" 2>/dev/null
sed -i 's/^ \{1,\}rule-providers:/rule-providers:/g' "$RULE_PROVIDER_FILE" 2>/dev/null
fi
config_load "openclash"
config_foreach yml_get_rule_provider "rule_provider_config"
config_foreach yml_set_custom_rule_provider "rule_providers"
if [ -n "$(grep "OpenClash-Rule-Providers-Set" $RULE_PROVIDER_FILE 2>/dev/null)" ]; then
echo "#===================== OpenClash-Rule-Providers-Set-End =====================#" >> "$RULE_PROVIDER_FILE"
fi
}
2020-03-13 20:30:31 +08:00
lan_ac()
{
2020-04-30 20:22:10 +08:00
if [ -z "$1" ]; then
2020-03-13 20:30:31 +08:00
return
2020-04-30 20:22:10 +08:00
fi
2020-03-13 20:30:31 +08:00
2020-04-30 20:22:10 +08:00
ipset add "$2" "$1" 2>/dev/null
2020-03-13 20:30:31 +08:00
}
2020-07-16 21:07:14 +08:00
firewall_redirect_exclude()
{
local section="$1"
local src_dport
config_get "src_dport" "$section" "src_dport" ""
if [ -z "$src_dport" ]; then
return
fi
if [ -z "$en_mode_tun" ]; then
iptables -t mangle -A openclash -p udp --dport "$src_dport" -j RETURN >/dev/null 2>&1
else
iptables -t mangle -A openclash -p tcp --dport "$src_dport" -j RETURN >/dev/null 2>&1
iptables -t mangle -A openclash -p udp --dport "$src_dport" -j RETURN >/dev/null 2>&1
fi
}
2020-04-14 21:03:36 +08:00
#配置文件选择
config_choose()
2019-07-19 18:18:45 +08:00
{
2020-02-20 02:53:49 +08:00
if [ -z "$CONFIG_FILE" ] || [ ! -f "$CONFIG_FILE" ]; then
CONFIG_NAME=$(ls -lt /etc/openclash/config/ | grep -E '.yaml|.yml' | head -n 1 |awk '{print $9}')
2020-05-26 20:20:32 +08:00
if [ -n "$CONFIG_NAME" ]; then
uci set openclash.config.config_path="/etc/openclash/config/$CONFIG_NAME"
uci commit openclash
CONFIG_FILE="/etc/openclash/config/$CONFIG_NAME"
elif [ -f "/etc/openclash/config.yaml" ]; then
mv "/etc/openclash/config.yaml" "/etc/openclash/config/config.yaml"
uci set openclash.config.config_path="/etc/openclash/config/config.yaml"
uci commit openclash
CONFIG_FILE="/etc/openclash/config/config.yaml"
elif [ -f "/etc/openclash/config.yml" ]; then
mv "/etc/openclash/config.yml" "/etc/openclash/config/config.yaml"
uci set openclash.config.config_path="/etc/openclash/config/config.yaml"
uci commit openclash
CONFIG_FILE="/etc/openclash/config/config.yaml"
fi
else
if [ ! -f "$CONFIG_FILE" ] && [ -f "$BACKUP_FILE" ]; then
2020-04-14 21:03:36 +08:00
cp "$BACKUP_FILE" "$CONFIG_FILE"
fi
2020-04-30 20:22:10 +08:00
fi 2>/dev/null
2020-02-10 14:07:24 +08:00
CONFIG_NAME=$(echo "$CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null)
2019-07-27 18:06:42 +08:00
}
2020-04-14 21:03:36 +08:00
#运行模式处理
do_run_mode()
{
2020-06-18 12:39:01 +08:00
en_mode=$(uci get openclash.config.en_mode 2>/dev/null)
if [ "$en_mode" = "fake-ip-tun" ]; then
en_mode_tun="1"
en_mode="fake-ip"
fi
if [ "$en_mode" = "redir-host-tun" ]; then
en_mode_tun="1"
en_mode="redir-host"
fi
if [ "$en_mode" = "redir-host-vpn" ]; then
en_mode_tun="2"
en_mode="redir-host"
fi
2020-04-14 21:03:36 +08:00
2020-06-18 12:39:01 +08:00
if [ "$en_mode" = "fake-ip-vpn" ]; then
en_mode_tun="2"
en_mode="fake-ip"
fi
}
do_run_core()
{
2020-04-14 21:03:36 +08:00
if [ ! -h "/etc/openclash/clash" ] && [ -s "/etc/openclash/clash" ] && [ ! -s "/etc/openclash/core/clash" ]; then
mv "/etc/openclash/clash" "/etc/openclash/core/clash" 2>/dev/null
fi
rm -rf "/etc/openclash/clash" 2>/dev/null
2020-06-18 12:39:01 +08:00
if [ "$en_mode_tun" = "1" ]; then
2020-04-14 21:03:36 +08:00
ln -s /etc/openclash/core/clash_tun /etc/openclash/clash 2>/dev/null
core_type="Tun"
fi
2020-04-14 21:03:36 +08:00
2020-06-18 12:39:01 +08:00
if [ "$en_mode_tun" = "1" ]; then
2020-04-14 21:03:36 +08:00
ln -s /etc/openclash/core/clash_tun /etc/openclash/clash 2>/dev/null
core_type="Tun"
fi
2020-04-14 21:03:36 +08:00
2020-06-18 12:39:01 +08:00
if [ "$en_mode_tun" = "2" ]; then
2020-04-14 21:03:36 +08:00
ln -s /etc/openclash/core/clash_game /etc/openclash/clash 2>/dev/null
core_type="Game"
fi
2020-04-14 21:03:36 +08:00
2020-06-18 12:39:01 +08:00
if [ "$en_mode_tun" = "2" ]; then
2020-04-14 21:03:36 +08:00
ln -s /etc/openclash/core/clash_game /etc/openclash/clash 2>/dev/null
core_type="Game"
fi
2020-07-16 21:07:14 +08:00
if [ "$proxy_mode" = "Script" ] || [ "$rule_source" = "ConnersHua" ]; then
2020-07-05 20:02:59 +08:00
ln -s /etc/openclash/core/clash_tun /etc/openclash/clash 2>/dev/null
core_type="Tun"
fi
if [ -n "$(grep "^ \{0,\}rule-providers:" "$RULE_PROVIDER_FILE" 2>/dev/null)" ] && [ -n "$(grep "^ \{0,\}behavior" "$RULE_PROVIDER_FILE" 2>/dev/null |grep -v "^ \{0,\}#")" ]; then
2020-05-26 20:20:32 +08:00
ln -s /etc/openclash/core/clash_tun /etc/openclash/clash 2>/dev/null
core_type="Tun"
fi
2020-06-18 12:39:01 +08:00
if [ ! -f "/etc/openclash/clash" ] && [ -f "/etc/openclash/core/clash" ] && [ -z "$core_type" ]; then
2020-07-05 20:02:59 +08:00
ln -s /etc/openclash/core/clash /etc/openclash/clash 2>/dev/null
fi
2020-04-14 21:03:36 +08:00
#权限检查
[ ! -x "/etc/openclash/core/clash_tun" ] && chmod 4755 /etc/openclash/core/clash_tun 2>/dev/null
[ ! -x "/etc/openclash/core/clash_game" ] && chmod 4755 /etc/openclash/core/clash_game 2>/dev/null
[ ! -x "/etc/openclash/core/clash" ] && chmod 4755 /etc/openclash/core/clash 2>/dev/null
}
2020-04-30 20:22:10 +08:00
set_firewall()
{
if [ "$(iptables -t nat -nL PREROUTING --line-number |grep "udp dpt:53" |grep "0.0.0.0/0 \{0,\}0.0.0.0/0" |wc -l)" -gt 1 ] && [ "$enable_redirect_dns" -eq "1" ]; then
echo "发现53端口被劫持清理防火墙规则..." >$START_LOG
pre_lines=$(iptables -nvL PREROUTING -t nat |sed 1,2d |sed -n '/0.0.0.0\/0 \{0,\}0.0.0.0\/0 \{0,\}udp dpt:53/=' 2>/dev/null |sort -rn)
for pre_line in $pre_lines; do
iptables -t nat -D PREROUTING "$pre_line" >/dev/null 2>&1
done
iptables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 53 >/dev/null 2>&1
sleep 2
fi
2020-06-18 12:39:01 +08:00
2020-04-30 20:22:10 +08:00
if [ -z "$(uci get firewall.openclash 2>/dev/null)" ] || [ -z "$(uci get ucitrack.@openclash[-1].init 2>/dev/null)" ]; then
uci delete ucitrack.@openclash[-1] >/dev/null 2>&1
uci add ucitrack openclash >/dev/null 2>&1
uci set ucitrack.@openclash[-1].init=openclash >/dev/null 2>&1
uci commit ucitrack >/dev/null 2>&1
uci delete firewall.openclash >/dev/null 2>&1
uci set firewall.openclash=include >/dev/null 2>&1
uci set firewall.openclash.type=script >/dev/null 2>&1
uci set firewall.openclash.path=/var/etc/openclash.include >/dev/null 2>&1
uci set firewall.openclash.reload=1 >/dev/null 2>&1
fi
if [ "$(uci get firewall.@defaults[0].forward)" != "ACCEPT" ]; then
uci set firewall.@defaults[0].forward=ACCEPT >/dev/null 2>&1
uci commit firewall >/dev/null 2>&1
/etc/init.d/firewall reload >/dev/null 2>&1
fi
mkdir -p /var/etc
cat > "/var/etc/openclash.include" <<-EOF
/etc/init.d/openclash reload >/dev/null 2>&1
EOF
#lan_ac
if [ "$operation_mode" = "redir-host" ] && [ "$en_mode" = "redir-host" ]; then
2020-05-26 20:20:32 +08:00
if [ "$lan_ac_mode" = "0" ] && [ -n "$(uci get openclash.config.lan_ac_black_ips 2>/dev/null)" ]; then
2020-04-30 20:22:10 +08:00
ipset create lan_ac_black_ips hash:net
config_load "openclash"
config_list_foreach "config" "lan_ac_black_ips" lan_ac "lan_ac_black_ips"
2020-05-26 20:20:32 +08:00
elif [ "$lan_ac_mode" = "1" ] && [ -n "$(uci get openclash.config.lan_ac_white_ips 2>/dev/null)" ]; then
2020-04-30 20:22:10 +08:00
ipset create lan_ac_white_ips hash:net
config_load "openclash"
config_list_foreach "config" "lan_ac_white_ips" lan_ac "lan_ac_white_ips"
fi
fi
2020-05-10 11:26:20 +08:00
#local
ipset create localnetwork hash:net
ipset add localnetwork 0.0.0.0/8
ipset add localnetwork 127.0.0.0/8
ipset add localnetwork 10.0.0.0/8
ipset add localnetwork 169.254.0.0/16
ipset add localnetwork 192.168.0.0/16
ipset add localnetwork 224.0.0.0/4
ipset add localnetwork 240.0.0.0/4
ipset add localnetwork 172.16.0.0/12
2020-05-26 20:20:32 +08:00
if [ -n "$wan_ip4" ]; then
2020-05-10 11:26:20 +08:00
for wan_ip4s in $wan_ip4; do
ipset add localnetwork "$wan_ip4s" 2>/dev/null
done
fi
2020-04-30 20:22:10 +08:00
if [ -z "$en_mode_tun" ]; then
#tcp
iptables -t nat -N openclash
2020-05-10 11:26:20 +08:00
iptables -t nat -F openclash
iptables -t nat -A openclash -m set --match-set localnetwork dst -j RETURN
2020-04-30 20:22:10 +08:00
iptables -t nat -A openclash -m set --match-set lan_ac_black_ips src -j RETURN >/dev/null 2>&1
iptables -t nat -A openclash -m set ! --match-set lan_ac_white_ips src -j RETURN >/dev/null 2>&1
iptables -t nat -A openclash -p tcp -j REDIRECT --to-ports "$proxy_port"
2020-05-10 11:26:20 +08:00
iptables -t nat -I PREROUTING -p tcp -d 8.8.8.8 -j REDIRECT --to-ports "$proxy_port"
iptables -t nat -I PREROUTING -p tcp -d 8.8.4.4 -j REDIRECT --to-ports "$proxy_port"
2020-04-30 20:22:10 +08:00
iptables -t nat -A PREROUTING -p tcp -j openclash
2020-05-10 11:26:20 +08:00
2020-04-30 20:22:10 +08:00
#udp
if [ "$enable_udp_proxy" -eq 1 ]; then
2020-05-02 16:38:01 +08:00
ip rule add fwmark "$PROXY_FWMARK" table "$PROXY_ROUTE_TABLE"
ip route add local 0.0.0.0/0 dev lo table "$PROXY_ROUTE_TABLE"
2020-04-30 20:22:10 +08:00
iptables -t mangle -N openclash
2020-05-10 11:26:20 +08:00
iptables -t mangle -A openclash -m set --match-set localnetwork dst -j RETURN
2020-04-30 20:22:10 +08:00
iptables -t mangle -A openclash -m set --match-set lan_ac_black_ips src -j RETURN >/dev/null 2>&1
iptables -t mangle -A openclash -m set ! --match-set lan_ac_white_ips src -j RETURN >/dev/null 2>&1
2020-07-16 21:07:14 +08:00
iptables -t mangle -A openclash -p udp --dport 53 -j RETURN >/dev/null 2>&1
#端口转发
config_load "firewall"
config_foreach firewall_redirect_exclude "redirect"
2020-05-02 16:38:01 +08:00
iptables -t mangle -A openclash -p udp -j TPROXY --on-port "$proxy_port" --on-ip 0.0.0.0 --tproxy-mark "$PROXY_FWMARK"
2020-04-30 20:22:10 +08:00
iptables -t mangle -A PREROUTING -p udp -j openclash
fi
2020-05-10 11:26:20 +08:00
2020-04-30 20:22:10 +08:00
if [ "$en_mode" = "fake-ip" ]; then
2020-05-10 11:26:20 +08:00
iptables -t nat -N openclash_output
iptables -t nat -F openclash_output
iptables -t nat -A openclash_output -m set --match-set localnetwork dst -j RETURN
iptables -t nat -A openclash_output -p tcp -d 198.18.0.0/16 -j REDIRECT --to-ports "$proxy_port"
iptables -t nat -A OUTPUT -p tcp -j openclash_output
2020-04-30 20:22:10 +08:00
fi
2020-05-10 11:26:20 +08:00
2020-04-30 20:22:10 +08:00
if [ "$ipv6_enable" -eq 1 ]; then
#tcp
ip6tables -t nat -N openclash
2020-05-26 20:20:32 +08:00
if [ -n "$lan_ip6" ]; then
2020-04-30 20:22:10 +08:00
for lan_ip6s in $lan_ip6; do
ip6tables -t nat -A openclash -d "$lan_ip6s" -j RETURN 2>/dev/null
done
fi
ip6tables -t nat -A openclash -p tcp -j REDIRECT --to-ports "$proxy_port"
ip6tables -t nat -A PREROUTING -p tcp -j openclash
2020-05-10 11:26:20 +08:00
2020-04-30 20:22:10 +08:00
#udp
2020-05-10 11:26:20 +08:00
#if [ "$enable_udp_proxy" -eq 1 ]; then
# ip6tables -t mangle -N openclash
2020-05-26 20:20:32 +08:00
# if [ -n "$lan_ip6" ]; then
2020-05-10 11:26:20 +08:00
# for lan_ip6s in $lan_ip6; do
# if [ "$enable_udp_proxy" -eq 1 ]; then
# ip6tables -t mangle -A openclash -d "$lan_ip6s" -j RETURN 2>/dev/null
# fi
# done
# fi
# ip6tables -t mangle -A openclash -p udp -j TPROXY --on-port "$proxy_port" --tproxy-mark "$PROXY_FWMARK"
# ip6tables -t mangle -A PREROUTING -p udp -j openclash
#fi
2020-05-26 20:20:32 +08:00
fi 2>/dev/null
2020-04-30 20:22:10 +08:00
else
#TUN模式
#启动TUN
if [ "$en_mode_tun" = "2" ]; then
ip tuntap add user root mode tun clash0
ip link set clash0 up
ip route replace default dev clash0 table "$PROXY_ROUTE_TABLE"
elif [ "$en_mode_tun" = "1" ]; then
TUN_WAIT=0
2020-05-26 20:20:32 +08:00
while ( [ -n "$(pidof clash)" ] && [ -z "$(ip route list |grep utun)" ] && [ "$TUN_WAIT" -le 3 ] )
2020-04-30 20:22:10 +08:00
do
TUN_WAIT=$(expr "$TUN_WAIT" + 1)
sleep 2
done
ip route replace default dev utun table "$PROXY_ROUTE_TABLE"
fi
2020-05-02 16:38:01 +08:00
ip rule add fwmark "$PROXY_FWMARK" table "$PROXY_ROUTE_TABLE"
2020-04-30 20:22:10 +08:00
#设置防火墙
2020-07-16 21:07:14 +08:00
iptables -t mangle -N openclash_output
iptables -t mangle -F openclash_output
iptables -t mangle -A openclash_output -m set --match-set localnetwork dst -j RETURN
2020-04-30 20:22:10 +08:00
if [ "$en_mode" = "fake-ip" ]; then
2020-07-16 21:07:14 +08:00
iptables -t mangle -A openclash_output -d 198.18.0.0/16 -j MARK --set-mark "$PROXY_FWMARK"
2020-04-30 20:22:10 +08:00
fi
2020-07-16 21:07:14 +08:00
iptables -t mangle -I OUTPUT -j openclash_output
iptables -t mangle -N openclash
iptables -t mangle -F openclash
#端口转发
config_load "firewall"
config_foreach firewall_redirect_exclude "redirect"
#其他流量
iptables -t mangle -A openclash -m set --match-set lan_ac_black_ips src -j RETURN >/dev/null 2>&1
iptables -t mangle -A openclash -m set ! --match-set lan_ac_white_ips src -j RETURN >/dev/null 2>&1
iptables -t mangle -A openclash -m set ! --match-set localnetwork dst -j MARK --set-mark "$PROXY_FWMARK"
iptables -t mangle -I PREROUTING -j openclash
2020-04-30 20:22:10 +08:00
iptables -t nat -I PREROUTING -p tcp --dport 53 -j ACCEPT
2020-07-16 21:07:14 +08:00
2020-04-30 20:22:10 +08:00
#ipv6
# if [ "$ipv6_enable" -eq 1 ]; then
# ip6tables -t mangle -I PREROUTING -j MARK --set-mark "$PROXY_FWMARK"
# fi
fi
}
revert_firewall()
{
rm -rf /var/etc/openclash.include 2>/dev/null
2020-05-10 11:26:20 +08:00
2020-04-30 20:22:10 +08:00
#ipv4
2020-05-02 16:38:01 +08:00
ip rule del fwmark "$PROXY_FWMARK" table "$PROXY_ROUTE_TABLE" >/dev/null 2>&1
ip route del local 0.0.0.0/0 dev lo table "$PROXY_ROUTE_TABLE" >/dev/null 2>&1
2020-05-10 11:26:20 +08:00
2020-04-30 20:22:10 +08:00
iptables -t nat -D PREROUTING -p tcp --dport 53 -j ACCEPT >/dev/null 2>&1
2020-05-10 11:26:20 +08:00
out_lines=$(iptables -nvL OUTPUT -t nat |sed 1,2d |sed -n '/openclash/=' 2>/dev/null |sort -rn)
2020-04-30 20:22:10 +08:00
for out_line in $out_lines; do
iptables -t nat -D OUTPUT "$out_line" >/dev/null 2>&1
2020-07-18 22:04:13 +08:00
done >/dev/null 2>&1
2020-06-18 12:39:01 +08:00
iptables -t nat -D OUTPUT -p tcp -j openclash_output >/dev/null 2>&1
2020-05-10 11:26:20 +08:00
pre_lines=$(iptables -nvL PREROUTING -t nat |sed 1,2d |sed -n '/8\.8\./=' 2>/dev/null |sort -rn)
for pre_line in $pre_lines; do
iptables -t nat -D PREROUTING "$pre_line" >/dev/null 2>&1
2020-07-18 22:04:13 +08:00
done >/dev/null 2>&1
2020-05-10 11:26:20 +08:00
pre_lines=$(iptables -nvL PREROUTING -t mangle |sed 1,2d |sed -n '/openclash/=' 2>/dev/null |sort -rn)
for pre_line in $pre_lines; do
iptables -t mangle -D PREROUTING "$pre_line" >/dev/null 2>&1
2020-07-18 22:04:13 +08:00
done >/dev/null 2>&1
2020-06-18 12:39:01 +08:00
iptables -t mangle -D PREROUTING -p udp -j openclash >/dev/null 2>&1
2020-05-10 11:26:20 +08:00
pre_lines=$(iptables -nvL PREROUTING -t nat |sed 1,2d |sed -n '/openclash/=' 2>/dev/null |sort -rn)
for pre_line in $pre_lines; do
iptables -t nat -D PREROUTING "$pre_line" >/dev/null 2>&1
2020-07-18 22:04:13 +08:00
done >/dev/null 2>&1
2020-06-18 12:39:01 +08:00
iptables -t nat -D PREROUTING -p tcp -j openclash >/dev/null 2>&1
2020-05-10 11:26:20 +08:00
2020-04-30 20:22:10 +08:00
#ipv6
2020-05-10 11:26:20 +08:00
#ip6tables -t mangle -F openclash >/dev/null 2>&1
#ip6tables -t mangle -D PREROUTING -p udp -j openclash >/dev/null 2>&1
#ip6tables -t mangle -X openclash >/dev/null 2>&1
2020-05-26 20:20:32 +08:00
iptables -t nat -F openclash >/dev/null 2>&1
iptables -t nat -X openclash >/dev/null 2>&1
iptables -t nat -F openclash_output >/dev/null 2>&1
iptables -t nat -X openclash_output >/dev/null 2>&1
2020-04-30 20:22:10 +08:00
ip6tables -t nat -F openclash >/dev/null 2>&1
ip6tables -t nat -D PREROUTING -p tcp -j openclash >/dev/null 2>&1
ip6tables -t nat -X openclash >/dev/null 2>&1
2020-05-10 11:26:20 +08:00
2020-04-30 20:22:10 +08:00
#TUN
ip route del default dev clash0 table "$PROXY_ROUTE_TABLE" >/dev/null 2>&1
ip route del default dev utun table "$PROXY_ROUTE_TABLE" >/dev/null 2>&1
2020-05-02 16:38:01 +08:00
ip rule del fwmark "$PROXY_FWMARK" table "$PROXY_ROUTE_TABLE" >/dev/null 2>&1
2020-04-30 20:22:10 +08:00
ip link set dev clash0 down >/dev/null 2>&1
ip tuntap del clash0 mode tun >/dev/null 2>&1
2020-05-10 11:26:20 +08:00
2020-07-16 21:07:14 +08:00
iptables -t mangle -D OUTPUT -j openclash_output >/dev/null 2>&1
2020-07-18 22:04:13 +08:00
iptables -t mangle -D PREROUTING -j openclash >/dev/null 2>&1
2020-04-30 20:22:10 +08:00
iptables -t mangle -F openclash >/dev/null 2>&1
iptables -t mangle -X openclash >/dev/null 2>&1
2020-07-16 21:07:14 +08:00
iptables -t mangle -F openclash_output >/dev/null 2>&1
iptables -t mangle -X openclash_output >/dev/null 2>&1
2020-05-26 20:20:32 +08:00
2020-05-10 11:26:20 +08:00
#ip6tables -t mangle -D PREROUTING -j MARK --set-mark "$PROXY_FWMARK" >/dev/null 2>&1
2020-04-30 20:22:10 +08:00
ipset destroy localnetwork >/dev/null 2>&1
ipset destroy lan_ac_white_ips >/dev/null 2>&1
ipset destroy lan_ac_black_ips >/dev/null 2>&1
}
get_config()
{
2020-06-18 12:39:01 +08:00
proxy_mode=$(uci get openclash.config.proxy_mode 2>/dev/null)
2020-04-30 20:22:10 +08:00
rule_source=$(uci get openclash.config.rule_source 2>/dev/null)
2020-06-18 12:39:01 +08:00
enable_custom_dns=$(uci get openclash.config.enable_custom_dns 2>/dev/null)
2020-04-30 20:22:10 +08:00
enable_custom_clash_rules=$(uci get openclash.config.enable_custom_clash_rules 2>/dev/null)
da_password=$(uci get openclash.config.dashboard_password 2>/dev/null)
cn_port=$(uci get openclash.config.cn_port 2>/dev/null)
proxy_port=$(uci get openclash.config.proxy_port 2>/dev/null)
ipv6_enable=$(uci get openclash.config.ipv6_enable 2>/dev/null)
http_port=$(uci get openclash.config.http_port 2>/dev/null)
socks_port=$(uci get openclash.config.socks_port 2>/dev/null)
enable_redirect_dns=$(uci get openclash.config.enable_redirect_dns 2>/dev/null)
lan_ip=$(uci get network.lan.ipaddr 2>/dev/null |awk -F '/' '{print $1}' 2>/dev/null)
wan_ip4=$(ifconfig | grep 'inet addr' | awk '{print $2}' | cut -d: -f2 2>/dev/null)
lan_ip6=$(ifconfig | grep 'inet6 addr' | awk '{print $3}' 2>/dev/null)
disable_masq_cache=$(uci get openclash.config.disable_masq_cache 2>/dev/null)
log_level=$(uci get openclash.config.log_level 2>/dev/null)
intranet_allowed=$(uci get openclash.config.intranet_allowed 2>/dev/null)
enable_udp_proxy=$(uci get openclash.config.enable_udp_proxy 2>/dev/null)
operation_mode=$(uci get openclash.config.operation_mode 2>/dev/null)
lan_ac_mode=$(uci get openclash.config.lan_ac_mode 2>/dev/null)
enable_rule_proxy=$(uci get openclash.config.enable_rule_proxy 2>/dev/null)
2020-05-26 20:20:32 +08:00
stack_type=$(uci get openclash.config.stack_type 2>/dev/null)
2020-04-30 20:22:10 +08:00
}
2020-04-14 21:03:36 +08:00
start()
{
#禁止多个实例
status=$(ps|grep -c /etc/init.d/openclash)
[ "$status" -gt "3" ] && exit 0
config_choose
enable=$(uci get openclash.config.enable 2>/dev/null)
2020-04-30 20:22:10 +08:00
2020-04-14 21:03:36 +08:00
if [ "$enable" -eq 1 ] && [ -f "$CONFIG_FILE" ]; then
2020-06-18 12:39:01 +08:00
do_run_mode
2020-04-14 21:03:36 +08:00
echo "OpenClash 开始启动..." >$START_LOG
echo "第一步: 获取配置..." >$START_LOG
2020-04-30 20:22:10 +08:00
get_config
2019-07-19 18:18:45 +08:00
echo "第二步: 配置文件检查..." >$START_LOG
2019-08-02 23:40:19 +08:00
yml_check "$en_mode" "$enable_custom_dns" "$CONFIG_FILE" "$BACKUP_FILE" "$START_BACKUP"
2020-06-18 12:39:01 +08:00
if [ -n "$(grep "^ \{0,\}proxy-groups:" "$CONFIG_FILE")" ]; then
if [ -z "$(grep "^ \{0,\}Proxy:" "$CONFIG_FILE" 2>/dev/null)" ] && [ -z "$(grep "^ \{0,\}proxy-providers:" "$CONFIG_FILE" 2>/dev/null)" ]; then
kill_clash
stop
echo "错误: 配置文件完整性检查不通过,已自动还原配置文件,请对照模板格式检查修改配置文件!" >$START_LOG
mv "$START_BACKUP" "$CONFIG_FILE"
sleep 5
echo "" >$START_LOG
elif [ -z "$(grep "^ \{0,\}rules:" "$CONFIG_FILE" 2>/dev/null)" ] && [ -z "$(grep "^ \{0,\}script:" "$CONFIG_FILE" 2>/dev/null)" ]; then
2020-05-26 20:20:32 +08:00
kill_clash
stop
2020-06-18 12:39:01 +08:00
echo "错误: 配置文件完整性检查不通过,已自动还原配置文件,请对照模板格式检查修改配置文件!" >$START_LOG
2020-02-10 14:07:24 +08:00
mv "$START_BACKUP" "$CONFIG_FILE"
sleep 5
2019-09-21 10:22:22 +08:00
echo "" >$START_LOG
else
echo "第三步: 修改配置文件..." >$START_LOG
config_load "openclash"
config_foreach yml_auth_get "authentication"
yml_auth_custom "$CONFIG_FILE"
yml_cut "$CHANGE_FILE" "$RULE_FILE" "$DNS_FILE" "$CONFIG_FILE" "$PROXY_FILE" "$PROXY_PROVIDER_FILE" "$GROUP_FILE"
yml_dns_custom "$enable_custom_dns" "$DNS_FILE"
2020-07-16 21:07:14 +08:00
/usr/share/openclash/yml_change.sh >/dev/null 2>&1 "$LOGTIME" "$en_mode" "$enable_custom_dns" "$da_password" "$cn_port" "$proxy_port" "$CHANGE_FILE" "$ipv6_enable" "$http_port" "$socks_port" "$lan_ip" "$log_level" "$proxy_mode" "$intranet_allowed" "$en_mode_tun" "$stack_type" &
/usr/share/openclash/yml_rules_change.sh >/dev/null 2>&1 "$LOGTIME" "$rule_source" "$enable_custom_clash_rules" "$RULE_FILE" "$set_rule_file" "$en_mode" "$enable_rule_proxy" "$BACKUP_FILE" "$RULE_PROVIDER_FILE" &
wait
2020-06-18 12:39:01 +08:00
yml_provider_path "$PROXY_PROVIDER_FILE" "proxy_provider"
yml_provider_path "$RULE_PROVIDER_FILE" "rule_provider"
yml_custom_rule_provider
yml_game_custom
echo "第四步: DNS设置检查..." >$START_LOG
2020-05-26 20:20:32 +08:00
if [ -n "$(sed -n '/^ \{0,\}nameserver:/{n;p}' "$CONFIG_FILE" |grep '^ \{0,\}fallback:')" ] || [ -n "$(sed -n '/^ \{0,\}nameserver:/{n;p}' "$CONFIG_FILE" |grep 'OpenClash-General')" ]; then
kill_clash
stop
echo "错误: 配置文件DNS选项下的Nameserver必须设置服务器已自动还原配置文件请重新设置" >$START_LOG
echo "${LOGTIME} Nameserver Must Be Set, Please Change Your Configrations In Config.yaml" >>$LOG_FILE
2020-02-10 14:07:24 +08:00
mv "$START_BACKUP" "$CONFIG_FILE"
sleep 10
echo "" >$START_LOG
else
echo "第五步: 启动主程序..." >$START_LOG
2020-06-18 12:39:01 +08:00
#检查是否存在核心文件
do_run_core
[ ! -f "$CLASH" ] && {
kill_clash
stop
echo "内核文件不存在,开始下载..." >$START_LOG
nohup /usr/share/openclash/openclash_core.sh "$core_type" &
exit 0
}
2020-05-26 20:20:32 +08:00
sed -i "s/^ \{0,\}Proxy:/proxies:/g" "$CONFIG_FILE" 2>/dev/null
2020-05-02 16:38:01 +08:00
ulimit -SHn 65535 2>/dev/null
2020-04-30 20:22:10 +08:00
config_reload=$(uci get openclash.config.config_reload 2>/dev/null)
2020-05-26 20:20:32 +08:00
if [ -n "$(pidof clash)" ] && [ "$core_type" != "Tun" ] && [ "$config_reload" != "0" ]; then
2020-04-30 20:22:10 +08:00
curl -s --connect-timeout 5 -m 5 -H 'Content-Type: application/json' -H "Authorization: Bearer ${da_password}" -XPUT http://"$lan_ip":"$cn_port"/configs -d "{\"path\": \"$CONFIG_FILE\"}" 2>/dev/null
else
2020-05-26 20:20:32 +08:00
kill_clash
2020-04-30 20:22:10 +08:00
nohup "$CLASH" -d "$CLASH_CONFIG" -f "$CONFIG_FILE" >> $LOG_FILE 2>&1 &
fi
2020-06-18 12:39:01 +08:00
uci set openclash.config.config_reload=1 2>/dev/null
2020-04-30 20:22:10 +08:00
uci commit openclash
#检测proxy_provider配置文件状态
2020-05-26 20:20:32 +08:00
echo "第六步: 等待主程序下载外部文件..." >$START_LOG
yml_provider_check "$PROXY_PROVIDER_FILE" "proxy_provider"
yml_provider_check "$RULE_PROVIDER_FILE" "rule_provider"
2020-02-06 22:42:33 +08:00
echo "第七步: 设置控制面板..." >$START_LOG
2020-02-11 19:52:30 +08:00
ln -s /usr/share/openclash/yacd /www/luci-static/openclash 2>/dev/null
2019-09-15 01:31:40 +08:00
echo "第八步: 设置防火墙规则..." >$START_LOG
2020-04-30 20:22:10 +08:00
set_firewall
2020-02-06 22:42:33 +08:00
echo "第九步: 重启 Dnsmasq 程序..." >$START_LOG
change_dns "$enable_redirect_dns" "$disable_masq_cache"
/etc/init.d/dnsmasq restart >/dev/null 2>&1
if pidof clash >/dev/null; then
echo "第十步: 还原策略组节点状态..." >$START_LOG
2020-02-11 19:52:30 +08:00
/usr/share/openclash/openclash_history_set.sh
echo "第十一步: 添加计划任务,启动进程守护程序..." >$START_LOG
add_cron
if [ -z "$(uci get dhcp.lan.dhcpv6 2>/dev/null)" ]; then
echo "OpenClash 启动成功,请等待服务器上线!" >$START_LOG
echo "${LOGTIME} OpenClash Start Successful" >> $LOG_FILE
sleep 5
else
echo "OpenClash 启动成功检测到您启用了IPV6的DHCP服务可能会造成连接异常" >$START_LOG
echo "${LOGTIME} OpenClash Start Successful, Please Note That Network May Abnormal With IPV6's DHCP Server" >> $LOG_FILE
sleep 10
fi
2020-02-20 02:53:49 +08:00
echo "OpenClash Already Start"
echo "" >$START_LOG
else
if [ "$rule_source" != 0 ] || [ "$enable_custom_clash_rules" != 0 ]; then
2020-04-09 01:39:30 +08:00
echo "错误: OpenClash 启动失败,尝试还原第三方规则并重新启动 Clash 主程序..." >$START_LOG
echo "${LOGTIME} OpenClash Can Not Start, Try Use Backup Rules Start Again" >> $LOG_FILE
2020-06-18 12:39:01 +08:00
mv "$START_BACKUP" /tmp/configrules.bak
sed -i -n '/^rules:/,$p' /tmp/configrules.bak
sed -i '/^rules:/,$d' "$CONFIG_FILE" 2>/dev/null
sed -i '/##Other-rule-providers##/,/##Other-rule-providers-end##/d' "$CONFIG_FILE" 2>/dev/null
cat /tmp/configrules.bak >> "$CONFIG_FILE"
rm -rf /tmp/configrules.bak
2020-02-15 22:06:30 +08:00
nohup "$CLASH" -d "$CLASH_CONFIG" -f "$CONFIG_FILE" >> $LOG_FILE 2>&1 &
sleep 3
if pidof clash >/dev/null; then
2020-02-11 19:52:30 +08:00
/usr/share/openclash/openclash_history_set.sh
add_cron
if [ -z "$(uci get dhcp.lan.dhcpv6 2>/dev/null)" ]; then
echo "OpenClash 使用备份规则启动成功,请更新、检查变动的规则后重试!" >$START_LOG
echo "${LOGTIME} OpenClash Start Successful With Backup Rules Config, Please Check Or Update Other Rules And Retry" >> $LOG_FILE
sleep 10
else
echo "OpenClash 使用备份规则启动成功,请更新、检查变动的规则后重试!" >$START_LOG
echo "${LOGTIME} OpenClash Start Successful With Backup Rules Config, Please Check Or Update Other Rules And Retry" >> $LOG_FILE
2020-02-06 22:42:33 +08:00
sleep 5
echo "检测到您启用了IPV6的DHCP服务可能会造成连接异常" >$START_LOG
echo "${LOGTIME} OpenClash Start Successful, Please Note That Network May Abnormal With IPV6's DHCP Server" >> $LOG_FILE
sleep 10
fi
2020-02-20 02:53:49 +08:00
echo "OpenClash Already Start"
echo "" >$START_LOG
2019-10-12 09:32:11 +08:00
else
2020-05-26 20:20:32 +08:00
kill_clash
stop
echo "错误: OpenClash 启动失败,请到日志页面查看详细错误信息!" >$START_LOG
echo "${LOGTIME} OpenClash Can Not Start, Please Check The Error Info And Try Again" >> $LOG_FILE
2019-10-12 09:32:11 +08:00
sleep 10
echo "" >$START_LOG
2019-10-12 09:32:11 +08:00
fi
2019-09-21 10:22:22 +08:00
else
2020-05-26 20:20:32 +08:00
kill_clash
stop
2019-09-21 10:22:22 +08:00
echo "错误: OpenClash 启动失败,请到日志页面查看详细错误信息!" >$START_LOG
echo "${LOGTIME} OpenClash Can Not Start, Please Check The Error Info And Try Again" >> $LOG_FILE
sleep 10
echo "" >$START_LOG
fi
2019-08-02 23:40:19 +08:00
fi
fi
2019-07-19 18:18:45 +08:00
fi
else
2020-02-15 22:06:30 +08:00
nohup "$CLASH" -d "$CLASH_CONFIG" -f "$CONFIG_FILE" >> $LOG_FILE 2>&1 &
2020-05-26 20:20:32 +08:00
kill_clash
stop
echo "错误: 配置文件完整性检查不通过,已自动还原配置文件,请根据日志信息对照模板格式检查修改配置文件!" >$START_LOG
2020-02-10 14:07:24 +08:00
mv "$START_BACKUP" "$CONFIG_FILE"
sleep 5
echo "" >$START_LOG
2019-07-19 18:18:45 +08:00
fi
2019-08-02 23:40:19 +08:00
rm -rf $START_BACKUP 2>/dev/null
2020-02-15 22:06:30 +08:00
rm -rf /tmp/yaml_* 2>/dev/null
2019-07-19 18:18:45 +08:00
else
2020-06-18 12:39:01 +08:00
subscribe_info=$(uci get openclash.@config_subscribe[0].address 2>/dev/null)
if [ ! -f "$CONFIG_FILE" ] && [ -n "$subscribe_info" ]; then
2020-05-26 20:20:32 +08:00
kill_clash
stop
2019-08-02 23:40:19 +08:00
echo "OpenClash 配置文件不存在,开始下载..." >$START_LOG
nohup /usr/share/openclash/openclash.sh &
exit 0
elif [ ! -f "$CONFIG_FILE" ]; then
2020-05-26 20:20:32 +08:00
kill_clash
stop
2019-07-27 18:06:42 +08:00
echo "错误: OpenClash 缺少配置文件,请上传或更新配置文件!" >$START_LOG
echo "${LOGTIME} Config Not Found" >> $LOG_FILE
sleep 5
echo "" >$START_LOG
fi
2019-07-19 18:18:45 +08:00
fi
}
stop()
{
2020-04-30 20:22:10 +08:00
enable=$(uci get openclash.config.enable 2>/dev/null)
2020-03-09 03:58:10 +08:00
2020-04-30 20:22:10 +08:00
echo "OpenClash 开始关闭..." >$START_LOG
echo "第一步: 备份当前节点状态..." >$START_LOG
2020-05-26 20:20:32 +08:00
/usr/share/openclash/openclash_history_get.sh 2>/dev/null
2020-04-30 20:22:10 +08:00
echo "第二步: 删除 OpenClash 防火墙规则..." >$START_LOG
revert_firewall
2020-03-09 03:58:10 +08:00
2020-04-30 20:22:10 +08:00
echo "第三步: 关闭 OpenClash 守护程序..." >$START_LOG
watchdog_pids=$(ps |grep openclash_watchdog.sh |grep -v grep |awk '{print $1}' 2>/dev/null)
for watchdog_pid in $watchdog_pids; do
kill -9 "$watchdog_pid" >/dev/null 2>&1
done
echo "第四步: 关闭 Clash 主程序..." >$START_LOG
if [ "$enable" -eq 0 ]; then
2020-05-26 20:20:32 +08:00
kill_clash
2020-04-30 20:22:10 +08:00
fi
2020-07-18 22:04:13 +08:00
2020-04-30 20:22:10 +08:00
echo "第五步: 重启 Dnsmasq 程序..." >$START_LOG
dns_port=$(uci get openclash.config.dns_port 2>/dev/null)
redirect_dns=$(uci get openclash.config.redirect_dns 2>/dev/null)
masq_cache=$(uci get openclash.config.masq_cache 2>/dev/null)
revert_dns "$redirect_dns" "$masq_cache" "$dns_port"
/etc/init.d/dnsmasq restart >/dev/null 2>&1
echo "第六步:删除 OpenClash 残留文件..." >$START_LOG
if [ "$enable" -eq 0 ]; then
rm -rf $LOG_FILE 2>/dev/null
rm -rf /tmp/openclash_debug.log 2>/dev/null
rm -rf /www/luci-static/openclash 2>/dev/null
rm -rf /tmp/openclash_last_version 2>/dev/null
rm -rf /tmp/clash_last_version 2>/dev/null
rm -rf /tmp/Proxy_Group 2>/dev/null
rm -rf /tmp/rules_name 2>/dev/null
echo "OpenClash 关闭成功!" >$START_LOG
sleep 5
fi
2020-05-26 20:20:32 +08:00
rm -rf /tmp/yaml_* 2>/dev/null
2020-04-30 20:22:10 +08:00
rm -rf $START_LOG 2>/dev/null
del_cron
echo "OpenClash Already Stop"
2019-07-19 18:18:45 +08:00
}
restart()
{
2020-04-30 20:22:10 +08:00
stop
start
}
reload()
{
2020-06-18 12:39:01 +08:00
if pidof clash >/dev/null; then
revert_firewall 2>/dev/null
do_run_mode 2>/dev/null
get_config 2>/dev/null
set_firewall 2>/dev/null
echo "${LOGTIME} OpenClash Reload After Firewall Restart" >> $LOG_FILE
fi
2020-04-23 03:35:30 +08:00
}