3164 lines
159 KiB
Bash
3164 lines
159 KiB
Bash
#!/bin/sh /etc/rc.common
|
||
# Copyright (c) 2019-2024 vernesong
|
||
|
||
START=99
|
||
STOP=15
|
||
USE_PROCD=1
|
||
|
||
. $IPKG_INSTROOT/usr/share/openclash/openclash_ps.sh
|
||
. $IPKG_INSTROOT/usr/share/openclash/ruby.sh
|
||
. $IPKG_INSTROOT/usr/share/openclash/log.sh
|
||
|
||
[ -f /etc/openwrt_release ] && {
|
||
RAW_CONFIG_FILE=$(uci -q get openclash.config.config_path)
|
||
BACKUP_FILE="/etc/openclash/backup/$(uci -q get openclash.config.config_path |awk -F '/' '{print $5}' 2>/dev/null)"
|
||
CONFIG_FILE="/etc/openclash/$(uci -q get openclash.config.config_path |awk -F '/' '{print $5}' 2>/dev/null)"
|
||
TMP_CONFIG_FILE="/tmp/yaml_config_tmp_$(uci -q get openclash.config.config_path |awk -F '/' '{print $5}' 2>/dev/null)"
|
||
FW4=$(command -v fw4)
|
||
# 获取默认的 DNSMASQ 配置 ID
|
||
DEFAULT_DNSMASQ_CFGID="$(uci -q show "dhcp.@dnsmasq[0]" | awk 'NR==1 {split($0, conf, /[.=]/); print conf[2]}')"
|
||
# 从 conf-dir 行中提取配置目录路径
|
||
if [ -f "/tmp/etc/dnsmasq.conf.$DEFAULT_DNSMASQ_CFGID" ]; then
|
||
DNSMASQ_CONF_DIR="$(awk -F '=' '/^conf-dir=/ {print $2}' "/tmp/etc/dnsmasq.conf.$DEFAULT_DNSMASQ_CFGID")"
|
||
else
|
||
DNSMASQ_CONF_DIR="/tmp/dnsmasq.d"
|
||
fi
|
||
# 设置 DNSMASQ_CONF_DIR,并去除路径末尾的斜杠
|
||
DNSMASQ_CONF_DIR=${DNSMASQ_CONF_DIR%*/}
|
||
}
|
||
CLASH="/etc/openclash/clash"
|
||
CLASH_CONFIG="/etc/openclash"
|
||
CRON_FILE="/etc/crontabs/root"
|
||
CACHE_PATH_OLD="/etc/openclash/.cache"
|
||
CACHE_PATH="/etc/openclash/cache.db"
|
||
LOG_FILE="/tmp/openclash.log"
|
||
START_LOG="/tmp/openclash_start.log"
|
||
PROXY_FWMARK="0x162"
|
||
PROXY_ROUTE_TABLE="0x162"
|
||
|
||
add_cron()
|
||
{
|
||
[ "$(tail -n1 /etc/crontabs/root | wc -l)" -eq 0 ] && [ -n "$(cat /etc/crontabs/root 2>/dev/null)" ] && echo >> /etc/crontabs/root
|
||
[ -z "$(grep "openclash.sh" "$CRON_FILE" 2>/dev/null)" ] && {
|
||
[ "$(uci -q get openclash.config.auto_update)" -eq 1 ] && [ "$(uci -q get openclash.config.config_auto_update_mode)" -ne 1 ] && echo "0 $(uci -q get openclash.config.auto_update_time) * * $(uci -q get openclash.config.config_update_week_time) /usr/share/openclash/openclash.sh" >> $CRON_FILE
|
||
}
|
||
[ -z "$(grep "openclash_rule.sh" "$CRON_FILE" 2>/dev/null)" ] && {
|
||
[ "$(uci -q get openclash.config.other_rule_auto_update)" -eq 1 ] && echo "0 $(uci -q get openclash.config.other_rule_update_day_time) * * $(uci -q get openclash.config.other_rule_update_week_time) /usr/share/openclash/openclash_rule.sh" >> $CRON_FILE
|
||
}
|
||
[ -z "$(grep "openclash_ipdb.sh" "$CRON_FILE" 2>/dev/null)" ] && {
|
||
[ "$(uci -q get openclash.config.geo_auto_update)" -eq 1 ] && echo "0 $(uci -q get openclash.config.geo_update_day_time) * * $(uci -q get openclash.config.geo_update_week_time) /usr/share/openclash/openclash_ipdb.sh" >> $CRON_FILE
|
||
}
|
||
[ -z "$(grep "openclash_geosite.sh" "$CRON_FILE" 2>/dev/null)" ] && {
|
||
[ "$(uci -q get openclash.config.geosite_auto_update)" -eq 1 ] && echo "0 $(uci -q get openclash.config.geosite_update_day_time) * * $(uci -q get openclash.config.geosite_update_week_time) /usr/share/openclash/openclash_geosite.sh" >> $CRON_FILE
|
||
}
|
||
[ -z "$(grep "openclash_geoip.sh" "$CRON_FILE" 2>/dev/null)" ] && {
|
||
[ "$(uci -q get openclash.config.geoip_auto_update)" -eq 1 ] && echo "0 $(uci -q get openclash.config.geoip_update_day_time) * * $(uci -q get openclash.config.geoip_update_week_time) /usr/share/openclash/openclash_geoip.sh" >> $CRON_FILE
|
||
}
|
||
[ -z "$(grep "openclash_chnroute.sh" "$CRON_FILE" 2>/dev/null)" ] && {
|
||
[ "$(uci -q get openclash.config.chnr_auto_update)" -eq 1 ] && echo "0 $(uci -q get openclash.config.chnr_update_day_time) * * $(uci -q get openclash.config.chnr_update_week_time) /usr/share/openclash/openclash_chnroute.sh" >> $CRON_FILE
|
||
}
|
||
[ -z "$(grep "/etc/init.d/openclash" "$CRON_FILE" 2>/dev/null)" ] && {
|
||
[ "$(uci -q get openclash.config.auto_restart)" -eq 1 ] && echo "0 $(uci -q get openclash.config.auto_restart_day_time) * * $(uci -q get openclash.config.auto_restart_week_time) /etc/init.d/openclash restart 2>/dev/null" >> $CRON_FILE
|
||
}
|
||
crontab $CRON_FILE
|
||
start_watchdog
|
||
}
|
||
|
||
del_cron()
|
||
{
|
||
sed -i '/openclash.sh/d' $CRON_FILE 2>/dev/null
|
||
sed -i '/openclash_rule.sh/d' $CRON_FILE 2>/dev/null
|
||
sed -i '/openclash_ipdb.sh/d' $CRON_FILE 2>/dev/null
|
||
sed -i '/openclash_geoip.sh/d' $CRON_FILE 2>/dev/null
|
||
sed -i '/openclash_geosite.sh/d' $CRON_FILE 2>/dev/null
|
||
sed -i '/openclash_chnroute.sh/d' $CRON_FILE 2>/dev/null
|
||
sed -i '/\/etc\/init.d\/openclash/d' $CRON_FILE 2>/dev/null
|
||
/etc/init.d/cron restart
|
||
}
|
||
|
||
save_dnsmasq_server() {
|
||
if [ -z "$1" ] || [ "$1" == "127.0.0.1#${dns_port}" ]; then
|
||
return
|
||
fi
|
||
|
||
uci -q add_list openclash.config.dnsmasq_server="$1"
|
||
}
|
||
|
||
set_dnsmasq_server() {
|
||
if [ -z "$1" ] || [ "$1" == "127.0.0.1#${dns_port}" ]; then
|
||
return
|
||
fi
|
||
|
||
uci -q add_list dhcp.@dnsmasq[0].server="$1"
|
||
}
|
||
|
||
change_dns() {
|
||
local settype nftflag
|
||
if dnsmasq --version | grep -q 'Compile time options:.* nftset'; then
|
||
settype="nftset"
|
||
nftflag="inet#fw4#"
|
||
else
|
||
settype="ipset"
|
||
[ -n "$FW4" ] && LOG_OUT "Warning: Dnsmasq not Support nftset, Use ipset..."
|
||
fi
|
||
if [ -n "$FW4" ]; then
|
||
if [ "$china_ip_route" != "0" ] || [ "$disable_udp_quic" = "1" ]; then
|
||
if [ "$enable_redirect_dns" != "2" ]; then
|
||
mkdir -p ${DNSMASQ_CONF_DIR}
|
||
awk '!/^$/&&!/^#/&&!/(^([1-9]|1[0-9]|1[1-9]{2}|2[0-4][0-9]|25[0-5])\.)(([0-9]{1,2}|1[1-9]{2}|2[0-4][0-9]|25[0-5])\.){2}([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-5][0-9]|25[0-4])((\/[0-9][0-9])?)$/{printf("'${settype}'=/%s/'${nftflag}'china_ip_route_pass'" "'\n",$0)}' /etc/openclash/custom/openclash_custom_chnroute_pass.list >>${DNSMASQ_CONF_DIR}/dnsmasq_openclash_chnroute_pass.conf 2>/dev/null
|
||
fi
|
||
fi
|
||
|
||
if [ "$ipv6_enable" -eq 1 ]; then
|
||
if [ "$china_ip6_route" != "0" ] || [ "$disable_udp_quic" = "1" ]; then
|
||
if [ "$enable_redirect_dns" != "2" ]; then
|
||
mkdir -p ${DNSMASQ_CONF_DIR}
|
||
awk '!/^$/&&!/^#/&&/([0-9a-zA-Z-]{1,}\.)+([a-zA-Z]{2,})/{printf("'${settype}'=/%s/'${nftflag}'china_ip_route_pass'" "'\n",$0)}' /etc/openclash/custom/openclash_custom_chnroute6_pass.list >>${DNSMASQ_CONF_DIR}/dnsmasq_openclash_chnroute6_pass.conf 2>/dev/null
|
||
#Prevent domain repeat
|
||
for i in `grep -wf ${DNSMASQ_CONF_DIR}/dnsmasq_openclash_chnroute6_pass.conf ${DNSMASQ_CONF_DIR}/dnsmasq_openclash_chnroute_pass.conf`
|
||
do
|
||
if [ -n "$nftflag" ]; then
|
||
sed -i "s:${i}:${i},6#${nftflag}china_ip6_route_pass:g" ${DNSMASQ_CONF_DIR}/dnsmasq_openclash_chnroute_pass.conf
|
||
else
|
||
sed -i "s:${i}:${i},china_ip6_route_pass:g" ${DNSMASQ_CONF_DIR}/dnsmasq_openclash_chnroute_pass.conf
|
||
fi
|
||
sed -i 's:'$i':EXCLUSIVE:;/EXCLUSIVE/d' ${DNSMASQ_CONF_DIR}/dnsmasq_openclash_chnroute6_pass.conf
|
||
done
|
||
if [ -n "$nftflag" ]; then
|
||
sed -i "s/\/${nftflag}/\/4#${nftflag}/g" ${DNSMASQ_CONF_DIR}/dnsmasq_openclash_chnroute_pass.conf
|
||
sed -i "s/${nftflag}china_ip_route_pass/6#${nftflag}china_ip6_route_pass/g" ${DNSMASQ_CONF_DIR}/dnsmasq_openclash_chnroute6_pass.conf
|
||
else
|
||
sed -i "s/china_ip_route_pass/china_ip6_route_pass/g" ${DNSMASQ_CONF_DIR}/dnsmasq_openclash_chnroute6_pass.conf
|
||
fi
|
||
fi
|
||
fi
|
||
fi
|
||
else
|
||
if [ "$china_ip_route" != "0" ] || [ "$disable_udp_quic" = "1" ]; then
|
||
if [ "$enable_redirect_dns" != "2" ]; then
|
||
mkdir -p ${DNSMASQ_CONF_DIR}
|
||
awk '!/^$/&&!/^#/&&!/(^([1-9]|1[0-9]|1[1-9]{2}|2[0-4][0-9]|25[0-5])\.)(([0-9]{1,2}|1[1-9]{2}|2[0-4][0-9]|25[0-5])\.){2}([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-5][0-9]|25[0-4])((\/[0-9][0-9])?)$/{printf("ipset=/%s/china_ip_route_pass'" "'\n",$0)}' /etc/openclash/custom/openclash_custom_chnroute_pass.list >>${DNSMASQ_CONF_DIR}/dnsmasq_openclash_chnroute_pass.conf 2>/dev/null
|
||
fi
|
||
fi
|
||
|
||
if [ "$ipv6_enable" -eq 1 ]; then
|
||
if [ "$china_ip6_route" != "0" ] || [ "$disable_udp_quic" = "1" ]; then
|
||
if [ "$enable_redirect_dns" != "2" ]; then
|
||
mkdir -p ${DNSMASQ_CONF_DIR}
|
||
awk '!/^$/&&!/^#/&&/([0-9a-zA-Z-]{1,}\.)+([a-zA-Z]{2,})/{printf("ipset=/%s/china_ip_route_pass'" "'\n",$0)}' /etc/openclash/custom/openclash_custom_chnroute6_pass.list >>${DNSMASQ_CONF_DIR}/dnsmasq_openclash_chnroute6_pass.conf
|
||
#Prevent domain repeat
|
||
for i in `grep -wf ${DNSMASQ_CONF_DIR}/dnsmasq_openclash_chnroute6_pass.conf ${DNSMASQ_CONF_DIR}/dnsmasq_openclash_chnroute_pass.conf`
|
||
do
|
||
sed -i "s:${i}:${i},china_ip6_route_pass:g" ${DNSMASQ_CONF_DIR}/dnsmasq_openclash_chnroute_pass.conf
|
||
sed -i 's:'$i':EXCLUSIVE:;/EXCLUSIVE/d' ${DNSMASQ_CONF_DIR}/dnsmasq_openclash_chnroute6_pass.conf
|
||
done
|
||
sed -i "s/china_ip_route_pass/china_ip6_route_pass/g" ${DNSMASQ_CONF_DIR}/dnsmasq_openclash_chnroute6_pass.conf
|
||
fi
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
/usr/share/openclash/openclash_custom_domain_dns.sh >/dev/null 2>&1
|
||
|
||
if [ "$1" -eq 1 ]; then
|
||
uci -q del openclash.config.dnsmasq_server
|
||
config_load "dhcp"
|
||
config_list_foreach "$(uci -q show dhcp.@dnsmasq[0].server |awk -F '.' '{print $2}')" "server" save_dnsmasq_server
|
||
uci -q del dhcp.@dnsmasq[-1].server
|
||
uci -q add_list dhcp.@dnsmasq[0].server=127.0.0.1#"$dns_port"
|
||
uci -q set openclash.config.dnsmasq_noresolv="$(uci -q get dhcp.@dnsmasq[0].noresolv)"
|
||
uci -q set openclash.config.dnsmasq_resolvfile="$(uci -q get dhcp.@dnsmasq[0].resolvfile)"
|
||
uci -q delete dhcp.@dnsmasq[0].resolvfile
|
||
uci -q set dhcp.@dnsmasq[0].noresolv=1
|
||
uci -q set dhcp.@dnsmasq[0].localuse=1
|
||
uci -q set openclash.config.redirect_dns=1
|
||
uci -q set openclash.config.dnsmasq_cachesize="$(uci -q get dhcp.@dnsmasq[0].cachesize)"
|
||
uci -q set dhcp.@dnsmasq[0].cachesize=0
|
||
uci -q set openclash.config.cachesize_dns=1
|
||
else
|
||
uci -q set openclash.config.redirect_dns=0
|
||
uci -q set openclash.config.cachesize_dns=0
|
||
fi
|
||
|
||
if [ "$1" -eq 1 ] && [ "$ipv6_dns" -eq 1 ] && [ -n "$(ip6tables -t mangle -L 2>&1 | grep -o 'Chain')" ]; then
|
||
#dnsmasq answer ipv6
|
||
uci -q set openclash.config.dnsmasq_filter_aaaa="$(uci -q get dhcp.@dnsmasq[0].filter_aaaa)"
|
||
uci -q set dhcp.@dnsmasq[0].filter_aaaa=0
|
||
uci -q set openclash.config.filter_aaaa_dns=1
|
||
else
|
||
uci -q set openclash.config.filter_aaaa_dns=0
|
||
fi
|
||
|
||
uci -q commit dhcp
|
||
uci -q commit openclash
|
||
/etc/init.d/dnsmasq restart >/dev/null 2>&1
|
||
}
|
||
|
||
revert_dns() {
|
||
|
||
rm -rf ${DNSMASQ_CONF_DIR}/dnsmasq_openclash_custom_domain.conf >/dev/null 2>&1
|
||
rm -rf ${DNSMASQ_CONF_DIR}/dnsmasq_openclash_chnroute_pass.conf >/dev/null 2>&1
|
||
rm -rf ${DNSMASQ_CONF_DIR}/dnsmasq_openclash_chnroute6_pass.conf >/dev/null 2>&1
|
||
|
||
[ "$1" -eq 1 ] && {
|
||
uci -q del dhcp.@dnsmasq[-1].server
|
||
[ -n "${10}" ] && {
|
||
config_load "openclash"
|
||
config_list_foreach "config" "dnsmasq_server" set_dnsmasq_server
|
||
}
|
||
|
||
if [ "$4" == "0" ] || [ -z "$4" ] || [ -z "$(uci -q show dhcp.@dnsmasq[0].server)" ]; then
|
||
uci -q set dhcp.@dnsmasq[0].noresolv=0
|
||
if [ -n "$5" ] && [ -n "$(grep nameserver $5)" ]; then
|
||
uci -q set dhcp.@dnsmasq[0].resolvfile="$5"
|
||
elif [ -n "$3" ] && [ -n "$(grep nameserver $3)" ]; then
|
||
uci -q set dhcp.@dnsmasq[0].resolvfile="$3"
|
||
elif [ -s "/tmp/resolv.conf.d/resolv.conf.auto" ] && [ -n "$(grep "nameserver" /tmp/resolv.conf.d/resolv.conf.auto)" ]; then
|
||
uci -q set dhcp.@dnsmasq[0].resolvfile=/tmp/resolv.conf.d/resolv.conf.auto
|
||
uci -q set openclash.config.default_resolvfile=/tmp/resolv.conf.d/resolv.conf.auto
|
||
elif [ -s "/tmp/resolv.conf.auto" ] && [ -n "$(grep "nameserver" /tmp/resolv.conf.auto)" ]; then
|
||
uci -q set dhcp.@dnsmasq[0].resolvfile=/tmp/resolv.conf.auto
|
||
uci -q set openclash.config.default_resolvfile=/tmp/resolv.conf.auto
|
||
else
|
||
uci -q set dhcp.@dnsmasq[0].resolvfile=/tmp/resolv.conf.d/resolv.conf.auto
|
||
uci -q set openclash.config.default_resolvfile=/tmp/resolv.conf.d/resolv.conf.auto
|
||
fi
|
||
uci -q set dhcp.@dnsmasq[0].localuse=1
|
||
uci -q commit dhcp
|
||
/etc/init.d/dnsmasq restart >/dev/null 2>&1
|
||
masq_port=$(uci -q get dhcp.@dnsmasq[0].port)
|
||
if [ "$(nslookup www.apple.com 127.0.0.1:${masq_port} >/dev/null 2>&1 || echo $?)" = "1" ]; then
|
||
uci -q set openclash.config.default_resolvfile="/tmp/resolv.conf.d/resolv.conf.auto"
|
||
mkdir -p /tmp/resolv.conf.d
|
||
rm -rf /tmp/resolv.conf.d/resolv.conf.auto
|
||
touch /tmp/resolv.conf.d/resolv.conf.auto 2>/dev/null
|
||
cat >> "/tmp/resolv.conf.d/resolv.conf.auto" <<-EOF
|
||
# Interface lan
|
||
nameserver 119.29.29.29
|
||
nameserver 8.8.8.8
|
||
EOF
|
||
uci -q set dhcp.@dnsmasq[0].resolvfile="/tmp/resolv.conf.d/resolv.conf.auto"
|
||
fi
|
||
fi
|
||
}
|
||
|
||
[ "$6" -eq 1 ] && {
|
||
uci -q set dhcp.@dnsmasq[0].cachesize="$7"
|
||
uci -q set openclash.config.cachesize_dns=0
|
||
uci -q delete openclash.config.dnsmasq_cachesize
|
||
}
|
||
|
||
[ "$8" -eq 1 ] && {
|
||
uci -q set dhcp.@dnsmasq[0].filter_aaaa="$9"
|
||
uci -q set openclash.config.filter_aaaa_dns=0
|
||
uci -q delete openclash.config.dnsmasq_filter_aaaa
|
||
}
|
||
|
||
[ "$1" -eq 1 ] && {
|
||
uci -q set openclash.config.redirect_dns=0
|
||
uci -q del openclash.config.dnsmasq_server
|
||
}
|
||
|
||
uci -q commit dhcp
|
||
uci -q commit openclash
|
||
|
||
}
|
||
|
||
kill_clash()
|
||
{
|
||
check_time=1
|
||
while ( [ "$check_time" -le 10 ] && [ -n "$(pidof clash)" ] )
|
||
do
|
||
clash_pids=$(pidof clash |sed 's/$//g')
|
||
for clash_pid in $clash_pids; do
|
||
kill -9 "$clash_pid" 2>/dev/null
|
||
done
|
||
sleep 1
|
||
let check_time++
|
||
done >/dev/null 2>&1
|
||
}
|
||
|
||
start_fail()
|
||
{
|
||
kill_clash
|
||
stop
|
||
exit 0
|
||
}
|
||
|
||
#获取订阅配置
|
||
sub_info_get()
|
||
{
|
||
local section="$1" address enabled name
|
||
config_get_bool "enabled" "$section" "enabled" "1"
|
||
config_get "address" "$section" "address" ""
|
||
config_get "name" "$section" "name" ""
|
||
|
||
if [ "$subscribe_enable" = "1" ]; then
|
||
return
|
||
fi
|
||
|
||
if [ "$enabled" -eq 0 ]; then
|
||
return
|
||
fi
|
||
|
||
if [ -z "$address" ]; then
|
||
return
|
||
fi
|
||
|
||
if [ -z "$name" ]; then
|
||
SUB_CONFIG_FILE="/etc/openclash/config/config.yaml"
|
||
else
|
||
SUB_CONFIG_FILE="/etc/openclash/config/$name.yaml"
|
||
fi
|
||
|
||
if [ "$SUB_CONFIG_FILE" != "$2" ]; then
|
||
return
|
||
fi
|
||
|
||
subscribe_enable=1
|
||
}
|
||
|
||
#配置文件选择
|
||
config_choose()
|
||
{
|
||
if [ ! -f "$RAW_CONFIG_FILE" ]; then
|
||
config_load "openclash"
|
||
config_foreach sub_info_get "config_subscribe" "$RAW_CONFIG_FILE"
|
||
if [ "$subscribe_enable" = "1" ]; then
|
||
LOG_OUT "【$RAW_CONFIG_FILE】Config File Does Not Exist, You Have Set Subscription Information, Ready To Download..."
|
||
/usr/share/openclash/openclash.sh "$RAW_CONFIG_FILE" &
|
||
exit 0
|
||
fi
|
||
fi
|
||
|
||
if [ -z "$RAW_CONFIG_FILE" ] || [ ! -f "$RAW_CONFIG_FILE" ]; then
|
||
for file_name in /etc/openclash/config/*
|
||
do
|
||
if [ -f "$file_name" ]; then
|
||
CONFIG_NAME=$(echo "$file_name" |awk -F '/' '{print $5}' 2>/dev/null)
|
||
uci -q set openclash.config.config_path="/etc/openclash/config/$CONFIG_NAME"
|
||
uci -q commit openclash
|
||
RAW_CONFIG_FILE="/etc/openclash/config/$CONFIG_NAME"
|
||
CONFIG_FILE="/etc/openclash/$CONFIG_NAME"
|
||
TMP_CONFIG_FILE="/tmp/yaml_config_tmp_$CONFIG_NAME"
|
||
LOG_OUT "Error: Config Not Found, Switch Config File to【$RAW_CONFIG_FILE】"
|
||
break
|
||
fi
|
||
done
|
||
fi 2>/dev/null
|
||
|
||
if [ ! -f "$RAW_CONFIG_FILE" ]; then
|
||
LOG_OUT "Error: Config Not Found"
|
||
exit 0
|
||
fi
|
||
|
||
CONFIG_NAME=$(echo "$RAW_CONFIG_FILE" |awk -F '/' '{print $5}' 2>/dev/null)
|
||
HISTORY_PATH_OLD="/etc/openclash/history/${CONFIG_NAME%.*}"
|
||
HISTORY_PATH="/etc/openclash/history/${CONFIG_NAME%.*}.db"
|
||
}
|
||
|
||
config_check()
|
||
{
|
||
#创建启动配置
|
||
#rm -rf "/etc/openclash/*.y*" 2>/dev/null
|
||
cp "$RAW_CONFIG_FILE" "$TMP_CONFIG_FILE"
|
||
|
||
ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
|
||
begin
|
||
YAML.load_file('$RAW_CONFIG_FILE');
|
||
rescue Exception => e
|
||
YAML.LOG('Error: Unable To Parse Config File,【' + e.message + '】');
|
||
system 'rm -rf ${TMP_CONFIG_FILE}';
|
||
end
|
||
" 2>/dev/null >> $LOG_FILE
|
||
if [ $? -ne 0 ]; then
|
||
LOG_OUT "Error: Ruby Works Abnormally, Please Check The Ruby Library Depends!"
|
||
start_fail
|
||
elif [ ! -f "$TMP_CONFIG_FILE" ] || [ ! -s "$TMP_CONFIG_FILE" ]; then
|
||
LOG_OUT "Error: Config File Format Validation Failed..."
|
||
start_fail
|
||
fi
|
||
}
|
||
|
||
check_run_quick()
|
||
{
|
||
quick_start=true
|
||
check_file="$(cat /tmp/openclash.change 2>/dev/null |awk '{print $1}')"
|
||
if [ -z "$check_file" ] || [ ! -f "$CONFIG_FILE" ] || [ ! -f "/tmp/openclash_config.tmp" ]; then
|
||
quick_start=false
|
||
return
|
||
fi
|
||
cmp -s "/etc/config/openclash" "/tmp/openclash_config.tmp"
|
||
if [ "$?" -ne "0" ]; then
|
||
LOG_OUT "Tip: Because of the file【 /etc/config/openclash 】modificated, Pause quick start..."
|
||
quick_start=false
|
||
else
|
||
if [ -s "/tmp/openclash.change" ]; then
|
||
for i in $check_file; do
|
||
if [ -z "$(grep "$i $(date -r "$i")$" "/tmp/openclash.change")" ]; then
|
||
LOG_OUT "Tip: Because of the file【 $i 】modificated, Pause quick start..."
|
||
quick_start=false
|
||
break
|
||
fi
|
||
done 2>/dev/null
|
||
fi
|
||
fi
|
||
}
|
||
|
||
write_run_quick()
|
||
{
|
||
check_file="$(echo $RAW_CONFIG_FILE | tr " " "?") $(ls -d /etc/openclash/custom/*) /usr/share/openclash/res/lhie1.yaml"
|
||
cmp -s "/etc/config/openclash" "/tmp/openclash_config.tmp"
|
||
if [ "$?" -ne "0" ]; then
|
||
cp "/etc/config/openclash" "/tmp/openclash_config.tmp"
|
||
fi
|
||
if ! $quick_start; then
|
||
: > "/tmp/openclash.change"
|
||
for i in $check_file; do
|
||
echo "$i $(date -r "$i")" >> "/tmp/openclash.change"
|
||
done 2>/dev/null
|
||
fi
|
||
}
|
||
|
||
#运行模式处理
|
||
do_run_mode()
|
||
{
|
||
en_mode=$(uci -q get openclash.config.en_mode)
|
||
|
||
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-mix" ]; then
|
||
en_mode_tun="2"
|
||
en_mode="redir-host"
|
||
fi
|
||
|
||
if [ "$en_mode" = "fake-ip-mix" ]; then
|
||
en_mode_tun="2"
|
||
en_mode="fake-ip"
|
||
fi
|
||
}
|
||
|
||
do_run_file()
|
||
{
|
||
|
||
#Some MIPS devices file system cound not use db
|
||
source "/etc/openwrt_release"
|
||
[ "$small_flash_memory" == "1" ] || [ -n "$(echo $core_version |grep mips)" ] || [ -n "$(echo $DISTRIB_ARCH |grep mips)" ] || [ -n "$(opkg status libc 2>/dev/null |grep 'Architecture' |awk -F ': ' '{print $2}' |grep mips)" ] || [ -n "$(apk list libc 2>/dev/null |grep mips)" ] && mkdir -p /tmp/etc/openclash && CACHE_PATH="/tmp/etc/openclash/cache.db"
|
||
|
||
[ -f "/etc/openclash/geosite.dat" ] && {
|
||
mv "/etc/openclash/geosite.dat" "/etc/openclash/GeoSite.dat" 2>/dev/null
|
||
}
|
||
|
||
[ -f "/etc/openclash/geoip.dat" ] && {
|
||
mv "/etc/openclash/geoip.dat" "/etc/openclash/GeoIP.dat" 2>/dev/null
|
||
}
|
||
|
||
if [ "$small_flash_memory" != "1" ]; then
|
||
meta_core_path="/etc/openclash/core/clash_meta"
|
||
ipdb_path="/etc/openclash/Country.mmdb"
|
||
chnr_path="/etc/openclash/china_ip_route.ipset"
|
||
chnr6_path="/etc/openclash/china_ip6_route.ipset"
|
||
geosite_path="/etc/openclash/GeoSite.dat"
|
||
geoip_path="/etc/openclash/GeoIP.dat"
|
||
mv "/tmp/etc/openclash/Country.mmdb" "$ipdb_path" 2>/dev/null
|
||
mv "/tmp/etc/openclash/china_ip_route.ipset" "$chnr_path" 2>/dev/null
|
||
mv "/tmp/etc/openclash/china_ip6_route.ipset" "$chnr6_path" 2>/dev/null
|
||
mv "/tmp/etc/openclash/GeoSite.dat" "$geosite_path" 2>/dev/null
|
||
mv "/tmp/etc/openclash/GeoIP.dat" "$geoip_path" 2>/dev/null
|
||
mv "/tmp/etc/openclash/core/" "/etc/openclash" 2>/dev/null
|
||
if [ "$CACHE_PATH" != "/tmp/etc/openclash/cache.db" ]; then
|
||
rm -rf "/tmp/etc/openclash" 2>/dev/null
|
||
fi
|
||
else
|
||
meta_core_path="/tmp/etc/openclash/core/clash_meta"
|
||
ipdb_path="/tmp/etc/openclash/Country.mmdb"
|
||
chnr_path="/tmp/etc/openclash/china_ip_route.ipset"
|
||
chnr6_path="/tmp/etc/openclash/china_ip6_route.ipset"
|
||
geosite_path="/tmp/etc/openclash/GeoSite.dat"
|
||
geoip_path="/tmp/etc/openclash/GeoIP.dat"
|
||
[ ! -h "/etc/openclash/Country.mmdb" ] && mv "/etc/openclash/Country.mmdb" "$ipdb_path" 2>/dev/null
|
||
[ ! -h "/etc/openclash/china_ip_route.ipset" ] && mv "/etc/openclash/china_ip_route.ipset" "$chnr_path" 2>/dev/null
|
||
[ ! -h "/etc/openclash/china_ip6_route.ipset" ] && mv "/etc/openclash/china_ip6_route.ipset" "$chnr6_path" 2>/dev/null
|
||
[ ! -h "/etc/openclash/GeoSite.dat" ] && mv "/etc/openclash/GeoSite.dat" "$geosite_path" 2>/dev/null
|
||
[ ! -h "/etc/openclash/GeoIP.dat" ] && mv "/etc/openclash/GeoIP.dat" "$geoip_path" 2>/dev/null
|
||
mv "/etc/openclash/core/" "/tmp/etc/openclash" 2>/dev/null
|
||
fi
|
||
|
||
rm -rf "/etc/openclash/cache.db" 2>/dev/null
|
||
rm -rf "/etc/openclash/clash" 2>/dev/null
|
||
|
||
ln -s "$meta_core_path" /etc/openclash/clash 2>/dev/null
|
||
core_type="Meta"
|
||
|
||
[ ! -f "$CLASH" ] && {
|
||
LOG_OUT "Tip: Detected that the Core is not Installed, Ready to Download..."
|
||
rm -rf "/tmp/clash_last_version"
|
||
/usr/share/openclash/openclash_core.sh "$core_type"
|
||
if [ ! -f "$meta_core_path" ]; then
|
||
start_fail
|
||
fi
|
||
}
|
||
|
||
[ ! -f "$ipdb_path" ] && {
|
||
LOG_OUT "Tip: Detected that the GEOIP Database is not Installed, Ready to Download..."
|
||
/usr/share/openclash/openclash_ipdb.sh
|
||
if [ ! -f "$ipdb_path" ]; then
|
||
start_fail
|
||
fi
|
||
}
|
||
|
||
[ ! -f "$geosite_path" ] && {
|
||
LOG_OUT "Tip: Detected that the GEOSITE Database is not Installed, Ready to Download..."
|
||
/usr/share/openclash/openclash_geosite.sh
|
||
if [ ! -f "$geosite_path" ]; then
|
||
start_fail
|
||
fi
|
||
}
|
||
|
||
[ ! -f "$geoip_path" ] && [ "$enable_geoip_dat" == "1" ] && {
|
||
LOG_OUT "Tip: Detected that the GEOIP Dat is not Installed, Ready to Download..."
|
||
/usr/share/openclash/openclash_geoip.sh
|
||
if [ "$enable_geoip_dat" == "1" ] && [ ! -f "$geoip_path" ]; then
|
||
start_fail
|
||
fi
|
||
}
|
||
|
||
if [ "$china_ip_route" != "0" ] || [ "$china_ip6_route" != "0" ] || [ "$disable_udp_quic" = "1" ]; then
|
||
if [ ! -f "$chnr_path" ] || [ ! -f "$chnr6_path" ]; then
|
||
LOG_OUT "Tip: Detected that the Chnroute Cidr is not Installed, Ready to Download..."
|
||
/usr/share/openclash/openclash_chnroute.sh
|
||
fi
|
||
if [ -n "$FW4" ]; then
|
||
if [ -z "$(cat "$chnr_path" |grep "define china_ip_route")" ] || [ -z "$(cat "$chnr6_path" |grep "define china_ip6_route")" ]; then
|
||
LOG_OUT "Tip: Detected that the Chnroute Cidr List Format is wrong, Ready to Reformat..."
|
||
/usr/share/openclash/openclash_chnroute.sh
|
||
if [ -z "$(cat "$chnr_path" |grep "define china_ip_route")" ] || [ -z "$(cat "$chnr6_path" |grep "define china_ip6_route")" ]; then
|
||
start_fail
|
||
fi
|
||
fi
|
||
else
|
||
if [ -n "$(cat "$chnr_path" |grep "define china_ip_route")" ] || [ -n "$(cat "$chnr6_path" |grep "define china_ip6_route")" ]; then
|
||
LOG_OUT "Tip: Detected that the Chnroute Cidr List Format is wrong, Ready to Reformat..."
|
||
/usr/share/openclash/openclash_chnroute.sh
|
||
if [ -n "$(cat "$chnr_path" |grep "define china_ip_route")" ] || [ -n "$(cat "$chnr6_path" |grep "define china_ip6_route")" ]; then
|
||
start_fail
|
||
fi
|
||
fi
|
||
fi
|
||
if [ ! -f "$chnr_path" ] || [ ! -f "$chnr6_path" ]; then
|
||
start_fail
|
||
fi
|
||
fi
|
||
|
||
[ ! -x "$meta_core_path" ] && chmod 4755 "$meta_core_path" 2>/dev/null
|
||
|
||
[ -f "$ipdb_path" ] && [ "$small_flash_memory" = "1" ] && {
|
||
ln -s "$ipdb_path" /etc/openclash/Country.mmdb 2>/dev/null
|
||
}
|
||
|
||
[ -f "$geosite_path" ] && [ "$small_flash_memory" = "1" ] && {
|
||
ln -s "$geosite_path" /etc/openclash/GeoSite.dat 2>/dev/null
|
||
}
|
||
|
||
[ -f "$geoip_path" ] && [ "$small_flash_memory" = "1" ] && {
|
||
ln -s "$geoip_path" /etc/openclash/GeoIP.dat 2>/dev/null
|
||
}
|
||
|
||
[ -f "$chnr_path" ] && [ "$small_flash_memory" = "1" ] && {
|
||
ln -s "$chnr_path" /etc/openclash/china_ip_route.ipset 2>/dev/null
|
||
}
|
||
|
||
[ -f "$chnr6_path" ] && [ "$small_flash_memory" = "1" ] && {
|
||
ln -s "$chnr6_path" /etc/openclash/china_ip6_route.ipset 2>/dev/null
|
||
}
|
||
|
||
#Restore history cache
|
||
if [ -f "$HISTORY_PATH" ] && [ -f "$HISTORY_PATH_OLD" ]; then
|
||
if [ "$(date -r $HISTORY_PATH +%s)" -ge "$(date -r $HISTORY_PATH_OLD +%s)" ]; then
|
||
cmp -s "$CACHE_PATH" "$HISTORY_PATH"
|
||
if [ "$?" -ne "0" ]; then
|
||
if [ "$CACHE_PATH" != "/tmp/etc/openclash/cache.db" ]; then
|
||
ln -s "$HISTORY_PATH" "$CACHE_PATH" 2>/dev/null
|
||
else
|
||
cp "$HISTORY_PATH" "$CACHE_PATH" 2>/dev/null
|
||
fi
|
||
fi
|
||
else
|
||
cmp -s "$CACHE_PATH_OLD" "$HISTORY_PATH_OLD"
|
||
if [ "$?" -ne "0" ]; then
|
||
cp "$HISTORY_PATH_OLD" "$CACHE_PATH_OLD" 2>/dev/null
|
||
fi
|
||
fi
|
||
else
|
||
if [ -f "$HISTORY_PATH" ]; then
|
||
cmp -s "$CACHE_PATH" "$HISTORY_PATH"
|
||
if [ "$?" -ne "0" ]; then
|
||
if [ "$CACHE_PATH" != "/tmp/etc/openclash/cache.db" ]; then
|
||
ln -s "$HISTORY_PATH" "$CACHE_PATH" 2>/dev/null
|
||
else
|
||
cp "$HISTORY_PATH" "$CACHE_PATH" 2>/dev/null
|
||
fi
|
||
fi
|
||
fi
|
||
if [ -f "$HISTORY_PATH_OLD" ]; then
|
||
cmp -s "$CACHE_PATH_OLD" "$HISTORY_PATH_OLD"
|
||
if [ "$?" -ne "0" ]; then
|
||
cp "$HISTORY_PATH_OLD" "$CACHE_PATH_OLD" 2>/dev/null
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
if [ "$CACHE_PATH" == "/tmp/etc/openclash/cache.db" ]; then
|
||
[ ! -f "$CACHE_PATH" ] && touch "$CACHE_PATH"
|
||
ln -s "$CACHE_PATH" /etc/openclash/cache.db 2>/dev/null
|
||
else
|
||
[ ! -f "$CACHE_PATH" ] && touch "$HISTORY_PATH"
|
||
ln -s "$HISTORY_PATH" "$CACHE_PATH" 2>/dev/null
|
||
fi
|
||
|
||
#创建原始备份
|
||
if [ ! -f "$2" ]; then
|
||
cp "$1" "$2"
|
||
fi
|
||
|
||
#保存启动内核类型
|
||
uci -q set openclash.config.core_type="$core_type"
|
||
uci -q commit openclash
|
||
|
||
}
|
||
|
||
start_run_core()
|
||
{
|
||
ulimit -SHn 1000000 2>/dev/null
|
||
ulimit -v unlimited 2>/dev/null
|
||
ulimit -u unlimited 2>/dev/null
|
||
modprobe tun >/dev/null 2>&1
|
||
if ! $quick_start; then
|
||
mv "$TMP_CONFIG_FILE" "$CONFIG_FILE" 2>/dev/null
|
||
rm -rf "$TMP_CONFIG_FILE" 2>/dev/null
|
||
fi
|
||
chown root:root /etc/openclash/core/* 2>/dev/null
|
||
kill_clash
|
||
procd_open_instance "openclash"
|
||
procd_set_param command /bin/sh -c "$CLASH -d $CLASH_CONFIG -f \"$CONFIG_FILE\" >> $LOG_FILE 2>&1"
|
||
procd_set_param user "root"
|
||
procd_set_param group "nogroup"
|
||
procd_set_param limits nproc="unlimited" as="unlimited" memlock="unlimited" nofile="1000000 1000000"
|
||
procd_set_param respawn 3600 3 10
|
||
procd_set_param stderr 1
|
||
procd_set_param no_new_privs 1
|
||
procd_close_instance
|
||
}
|
||
|
||
#防火墙设置部分
|
||
nft_ac_add()
|
||
{
|
||
if [ -z "$1" ]; then
|
||
return
|
||
fi
|
||
|
||
nft add element inet fw4 "$2" { "$1" } 2>/dev/null
|
||
[ -n "$3" ] && nft add element inet fw4 "$3" { "$1" } 2>/dev/null
|
||
}
|
||
|
||
ac_add()
|
||
{
|
||
if [ -z "$1" ]; then
|
||
return
|
||
fi
|
||
|
||
ipset add "$2" "$1" 2>/dev/null
|
||
[ -n "$3" ] && ipset add "$3" "$1" 2>/dev/null
|
||
}
|
||
|
||
wan_name_add()
|
||
{
|
||
if [ -z "$1" ]; then
|
||
return
|
||
fi
|
||
|
||
if [ -n "$wan_ints" ]; then
|
||
wan_ints="$wan_ints $1"
|
||
else
|
||
wan_ints="$1"
|
||
fi
|
||
}
|
||
|
||
wan6_name_add()
|
||
{
|
||
if [ -z "$1" ]; then
|
||
return
|
||
fi
|
||
|
||
if [ -n "$wan6_ints" ]; then
|
||
wan6_ints="$wan6_ints $1"
|
||
else
|
||
wan6_ints="$1"
|
||
fi
|
||
}
|
||
|
||
upnp_exclude()
|
||
{
|
||
if [ -s "$upnp_lease_file" ]; then
|
||
cat "$upnp_lease_file" |while read -r line
|
||
do
|
||
if [ -n "$line" ]; then
|
||
upnp_ip=$(echo "$line" |awk -F ':' '{print $3}')
|
||
upnp_dp=$(echo "$line" |awk -F ':' '{print $4}')
|
||
upnp_type=$(echo "$line" |awk -F ':' '{print $1}' |tr '[A-Z]' '[a-z]')
|
||
if [ -n "$upnp_ip" ] && [ -n "$upnp_dp" ] && [ -n "$upnp_type" ]; then
|
||
if [ -n "$FW4" ]; then
|
||
if [ -z "$(nft list chain inet fw4 openclash_upnp |grep "$upnp_ip" |grep "$upnp_dp" |grep "$upnp_type")" ]; then
|
||
nft add rule inet fw4 openclash_upnp ip saddr { "$upnp_ip" } "$upnp_type" sport "$upnp_dp" counter return 2>/dev/null
|
||
fi
|
||
else
|
||
if [ -z "$(iptables -t mangle -nL openclash_upnp |grep "$upnp_ip" |grep "$upnp_dp" |grep "$upnp_type")" ]; then
|
||
iptables -t mangle -A openclash_upnp -p "$upnp_type" -s "$upnp_ip" --sport "$upnp_dp" -j RETURN 2>/dev/null
|
||
fi
|
||
fi
|
||
fi
|
||
fi
|
||
done >/dev/null 2>&1
|
||
fi
|
||
}
|
||
|
||
check_core_status()
|
||
{
|
||
TUN_WAIT=0
|
||
TUN_RESTART=1
|
||
CORE_HTTP_CODE=0
|
||
|
||
if [ -z "$(pidof clash)" ]; then
|
||
sleep 5
|
||
fi
|
||
|
||
if [ -n "$en_mode_tun" ] || [ "$ipv6_mode" -eq 2 ] || [ "$ipv6_mode" -eq 3 ]; then
|
||
if [ -n "$en_mode_tun" ]; then
|
||
ip_="ip"
|
||
else
|
||
ip_="ip -6"
|
||
fi
|
||
|
||
#wait 120s most for tun interface start
|
||
while ( [ -n "$(pidof clash)" ] && [ -z "$($ip_ route list |grep utun)" ] && [ "$TUN_WAIT" -le 120 ] )
|
||
do
|
||
$ip_ link set utun up
|
||
let TUN_WAIT++
|
||
sleep 1
|
||
done >/dev/null 2>&1
|
||
|
||
if [ -n "$(pidof clash)" ] && [ -z "$($ip_ route list |grep utun)" ] && [ "$TUN_WAIT" -gt 120 ]; then
|
||
while ( [ -n "$(pidof clash)" ] && [ -z "$($ip_ route list |grep utun)" ] && [ "$TUN_RESTART" -le 3 ] )
|
||
do
|
||
LOG_OUT "Warning: TUN Interface Start Failed, Try to Restart Again..."
|
||
kill_clash
|
||
start_run_core
|
||
sleep 120
|
||
let TUN_RESTART++
|
||
done >/dev/null 2>&1
|
||
if [ -n "$(pidof clash)" ] && [ -z "$($ip_ route list |grep utun)" ] && [ "$TUN_RESTART" -gt 3 ]; then
|
||
LOG_OUT "Warning: TUN Interface Start Failed, Please Check The Dependence or Try to Restart Again!"
|
||
start_fail
|
||
fi
|
||
fi
|
||
|
||
if [ -n "$(pidof clash)" ]; then
|
||
if [ "$ipv6_mode" -eq 2 ] || [ "$ipv6_mode" -eq 3 ]; then
|
||
ip -6 rule del oif utun table 2022 >/dev/null 2>&1
|
||
ip -6 route del default dev utun table 2022 >/dev/null 2>&1
|
||
ip -6 route add default dev utun table "$PROXY_ROUTE_TABLE"
|
||
ip -6 rule add fwmark "$PROXY_FWMARK" ipproto icmp table main pref 1888
|
||
ip -6 rule add fwmark "$PROXY_FWMARK" table "$PROXY_ROUTE_TABLE" pref 1889
|
||
fi
|
||
|
||
ip route add default dev utun table "$PROXY_ROUTE_TABLE"
|
||
ip rule add fwmark "$PROXY_FWMARK" ipproto icmp table main pref 1888
|
||
ip rule add fwmark "$PROXY_FWMARK" table "$PROXY_ROUTE_TABLE" pref 1889
|
||
fi
|
||
else
|
||
reg4='^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$'
|
||
while ( [ -n "$(pidof clash)" ] && [ "$CORE_HTTP_CODE" != "200" ] && [ "$TUN_WAIT" -le 120 ] && [ -n "$(echo ${lan_ip} | grep -Eo ${reg4})" ] )
|
||
do
|
||
CORE_HTTP_CODE=$(curl -m 5 -o /dev/null -s -w '%{http_code}' -H 'Content-Type: application/json' -H "Authorization: Bearer ${da_password}" -XGET http://${lan_ip}:${cn_port}/group)
|
||
let TUN_WAIT++
|
||
sleep 1
|
||
done >/dev/null 2>&1
|
||
if [ -z "$(echo ${lan_ip} | grep -Eo ${reg4})" ]; then
|
||
LOG_OUT "Error: LAN IP Address Get Error, Please Check The LAN Interface Setting or Choose the Correct Interface in the Setting!"
|
||
sleep 10
|
||
fi
|
||
if [ "$CORE_HTTP_CODE" != "200" ]; then
|
||
LOG_OUT "Error: Core Status Abnormal, Please Check The Log Infos!"
|
||
start_fail
|
||
fi
|
||
fi
|
||
if [ -z "$(pidof clash)" ]; then
|
||
LOG_OUT "Error: Core Start Failed, Please Check The Log Infos!"
|
||
start_fail
|
||
fi
|
||
}
|
||
|
||
firewall_lan_ac_traffic()
|
||
{
|
||
local src_port src_ip proto target enabled family comment
|
||
config_get "src_port" "$section" "src_port" ""
|
||
config_get "src_ip" "$section" "src_ip" "localnetwork"
|
||
config_get "proto" "$section" "proto" "both"
|
||
config_get "target" "$section" "target" "return"
|
||
config_get "enabled" "$section" "enabled" "0"
|
||
config_get "family" "$section" "family" "both"
|
||
config_get "comment" "$section" "comment" "lan_ac_traffic"
|
||
|
||
if [ "$enabled" == "0" ] || [ -z "$src_port" ] || [ -z "$src_ip" ]; then
|
||
return
|
||
fi
|
||
|
||
local e_udp=false
|
||
local e_tcp=false
|
||
if [ $proto == "tcp" ]; then e_tcp=true; fi
|
||
if [ $proto == "udp" ]; then e_udp=true; fi
|
||
if [ $proto == "both" ]; then e_tcp=true; e_udp=true; fi
|
||
|
||
if [ -n "$FW4" ]; then
|
||
if [ "$src_ip" == "localnetwork" ]; then
|
||
src_ip="@localnetwork"
|
||
src_ip_v6="@localnetwork6"
|
||
else
|
||
src_ip="{ $src_ip }"
|
||
src_ip_v6="{ $src_ip }"
|
||
fi
|
||
|
||
if [ "$family" == "both" ] || [ "$family" == "ipv4" ]; then
|
||
if [ -z "$en_mode_tun" ] || [ "$en_mode_tun" -eq 2 ]; then
|
||
if $e_tcp ; then
|
||
nft insert rule inet fw4 openclash_output position 0 meta nfproto {ipv4} ip daddr != { "$fakeip_range" } ip saddr "$src_ip" tcp sport "$src_port" counter $target comment "\"$comment\"" >/dev/null 2>&1
|
||
nft insert rule inet fw4 openclash position 0 ip daddr != { "$fakeip_range" } ip saddr "$src_ip" tcp sport "$src_port" counter $target comment "\"$comment\"" >/dev/null 2>&1
|
||
fi
|
||
if $e_udp ; then
|
||
nft insert rule inet fw4 openclash_mangle_output position 0 meta nfproto {ipv4} ip daddr != { "$fakeip_range" } ip saddr "$src_ip" udp sport "$src_port" counter $target comment "\"$comment\"" >/dev/null 2>&1
|
||
nft insert rule inet fw4 openclash_mangle position 0 ip daddr != { "$fakeip_range" } ip saddr "$src_ip" udp sport "$src_port" counter $target comment "\"$comment\"" >/dev/null 2>&1
|
||
fi
|
||
elif [ "$en_mode_tun" -eq 1 ]; then
|
||
if $e_tcp ; then
|
||
nft insert rule inet fw4 openclash_mangle_output position 0 meta nfproto {ipv4} ip daddr != { "$fakeip_range" } ip saddr "$src_ip" tcp sport "$src_port" counter $target comment "\"$comment\"" >/dev/null 2>&1
|
||
nft insert rule inet fw4 openclash_mangle position 0 ip daddr != { "$fakeip_range" } ip saddr "$src_ip" tcp sport "$src_port" counter $target comment "\"$comment\"" >/dev/null 2>&1
|
||
fi
|
||
if $e_udp ; then
|
||
nft insert rule inet fw4 openclash_mangle_output position 0 meta nfproto {ipv4} ip daddr != { "$fakeip_range" } ip saddr "$src_ip" udp sport "$src_port" counter $target comment "\"$comment\"" >/dev/null 2>&1
|
||
nft insert rule inet fw4 openclash_mangle position 0 ip daddr != { "$fakeip_range" } ip saddr "$src_ip" udp sport "$src_port" counter $target comment "\"$comment\"" >/dev/null 2>&1
|
||
fi
|
||
fi
|
||
if $e_tcp ; then
|
||
nft insert rule inet fw4 openclash_post position 0 ip daddr != { "$fakeip_range" } ip saddr "$src_ip" tcp sport "$src_port" counter $target comment "\"$comment\"" >/dev/null 2>&1
|
||
fi
|
||
if $e_udp ; then
|
||
nft insert rule inet fw4 openclash_post position 0 ip daddr != { "$fakeip_range" } ip saddr "$src_ip" udp sport "$src_port" counter $target comment "\"$comment\"" >/dev/null 2>&1
|
||
fi
|
||
fi
|
||
|
||
if [ "$ipv6_enable" -eq 1 ]; then
|
||
if [ "$family" == "both" ] || [ "$family" == "ipv6" ]; then
|
||
if $e_tcp ; then
|
||
nft insert rule inet fw4 openclash_v6 position 0 ip6 saddr "$src_ip_v6" tcp sport "$src_port" counter $target comment "\"$comment\"" >/dev/null 2>&1
|
||
nft insert rule inet fw4 openclash_output_v6 position 0 ip6 saddr "$src_ip_v6" tcp sport "$src_port" counter $target comment "\"$comment\"" >/dev/null 2>&1
|
||
nft insert rule inet fw4 openclash_mangle_v6 position 0 ip6 saddr "$src_ip_v6" tcp sport "$src_port" counter $target comment "\"$comment\"" >/dev/null 2>&1
|
||
nft insert rule inet fw4 openclash_mangle_output_v6 position 0 meta nfproto {ipv6} ip6 saddr "$src_ip_v6" tcp sport "$src_port" counter $target comment "\"$comment\"" >/dev/null 2>&1
|
||
nft insert rule inet fw4 openclash_post_v6 position 0 ip6 saddr "$src_ip_v6" tcp sport "$src_port" counter $target comment "\"$comment\"" >/dev/null 2>&1
|
||
fi
|
||
if $e_udp ; then
|
||
nft insert rule inet fw4 openclash_mangle_v6 position 0 ip6 saddr "$src_ip_v6" udp sport "$src_port" counter $target comment "\"$comment\"" >/dev/null 2>&1
|
||
nft insert rule inet fw4 openclash_mangle_output_v6 position 0 meta nfproto {ipv6} ip6 saddr "$src_ip_v6" udp sport "$src_port" counter $target comment "\"$comment\"" >/dev/null 2>&1
|
||
nft insert rule inet fw4 openclash_post_v6 position 0 ip6 saddr "$src_ip_v6" udp sport "$src_port" counter $target comment "\"$comment\"" >/dev/null 2>&1
|
||
fi
|
||
fi
|
||
fi
|
||
else
|
||
if [ "$src_ip" == "localnetwork" ]; then
|
||
src_ip="-m set --match-set localnetwork src"
|
||
src_ip_v6="-m set --match-set localnetwork6 src"
|
||
else
|
||
src_ip="-s ${src_ip}"
|
||
src_ip_v6="-s ${src_ip}"
|
||
fi
|
||
src_port=$(echo $src_port |sed "s/-/:/g" 2>/dev/null)
|
||
if [ $target == "accept" ]; then target="ACCEPT"; fi
|
||
if [ $target == "return" ]; then target="RETURN"; fi
|
||
if [ $target == "drop" ]; then target="DROP"; fi
|
||
|
||
if [ "$family" == "both" ] || [ "$family" == "ipv4" ]; then
|
||
if [ -z "$en_mode_tun" ] || [ "$en_mode_tun" -eq 2 ]; then
|
||
if $e_tcp ; then
|
||
iptables -t nat -I openclash_output -p tcp ! -d "$fakeip_range" "$src_ip" --sport "$src_port" -j $target -m comment --comment "$comment" >/dev/null 2>&1
|
||
iptables -t nat -I openclash -p tcp ! -d "$fakeip_range" "$src_ip" --sport "$src_port" -j $target -m comment --comment "$comment" >/dev/null 2>&1
|
||
fi
|
||
if $e_udp ; then
|
||
iptables -t mangle -I openclash_output -p udp ! -d "$fakeip_range" "$src_ip" --sport "$src_port" -j $target -m comment --comment "$comment" >/dev/null 2>&1
|
||
iptables -t mangle -I openclash -p udp ! -d "$fakeip_range" "$src_ip" --sport "$src_port" -j $target -m comment --comment "$comment" >/dev/null 2>&1
|
||
fi
|
||
elif [ "$en_mode_tun" -eq 1 ]; then
|
||
if $e_tcp ; then
|
||
iptables -t mangle -I openclash_output -p tcp ! -d "$fakeip_range" "$src_ip" --sport "$src_port" -j $target -m comment --comment "$comment" >/dev/null 2>&1
|
||
iptables -t mangle -I openclash -p tcp ! -d "$fakeip_range" "$src_ip" --sport "$src_port" -j $target -m comment --comment "$comment" >/dev/null 2>&1
|
||
fi
|
||
if $e_udp ; then
|
||
iptables -t mangle -I openclash_output -p udp ! -d "$fakeip_range" "$src_ip" --sport "$src_port" -j $target -m comment --comment "$comment" >/dev/null 2>&1
|
||
iptables -t mangle -I openclash -p udp ! -d "$fakeip_range" "$src_ip" --sport "$src_port" -j $target -m comment --comment "$comment" >/dev/null 2>&1
|
||
fi
|
||
fi
|
||
if $e_tcp ; then
|
||
iptables -t nat -I openclash_post -p tcp ! -d "$fakeip_range" "$src_ip" --sport "$src_port" -j $target -m comment --comment "$comment" >/dev/null 2>&1
|
||
fi
|
||
if $e_udp ; then
|
||
iptables -t nat -I openclash_post -p udp ! -d "$fakeip_range" "$src_ip" --sport "$src_port" -j $target -m comment --comment "$comment" >/dev/null 2>&1
|
||
fi
|
||
fi
|
||
|
||
if [ "$ipv6_enable" -eq 1 ]; then
|
||
if [ "$family" == "both" ] || [ "$family" == "ipv6" ]; then
|
||
if $e_tcp ; then
|
||
ip6tables -t nat -I openclash "$src_ip_v6" -p tcp --sport "$src_port" -j $target -m comment --comment "$comment" >/dev/null 2>&1
|
||
ip6tables -t nat -A openclash_output "$src_ip_v6" -p tcp --sport "$src_port" -j $target -m comment --comment "$comment" >/dev/null 2>&1
|
||
ip6tables -t mangle -I openclash "$src_ip_v6" -p tcp --sport "$src_port" -j $target -m comment --comment "$comment" >/dev/null 2>&1
|
||
ip6tables -t mangle -I openclash_output -p tcp "$src_ip_v6" --sport "$src_port" -j $target -m comment --comment "$comment" >/dev/null 2>&1
|
||
ip6tables -t nat -I openclash_post -p tcp "$src_ip_v6" --sport "$src_port" -j $target -m comment --comment "$comment" >/dev/null 2>&1
|
||
fi
|
||
if $e_udp ; then
|
||
ip6tables -t mangle -I openclash -p udp "$src_ip_v6" --sport "$src_port" -j $target -m comment --comment "$comment" >/dev/null 2>&1
|
||
ip6tables -t mangle -I openclash_output -p udp "$src_ip_v6" --sport "$src_port" -j $target -m comment --comment "$comment" >/dev/null 2>&1
|
||
ip6tables -t nat -I openclash_post -p udp "$src_ip_v6" --sport "$src_port" -j $target -m comment --comment "$comment" >/dev/null 2>&1
|
||
fi
|
||
fi
|
||
fi
|
||
fi
|
||
}
|
||
|
||
firewall_rule_exclude()
|
||
{
|
||
local section="$1"
|
||
local name src dest dest_port dest_ip proto target enabled family
|
||
|
||
config_get "name" "$section" "name" ""
|
||
config_get "src" "$section" "src" ""
|
||
config_get "dest" "$section" "dest" ""
|
||
config_get "dest_port" "$section" "dest_port" ""
|
||
config_get "dest_ip" "$section" "dest_ip" ""
|
||
config_get "proto" "$section" "proto" ""
|
||
config_get "target" "$section" "target" ""
|
||
config_get "enabled" "$section" "enabled" ""
|
||
config_get "family" "$section" "family" ""
|
||
|
||
ipv6_suffix_to_nft_format() {
|
||
local ipv6_with_prefix="$1"
|
||
if [[ "$ipv6_with_prefix" =~ / ]] || [ -n "$(echo ${ipv6_with_prefix} | grep '/')" ]; then
|
||
local suffix="${ipv6_with_prefix%%/*}"
|
||
local prefix="${ipv6_with_prefix##*/}"
|
||
echo "& $prefix == $suffix"
|
||
else
|
||
echo "$ipv6_with_prefix"
|
||
fi
|
||
}
|
||
nft_ipv6=$(ipv6_suffix_to_nft_format "$dest_ip")
|
||
|
||
if [ a"$target" != aACCEPT ] || [ a"$enabled" == a0 ]; then
|
||
return
|
||
fi
|
||
|
||
local e_udp=false
|
||
local e_tcp=false
|
||
for p in $proto; do
|
||
if [ $p == tcp ]; then e_tcp=true; fi
|
||
if [ $p == udp ]; then e_udp=true; fi
|
||
if [ $p == all ]; then e_tcp=true; e_udp=true; fi
|
||
done
|
||
|
||
if [ -z "$proto" ]; then e_tcp=true; e_udp=true; fi
|
||
|
||
if ! $e_udp && ! $e_tcp ; then
|
||
return
|
||
fi
|
||
|
||
if [ -n "$(echo $dest_port |grep -E '\-|\:' 2>/dev/null)" ]; then
|
||
LOG_OUT "Warning: Because there is a port range【$dest_port】in the firewall rule settings【$name】auto bypassing may cause the normal connection of the client not to reach the core, if necessary, please add your own in the access control!"
|
||
return
|
||
fi
|
||
|
||
if [ -n "$FW4" ]; then
|
||
dest_ip=$(echo $dest_ip |sed "s/ /,/g" 2>/dev/null)
|
||
|
||
if [ -z "$family" ] || [ "$family" == "ipv4" ]; then
|
||
if [ -z "$en_mode_tun" ] || [ "$en_mode_tun" -eq 2 ]; then
|
||
for i in $dest_port; do
|
||
if $e_tcp ; then
|
||
nft insert rule inet fw4 openclash_output position 0 meta nfproto {ipv4} tcp sport "$i" counter return >/dev/null 2>&1
|
||
if [ -z "$dest_ip" ]; then
|
||
nft insert rule inet fw4 openclash position 0 meta nfproto {ipv4} tcp sport "$i" counter return >/dev/null 2>&1
|
||
else
|
||
nft insert rule inet fw4 openclash position 0 ip saddr { "$dest_ip" } tcp sport "$i" counter return >/dev/null 2>&1
|
||
fi
|
||
fi
|
||
if $e_udp ; then
|
||
nft insert rule inet fw4 openclash_mangle_output position 0 meta nfproto {ipv4} udp sport "$i" counter return >/dev/null 2>&1
|
||
if [ -z "$dest_ip" ]; then
|
||
nft insert rule inet fw4 openclash_mangle position 0 meta nfproto {ipv4} udp sport "$i" counter return >/dev/null 2>&1
|
||
else
|
||
nft insert rule inet fw4 openclash_mangle position 0 ip saddr { "$dest_ip" } udp sport "$i" counter return >/dev/null 2>&1
|
||
fi
|
||
fi
|
||
done
|
||
elif [ "$en_mode_tun" -eq 1 ]; then
|
||
for i in $dest_port; do
|
||
if $e_tcp ; then
|
||
nft insert rule inet fw4 openclash_mangle_output position 0 meta nfproto {ipv4} tcp sport "$i" counter return >/dev/null 2>&1
|
||
if [ -z "$dest_ip" ]; then
|
||
nft insert rule inet fw4 openclash_mangle position 0 meta nfproto {ipv4} tcp sport "$i" counter return >/dev/null 2>&1
|
||
else
|
||
nft insert rule inet fw4 openclash_mangle position 0 ip saddr { "$dest_ip" } tcp sport "$i" counter return >/dev/null 2>&1
|
||
fi
|
||
fi
|
||
if $e_udp ; then
|
||
nft insert rule inet fw4 openclash_mangle_output position 0 meta nfproto {ipv4} udp sport "$i" counter return >/dev/null 2>&1
|
||
if [ -z "$dest_ip" ]; then
|
||
nft insert rule inet fw4 openclash_mangle position 0 meta nfproto {ipv4} udp sport "$i" counter return >/dev/null 2>&1
|
||
else
|
||
nft insert rule inet fw4 openclash_mangle position 0 ip saddr { "$dest_ip" } udp sport "$i" counter return >/dev/null 2>&1
|
||
fi
|
||
fi
|
||
done
|
||
fi
|
||
fi
|
||
|
||
if [ "$ipv6_enable" -eq 1 ]; then
|
||
if [ -z "$family" ] || [ "$family" == "ipv6" ]; then
|
||
for i in $dest_port; do
|
||
if $e_tcp ; then
|
||
if [ -z "$dest_ip" ]; then
|
||
nft insert rule inet fw4 openclash_mangle_v6 position 0 meta nfproto {ipv6} tcp sport "$i" counter return >/dev/null 2>&1
|
||
nft insert rule inet fw4 openclash_v6 position 0 meta nfproto {ipv6} tcp sport "$i" counter return >/dev/null 2>&1
|
||
else
|
||
if [[ "$dest_ip" =~ , ]] || [ -n "$(echo ${dest_ip} | grep ',')" ]; then
|
||
nft insert rule inet fw4 openclash_mangle_v6 position 0 ip6 saddr { "$dest_ip" } tcp sport "$i" counter return >/dev/null 2>&1
|
||
nft insert rule inet fw4 openclash_v6 position 0 ip6 saddr { "$dest_ip" } tcp sport "$i" counter return >/dev/null 2>&1
|
||
else
|
||
nft insert rule inet fw4 openclash_mangle_v6 position 0 ip6 saddr "$nft_ipv6" tcp sport "$i" counter return >/dev/null 2>&1
|
||
nft insert rule inet fw4 openclash_v6 position 0 ip6 saddr "$nft_ipv6" tcp sport "$i" counter return >/dev/null 2>&1
|
||
fi
|
||
fi
|
||
nft insert rule inet fw4 openclash_mangle_output_v6 position 0 meta nfproto {ipv6} tcp sport "$i" counter return >/dev/null 2>&1
|
||
nft insert rule inet fw4 openclash_output_v6 position 0 meta nfproto {ipv6} tcp sport "$i" counter return >/dev/null 2>&1
|
||
fi
|
||
if $e_udp ; then
|
||
if [ -z "$dest_ip" ]; then
|
||
nft insert rule inet fw4 openclash_mangle_v6 position 0 meta nfproto {ipv6} udp sport "$i" counter return >/dev/null 2>&1
|
||
else
|
||
if [[ "$dest_ip" =~ , ]] || [ -n "$(echo ${dest_ip} | grep ',')" ]; then
|
||
nft insert rule inet fw4 openclash_mangle_v6 position 0 ip6 saddr { "$dest_ip" } udp sport "$i" counter return >/dev/null 2>&1
|
||
else
|
||
nft insert rule inet fw4 openclash_mangle_v6 position 0 ip6 saddr "$nft_ipv6" udp sport "$i" counter return >/dev/null 2>&1
|
||
fi
|
||
fi
|
||
nft insert rule inet fw4 openclash_mangle_output_v6 position 0 meta nfproto {ipv6} udp sport "$i" counter return >/dev/null 2>&1
|
||
fi
|
||
done
|
||
fi
|
||
fi
|
||
|
||
else
|
||
dest_port=$(echo $dest_port |sed "s/-/:/g" 2>/dev/null)
|
||
dest_ip=$(echo $dest_ip |sed "s/ /,/g" 2>/dev/null)
|
||
|
||
if [ -z "$family" ] || [ "$family" == "ipv4" ]; then
|
||
if [ -z "$en_mode_tun" ] || [ "$en_mode_tun" -eq 2 ]; then
|
||
for i in $dest_port; do
|
||
if $e_tcp ; then
|
||
iptables -t nat -I openclash_output -p tcp --sport "$i" -j RETURN >/dev/null 2>&1
|
||
if [ -z "$dest_ip" ]; then
|
||
iptables -t nat -I openclash -p tcp --sport "$i" -j RETURN >/dev/null 2>&1
|
||
else
|
||
iptables -t nat -I openclash -p tcp -s "$dest_ip" --sport "$i" -j RETURN >/dev/null 2>&1
|
||
fi
|
||
fi
|
||
if $e_udp ; then
|
||
iptables -t mangle -I openclash_output -p udp --sport "$i" -j RETURN >/dev/null 2>&1
|
||
if [ -z "$dest_ip" ]; then
|
||
iptables -t mangle -I openclash -p udp --sport "$i" -j RETURN >/dev/null 2>&1
|
||
else
|
||
iptables -t mangle -I openclash -p udp -s "$dest_ip" --sport "$i" -j RETURN >/dev/null 2>&1
|
||
fi
|
||
fi
|
||
done
|
||
elif [ "$en_mode_tun" -eq 1 ]; then
|
||
for i in $dest_port; do
|
||
if $e_tcp ; then
|
||
iptables -t mangle -I openclash_output -p tcp --sport "$i" -j RETURN >/dev/null 2>&1
|
||
if [ -z "$dest_ip" ]; then
|
||
iptables -t mangle -I openclash -p tcp --sport "$i" -j RETURN >/dev/null 2>&1
|
||
else
|
||
iptables -t mangle -I openclash -p tcp -s "$dest_ip" --sport "$i" -j RETURN >/dev/null 2>&1
|
||
fi
|
||
fi
|
||
if $e_udp ; then
|
||
iptables -t mangle -I openclash_output -p udp --sport "$i" -j RETURN >/dev/null 2>&1
|
||
if [ -z "$dest_ip" ]; then
|
||
iptables -t mangle -I openclash -p udp --sport "$i" -j RETURN >/dev/null 2>&1
|
||
else
|
||
iptables -t mangle -I openclash -p udp -s "$dest_ip" --sport "$i" -j RETURN >/dev/null 2>&1
|
||
fi
|
||
fi
|
||
done
|
||
fi
|
||
fi
|
||
|
||
if [ "$ipv6_enable" -eq 1 ]; then
|
||
if [ -z "$family" ] || [ "$family" == "ipv6" ]; then
|
||
for i in $dest_port; do
|
||
if $e_tcp ; then
|
||
if [ -z "$dest_ip" ]; then
|
||
ip6tables -t mangle -I openclash -p tcp --sport "$i" -j RETURN >/dev/null 2>&1
|
||
ip6tables -t nat -I openclash -p tcp --sport "$i" -j RETURN >/dev/null 2>&1
|
||
else
|
||
ip6tables -t mangle -I openclash -s "$dest_ip" -p tcp --sport "$i" -j RETURN >/dev/null 2>&1
|
||
ip6tables -t nat -I openclash -s "$dest_ip" -p tcp --sport "$i" -j RETURN >/dev/null 2>&1
|
||
fi
|
||
ip6tables -t mangle -I openclash_output -p tcp --sport "$i" -j RETURN >/dev/null 2>&1
|
||
ip6tables -t nat -I openclash_output -p tcp --sport "$i" -j RETURN >/dev/null 2>&1
|
||
fi
|
||
if $e_udp ; then
|
||
if [ -z "$dest_ip" ]; then
|
||
ip6tables -t mangle -I openclash -p udp --sport "$i" -j RETURN >/dev/null 2>&1
|
||
else
|
||
ip6tables -t mangle -I openclash -s "$dest_ip" -p udp --sport "$i" -j RETURN >/dev/null 2>&1
|
||
fi
|
||
ip6tables -t mangle -I openclash_output -p udp --sport "$i" -j RETURN >/dev/null 2>&1
|
||
fi
|
||
done
|
||
fi
|
||
fi
|
||
fi
|
||
}
|
||
|
||
firewall_redirect_exclude()
|
||
{
|
||
local section="$1"
|
||
local name src_dport dest_port dest_ip proto enabled
|
||
config_get "name" "$section" "name" ""
|
||
config_get "src_dport" "$section" "src_dport" ""
|
||
config_get "dest_port" "$section" "dest_port" ""
|
||
config_get "dest_ip" "$section" "dest_ip" ""
|
||
config_get "proto" "$section" "proto" ""
|
||
config_get "enabled" "$section" "enabled" ""
|
||
|
||
if [ -z "$src_dport" ] || [ a"$enabled" == a0 ]; then
|
||
return
|
||
fi
|
||
|
||
if [ -n "$(echo $dest_port |grep -E '\-|\:' 2>/dev/null)" ]; then
|
||
LOG_OUT "Warning: Because there is a port range【$dest_port】in the firewall rule settings【$name】auto bypassing may cause the normal connection of the client not to reach the core, if necessary, please add your own in the access control!"
|
||
return
|
||
fi
|
||
|
||
local e_udp=false
|
||
local e_tcp=false
|
||
for p in $proto; do
|
||
if [ $p == tcp ]; then e_tcp=true; fi
|
||
if [ $p == udp ]; then e_udp=true; fi
|
||
if [ $p == all ]; then e_tcp=true; e_udp=true; fi
|
||
done
|
||
|
||
if [ -z "$proto" ]; then e_tcp=true; e_udp=true; fi
|
||
|
||
if ! $e_udp && ! $e_tcp ; then
|
||
return
|
||
fi
|
||
|
||
if [ -n "$FW4" ]; then
|
||
if [ -z "$en_mode_tun" ] || [ "$en_mode_tun" -eq 2 ]; then
|
||
if $e_tcp ; then
|
||
nft insert rule inet fw4 openclash_output position 0 ip saddr { "$dest_ip" } tcp sport "$dest_port" counter return >/dev/null 2>&1
|
||
fi
|
||
if $e_udp ; then
|
||
nft insert rule inet fw4 openclash_mangle_output position 0 ip saddr { "$dest_ip" } udp sport "$dest_port" counter return >/dev/null 2>&1
|
||
if [ -n "$dest_ip" ]; then
|
||
nft insert rule inet fw4 openclash_mangle position 0 ip saddr { "$dest_ip" } udp sport "$dest_port" counter return >/dev/null 2>&1
|
||
fi
|
||
fi
|
||
elif [ "$en_mode_tun" -eq 1 ]; then
|
||
if $e_tcp ; then
|
||
nft insert rule inet fw4 openclash_mangle_output position 0 ip saddr { "$dest_ip" } tcp sport "$dest_port" counter return >/dev/null 2>&1
|
||
if [ -n "$dest_ip" ]; then
|
||
nft insert rule inet fw4 openclash_mangle position 0 ip saddr { "$dest_ip" } tcp sport "$dest_port" counter return >/dev/null 2>&1
|
||
fi
|
||
fi
|
||
if $e_udp ; then
|
||
nft insert rule inet fw4 openclash_mangle_output position 0 ip saddr { "$dest_ip" } udp sport "$dest_port" counter return >/dev/null 2>&1
|
||
if [ -n "$dest_ip" ]; then
|
||
nft insert rule inet fw4 openclash_mangle position 0 ip saddr { "$dest_ip" } udp sport "$dest_port" counter return >/dev/null 2>&1
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
if [ "$ipv6_enable" -eq 1 ]; then
|
||
if $e_tcp ; then
|
||
if [ -n "$dest_ip" ]; then
|
||
if [ "$ipv6_mode" -eq 1 ] || [ "$ipv6_mode" -eq 3 ]; then
|
||
nft insert rule inet fw4 openclash_v6 position 0 ip6 saddr { "$dest_ip" } tcp sport "$dest_port" counter return >/dev/null 2>&1
|
||
nft insert rule inet fw4 openclash_output_v6 position 0 ip6 saddr { "$dest_ip" } tcp sport "$dest_port" counter return >/dev/null 2>&1
|
||
else
|
||
nft insert rule inet fw4 openclash_mangle_v6 position 0 ip6 saddr { "$dest_ip" } tcp sport "$dest_port" counter return >/dev/null 2>&1
|
||
nft insert rule inet fw4 openclash_mangle_output_v6 position 0 ip6 saddr { "$dest_ip" } tcp sport "$dest_port" counter return >/dev/null 2>&1
|
||
fi
|
||
fi
|
||
fi
|
||
if $e_udp ; then
|
||
if [ -n "$dest_ip" ]; then
|
||
nft insert rule inet fw4 openclash_mangle_v6 position 0 ip6 saddr { "$dest_ip" } udp sport "$dest_port" counter return >/dev/null 2>&1
|
||
nft insert rule inet fw4 openclash_mangle_output_v6 position 0 ip6 saddr { "$dest_ip" } udp sport "$dest_port" counter return >/dev/null 2>&1
|
||
fi
|
||
fi
|
||
fi
|
||
else
|
||
dest_port=$(echo $dest_port |sed "s/-/:/g" 2>/dev/null)
|
||
dest_ip=$(echo $dest_ip |sed "s/ /,/g" 2>/dev/null)
|
||
[ -n "$dest_ip" ] && dest_ip="-s ${dest_ip}"
|
||
|
||
if [ -z "$en_mode_tun" ] || [ "$en_mode_tun" -eq 2 ]; then
|
||
if $e_tcp ; then
|
||
iptables -t nat -I openclash_output "$dest_ip" -p tcp --sport "$dest_port" -j RETURN >/dev/null 2>&1
|
||
fi
|
||
if $e_udp ; then
|
||
iptables -t mangle -I openclash_output "$dest_ip" -p udp --sport "$dest_port" -j RETURN >/dev/null 2>&1
|
||
if [ -n "$dest_ip" ]; then
|
||
iptables -t mangle -I openclash "$dest_ip" -p udp --sport "$dest_port" -j RETURN >/dev/null 2>&1
|
||
fi
|
||
fi
|
||
elif [ "$en_mode_tun" -eq 1 ]; then
|
||
if $e_tcp ; then
|
||
iptables -t mangle -I openclash_output -p tcp "$dest_ip" --sport "$dest_port" -j RETURN >/dev/null 2>&1
|
||
if [ -n "$dest_ip" ]; then
|
||
iptables -t mangle -I openclash -p tcp "$dest_ip" --sport "$dest_port" -j RETURN >/dev/null 2>&1
|
||
fi
|
||
fi
|
||
if $e_udp ; then
|
||
iptables -t mangle -I openclash_output -p udp "$dest_ip" --sport "$dest_port" -j RETURN >/dev/null 2>&1
|
||
if [ -n "$dest_ip" ]; then
|
||
iptables -t mangle -I openclash -p udp "$dest_ip" --sport "$dest_port" -j RETURN >/dev/null 2>&1
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
if [ "$ipv6_enable" -eq 1 ] && [ -n "$(ip6tables -t mangle -L 2>&1 | grep -o 'Chain')" ]; then
|
||
if $e_tcp ; then
|
||
if [ -n "$dest_ip" ]; then
|
||
if [ "$ipv6_mode" -eq 1 ] || [ "$ipv6_mode" -eq 3 ]; then
|
||
ip6tables -t nat -I openclash -p tcp "$dest_ip" --sport "$dest_port" -j RETURN >/dev/null 2>&1
|
||
ip6tables -t nat -I openclash_output -p tcp "$dest_ip" --sport "$dest_port" -j RETURN >/dev/null 2>&1
|
||
else
|
||
ip6tables -t mangle -I openclash -p tcp "$dest_ip" --sport "$dest_port" -j RETURN >/dev/null 2>&1
|
||
ip6tables -t mangle -I openclash_output -p tcp "$dest_ip" --sport "$dest_port" -j RETURN >/dev/null 2>&1
|
||
fi
|
||
fi
|
||
|
||
fi
|
||
if $e_udp ; then
|
||
if [ -n "$dest_ip" ]; then
|
||
ip6tables -t mangle -I openclash -p udp "$dest_ip" --sport "$dest_port" -j RETURN >/dev/null 2>&1
|
||
ip6tables -t mangle -I openclash_output -p udp "$dest_ip" --sport "$dest_port" -j RETURN >/dev/null 2>&1
|
||
fi
|
||
fi
|
||
fi
|
||
fi
|
||
}
|
||
|
||
set_firewall()
|
||
{
|
||
|
||
if [ -z "$(uci -q get firewall.openclash)" ] || [ -z "$(uci -q get ucitrack.@openclash[-1].init)" ]; then
|
||
uci -q delete ucitrack.@openclash[-1]
|
||
uci -q add ucitrack openclash
|
||
uci -q set ucitrack.@openclash[-1].init=openclash
|
||
uci -q commit ucitrack
|
||
uci -q delete firewall.openclash
|
||
uci -q set firewall.openclash=include
|
||
uci -q set firewall.openclash.type=script
|
||
uci -q set firewall.openclash.path=/var/etc/openclash.include
|
||
[ -n "$FW4" ] || uci -q set firewall.openclash.reload=1
|
||
uci -q commit firewall
|
||
fi
|
||
|
||
mkdir -p /var/etc
|
||
cat > "/var/etc/openclash.include" <<-EOF
|
||
/etc/init.d/openclash reload "firewall" >/dev/null 2>&1
|
||
EOF
|
||
|
||
#common ports
|
||
if [ -n "$common_ports" ] && [ "$common_ports" != "0" ]; then
|
||
if [ "$common_ports" = "1" ]; then
|
||
common_port="21 22 23 53 80 123 143 194 443 465 587 853 993 995 998 2052 2053 2082 2083 2086 2095 2096 5222 5228 5229 5230 8080 8443 8880 8888 8889"
|
||
else
|
||
common_port=$common_ports
|
||
fi
|
||
fi
|
||
|
||
case $enable_redirect_dns in
|
||
"1")
|
||
LOG_OUT "Tip: DNS Hijacking Mode is Dnsmasq Redirect..."
|
||
;;
|
||
"2")
|
||
LOG_OUT "Tip: DNS Hijacking Mode is Firewall Redirect..."
|
||
;;
|
||
*)
|
||
LOG_OUT "Tip: DNS Hijacking is Disabled..."
|
||
esac
|
||
|
||
if [ "$ipv6_enable" -eq 1 ]; then
|
||
case $ipv6_mode in
|
||
"1")
|
||
LOG_OUT "Tip: IPv6 Proxy Mode is Redirect..."
|
||
;;
|
||
"2")
|
||
LOG_OUT "Tip: IPv6 Proxy Mode is TUN..."
|
||
;;
|
||
"3")
|
||
LOG_OUT "Tip: IPv6 Proxy Mode is Mix..."
|
||
;;
|
||
*)
|
||
LOG_OUT "Tip: IPv6 Proxy Mode is TProxy..."
|
||
esac
|
||
fi
|
||
|
||
#NFTABLES
|
||
if [ -n "$FW4" ]; then
|
||
LOG_OUT "Tip: Firewall4 was Detected, Use NFTABLE Rules..."
|
||
|
||
#china ip route
|
||
if [ "$china_ip_route" != "0" ] || [ "$disable_udp_quic" = "1" ]; then
|
||
nft 'flush set inet fw4 china_ip_route'
|
||
nft -f '/etc/openclash/china_ip_route.ipset'
|
||
CHNROUTE_WAIT=0
|
||
while ( [ -z "$(nft list sets |grep "set china_ip_route {")" ] && [ "$CHNROUTE_WAIT" -le 3 ] )
|
||
do
|
||
nft -f '/etc/openclash/china_ip_route.ipset'
|
||
let CHNROUTE_WAIT++
|
||
done
|
||
|
||
if [ "$enable_redirect_dns" != "2" ]; then
|
||
echo "add set inet fw4 china_ip_route_pass { type ipv4_addr; flags interval; auto-merge; }" >/tmp/openclash_china_ip_route_pass.list
|
||
[ -z `(awk '!/^$/&&!/^#/&&!/([0-9a-zA-Z-]{1,}\.)+([a-zA-Z]{2,})/{printf(" %s\n",$0)}' /etc/openclash/custom/openclash_custom_chnroute_pass.list)` ] || {
|
||
echo "define china_ip_route_pass = {" >>/tmp/openclash_china_ip_route_pass.list
|
||
awk '!/^$/&&!/^#/&&!/([0-9a-zA-Z-]{1,}\.)+([a-zA-Z]{2,})/{printf(" %s,\n",$0)}' /etc/openclash/custom/openclash_custom_chnroute_pass.list |sed '$ s/.$//' >>/tmp/openclash_china_ip_route_pass.list 2>/dev/null
|
||
echo "}" >>/tmp/openclash_china_ip_route_pass.list
|
||
echo 'add element inet fw4 china_ip_route_pass $china_ip_route_pass' >>/tmp/openclash_china_ip_route_pass.list
|
||
}
|
||
nft 'flush set inet fw4 china_ip_route_pass'
|
||
nft -f '/tmp/openclash_china_ip_route_pass.list'
|
||
rm -rf /tmp/openclash_china_ip_route_pass.list
|
||
fi
|
||
fi
|
||
|
||
#lan_ac
|
||
if [ "$lan_ac_mode" = "0" ]; then
|
||
if [ -n "$(uci -q get openclash.config.lan_ac_black_ips)" ]; then
|
||
nft 'add set inet fw4 lan_ac_black_ips { type ipv4_addr; flags interval; auto-merge; }'
|
||
nft 'add set inet fw4 lan_ac_black_ipv6s { type ipv6_addr; flags interval; auto-merge; }'
|
||
config_load "openclash"
|
||
config_list_foreach "config" "lan_ac_black_ips" nft_ac_add "lan_ac_black_ips" "lan_ac_black_ipv6s"
|
||
fi
|
||
if [ -n "$(uci -q get openclash.config.lan_ac_black_macs)" ]; then
|
||
nft 'add set inet fw4 lan_ac_black_macs { type ether_addr; }'
|
||
config_load "openclash"
|
||
config_list_foreach "config" "lan_ac_black_macs" nft_ac_add "lan_ac_black_macs"
|
||
fi
|
||
elif [ "$lan_ac_mode" = "1" ]; then
|
||
if [ -n "$(uci -q get openclash.config.lan_ac_white_ips)" ]; then
|
||
nft 'add set inet fw4 lan_ac_white_ips { type ipv4_addr; flags interval; auto-merge; }'
|
||
nft 'add set inet fw4 lan_ac_white_ipv6s { type ipv6_addr; flags interval; auto-merge; }'
|
||
config_load "openclash"
|
||
config_list_foreach "config" "lan_ac_white_ips" nft_ac_add "lan_ac_white_ips" "lan_ac_white_ipv6s"
|
||
fi
|
||
if [ -n "$(uci -q get openclash.config.lan_ac_white_macs)" ]; then
|
||
nft 'add set inet fw4 lan_ac_white_macs { type ether_addr; }'
|
||
config_load "openclash"
|
||
config_list_foreach "config" "lan_ac_white_macs" nft_ac_add "lan_ac_white_macs"
|
||
fi
|
||
fi
|
||
|
||
#wan ac
|
||
if [ -n "$(uci -q get openclash.config.wan_ac_black_ips)" ]; then
|
||
nft 'add set inet fw4 wan_ac_black_ips { type ipv4_addr; flags interval; auto-merge; }'
|
||
nft 'add set inet fw4 wan_ac_black_ipv6s { type ipv6_addr; flags interval; auto-merge; }'
|
||
config_load "openclash"
|
||
config_list_foreach "config" "wan_ac_black_ips" nft_ac_add "wan_ac_black_ips" "wan_ac_black_ipv6s"
|
||
fi
|
||
|
||
#local
|
||
nft 'add set inet fw4 localnetwork { type ipv4_addr; flags interval; auto-merge; }'
|
||
#nft 'delete set inet fw4 localnetwork'
|
||
if [ -f "/etc/openclash/custom/openclash_custom_localnetwork_ipv4.list" ]; then
|
||
for line in `cat "/etc/openclash/custom/openclash_custom_localnetwork_ipv4.list"`
|
||
do
|
||
nft add element inet fw4 localnetwork { "$line" }
|
||
done
|
||
else
|
||
nft 'add element inet fw4 localnetwork { 0.0.0.0/8, 127.0.0.0/8, 10.0.0.0/8, 169.254.0.0/16, 192.168.0.0/16, 224.0.0.0/4, 240.0.0.0/4, 172.16.0.0/12, 100.64.0.0/10}'
|
||
fi
|
||
|
||
if [ -n "$wan_ip4s" ]; then
|
||
for wan_ip4 in $wan_ip4s; do
|
||
nft add element inet fw4 localnetwork { "$wan_ip4" }
|
||
done
|
||
fi
|
||
|
||
#common ports
|
||
if [ -n "$common_ports" ] && [ "$common_ports" != "0" ]; then
|
||
nft 'add set inet fw4 common_ports { type inet_service; flags interval; }'
|
||
for i in $common_port; do
|
||
nft add element inet fw4 common_ports { "$i" }
|
||
done
|
||
fi
|
||
|
||
#bypass gateway compatible
|
||
if [ "$bypass_gateway_compatible" -eq 1 ]; then
|
||
#nft 'delete chain inet fw4 openclash_post'
|
||
nft 'add chain inet fw4 openclash_post'
|
||
nft 'flush chain inet fw4 openclash_post'
|
||
nft 'add rule inet fw4 openclash_post skgid == 65534 counter return'
|
||
nft add rule inet fw4 openclash_post mark "$PROXY_FWMARK" counter accept
|
||
nft 'add rule inet fw4 openclash_post ip daddr @localnetwork counter return'
|
||
nft 'add rule inet fw4 openclash_post ct direction reply counter return'
|
||
nft 'add rule inet fw4 openclash_post fib saddr type != { local } counter masquerade'
|
||
nft add rule inet fw4 srcnat meta nfproto {ipv4} counter jump openclash_post comment \"OpenClash Bypass Gateway Compatible\"
|
||
fi
|
||
|
||
#intranet allowed
|
||
if [ "$intranet_allowed" -eq 1 ]; then
|
||
if [ -n "$intranet_allowed_wan_name" ] && [ "$intranet_allowed_wan_name" != "0" ]; then
|
||
config_load "openclash"
|
||
config_list_foreach "config" "intranet_allowed_wan_name" wan_name_add
|
||
else
|
||
wan_ints=$(nft list chain inet fw4 input |grep -e "jump input_wan" 2>/dev/null |awk '{for (i=1;i<=NF;i++){if ($i ~ /iifname/ && $(i+1) != "{") {print $(i+1)} if ($i ~ /iifname/ && $(i+1) == "{"){for (j=i+1;j<=NF;j++){if ($j~ /}/) {out="";for (k=i+1;k<=j;k++){out=out" "$k};print out}}}}}' 2>/dev/null |sed 's/"//g'|sed 's/{//g'|sed 's/}//g'|sed 's/,//g')
|
||
fi
|
||
if [ -n "$wan_ints" ]; then
|
||
nft 'add chain inet fw4 openclash_wan_input'
|
||
nft 'flush chain inet fw4 openclash_wan_input'
|
||
for wan_int in $wan_ints; do
|
||
#nft delete rule inet fw4 input $(nft -a list chain inet fw4 input |grep "@localnetwork" |awk -F '# ' '{print$2}')
|
||
nft insert rule inet fw4 input position 0 iifname "$wan_int" ip saddr != @localnetwork counter jump openclash_wan_input
|
||
done
|
||
nft add rule inet fw4 openclash_wan_input th dport {$proxy_port,$tproxy_port,$cn_port,$http_port,$socks_port,$mixed_port,$dns_port} counter reject
|
||
else
|
||
LOG_OUT "Warning: Can't Settting Only Intranet Allowed Function, Get IPv4 WAN Interfaces error, Please Verify The Firewall's WAN Zone Name is wan, Ignore This IF The Device Does not Have a WAN Interfaces..."
|
||
fi
|
||
fi
|
||
|
||
DNSPORT=$(uci -q get dhcp.@dnsmasq[0].port)
|
||
if [ -z "$DNSPORT" ]; then
|
||
DNSPORT=$(netstat -nlp |grep -E '127.0.0.1:.*dnsmasq' |awk -F '127.0.0.1:' '{print $2}' |awk '{print $1}' |head -1 || echo 53)
|
||
fi
|
||
|
||
if [ "$enable_redirect_dns" -eq 1 ]; then
|
||
if [ -z "$(nft list chain inet fw4 dstnat |grep 'OpenClash DNS Hijack')" ]; then
|
||
if [ "$lan_ac_mode" != "1" ]; then
|
||
ACBLACKDNSFILTER=""
|
||
if [ "$lan_ac_mode" = "0" ]; then
|
||
if [ -n "$(uci -q get openclash.config.lan_ac_black_ips)" ]; then
|
||
ACBLACKDNSFILTER="ip saddr != @lan_ac_black_ips"
|
||
fi
|
||
if [ -n "$(uci -q get openclash.config.lan_ac_black_macs)" ]; then
|
||
ACBLACKDNSFILTER="$ACBLACKDNSFILTER ether saddr != @lan_ac_black_macs"
|
||
fi
|
||
fi
|
||
nft insert rule inet fw4 dstnat position 0 meta l4proto {tcp,udp} th dport 53 ${ACBLACKDNSFILTER} counter redirect to "$DNSPORT" comment \"OpenClash DNS Hijack\"
|
||
else
|
||
nft insert rule inet fw4 dstnat position 0 meta l4proto {tcp,udp} th dport 53 ip saddr @lan_ac_white_ips counter redirect to "$DNSPORT" comment \"OpenClash DNS Hijack\"
|
||
nft insert rule inet fw4 dstnat position 0 meta l4proto {tcp,udp} th dport 53 ether saddr @lan_ac_white_macs counter redirect to "$DNSPORT" comment \"OpenClash DNS Hijack\"
|
||
fi
|
||
fi
|
||
if [ "$router_self_proxy" = 1 ]; then
|
||
nft 'add chain inet fw4 nat_output { type nat hook output priority -1; }'
|
||
nft insert rule inet fw4 nat_output position 0 skgid != 65534 meta l4proto {tcp,udp} th dport 53 ip daddr {127.0.0.1} counter redirect to "$DNSPORT" comment \"OpenClash DNS Hijack\"
|
||
fi
|
||
elif [ "$enable_redirect_dns" -eq 2 ]; then
|
||
nft 'add chain inet fw4 openclash_dns_redirect'
|
||
if [ "$lan_ac_mode" != "1" ]; then
|
||
ACBLACKDNSFILTER=""
|
||
if [ "$lan_ac_mode" = "0" ]; then
|
||
if [ -n "$(uci -q get openclash.config.lan_ac_black_ips)" ]; then
|
||
ACBLACKDNSFILTER="ip saddr != @lan_ac_black_ips"
|
||
fi
|
||
if [ -n "$(uci -q get openclash.config.lan_ac_black_macs)" ]; then
|
||
ACBLACKDNSFILTER="$ACBLACKDNSFILTER ether saddr != @lan_ac_black_macs"
|
||
fi
|
||
fi
|
||
nft add rule inet fw4 openclash_dns_redirect meta l4proto {tcp,udp} th dport 53 ${ACBLACKDNSFILTER} counter redirect to "$dns_port" comment \"OpenClash DNS Hijack\"
|
||
else
|
||
nft add rule inet fw4 openclash_dns_redirect meta l4proto {tcp,udp} th dport 53 ip saddr @lan_ac_white_ips counter redirect to "$dns_port" comment \"OpenClash DNS Hijack\"
|
||
nft add rule inet fw4 openclash_dns_redirect meta l4proto {tcp,udp} th dport 53 ether saddr @lan_ac_white_macs counter redirect to "$dns_port" comment \"OpenClash DNS Hijack\"
|
||
fi
|
||
nft 'insert rule inet fw4 dstnat position 0 meta l4proto {tcp,udp} th dport 53 counter jump openclash_dns_redirect'
|
||
if [ "$router_self_proxy" = 1 ]; then
|
||
nft 'add chain inet fw4 nat_output { type nat hook output priority -1; }'
|
||
nft insert rule inet fw4 nat_output position 0 meta l4proto {tcp,udp} th dport 53 ip daddr {127.0.0.1} meta skgid != 65534 counter redirect to "$dns_port" comment \"OpenClash DNS Hijack\"
|
||
fi
|
||
fi
|
||
|
||
if [ -z "$en_mode_tun" ] || [ "$en_mode_tun" -eq 2 ]; then
|
||
#tcp
|
||
nft 'add chain inet fw4 openclash'
|
||
nft 'flush chain inet fw4 openclash'
|
||
nft 'add rule inet fw4 openclash ip daddr @localnetwork counter return'
|
||
nft 'add rule inet fw4 openclash ct direction reply counter return'
|
||
if [ -z "$en_mode_tun" ] && [ "$en_mode" = "fake-ip" ]; then
|
||
nft add rule inet fw4 openclash ip protocol tcp ip daddr { "$fakeip_range" } counter redirect to "$proxy_port"
|
||
fi
|
||
nft 'add rule inet fw4 openclash ip daddr @wan_ac_black_ips counter return'
|
||
nft 'add rule inet fw4 openclash ip saddr @lan_ac_black_ips counter return'
|
||
nft 'add rule inet fw4 openclash ether saddr @lan_ac_black_macs counter return'
|
||
if [ "$lan_ac_mode" = "1" ] && [ -n "$(uci -q get openclash.config.lan_ac_white_ips)" ] && [ -n "$(uci -q get openclash.config.lan_ac_white_macs)" ]; then
|
||
nft 'add rule inet fw4 openclash ether saddr != @lan_ac_white_macs ip saddr != @lan_ac_white_ips counter return'
|
||
else
|
||
nft 'add rule inet fw4 openclash ether saddr != @lan_ac_white_macs counter return'
|
||
nft 'add rule inet fw4 openclash ip saddr != @lan_ac_white_ips counter return'
|
||
fi
|
||
|
||
if [ "$en_mode" = "redir-host" ]; then
|
||
nft 'add rule inet fw4 openclash th dport != @common_ports counter return'
|
||
fi
|
||
if [ "$china_ip_route" != "0" ]; then
|
||
if [ "$china_ip_route" = "1" ]; then
|
||
rule="ip daddr @china_ip_route"
|
||
elif [ "$china_ip_route" = "2" ]; then
|
||
rule="ip daddr != @china_ip_route"
|
||
fi
|
||
[ "$enable_redirect_dns" != "2" ] && rule="$rule ip daddr != @china_ip_route_pass"
|
||
nft "add rule inet fw4 openclash $rule counter return"
|
||
fi
|
||
|
||
nft add rule inet fw4 openclash ip protocol tcp counter redirect to "$proxy_port"
|
||
nft 'add rule inet fw4 dstnat meta nfproto {ipv4} ip protocol tcp counter jump openclash'
|
||
if [ -z "$en_mode_tun" ]; then
|
||
#udp
|
||
if [ "$enable_udp_proxy" -eq 1 ]; then
|
||
modprobe nft_tproxy >/dev/null 2>&1
|
||
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"
|
||
nft 'add chain inet fw4 openclash_mangle'
|
||
nft 'flush chain inet fw4 openclash_mangle'
|
||
nft 'add chain inet fw4 openclash_upnp'
|
||
nft 'flush chain inet fw4 openclash_upnp'
|
||
upnp_exclude
|
||
nft 'add rule inet fw4 openclash_mangle ip daddr @localnetwork counter return'
|
||
nft 'add rule inet fw4 openclash_mangle ct direction reply counter return'
|
||
if [ "$en_mode" = "fake-ip" ]; then
|
||
nft add rule inet fw4 openclash_mangle meta l4proto { udp } ip daddr { "$fakeip_range" } mark set "$PROXY_FWMARK" tproxy ip to 127.0.0.1:"$tproxy_port" counter accept
|
||
fi
|
||
nft 'add rule inet fw4 openclash_mangle ip daddr @wan_ac_black_ips counter return'
|
||
nft 'add rule inet fw4 openclash_mangle ip saddr @lan_ac_black_ips counter return'
|
||
nft 'add rule inet fw4 openclash_mangle ether saddr @lan_ac_black_macs counter return'
|
||
if [ "$lan_ac_mode" = "1" ] && [ -n "$(uci -q get openclash.config.lan_ac_white_ips)" ] && [ -n "$(uci -q get openclash.config.lan_ac_white_macs)" ]; then
|
||
nft 'add rule inet fw4 openclash_mangle ether saddr != @lan_ac_white_macs ip saddr != @lan_ac_white_ips counter return'
|
||
else
|
||
nft 'add rule inet fw4 openclash_mangle ether saddr != @lan_ac_white_macs counter return'
|
||
nft 'add rule inet fw4 openclash_mangle ip saddr != @lan_ac_white_ips counter return'
|
||
fi
|
||
|
||
if [ "$en_mode" = "redir-host" ]; then
|
||
nft 'add rule inet fw4 openclash_mangle th dport != @common_ports counter return'
|
||
fi
|
||
if [ "$china_ip_route" != "0" ]; then
|
||
if [ "$china_ip_route" = "1" ]; then
|
||
rule="ip daddr @china_ip_route"
|
||
elif [ "$china_ip_route" = "2" ]; then
|
||
rule="ip daddr != @china_ip_route"
|
||
fi
|
||
[ "$enable_redirect_dns" != "2" ] && rule="$rule ip daddr != @china_ip_route_pass"
|
||
nft "add rule inet fw4 openclash_mangle $rule counter return"
|
||
fi
|
||
|
||
nft 'add rule inet fw4 openclash_mangle ip protocol udp counter jump openclash_upnp'
|
||
nft add rule inet fw4 openclash_mangle meta l4proto { udp } mark set "$PROXY_FWMARK" tproxy ip to 127.0.0.1:"$tproxy_port" counter accept
|
||
nft 'add rule inet fw4 mangle_prerouting meta nfproto {ipv4} ip protocol udp counter jump openclash_mangle'
|
||
fi
|
||
if [ "$enable_udp_proxy" -ne 1 ] && [ "$en_mode" = "fake-ip" ]; then
|
||
modprobe nft_tproxy >/dev/null 2>&1
|
||
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"
|
||
nft 'add chain inet fw4 openclash_mangle'
|
||
nft 'flush chain inet fw4 openclash_mangle'
|
||
nft add rule inet fw4 openclash_mangle meta l4proto { udp } ip daddr { "$fakeip_range" } mark set "$PROXY_FWMARK" tproxy ip to 127.0.0.1:"$tproxy_port" counter accept 2>/dev/null
|
||
nft 'add rule inet fw4 mangle_prerouting meta nfproto {ipv4} ip protocol udp counter jump openclash_mangle'
|
||
fi
|
||
|
||
#router self proxy udp
|
||
if ([ "$router_self_proxy" = "1" ] && [ "$enable_udp_proxy" -eq 1 ]) || ([ "$enable_redirect_dns" != "2" ] && [ "$en_mode" = "fake-ip" ]); then
|
||
nft 'add chain inet fw4 openclash_mangle_output'
|
||
nft 'flush chain inet fw4 openclash_mangle_output'
|
||
nft 'add rule inet fw4 openclash_mangle_output skgid == 65534 counter return'
|
||
nft 'add rule inet fw4 openclash_mangle_output ip daddr @localnetwork counter return'
|
||
nft 'add rule inet fw4 openclash_mangle_output ct direction reply counter return'
|
||
nft 'add rule inet fw4 openclash_mangle_output ip daddr @wan_ac_black_ips counter return'
|
||
if [ "$en_mode" = "redir-host" ]; then
|
||
nft add rule inet fw4 openclash_mangle_output th dport != @common_ports counter return
|
||
fi
|
||
if [ "$en_mode" = "fake-ip" ]; then
|
||
nft add rule inet fw4 openclash_mangle_output meta l4proto { udp } ip daddr { "$fakeip_range" } mark set "$PROXY_FWMARK" counter accept
|
||
fi
|
||
if [ "$china_ip_route" != "0" ]; then
|
||
if [ "$china_ip_route" = "1" ]; then
|
||
rule="ip daddr @china_ip_route"
|
||
elif [ "$china_ip_route" = "2" ]; then
|
||
rule="ip daddr != @china_ip_route"
|
||
fi
|
||
[ "$enable_redirect_dns" != "2" ] && rule="$rule ip daddr != @china_ip_route_pass"
|
||
nft "add rule inet fw4 openclash_mangle_output $rule counter return"
|
||
fi
|
||
if [ "$router_self_proxy" = "1" ] && [ "$enable_udp_proxy" -eq 1 ]; then
|
||
nft add rule inet fw4 openclash_mangle_output mark set "$PROXY_FWMARK" counter accept
|
||
fi
|
||
nft 'add rule inet fw4 mangle_output meta nfproto {ipv4} ip protocol udp counter jump openclash_mangle_output'
|
||
fi
|
||
|
||
#quic
|
||
if [ "$disable_udp_quic" -eq 1 ]; then
|
||
if [ "$china_ip_route" = "2" ]; then
|
||
nft insert rule inet fw4 input position 0 udp dport 443 ip daddr @china_ip_route counter reject comment \"OpenClash QUIC REJECT\"
|
||
else
|
||
nft insert rule inet fw4 input position 0 udp dport 443 ip daddr != @china_ip_route counter reject comment \"OpenClash QUIC REJECT\"
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
#router self proxy tcp
|
||
if [ "$router_self_proxy" = "1" ] || ([ "$enable_redirect_dns" != "2" ] && [ "$en_mode" = "fake-ip" ]); then
|
||
nft 'add chain inet fw4 openclash_output'
|
||
nft 'flush chain inet fw4 openclash_output'
|
||
nft 'add rule inet fw4 openclash_output skgid == 65534 counter return'
|
||
nft 'add rule inet fw4 openclash_output ip daddr @localnetwork counter return'
|
||
nft 'add rule inet fw4 openclash_output ct direction reply counter return'
|
||
if [ "$en_mode" = "fake-ip" ] && [ "$en_mode_tun" != "1" ]; then
|
||
nft add rule inet fw4 openclash_output ip protocol tcp ip daddr { "$fakeip_range" } counter redirect to "$proxy_port"
|
||
fi
|
||
if [ "$router_self_proxy" = "1" ]; then
|
||
nft 'add rule inet fw4 openclash_output ip daddr @wan_ac_black_ips counter return'
|
||
if [ "$en_mode" = "redir-host" ]; then
|
||
nft add rule inet fw4 openclash_output th dport != @common_ports counter return
|
||
fi
|
||
if [ "$china_ip_route" != "0" ]; then
|
||
if [ "$china_ip_route" = "1" ]; then
|
||
rule="ip daddr @china_ip_route"
|
||
elif [ "$china_ip_route" = "2" ]; then
|
||
rule="ip daddr != @china_ip_route"
|
||
fi
|
||
[ "$enable_redirect_dns" != "2" ] && rule="$rule ip daddr != @china_ip_route_pass"
|
||
nft "add rule inet fw4 openclash_output $rule counter return"
|
||
fi
|
||
nft add rule inet fw4 openclash_output ip protocol tcp counter redirect to "$proxy_port"
|
||
fi
|
||
nft 'add chain inet fw4 nat_output { type nat hook output priority -1; }'
|
||
nft 'add rule inet fw4 nat_output meta nfproto {ipv4} ip protocol tcp counter jump openclash_output'
|
||
fi
|
||
fi
|
||
|
||
if [ -n "$en_mode_tun" ]; then
|
||
#TUN模式
|
||
#设置防火墙
|
||
#router self proxy
|
||
if [ "$router_self_proxy" = "1" ] || ([ "$enable_redirect_dns" != "2" ] && [ "$en_mode" = "fake-ip" ]); then
|
||
nft 'add chain inet fw4 openclash_mangle_output'
|
||
nft 'flush chain inet fw4 openclash_mangle_output'
|
||
nft 'add rule inet fw4 openclash_mangle_output skgid == 65534 counter return'
|
||
nft 'add rule inet fw4 openclash_mangle_output ip daddr @localnetwork counter return'
|
||
nft 'add rule inet fw4 openclash_mangle_output ct direction reply counter return'
|
||
nft add rule inet fw4 openclash_mangle_output meta l4proto {tcp,udp} ip daddr { "$fakeip_range" } mark set "$PROXY_FWMARK" counter
|
||
if [ "$en_mode" = "redir-host" ]; then
|
||
nft 'add rule inet fw4 openclash_mangle_output th dport != @common_ports counter return'
|
||
fi
|
||
if [ "$router_self_proxy" = "1" ]; then
|
||
nft 'add rule inet fw4 openclash_mangle_output ip daddr @wan_ac_black_ips counter return'
|
||
if [ "$china_ip_route" != "0" ]; then
|
||
if [ "$china_ip_route" = "1" ]; then
|
||
rule="ip daddr @china_ip_route"
|
||
elif [ "$china_ip_route" = "2" ]; then
|
||
rule="ip daddr != @china_ip_route"
|
||
fi
|
||
[ "$enable_redirect_dns" != "2" ] && rule="$rule ip daddr != @china_ip_route_pass"
|
||
nft "add rule inet fw4 openclash_mangle_output $rule counter return"
|
||
fi
|
||
if [ "$en_mode_tun" -eq 1 ]; then
|
||
nft add rule inet fw4 openclash_mangle_output meta l4proto {tcp,udp} meta mark set "$PROXY_FWMARK" counter
|
||
else
|
||
nft add rule inet fw4 openclash_mangle_output meta l4proto { udp } meta mark set "$PROXY_FWMARK" counter
|
||
fi
|
||
fi
|
||
nft 'add rule inet fw4 mangle_output meta nfproto {ipv4} meta l4proto {tcp,udp} counter jump openclash_mangle_output'
|
||
fi
|
||
|
||
nft 'add chain inet fw4 openclash_mangle'
|
||
nft 'flush chain inet fw4 openclash_mangle'
|
||
nft 'add chain inet fw4 openclash_upnp'
|
||
nft 'flush chain inet fw4 openclash_upnp'
|
||
upnp_exclude
|
||
|
||
#其他流量
|
||
nft 'add rule inet fw4 openclash_mangle meta l4proto {tcp,udp} iifname utun counter return'
|
||
nft 'add rule inet fw4 openclash_mangle ip daddr @localnetwork counter return'
|
||
nft 'add rule inet fw4 openclash_mangle ct direction reply counter return'
|
||
nft 'add rule inet fw4 openclash_mangle ip daddr @wan_ac_black_ips counter return'
|
||
nft 'add rule inet fw4 openclash_mangle ip saddr @lan_ac_black_ips counter return'
|
||
nft 'add rule inet fw4 openclash_mangle ether saddr @lan_ac_black_macs counter return'
|
||
if [ "$lan_ac_mode" = "1" ] && [ -n "$(uci -q get openclash.config.lan_ac_white_ips)" ] && [ -n "$(uci -q get openclash.config.lan_ac_white_macs)" ]; then
|
||
nft 'add rule inet fw4 openclash_mangle ether saddr != @lan_ac_white_macs ip saddr != @lan_ac_white_ips counter return'
|
||
else
|
||
nft 'add rule inet fw4 openclash_mangle ether saddr != @lan_ac_white_macs counter return'
|
||
nft 'add rule inet fw4 openclash_mangle ip saddr != @lan_ac_white_ips counter return'
|
||
fi
|
||
|
||
if [ "$en_mode" = "redir-host" ]; then
|
||
nft 'add rule inet fw4 openclash_mangle th dport != @common_ports counter return'
|
||
fi
|
||
if [ "$china_ip_route" != "0" ]; then
|
||
if [ "$china_ip_route" = "1" ]; then
|
||
rule="ip daddr @china_ip_route"
|
||
elif [ "$china_ip_route" = "2" ]; then
|
||
rule="ip daddr != @china_ip_route"
|
||
fi
|
||
[ "$enable_redirect_dns" != "2" ] && rule="$rule ip daddr != @china_ip_route_pass"
|
||
nft "add rule inet fw4 openclash_mangle $rule counter return"
|
||
fi
|
||
nft 'add rule inet fw4 openclash_mangle ip protocol udp counter jump openclash_upnp'
|
||
nft add rule inet fw4 openclash_mangle mark set "$PROXY_FWMARK" counter
|
||
|
||
if [ "$en_mode_tun" -eq 1 ]; then
|
||
nft 'add rule inet fw4 mangle_prerouting meta nfproto {ipv4} meta l4proto {tcp,udp} counter jump openclash_mangle'
|
||
else
|
||
nft 'add rule inet fw4 mangle_prerouting meta nfproto {ipv4} ip protocol udp counter jump openclash_mangle'
|
||
fi
|
||
|
||
#TUN FORWORD
|
||
nft insert rule inet fw4 forward position 0 meta l4proto {tcp,udp} oifname utun counter accept comment \"OpenClash TUN Forward\"
|
||
nft insert rule inet fw4 forward position 0 meta l4proto {tcp,udp} iifname utun counter accept comment \"OpenClash TUN Forward\"
|
||
nft insert rule inet fw4 input position 0 meta l4proto {tcp,udp} iifname utun counter accept comment \"OpenClash TUN Input\"
|
||
nft insert rule inet fw4 srcnat position 0 meta nfproto {ipv4} oifname utun counter return comment \"OpenClash TUN Postrouting\"
|
||
|
||
#quic
|
||
if [ "$disable_udp_quic" -eq 1 ]; then
|
||
if [ "$china_ip_route" = "2" ]; then
|
||
nft insert rule inet fw4 forward position 0 oifname utun udp dport 443 ip daddr @china_ip_route counter reject comment \"OpenClash QUIC REJECT\"
|
||
else
|
||
nft insert rule inet fw4 forward position 0 oifname utun udp dport 443 ip daddr != @china_ip_route counter reject comment \"OpenClash QUIC REJECT\"
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
#ipv6
|
||
if [ "$ipv6_enable" -eq 1 ]; then
|
||
#china ip route
|
||
if [ "$china_ip6_route" != "0" ] || [ "$disable_udp_quic" = "1" ]; then
|
||
nft 'flush set inet fw4 china_ip6_route'
|
||
nft -f '/etc/openclash/china_ip6_route.ipset'
|
||
CHNROUTE_WAIT=0
|
||
while ( [ -z "$(nft list sets |grep "set china_ip6_route {")" ] && [ "$CHNROUTE_WAIT" -le 3 ] )
|
||
do
|
||
nft -f '/etc/openclash/china_ip6_route.ipset'
|
||
let CHNROUTE_WAIT++
|
||
done
|
||
|
||
if [ "$enable_redirect_dns" != "2" ]; then
|
||
echo "add set inet fw4 china_ip6_route_pass { type ipv6_addr; flags interval; auto-merge; }" >/tmp/openclash_china_ip6_route_pass.list
|
||
[ -z `(awk '!/^$/&&!/^#/&&!/([0-9a-zA-Z-]{1,}\.)+([a-zA-Z]{2,})/{printf(" %s,\n",$0)}' /etc/openclash/custom/openclash_custom_chnroute6_pass.list)` ] || {
|
||
echo "define china_ip6_route_pass = {" >>/tmp/openclash_china_ip6_route_pass.list
|
||
awk '!/^$/&&!/^#/&&!/([0-9a-zA-Z-]{1,}\.)+([a-zA-Z]{2,})/{printf(" %s,\n",$0)}' /etc/openclash/custom/openclash_custom_chnroute6_pass.list |sed '$ s/.$//' >>/tmp/openclash_china_ip6_route_pass.list 2>/dev/null
|
||
echo "}" >>/tmp/openclash_china_ip6_route_pass.list
|
||
echo 'add element inet fw4 china_ip6_route_pass $china_ip6_route_pass' >>/tmp/openclash_china_ip6_route_pass.list
|
||
}
|
||
nft 'flush set inet fw4 china_ip6_route_pass'
|
||
nft -f '/tmp/openclash_china_ip6_route_pass.list'
|
||
rm -rf /tmp/openclash_china_ip6_route_pass.list
|
||
fi
|
||
fi
|
||
|
||
if [ -z "$(nft list chain inet fw4 dstnat |grep 'OpenClash DNS Hijack')" ]; then
|
||
if [ "$enable_redirect_dns" -eq 1 ]; then
|
||
if [ "$lan_ac_mode" != "1" ]; then
|
||
ACBLACKDNSFILTER=""
|
||
if [ "$lan_ac_mode" = "0" ]; then
|
||
if [ -n "$(uci -q get openclash.config.lan_ac_black_ips)" ]; then
|
||
ACBLACKDNSFILTER="ip6 saddr != @lan_ac_black_ipv6s"
|
||
fi
|
||
if [ -n "$(uci -q get openclash.config.lan_ac_black_macs)" ]; then
|
||
ACBLACKDNSFILTER="$ACBLACKDNSFILTER ether saddr != @lan_ac_black_macs"
|
||
fi
|
||
fi
|
||
nft insert rule inet fw4 dstnat position 0 meta nfproto {ipv6} ip6 nexthdr {tcp,udp} th dport 53 ${ACBLACKDNSFILTER} counter redirect to "$DNSPORT" comment \"OpenClash DNS Hijack\"
|
||
else
|
||
nft insert rule inet fw4 dstnat position 0 meta nfproto {ipv6} ip6 nexthdr {tcp,udp} th dport 53 ip6 saddr @lan_ac_white_ipv6s counter redirect to "$DNSPORT" comment \"OpenClash DNS Hijack\"
|
||
nft insert rule inet fw4 dstnat position 0 meta nfproto {ipv6} ip6 nexthdr {tcp,udp} th dport 53 ether saddr @lan_ac_white_macs counter redirect to "$DNSPORT" comment \"OpenClash DNS Hijack\"
|
||
fi
|
||
if [ "$router_self_proxy" = 1 ]; then
|
||
nft 'add chain inet fw4 nat_output { type nat hook output priority -1; }'
|
||
nft insert rule inet fw4 nat_output position 0 skgid != 65534 meta nfproto {ipv6} ip6 nexthdr {tcp,udp} th dport 53 ip6 daddr {::/0} counter redirect to "$DNSPORT" comment \"OpenClash DNS Hijack\"
|
||
fi
|
||
elif [ "$enable_redirect_dns" -eq 2 ]; then
|
||
if [ "$lan_ac_mode" != "1" ]; then
|
||
ACBLACKDNSFILTER=""
|
||
if [ "$lan_ac_mode" = "0" ]; then
|
||
if [ -n "$(uci -q get openclash.config.lan_ac_black_ips)" ]; then
|
||
ACBLACKDNSFILTER="ip6 saddr != @lan_ac_black_ipv6s"
|
||
fi
|
||
if [ -n "$(uci -q get openclash.config.lan_ac_black_macs)" ]; then
|
||
ACBLACKDNSFILTER="$ACBLACKDNSFILTER ether saddr != @lan_ac_black_macs"
|
||
fi
|
||
fi
|
||
nft add rule inet fw4 openclash_dns_redirect meta nfproto {ipv6} ip6 nexthdr {tcp,udp} th dport 53 ${ACBLACKDNSFILTER} counter redirect to "$dns_port" comment \"OpenClash DNS Hijack\"
|
||
else
|
||
nft add rule inet fw4 openclash_dns_redirect meta nfproto {ipv6} ip6 nexthdr {tcp,udp} th dport 53 ip6 saddr @lan_ac_white_ipv6s counter redirect to "$dns_port" comment \"OpenClash DNS Hijack\"
|
||
nft add rule inet fw4 openclash_dns_redirect meta nfproto {ipv6} ip6 nexthdr {tcp,udp} th dport 53 ether saddr @lan_ac_white_macs counter redirect to "$dns_port" comment \"OpenClash DNS Hijack\"
|
||
fi
|
||
nft 'insert rule inet fw4 dstnat position 0 meta nfproto {ipv6} ip6 nexthdr {tcp,udp} th dport 53 counter jump openclash_dns_redirect'
|
||
if [ "$router_self_proxy" = 1 ]; then
|
||
nft 'add chain inet fw4 nat_output { type nat hook output priority -1; }'
|
||
nft insert rule inet fw4 nat_output position 0 meta nfproto {ipv6} ip6 nexthdr {tcp,udp} th dport 53 ip6 daddr {::/0} meta skgid != 65534 counter redirect to "$dns_port" comment \"OpenClash DNS Hijack\"
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
#local
|
||
nft 'add set inet fw4 localnetwork6 { type ipv6_addr; flags interval; auto-merge; }'
|
||
#nft 'delete set inet fw4 localnetwork6'
|
||
if [ -f "/etc/openclash/custom/openclash_custom_localnetwork_ipv6.list" ]; then
|
||
for line in `cat "/etc/openclash/custom/openclash_custom_localnetwork_ipv6.list"`
|
||
do
|
||
nft add element inet fw4 localnetwork6 { "$line" }
|
||
done
|
||
else
|
||
nft 'add element inet fw4 localnetwork6 { ::/128, ::1/128, ::ffff:0:0/96, ::ffff:0:0:0/96, 64:ff9b::/96, 100::/64, 2001::/32, 2001:20::/28, 2001:db8::/32, 2002::/16, fc00::/7, fe80::/10, ff00::/8}'
|
||
fi
|
||
|
||
if [ -n "$wan_ip6s" ]; then
|
||
for wan_ip6 in $wan_ip6s; do
|
||
nft add element inet fw4 localnetwork6 { "$wan_ip6" }
|
||
done
|
||
fi
|
||
|
||
if [ "$ipv6_mode" -eq 1 ] || [ "$ipv6_mode" -eq 3 ]; then
|
||
#tcp
|
||
nft 'add chain inet fw4 openclash_v6'
|
||
nft 'flush chain inet fw4 openclash_v6'
|
||
nft 'add rule inet fw4 openclash_v6 ip6 daddr @localnetwork6 counter return'
|
||
nft 'add rule inet fw4 openclash_v6 ct direction reply counter return'
|
||
nft 'add rule inet fw4 openclash_v6 ip6 daddr @wan_ac_black_ipv6s counter return'
|
||
nft 'add rule inet fw4 openclash_v6 ip6 saddr @lan_ac_black_ipv6s counter return'
|
||
nft 'add rule inet fw4 openclash_v6 ether saddr @lan_ac_black_macs counter return'
|
||
if [ "$lan_ac_mode" = "1" ] && [ -n "$(uci -q get openclash.config.lan_ac_white_ips)" ] && [ -n "$(uci -q get openclash.config.lan_ac_white_macs)" ]; then
|
||
nft 'add rule inet fw4 openclash_v6 ether saddr != @lan_ac_white_macs ip6 saddr != @lan_ac_white_ipv6s counter return'
|
||
else
|
||
nft 'add rule inet fw4 openclash_v6 ether saddr != @lan_ac_white_macs counter return'
|
||
nft 'add rule inet fw4 openclash_v6 ip6 saddr != @lan_ac_white_ipv6s counter return'
|
||
fi
|
||
|
||
if [ "$en_mode" = "redir-host" ]; then
|
||
nft 'add rule inet fw4 openclash_v6 th dport != @common_ports counter return'
|
||
fi
|
||
|
||
if [ "$china_ip6_route" != "0" ]; then
|
||
if [ "$china_ip6_route" = "1" ]; then
|
||
rule="ip6 daddr @china_ip6_route"
|
||
elif [ "$china_ip6_route" = "2" ]; then
|
||
rule="ip6 daddr != @china_ip6_route"
|
||
fi
|
||
[ "$enable_redirect_dns" != "2" ] && rule="$rule ip6 daddr != @china_ip6_route_pass"
|
||
nft "add rule inet fw4 openclash_v6 $rule counter return"
|
||
fi
|
||
nft add rule inet fw4 openclash_v6 ip6 nexthdr {tcp} counter redirect to "$proxy_port"
|
||
nft 'add rule inet fw4 dstnat ip6 nexthdr {tcp} counter jump openclash_v6'
|
||
fi
|
||
|
||
#TProxy & TUN & Redirect udp
|
||
if [ "$enable_v6_udp_proxy" -eq 1 ] || [ "$ipv6_mode" -ne 1 ]; then
|
||
nft 'add chain inet fw4 openclash_mangle_v6'
|
||
nft 'flush chain inet fw4 openclash_mangle_v6'
|
||
nft 'add rule inet fw4 openclash_mangle_v6 ip6 daddr @localnetwork6 counter return'
|
||
nft 'add rule inet fw4 openclash_mangle_v6 ct direction reply counter return'
|
||
nft 'add rule inet fw4 openclash_mangle_v6 ip6 daddr @wan_ac_black_ipv6s counter return'
|
||
|
||
if [ "$en_mode" == "redir-host" ]; then
|
||
nft 'add rule inet fw4 openclash_mangle_v6 th dport != @common_ports counter return'
|
||
fi
|
||
|
||
nft 'add rule inet fw4 openclash_mangle_v6 ip6 saddr @lan_ac_black_ipv6s counter return'
|
||
nft 'add rule inet fw4 openclash_mangle_v6 ether saddr @lan_ac_black_macs counter return'
|
||
if [ "$lan_ac_mode" = "1" ] && [ -n "$(uci -q get openclash.config.lan_ac_white_ips)" ] && [ -n "$(uci -q get openclash.config.lan_ac_white_macs)" ]; then
|
||
nft 'add rule inet fw4 openclash_mangle_v6 ether saddr != @lan_ac_white_macs ip6 saddr != @lan_ac_white_ipv6s counter return'
|
||
else
|
||
nft 'add rule inet fw4 openclash_mangle_v6 ether saddr != @lan_ac_white_macs counter return'
|
||
nft 'add rule inet fw4 openclash_mangle_v6 ip6 saddr != @lan_ac_white_ipv6s counter return'
|
||
fi
|
||
|
||
if [ "$china_ip6_route" != "0" ]; then
|
||
if [ "$china_ip6_route" = "1" ]; then
|
||
rule="ip6 daddr @china_ip6_route"
|
||
elif [ "$china_ip6_route" = "2" ]; then
|
||
rule="ip6 daddr != @china_ip6_route"
|
||
fi
|
||
[ "$enable_redirect_dns" != "2" ] && rule="$rule ip6 daddr != @china_ip6_route_pass"
|
||
nft "add rule inet fw4 openclash_mangle_v6 $rule counter return"
|
||
fi
|
||
fi
|
||
|
||
#tcp Tproxy && TUN
|
||
if [ "$ipv6_mode" -ne 1 ] && [ "$ipv6_mode" -ne 3 ]; then
|
||
if [ "$ipv6_mode" -eq 0 ]; then
|
||
nft add rule inet fw4 openclash_mangle_v6 ip6 nexthdr {tcp} mark set "$PROXY_FWMARK" tproxy ip6 to :"$tproxy_port" counter accept comment \"OpenClash TCP Tproxy\"
|
||
else
|
||
nft add rule inet fw4 openclash_mangle_v6 ip6 nexthdr {tcp} mark set "$PROXY_FWMARK" counter
|
||
fi
|
||
fi
|
||
|
||
#udp
|
||
if [ "$ipv6_mode" -eq 2 ] || [ "$ipv6_mode" -eq 3 ]; then
|
||
nft add rule inet fw4 openclash_mangle_v6 ip6 nexthdr {udp} mark set "$PROXY_FWMARK" counter
|
||
else
|
||
if [ "$enable_v6_udp_proxy" -eq 1 ]; then
|
||
nft add rule inet fw4 openclash_mangle_v6 ip6 nexthdr {udp} mark set "$PROXY_FWMARK" tproxy ip6 to :"$tproxy_port" counter accept comment \"OpenClash UDP Tproxy\"
|
||
fi
|
||
fi
|
||
|
||
nft 'add rule inet fw4 mangle_prerouting meta nfproto {ipv6} counter jump openclash_mangle_v6'
|
||
|
||
#router self proxy
|
||
if [ "$router_self_proxy" = "1" ]; then
|
||
if [ "$ipv6_mode" -eq 1 ] || [ "$ipv6_mode" -eq 3 ]; then
|
||
#tcp Redirect Mode
|
||
nft 'add chain inet fw4 openclash_output_v6'
|
||
nft 'flush chain inet fw4 openclash_output_v6'
|
||
nft 'add rule inet fw4 openclash_output_v6 skgid == 65534 counter return'
|
||
nft 'add rule inet fw4 openclash_output_v6 ip6 daddr @localnetwork6 counter return'
|
||
nft 'add rule inet fw4 openclash_output_v6 ct direction reply counter return'
|
||
nft 'add rule inet fw4 openclash_output_v6 ip6 daddr @wan_ac_black_ipv6s counter return'
|
||
if [ "$en_mode" = "redir-host" ]; then
|
||
nft 'add rule inet fw4 openclash_output_v6 th dport != @common_ports counter return'
|
||
fi
|
||
|
||
if [ "$china_ip6_route" != "0" ]; then
|
||
if [ "$china_ip6_route" = "1" ]; then
|
||
rule="ip6 daddr @china_ip6_route"
|
||
elif [ "$china_ip6_route" = "2" ]; then
|
||
rule="ip6 daddr != @china_ip6_route"
|
||
fi
|
||
[ "$enable_redirect_dns" != "2" ] && rule="$rule ip6 daddr != @china_ip6_route_pass"
|
||
nft "add rule inet fw4 openclash_output_v6 $rule counter return"
|
||
fi
|
||
|
||
nft add rule inet fw4 openclash_output_v6 ip6 nexthdr {tcp} counter redirect to "$proxy_port"
|
||
nft 'add chain inet fw4 nat_output { type nat hook output priority -1; }'
|
||
nft 'add rule inet fw4 nat_output meta nfproto {ipv6} counter jump openclash_output_v6'
|
||
fi
|
||
|
||
#other mode and Redirect Mode udp
|
||
nft 'add chain inet fw4 openclash_mangle_output_v6'
|
||
nft 'flush chain inet fw4 openclash_mangle_output_v6'
|
||
nft 'add rule inet fw4 openclash_mangle_output_v6 skgid == 65534 counter return'
|
||
nft 'add rule inet fw4 openclash_mangle_output_v6 ip6 daddr @localnetwork6 counter return'
|
||
nft 'add rule inet fw4 openclash_mangle_output_v6 ct direction reply counter return'
|
||
nft 'add rule inet fw4 openclash_mangle_output_v6 ip6 daddr @wan_ac_black_ipv6s counter return'
|
||
if [ "$en_mode" = "redir-host" ]; then
|
||
nft 'add rule inet fw4 openclash_mangle_output_v6 th dport != @common_ports counter return'
|
||
fi
|
||
|
||
if [ "$china_ip6_route" != "0" ]; then
|
||
if [ "$china_ip6_route" = "1" ]; then
|
||
rule="ip6 daddr @china_ip6_route"
|
||
elif [ "$china_ip6_route" = "2" ]; then
|
||
rule="ip6 daddr != @china_ip6_route"
|
||
fi
|
||
[ "$enable_redirect_dns" != "2" ] && rule="$rule ip6 daddr != @china_ip6_route_pass"
|
||
nft 'add rule inet fw4 openclash_mangle_output_v6 $rule counter return'
|
||
fi
|
||
|
||
if ([ "$ipv6_mode" -eq 1 ] && [ "$enable_v6_udp_proxy" -eq 1 ]) || [ "$ipv6_mode" -eq 3 ]; then
|
||
nft add rule inet fw4 openclash_mangle_output_v6 ip6 nexthdr {udp} mark set "$PROXY_FWMARK" counter
|
||
fi
|
||
if ([ "$ipv6_mode" -eq 0 ] && [ "$enable_v6_udp_proxy" -eq 1 ]) || [ "$ipv6_mode" -eq 2 ]; then
|
||
nft add rule inet fw4 openclash_mangle_output_v6 ip6 nexthdr {tcp,udp} mark set "$PROXY_FWMARK" counter
|
||
fi
|
||
if [ "$ipv6_mode" -eq 0 ] && [ "$enable_v6_udp_proxy" -ne 1 ]; then
|
||
nft add rule inet fw4 openclash_mangle_output_v6 ip6 nexthdr {tcp} mark set "$PROXY_FWMARK" counter
|
||
fi
|
||
nft 'add rule inet fw4 mangle_output meta nfproto {ipv6} counter jump openclash_mangle_output_v6'
|
||
fi
|
||
|
||
#route
|
||
if [ "$ipv6_mode" -ne 2 ] && [ "$ipv6_mode" -ne 3 ]; then
|
||
if [ "$enable_v6_udp_proxy" -eq 1 ] || [ "$ipv6_mode" -eq 0 ]; then
|
||
modprobe nft_tproxy >/dev/null 2>&1
|
||
ip -6 rule add fwmark "$PROXY_FWMARK" table "$PROXY_ROUTE_TABLE"
|
||
ip -6 route add local ::/0 dev lo table "$PROXY_ROUTE_TABLE"
|
||
fi
|
||
fi
|
||
|
||
#TUN FORWORD
|
||
if [ "$ipv6_mode" -eq 2 ] || [ "$ipv6_mode" -eq 3 ]; then
|
||
nft insert rule inet fw4 forward position 0 meta nfproto {ipv6} oifname utun counter accept comment \"OpenClash TUN Forward\"
|
||
nft insert rule inet fw4 forward position 0 meta nfproto {ipv6} iifname utun counter accept comment \"OpenClash TUN Forward\"
|
||
nft insert rule inet fw4 input position 0 meta nfproto {ipv6} iifname utun counter accept comment \"OpenClash TUN Input\"
|
||
nft insert rule inet fw4 srcnat position 0 meta nfproto {ipv6} oifname utun counter return comment \"OpenClash TUN Postrouting\"
|
||
fi
|
||
|
||
#quic
|
||
if [ "$disable_udp_quic" -eq 1 ]; then
|
||
if [ "$ipv6_mode" -eq 2 ] || [ "$ipv6_mode" -eq 3 ]; then
|
||
chain="forward"
|
||
else
|
||
chain="input"
|
||
fi
|
||
if [ "$china_ip6_route" = "2" ]; then
|
||
rule="ip6 daddr @china_ip6_route"
|
||
else
|
||
rule="ip6 daddr != @china_ip6_route"
|
||
fi
|
||
nft insert rule inet fw4 $chain position 0 udp dport 443 $rule counter reject comment \"OpenClash QUIC REJECT\"
|
||
fi
|
||
|
||
#bypass gateway compatible
|
||
if [ "$bypass_gateway_compatible" -eq 1 ]; then
|
||
#nft 'delete chain inet fw4 openclash_post_v6'
|
||
nft 'add chain inet fw4 openclash_post_v6'
|
||
nft 'flush chain inet fw4 openclash_post_v6'
|
||
nft 'add rule inet fw4 openclash_post_v6 skgid == 65534 counter return'
|
||
nft add rule inet fw4 openclash_post_v6 mark "$PROXY_FWMARK" counter accept
|
||
nft 'add rule inet fw4 openclash_post_v6 ip6 daddr @localnetwork6 counter return'
|
||
nft 'add rule inet fw4 openclash_post_v6 ct direction reply counter return'
|
||
nft 'add rule inet fw4 openclash_post_v6 fib saddr type != { local } counter masquerade'
|
||
nft add rule inet fw4 srcnat meta nfproto {ipv6} counter jump openclash_post_v6 comment \"OpenClash Bypass Gateway Compatible\"
|
||
fi
|
||
|
||
#intranet allowed
|
||
if [ "$intranet_allowed" -eq 1 ]; then
|
||
if [ -n "$intranet_allowed_wan_name" ] && [ "$intranet_allowed_wan_name" != "0" ]; then
|
||
config_load "openclash"
|
||
config_list_foreach "config" "intranet_allowed_wan_name" wan6_name_add
|
||
else
|
||
wan6_ints=$(nft list chain inet fw4 input |grep -e "jump input_wan" 2>/dev/null |awk '{for (i=1;i<=NF;i++){if ($i ~ /iifname/ && $(i+1) != "{") {print $(i+1)} if ($i ~ /iifname/ && $(i+1) == "{"){for (j=i+1;j<=NF;j++){if ($j~ /}/) {out="";for (k=i+1;k<=j;k++){out=out" "$k};print out}}}}}' 2>/dev/null |sed 's/"//g'|sed 's/{//g'|sed 's/}//g'|sed 's/,//g')
|
||
fi
|
||
if [ -n "$wan6_ints" ]; then
|
||
nft 'add chain inet fw4 openclash_wan6_input'
|
||
nft 'flush chain inet fw4 openclash_wan6_input'
|
||
for wan6_int in $wan6_ints; do
|
||
#nft delete rule inet fw4 input $(nft -a list chain inet fw4 input |grep "@localnetwork6" |awk -F '# ' '{print$2}')
|
||
nft insert rule inet fw4 input position 0 iifname "$wan6_int" ip6 saddr != @localnetwork6 counter jump openclash_wan6_input
|
||
done
|
||
nft add rule inet fw4 openclash_wan6_input ip6 nexthdr {tcp,udp} th dport {$proxy_port,$tproxy_port,$cn_port,$http_port,$socks_port,$mixed_port,$dns_port} counter reject
|
||
else
|
||
LOG_OUT "Warning: Can't Settting Only Intranet Allowed Function, Get IPv6 WAN Interfaces error, Please Verify The Firewall's WAN Zone Name is wan, Ignore This IF The Device Does not Have a WAN Interfaces..."
|
||
fi
|
||
fi
|
||
fi
|
||
fi 2>/dev/null
|
||
|
||
#IPTABLES
|
||
if [ -z "$FW4" ]; then
|
||
#iptables owner module
|
||
if [ "$iptables_compat" -eq 0 ]; then
|
||
owner="-m mark --mark 0x1a0a"
|
||
noowner="-m mark ! --mark 0x1a0a"
|
||
addr_local="! -i lo"
|
||
else
|
||
owner="-m owner --gid-owner 65534"
|
||
noowner="-m owner ! --gid-owner 65534"
|
||
addr_local="-m addrtype ! --src-type LOCAL"
|
||
fi
|
||
|
||
#china ip route
|
||
if [ "$china_ip_route" != "0" ] || [ "$disable_udp_quic" = "1" ]; then
|
||
ipset -! flush china_ip_route
|
||
ipset -! restore </etc/openclash/china_ip_route.ipset
|
||
|
||
if [ "$enable_redirect_dns" != "2" ]; then
|
||
echo "create china_ip_route_pass hash:net family inet hashsize 1024 maxelem 1000000" >/tmp/openclash_china_ip_route_pass.list
|
||
awk '!/^$/&&!/^#/&&/(^([1-9]|1[0-9]|1[1-9]{2}|2[0-4][0-9]|25[0-5])\.)(([0-9]{1,2}|1[1-9]{2}|2[0-4][0-9]|25[0-5])\.){2}([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-5][0-9]|25[0-4])((\/[0-9][0-9])?)$/{printf("add china_ip_route_pass %s'" "'\n",$0)}' /etc/openclash/custom/openclash_custom_chnroute_pass.list >>/tmp/openclash_china_ip_route_pass.list 2>/dev/null
|
||
ipset -! flush china_ip_route_pass
|
||
ipset -! restore </tmp/openclash_china_ip_route_pass.list
|
||
rm -rf /tmp/openclash_china_ip_route_pass.list
|
||
fi
|
||
fi
|
||
|
||
#lan_ac
|
||
if [ "$lan_ac_mode" = "0" ]; then
|
||
if [ -n "$(uci -q get openclash.config.lan_ac_black_ips)" ]; then
|
||
ipset create lan_ac_black_ips hash:net
|
||
ipset create lan_ac_black_ipv6s hash:net family inet6
|
||
config_load "openclash"
|
||
config_list_foreach "config" "lan_ac_black_ips" ac_add "lan_ac_black_ips" "lan_ac_black_ipv6s"
|
||
fi
|
||
if [ -n "$(uci -q get openclash.config.lan_ac_black_macs)" ]; then
|
||
ipset create lan_ac_black_macs hash:mac
|
||
config_load "openclash"
|
||
config_list_foreach "config" "lan_ac_black_macs" ac_add "lan_ac_black_macs"
|
||
fi
|
||
elif [ "$lan_ac_mode" = "1" ]; then
|
||
if [ -n "$(uci -q get openclash.config.lan_ac_white_ips)" ]; then
|
||
ipset create lan_ac_white_ips hash:net
|
||
ipset create lan_ac_white_ipv6s hash:net family inet6
|
||
config_load "openclash"
|
||
config_list_foreach "config" "lan_ac_white_ips" ac_add "lan_ac_white_ips" "lan_ac_white_ipv6s"
|
||
fi
|
||
if [ -n "$(uci -q get openclash.config.lan_ac_white_macs)" ]; then
|
||
ipset create lan_ac_white_macs hash:mac
|
||
config_load "openclash"
|
||
config_list_foreach "config" "lan_ac_white_macs" ac_add "lan_ac_white_macs"
|
||
fi
|
||
fi
|
||
|
||
#wan ac
|
||
if [ -n "$(uci -q get openclash.config.wan_ac_black_ips)" ]; then
|
||
ipset create wan_ac_black_ips hash:net
|
||
ipset create wan_ac_black_ipv6s hash:net family inet6
|
||
config_load "openclash"
|
||
config_list_foreach "config" "wan_ac_black_ips" ac_add "wan_ac_black_ips" "wan_ac_black_ipv6s"
|
||
fi
|
||
|
||
#local
|
||
ipset create localnetwork hash:net
|
||
if [ -f "/etc/openclash/custom/openclash_custom_localnetwork_ipv4.list" ]; then
|
||
for line in `cat "/etc/openclash/custom/openclash_custom_localnetwork_ipv4.list"`
|
||
do
|
||
ipset add localnetwork "$line"
|
||
done
|
||
else
|
||
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
|
||
ipset add localnetwork 100.64.0.0/10
|
||
fi
|
||
|
||
if [ -n "$wan_ip4s" ]; then
|
||
for wan_ip4 in $wan_ip4s; do
|
||
ipset add localnetwork "$wan_ip4"
|
||
done
|
||
fi
|
||
|
||
#common ports
|
||
if [ -n "$common_ports" ] && [ "$common_ports" != "0" ]; then
|
||
ipset create common_ports bitmap:port range 0-65535
|
||
for i in $common_port; do
|
||
ipset add common_ports $i
|
||
done
|
||
fi
|
||
|
||
#bypass gateway compatible
|
||
if [ "$bypass_gateway_compatible" -eq 1 ]; then
|
||
iptables -t nat -N openclash_post
|
||
iptables -t nat -F openclash_post
|
||
iptables -t nat -A openclash_post $owner -j RETURN
|
||
iptables -t nat -A openclash_post -m mark --mark "$PROXY_FWMARK" -j ACCEPT
|
||
iptables -t nat -A openclash_post -m set --match-set localnetwork dst -j RETURN
|
||
iptables -t nat -A openclash_post -m conntrack --ctdir REPLY -j RETURN
|
||
iptables -t nat -A openclash_post $addr_local -j MASQUERADE
|
||
iptables -t nat -A POSTROUTING -m comment --comment "OpenClash Bypass Gateway Compatible" -j openclash_post
|
||
fi
|
||
|
||
#intranet allowed
|
||
if [ "$intranet_allowed" -eq 1 ]; then
|
||
if [ -n "$intranet_allowed_wan_name" ] && [ "$intranet_allowed_wan_name" != "0" ]; then
|
||
config_load "openclash"
|
||
config_list_foreach "config" "intranet_allowed_wan_name" wan_name_add
|
||
else
|
||
wan_ints=$(iptables-save -t filter |grep -e "-j zone_wan_input" 2>/dev/null |awk '{for (i=1;i<=NF;i++) {if ($i ~ /-i/) {print $(i+1)}}}' 2>/dev/null)
|
||
fi
|
||
if [ -n "$wan_ints" ]; then
|
||
iptables -t filter -N openclash_wan_input
|
||
iptables -t filter -F openclash_wan_input
|
||
for wan_int in $wan_ints; do
|
||
iptables -t filter -I INPUT -i "$wan_int" -m set ! --match-set localnetwork src -j openclash_wan_input
|
||
done
|
||
iptables -t filter -A openclash_wan_input -p udp -m multiport --dport "$proxy_port,$tproxy_port,$cn_port,$http_port,$socks_port,$mixed_port,$dns_port" -j REJECT >/dev/null 2>&1
|
||
iptables -t filter -A openclash_wan_input -p tcp -m multiport --dport "$proxy_port,$tproxy_port,$cn_port,$http_port,$socks_port,$mixed_port,$dns_port" -j REJECT >/dev/null 2>&1
|
||
else
|
||
LOG_OUT "Warning: Can't Settting Only Intranet Allowed Function, Get IPv4 WAN Interfaces error, Please Verify The Firewall's WAN Zone Name is wan, Ignore This IF The Device Does not Have a WAN Interfaces..."
|
||
fi
|
||
fi
|
||
|
||
DNSPORT=$(uci -q get dhcp.@dnsmasq[0].port)
|
||
if [ -z "$DNSPORT" ]; then
|
||
DNSPORT=$(netstat -nlp |grep -E '127.0.0.1:.*dnsmasq' |awk -F '127.0.0.1:' '{print $2}' |awk '{print $1}' |head -1 || echo 53)
|
||
fi
|
||
|
||
if [ "$enable_redirect_dns" -eq 1 ]; then
|
||
if [ -z "$(iptables -t nat -nL PREROUTING --line-number |grep 'OpenClash DNS Hijack')" ]; then
|
||
if [ "$lan_ac_mode" != "1" ]; then
|
||
ACBLACKDNSFILTER=""
|
||
if [ "$lan_ac_mode" = "0" ]; then
|
||
if [ -n "$(uci -q get openclash.config.lan_ac_black_ips)" ]; then
|
||
ACBLACKDNSFILTER="-m set ! --match-set lan_ac_black_ips src"
|
||
fi
|
||
if [ -n "$(uci -q get openclash.config.lan_ac_black_macs)" ]; then
|
||
ACBLACKDNSFILTER="$ACBLACKDNSFILTER -m set ! --match-set lan_ac_black_macs src"
|
||
fi
|
||
fi
|
||
iptables -t nat -I PREROUTING -p udp --dport 53 ${ACBLACKDNSFILTER} -j REDIRECT --to-ports "$DNSPORT" -m comment --comment "OpenClash DNS Hijack"
|
||
iptables -t nat -I PREROUTING -p tcp --dport 53 ${ACBLACKDNSFILTER} -j REDIRECT --to-ports "$DNSPORT" -m comment --comment "OpenClash DNS Hijack"
|
||
else
|
||
iptables -t nat -I PREROUTING -p udp --dport 53 -m set --match-set lan_ac_white_ips src -j REDIRECT --to-ports "$DNSPORT" -m comment --comment "OpenClash DNS Hijack"
|
||
iptables -t nat -I PREROUTING -p tcp --dport 53 -m set --match-set lan_ac_white_ips src -j REDIRECT --to-ports "$DNSPORT" -m comment --comment "OpenClash DNS Hijack"
|
||
iptables -t nat -I PREROUTING -p udp --dport 53 -m set --match-set lan_ac_white_macs src -j REDIRECT --to-ports "$DNSPORT" -m comment --comment "OpenClash DNS Hijack"
|
||
iptables -t nat -I PREROUTING -p tcp --dport 53 -m set --match-set lan_ac_white_macs src -j REDIRECT --to-ports "$DNSPORT" -m comment --comment "OpenClash DNS Hijack"
|
||
fi
|
||
fi
|
||
if [ "$router_self_proxy" = 1 ]; then
|
||
iptables -t nat -I OUTPUT $noowner -m comment --comment "OpenClash DNS Hijack" -p tcp --dport 53 -d 127.0.0.1 -j REDIRECT --to-ports "$DNSPORT"
|
||
iptables -t nat -I OUTPUT $noowner -m comment --comment "OpenClash DNS Hijack" -p udp --dport 53 -d 127.0.0.1 -j REDIRECT --to-ports "$DNSPORT"
|
||
fi
|
||
elif [ "$enable_redirect_dns" -eq 2 ]; then
|
||
iptables -t nat -N openclash_dns_redirect
|
||
iptables -t nat -F openclash_dns_redirect
|
||
if [ "$lan_ac_mode" != "1" ]; then
|
||
ACBLACKDNSFILTER=""
|
||
if [ "$lan_ac_mode" = "0" ]; then
|
||
if [ -n "$(uci -q get openclash.config.lan_ac_black_ips)" ]; then
|
||
ACBLACKDNSFILTER="-m set ! --match-set lan_ac_black_ips src"
|
||
fi
|
||
if [ -n "$(uci -q get openclash.config.lan_ac_black_macs)" ]; then
|
||
ACBLACKDNSFILTER="$ACBLACKDNSFILTER -m set ! --match-set lan_ac_black_macs src"
|
||
fi
|
||
fi
|
||
iptables -t nat -A openclash_dns_redirect -p udp --dport 53 ${ACBLACKDNSFILTER} -j REDIRECT --to-ports "$dns_port" -m comment --comment "OpenClash DNS Hijack"
|
||
iptables -t nat -A openclash_dns_redirect -p tcp --dport 53 ${ACBLACKDNSFILTER} -j REDIRECT --to-ports "$dns_port" -m comment --comment "OpenClash DNS Hijack"
|
||
else
|
||
iptables -t nat -A openclash_dns_redirect -p udp --dport 53 -m set --match-set lan_ac_white_ips src -j REDIRECT --to-ports "$dns_port" -m comment --comment "OpenClash DNS Hijack"
|
||
iptables -t nat -A openclash_dns_redirect -p tcp --dport 53 -m set --match-set lan_ac_white_ips src -j REDIRECT --to-ports "$dns_port" -m comment --comment "OpenClash DNS Hijack"
|
||
iptables -t nat -A openclash_dns_redirect -p udp --dport 53 -m set --match-set lan_ac_white_macs src -j REDIRECT --to-ports "$dns_port" -m comment --comment "OpenClash DNS Hijack"
|
||
iptables -t nat -A openclash_dns_redirect -p tcp --dport 53 -m set --match-set lan_ac_white_macs src -j REDIRECT --to-ports "$dns_port" -m comment --comment "OpenClash DNS Hijack"
|
||
fi
|
||
iptables -t nat -I PREROUTING -p udp --dport 53 -j openclash_dns_redirect
|
||
iptables -t nat -I PREROUTING -p tcp --dport 53 -j openclash_dns_redirect
|
||
if [ "$router_self_proxy" = 1 ]; then
|
||
iptables -t nat -I OUTPUT -p udp --dport 53 -d 127.0.0.1 $noowner -j REDIRECT --to-ports "$dns_port" -m comment --comment "OpenClash DNS Hijack"
|
||
iptables -t nat -I OUTPUT -p tcp --dport 53 -d 127.0.0.1 $noowner -j REDIRECT --to-ports "$dns_port" -m comment --comment "OpenClash DNS Hijack"
|
||
fi
|
||
fi
|
||
|
||
if [ -z "$en_mode_tun" ] || [ "$en_mode_tun" -eq 2 ]; then
|
||
#tcp
|
||
iptables -t nat -N openclash
|
||
iptables -t nat -F openclash
|
||
iptables -t nat -A openclash -m set --match-set localnetwork dst -j RETURN
|
||
iptables -t nat -A openclash -m conntrack --ctdir REPLY -j RETURN
|
||
if [ -z "$en_mode_tun" ] && [ "$en_mode" = "fake-ip" ]; then
|
||
iptables -t nat -A openclash -p tcp -d "$fakeip_range" -j REDIRECT --to-ports "$proxy_port"
|
||
fi
|
||
iptables -t nat -A openclash -m set --match-set wan_ac_black_ips dst -j RETURN >/dev/null 2>&1
|
||
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_black_macs src -j RETURN >/dev/null 2>&1
|
||
if [ "$lan_ac_mode" = "1" ] && [ -n "$(uci -q get openclash.config.lan_ac_white_ips)" ] && [ -n "$(uci -q get openclash.config.lan_ac_white_macs)" ]; then
|
||
iptables -t nat -A openclash -m set ! --match-set lan_ac_white_ips src -m set ! --match-set lan_ac_white_macs src -j RETURN >/dev/null 2>&1
|
||
else
|
||
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 -m set ! --match-set lan_ac_white_macs src -j RETURN >/dev/null 2>&1
|
||
fi
|
||
if [ "$en_mode" = "redir-host" ]; then
|
||
iptables -t nat -A openclash -m set ! --match-set common_ports dst -j RETURN >/dev/null 2>&1
|
||
fi
|
||
if [ "$china_ip_route" != "0" ]; then
|
||
if [ "$china_ip_route" = "1" ]; then
|
||
rule="-m set --match-set china_ip_route dst"
|
||
elif [ "$china_ip_route" = "2" ]; then
|
||
rule="-m set ! --match-set china_ip_route dst"
|
||
fi
|
||
[ "$enable_redirect_dns" != "2" ] && rule="$rule -m set ! --match-set china_ip_route_pass dst"
|
||
iptables -t nat -A openclash $rule -j RETURN >/dev/null 2>&1
|
||
fi
|
||
iptables -t nat -A openclash -p tcp -j REDIRECT --to-ports "$proxy_port"
|
||
iptables -t nat -A PREROUTING -p tcp -j openclash
|
||
|
||
if [ -z "$en_mode_tun" ]; then
|
||
#udp
|
||
if [ "$enable_udp_proxy" -eq 1 ]; then
|
||
modprobe xt_TPROXY >/dev/null 2>&1
|
||
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"
|
||
iptables -t mangle -N openclash
|
||
iptables -t mangle -F openclash
|
||
iptables -t mangle -N openclash_upnp
|
||
iptables -t mangle -F openclash_upnp
|
||
upnp_exclude
|
||
iptables -t mangle -A openclash -m set --match-set localnetwork dst -j RETURN
|
||
iptables -t mangle -A openclash -m conntrack --ctdir REPLY -j RETURN
|
||
if [ "$en_mode" = "fake-ip" ]; then
|
||
iptables -t mangle -A openclash -p udp -d "$fakeip_range" -j TPROXY --on-port "$tproxy_port" --tproxy-mark "$PROXY_FWMARK"
|
||
fi
|
||
iptables -t mangle -A openclash -m set --match-set wan_ac_black_ips dst -j RETURN >/dev/null 2>&1
|
||
iptables -t mangle -A openclash -m set --match-set lan_ac_black_macs src -j RETURN >/dev/null 2>&1
|
||
iptables -t mangle -A openclash -m set --match-set lan_ac_black_ips src -j RETURN >/dev/null 2>&1
|
||
if [ "$lan_ac_mode" = "1" ] && [ -n "$(uci -q get openclash.config.lan_ac_white_ips)" ] && [ -n "$(uci -q get openclash.config.lan_ac_white_macs)" ]; then
|
||
iptables -t mangle -A openclash -m set ! --match-set lan_ac_white_ips src -m set ! --match-set lan_ac_white_macs src -j RETURN >/dev/null 2>&1
|
||
else
|
||
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 lan_ac_white_macs src -j RETURN >/dev/null 2>&1
|
||
fi
|
||
if [ "$en_mode" = "redir-host" ]; then
|
||
iptables -t mangle -A openclash -m set ! --match-set common_ports dst -j RETURN >/dev/null 2>&1
|
||
fi
|
||
if [ "$china_ip_route" != "0" ]; then
|
||
if [ "$china_ip_route" = "1" ]; then
|
||
rule="-m set --match-set china_ip_route dst"
|
||
elif [ "$china_ip_route" = "2" ]; then
|
||
rule="-m set ! --match-set china_ip_route dst"
|
||
fi
|
||
[ "$enable_redirect_dns" != "2" ] && rule="$rule -m set ! --match-set china_ip_route_pass dst"
|
||
iptables -t mangle -A openclash $rule -j RETURN >/dev/null 2>&1
|
||
fi
|
||
iptables -t mangle -A openclash -p udp -j openclash_upnp >/dev/null 2>&1
|
||
iptables -t mangle -A openclash -p udp -j TPROXY --on-port "$tproxy_port" --tproxy-mark "$PROXY_FWMARK"
|
||
iptables -t mangle -A PREROUTING -p udp -j openclash
|
||
fi
|
||
|
||
if [ "$enable_udp_proxy" -ne 1 ] && [ "$en_mode" = "fake-ip" ]; then
|
||
modprobe xt_TPROXY >/dev/null 2>&1
|
||
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"
|
||
iptables -t mangle -N openclash
|
||
iptables -t mangle -F openclash
|
||
iptables -t mangle -A openclash -p udp -d "$fakeip_range" -j TPROXY --on-port "$tproxy_port" --tproxy-mark "$PROXY_FWMARK"
|
||
iptables -t mangle -A PREROUTING -p udp -j openclash
|
||
fi
|
||
|
||
#router self proxy udp
|
||
if ([ "$router_self_proxy" = "1" ] && [ "$enable_udp_proxy" -eq 1 ]) || ([ "$enable_redirect_dns" != "2" ] && [ "$en_mode" = "fake-ip" ]); then
|
||
iptables -t mangle -N openclash_output
|
||
iptables -t mangle -F openclash_output
|
||
iptables -t mangle -A openclash_output $owner -j RETURN
|
||
iptables -t mangle -A openclash_output -m set --match-set localnetwork dst -j RETURN
|
||
iptables -t mangle -A openclash_output -m conntrack --ctdir REPLY -j RETURN
|
||
iptables -t mangle -A openclash_output -m set --match-set wan_ac_black_ips dst -j RETURN >/dev/null 2>&1
|
||
if [ "$en_mode" = "fake-ip" ]; then
|
||
iptables -t mangle -A openclash_output -p udp -d "$fakeip_range" -j MARK --set-mark "$PROXY_FWMARK"
|
||
fi
|
||
if [ "$en_mode" = "redir-host" ]; then
|
||
iptables -t mangle -A openclash_output -m set ! --match-set common_ports dst -j RETURN >/dev/null 2>&1
|
||
fi
|
||
if [ "$china_ip_route" != "0" ]; then
|
||
if [ "$china_ip_route" = "1" ]; then
|
||
rule="-m set --match-set china_ip_route dst"
|
||
elif [ "$china_ip_route" = "2" ]; then
|
||
rule="-m set ! --match-set china_ip_route dst"
|
||
fi
|
||
[ "$enable_redirect_dns" != "2" ] && rule="$rule -m set ! --match-set china_ip_route_pass dst"
|
||
iptables -t mangle -A openclash_output $rule -j RETURN >/dev/null 2>&1
|
||
fi
|
||
if [ "$router_self_proxy" = "1" ] && [ "$enable_udp_proxy" -eq 1 ]; then
|
||
iptables -t mangle -A openclash_output -p udp -j MARK --set-mark "$PROXY_FWMARK"
|
||
fi
|
||
iptables -t mangle -A OUTPUT -p udp -j openclash_output
|
||
fi
|
||
|
||
#quic
|
||
if [ "$disable_udp_quic" -eq 1 ]; then
|
||
if [ "$china_ip_route" = "2" ]; then
|
||
iptables -I INPUT -p udp --dport 443 -m comment --comment "OpenClash QUIC REJECT" -m set --match-set china_ip_route dst -j REJECT >/dev/null 2>&1
|
||
else
|
||
iptables -I INPUT -p udp --dport 443 -m comment --comment "OpenClash QUIC REJECT" -m set ! --match-set china_ip_route dst -j REJECT >/dev/null 2>&1
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
#router self proxy tcp
|
||
if [ "$router_self_proxy" = "1" ] || ([ "$enable_redirect_dns" != "2" ] && [ "$en_mode" = "fake-ip" ]); then
|
||
iptables -t nat -N openclash_output
|
||
iptables -t nat -F openclash_output
|
||
iptables -t nat -A openclash_output $owner -j RETURN
|
||
if [ "$en_mode" = "fake-ip" ] && [ "$en_mode_tun" != "1" ]; then
|
||
iptables -t nat -A openclash_output -p tcp -d "$fakeip_range" -j REDIRECT --to-ports "$proxy_port"
|
||
fi
|
||
if [ "$router_self_proxy" = "1" ]; then
|
||
iptables -t nat -A openclash_output -m set --match-set localnetwork dst -j RETURN
|
||
iptables -t nat -A openclash_output -m conntrack --ctdir REPLY -j RETURN
|
||
iptables -t nat -A openclash_output -m set --match-set wan_ac_black_ips dst -j RETURN >/dev/null 2>&1
|
||
if [ "$en_mode" = "redir-host" ]; then
|
||
iptables -t nat -A openclash_output -m set ! --match-set common_ports dst -j RETURN >/dev/null 2>&1
|
||
fi
|
||
if [ "$china_ip_route" != "0" ]; then
|
||
if [ "$china_ip_route" = "1" ]; then
|
||
rule="-m set --match-set china_ip_route dst"
|
||
elif [ "$china_ip_route" = "2" ]; then
|
||
rule="-m set ! --match-set china_ip_route dst"
|
||
fi
|
||
[ "$enable_redirect_dns" != "2" ] && rule="$rule -m set ! --match-set china_ip_route_pass dst"
|
||
iptables -t nat -A openclash_output $rule -j RETURN >/dev/null 2>&1
|
||
fi
|
||
iptables -t nat -A openclash_output -p tcp -j REDIRECT --to-ports "$proxy_port"
|
||
fi
|
||
iptables -t nat -A OUTPUT -j openclash_output >/dev/null 2>&1
|
||
fi
|
||
fi
|
||
|
||
if [ -n "$en_mode_tun" ]; then
|
||
#TUN模式
|
||
#设置防火墙
|
||
#router self proxy
|
||
if [ "$router_self_proxy" = "1" ] || ([ "$enable_redirect_dns" != "2" ] && [ "$en_mode" = "fake-ip" ]); then
|
||
iptables -t mangle -N openclash_output
|
||
iptables -t mangle -F openclash_output
|
||
iptables -t mangle -A openclash_output $owner -j RETURN
|
||
iptables -t mangle -A openclash_output -m set --match-set localnetwork dst -j RETURN
|
||
iptables -t mangle -A openclash_output -m conntrack --ctdir REPLY -j RETURN
|
||
iptables -t mangle -A openclash_output -d "$fakeip_range" -j MARK --set-mark "$PROXY_FWMARK"
|
||
if [ "$en_mode" = "redir-host" ]; then
|
||
iptables -t mangle -A openclash_output -m set ! --match-set common_ports dst -j RETURN >/dev/null 2>&1
|
||
fi
|
||
if [ "$router_self_proxy" = "1" ]; then
|
||
iptables -t mangle -A openclash_output -m set --match-set wan_ac_black_ips dst -j RETURN >/dev/null 2>&1
|
||
if [ "$china_ip_route" != "0" ]; then
|
||
if [ "$china_ip_route" = "1" ]; then
|
||
rule="-m set --match-set china_ip_route dst"
|
||
elif [ "$china_ip_route" = "2" ]; then
|
||
rule="-m set ! --match-set china_ip_route dst"
|
||
fi
|
||
[ "$enable_redirect_dns" != "2" ] && rule="$rule -m set ! --match-set china_ip_route_pass dst"
|
||
iptables -t mangle -A openclash_output $rule -j RETURN >/dev/null 2>&1
|
||
fi
|
||
if [ "$en_mode_tun" -eq 1 ]; then
|
||
iptables -t mangle -A openclash_output -j MARK --set-mark "$PROXY_FWMARK"
|
||
else
|
||
iptables -t mangle -A openclash_output -p udp -j MARK --set-mark "$PROXY_FWMARK"
|
||
fi
|
||
fi
|
||
iptables -t mangle -A OUTPUT -j openclash_output
|
||
fi
|
||
|
||
iptables -t mangle -N openclash
|
||
iptables -t mangle -F openclash
|
||
iptables -t mangle -N openclash_upnp
|
||
iptables -t mangle -F openclash_upnp
|
||
upnp_exclude
|
||
#其他流量
|
||
iptables -t mangle -A openclash -i utun -j RETURN
|
||
iptables -t mangle -A openclash -m set --match-set localnetwork dst -j RETURN
|
||
iptables -t mangle -A openclash -m conntrack --ctdir REPLY -j RETURN
|
||
iptables -t mangle -A openclash -m set --match-set wan_ac_black_ips dst -j RETURN >/dev/null 2>&1
|
||
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_black_macs src -j RETURN >/dev/null 2>&1
|
||
if [ "$lan_ac_mode" = "1" ] && [ -n "$(uci -q get openclash.config.lan_ac_white_ips)" ] && [ -n "$(uci -q get openclash.config.lan_ac_white_macs)" ]; then
|
||
iptables -t mangle -A openclash -m set ! --match-set lan_ac_white_ips src -m set ! --match-set lan_ac_white_macs src -j RETURN >/dev/null 2>&1
|
||
else
|
||
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 lan_ac_white_macs src -j RETURN >/dev/null 2>&1
|
||
fi
|
||
|
||
if [ "$en_mode" = "redir-host" ]; then
|
||
iptables -t mangle -A openclash -m set ! --match-set common_ports dst -j RETURN >/dev/null 2>&1
|
||
fi
|
||
if [ "$china_ip_route" != "0" ]; then
|
||
if [ "$china_ip_route" = "1" ]; then
|
||
rule="-m set --match-set china_ip_route dst"
|
||
elif [ "$china_ip_route" = "2" ]; then
|
||
rule="-m set ! --match-set china_ip_route dst"
|
||
fi
|
||
[ "$enable_redirect_dns" != "2" ] && rule="$rule -m set ! --match-set china_ip_route_pass dst"
|
||
iptables -t mangle -A openclash $rule -j RETURN >/dev/null 2>&1
|
||
fi
|
||
|
||
iptables -t mangle -A openclash -p udp -j openclash_upnp >/dev/null 2>&1
|
||
|
||
iptables -t mangle -A openclash -j MARK --set-mark "$PROXY_FWMARK"
|
||
|
||
if [ "$en_mode_tun" -eq 1 ]; then
|
||
iptables -t mangle -A PREROUTING -j openclash
|
||
else
|
||
iptables -t mangle -A PREROUTING -p udp -j openclash
|
||
fi
|
||
|
||
#TUN FORWORD
|
||
iptables -I FORWARD -m comment --comment "OpenClash TUN Forward" -o utun -j ACCEPT >/dev/null 2>&1
|
||
iptables -I FORWARD -m comment --comment "OpenClash TUN Forward" -i utun -j ACCEPT >/dev/null 2>&1
|
||
iptables -I INPUT -m comment --comment "OpenClash TUN Input" -i utun -j ACCEPT >/dev/null 2>&1
|
||
iptables -t nat -I POSTROUTING -m comment --comment "OpenClash TUN Postrouting" -o utun -j RETURN >/dev/null 2>&1
|
||
|
||
#quic
|
||
if [ "$disable_udp_quic" -eq 1 ]; then
|
||
if [ "$china_ip_route" = "2" ]; then
|
||
iptables -I FORWARD -p udp --dport 443 -o utun -m comment --comment "OpenClash QUIC REJECT" -m set --match-set china_ip_route dst -j REJECT >/dev/null 2>&1
|
||
else
|
||
iptables -I FORWARD -p udp --dport 443 -o utun -m comment --comment "OpenClash QUIC REJECT" -m set ! --match-set china_ip_route dst -j REJECT >/dev/null 2>&1
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
#ipv6
|
||
if [ "$ipv6_enable" -eq 1 ] && [ -n "$(ip6tables -t mangle -L 2>&1 | grep -o 'Chain')" ]; then
|
||
#china ip route
|
||
if [ "$china_ip6_route" != "0" ] || [ "$disable_udp_quic" = "1" ]; then
|
||
ipset -! flush china_ip6_route
|
||
ipset -! restore </etc/openclash/china_ip6_route.ipset
|
||
if [ "$enable_redirect_dns" != "2" ]; then
|
||
echo "create china_ip6_route_pass hash:net family inet6 hashsize 1024 maxelem 1000000" >/tmp/openclash_china_ip6_route_pass.list
|
||
awk '!/^$/&&!/^#/&&!/([0-9a-zA-Z-]{1,}\.)+([a-zA-Z]{2,})/{printf("add china_ip6_route_pass %s'" "'\n",$0)}' /etc/openclash/custom/openclash_custom_chnroute6_pass.list >>/tmp/openclash_china_ip6_route_pass.list
|
||
ipset -! flush china_ip6_route_pass
|
||
ipset -! restore </tmp/openclash_china_ip6_route_pass.list
|
||
rm -rf /tmp/openclash_china_ip6_route_pass.list
|
||
fi
|
||
fi
|
||
|
||
if [ -z "$(ip6tables -t nat -nL PREROUTING --line-number |grep 'DNS Hijack')" ]; then
|
||
if [ "$enable_redirect_dns" -eq 1 ]; then
|
||
if [ "$lan_ac_mode" != "1" ]; then
|
||
ACBLACKDNSFILTER=""
|
||
if [ "$lan_ac_mode" = "0" ]; then
|
||
if [ -n "$(uci -q get openclash.config.lan_ac_black_ips)" ]; then
|
||
ACBLACKDNSFILTER="-m set ! --match-set lan_ac_black_ipv6s src"
|
||
fi
|
||
if [ -n "$(uci -q get openclash.config.lan_ac_black_macs)" ]; then
|
||
ACBLACKDNSFILTER="$ACBLACKDNSFILTER -m set ! --match-set lan_ac_black_macs src"
|
||
fi
|
||
fi
|
||
ip6tables -t nat -I PREROUTING -p udp --dport 53 ${ACBLACKDNSFILTER} -j REDIRECT --to-ports "$DNSPORT" -m comment --comment "OpenClash DNS Hijack"
|
||
ip6tables -t nat -I PREROUTING -p tcp --dport 53 ${ACBLACKDNSFILTER} -j REDIRECT --to-ports "$DNSPORT" -m comment --comment "OpenClash DNS Hijack"
|
||
else
|
||
ip6tables -t nat -I PREROUTING -p udp --dport 53 -m set --match-set lan_ac_white_ipv6s src -j REDIRECT --to-ports "$DNSPORT" -m comment --comment "OpenClash DNS Hijack"
|
||
ip6tables -t nat -I PREROUTING -p tcp --dport 53 -m set --match-set lan_ac_white_ipv6s src -j REDIRECT --to-ports "$DNSPORT" -m comment --comment "OpenClash DNS Hijack"
|
||
ip6tables -t nat -I PREROUTING -p udp --dport 53 -m set --match-set lan_ac_white_macs src -j REDIRECT --to-ports "$DNSPORT" -m comment --comment "OpenClash DNS Hijack"
|
||
ip6tables -t nat -I PREROUTING -p tcp --dport 53 -m set --match-set lan_ac_white_macs src -j REDIRECT --to-ports "$DNSPORT" -m comment --comment "OpenClash DNS Hijack"
|
||
fi
|
||
if [ "$router_self_proxy" = 1 ]; then
|
||
ip6tables -t nat -I OUTPUT -p tcp --dport 53 -d ::/0 $noowner -j REDIRECT --to-ports "$DNSPORT" -m comment --comment "OpenClash DNS Hijack"
|
||
ip6tables -t nat -I OUTPUT -p udp --dport 53 -d ::/0 $noowner -j REDIRECT --to-ports "$DNSPORT" -m comment --comment "OpenClash DNS Hijack"
|
||
fi
|
||
elif [ "$enable_redirect_dns" -eq 2 ]; then
|
||
ip6tables -t nat -N openclash_dns_redirect
|
||
ip6tables -t nat -F openclash_dns_redirect
|
||
if [ "$lan_ac_mode" != "1" ]; then
|
||
ACBLACKDNSFILTER=""
|
||
if [ "$lan_ac_mode" = "0" ]; then
|
||
if [ -n "$(uci -q get openclash.config.lan_ac_black_ips)" ]; then
|
||
ACBLACKDNSFILTER="-m set ! --match-set lan_ac_black_ipv6s src"
|
||
fi
|
||
if [ -n "$(uci -q get openclash.config.lan_ac_black_macs)" ]; then
|
||
ACBLACKDNSFILTER="$ACBLACKDNSFILTER -m set ! --match-set lan_ac_black_macs src"
|
||
fi
|
||
fi
|
||
ip6tables -t nat -A openclash_dns_redirect -p udp --dport 53 ${ACBLACKDNSFILTER} -j REDIRECT --to-ports "$dns_port" -m comment --comment "OpenClash DNS Hijack"
|
||
ip6tables -t nat -A openclash_dns_redirect -p tcp --dport 53 ${ACBLACKDNSFILTER} -j REDIRECT --to-ports "$dns_port" -m comment --comment "OpenClash DNS Hijack"
|
||
else
|
||
ip6tables -t nat -A openclash_dns_redirect -p udp --dport 53 -m set --match-set lan_ac_white_ipv6s src -j REDIRECT --to-ports "$dns_port" -m comment --comment "OpenClash DNS Hijack"
|
||
ip6tables -t nat -A openclash_dns_redirect -p tcp --dport 53 -m set --match-set lan_ac_white_ipv6s src -j REDIRECT --to-ports "$dns_port" -m comment --comment "OpenClash DNS Hijack"
|
||
ip6tables -t nat -A openclash_dns_redirect -p udp --dport 53 -m set --match-set lan_ac_white_macs src -j REDIRECT --to-ports "$dns_port" -m comment --comment "OpenClash DNS Hijack"
|
||
ip6tables -t nat -A openclash_dns_redirect -p tcp --dport 53 -m set --match-set lan_ac_white_macs src -j REDIRECT --to-ports "$dns_port" -m comment --comment "OpenClash DNS Hijack"
|
||
fi
|
||
ip6tables -t nat -I PREROUTING -p udp --dport 53 -j openclash_dns_redirect
|
||
ip6tables -t nat -I PREROUTING -p tcp --dport 53 -j openclash_dns_redirect
|
||
if [ "$router_self_proxy" = 1 ]; then
|
||
ip6tables -t nat -I OUTPUT -p udp --dport 53 -d ::/0 $noowner -j REDIRECT --to-ports "$dns_port" -m comment --comment "OpenClash DNS Hijack"
|
||
ip6tables -t nat -I OUTPUT -p tcp --dport 53 -d ::/0 $noowner -j REDIRECT --to-ports "$dns_port" -m comment --comment "OpenClash DNS Hijack"
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
#local
|
||
ipset create localnetwork6 hash:net family inet6
|
||
if [ -f "/etc/openclash/custom/openclash_custom_localnetwork_ipv6.list" ]; then
|
||
for line in `cat "/etc/openclash/custom/openclash_custom_localnetwork_ipv6.list"`
|
||
do
|
||
ipset add localnetwork6 "$line"
|
||
done
|
||
else
|
||
ipset add localnetwork6 ::/128
|
||
ipset add localnetwork6 ::1/128
|
||
ipset add localnetwork6 ::ffff:0:0/96
|
||
ipset add localnetwork6 ::ffff:0:0:0/96
|
||
ipset add localnetwork6 64:ff9b::/96
|
||
ipset add localnetwork6 100::/64
|
||
ipset add localnetwork6 2001::/32
|
||
ipset add localnetwork6 2001:20::/28
|
||
ipset add localnetwork6 2001:db8::/32
|
||
ipset add localnetwork6 2002::/16
|
||
ipset add localnetwork6 fc00::/7
|
||
ipset add localnetwork6 fe80::/10
|
||
ipset add localnetwork6 ff00::/8
|
||
fi
|
||
|
||
if [ -n "$wan_ip6s" ]; then
|
||
for wan_ip6 in $wan_ip6s; do
|
||
ipset add localnetwork6 "$wan_ip6"
|
||
done
|
||
fi
|
||
|
||
if [ "$ipv6_mode" -eq 1 ] || [ "$ipv6_mode" -eq 3 ]; then
|
||
#tcp
|
||
ip6tables -t nat -N openclash
|
||
ip6tables -t nat -F openclash
|
||
ip6tables -t nat -A openclash -m set --match-set localnetwork6 dst -j RETURN
|
||
ip6tables -t nat -A openclash -m conntrack --ctdir REPLY -j RETURN
|
||
ip6tables -t nat -A openclash -m set --match-set wan_ac_black_ipv6s dst -j RETURN >/dev/null 2>&1
|
||
ip6tables -t nat -A openclash -m set --match-set lan_ac_black_ipv6s src -j RETURN >/dev/null 2>&1
|
||
ip6tables -t nat -A openclash -m set --match-set lan_ac_black_macs src -j RETURN >/dev/null 2>&1
|
||
if [ "$lan_ac_mode" = "1" ] && [ -n "$(uci -q get openclash.config.lan_ac_white_ips)" ] && [ -n "$(uci -q get openclash.config.lan_ac_white_macs)" ]; then
|
||
ip6tables -t nat -A openclash -m set ! --match-set lan_ac_white_ipv6s src -m set ! --match-set lan_ac_white_macs src -j RETURN >/dev/null 2>&1
|
||
else
|
||
ip6tables -t nat -A openclash -m set ! --match-set lan_ac_white_ipv6s src -j RETURN >/dev/null 2>&1
|
||
ip6tables -t nat -A openclash -m set ! --match-set lan_ac_white_macs src -j RETURN >/dev/null 2>&1
|
||
fi
|
||
if [ "$en_mode" = "redir-host" ]; then
|
||
ip6tables -t nat -A openclash -m set ! --match-set common_ports dst -j RETURN >/dev/null 2>&1
|
||
fi
|
||
if [ "$china_ip6_route" != "0" ]; then
|
||
if [ "$china_ip6_route" = "1" ]; then
|
||
rule="-m set --match-set china_ip6_route dst"
|
||
elif [ "$china_ip6_route" = "2" ]; then
|
||
rule="-m set ! --match-set china_ip6_route dst"
|
||
fi
|
||
[ "$enable_redirect_dns" != "2" ] && rule="$rule -m set ! --match-set china_ip6_route_pass dst"
|
||
ip6tables -t nat -A openclash $rule -j RETURN >/dev/null 2>&1
|
||
fi
|
||
ip6tables -t nat -A openclash -p tcp -j REDIRECT --to-ports "$proxy_port"
|
||
ip6tables -t nat -A PREROUTING -p tcp -j openclash
|
||
fi
|
||
|
||
#TProxy & TUN & Redirect udp
|
||
if [ "$enable_v6_udp_proxy" -eq 1 ] || [ "$ipv6_mode" -ne 1 ]; then
|
||
ip6tables -t mangle -N openclash
|
||
ip6tables -t mangle -F openclash
|
||
ip6tables -t mangle -A openclash -m set --match-set localnetwork6 dst -j RETURN
|
||
ip6tables -t mangle -A openclash -m conntrack --ctdir REPLY -j RETURN
|
||
ip6tables -t mangle -A openclash -m set --match-set wan_ac_black_ipv6s dst -j RETURN >/dev/null 2>&1
|
||
ip6tables -t mangle -A openclash -m set --match-set lan_ac_black_macs src -j RETURN >/dev/null 2>&1
|
||
ip6tables -t mangle -A openclash -m set --match-set lan_ac_black_ipv6s src -j RETURN >/dev/null 2>&1
|
||
if [ "$lan_ac_mode" = "1" ] && [ -n "$(uci -q get openclash.config.lan_ac_white_ips)" ] && [ -n "$(uci -q get openclash.config.lan_ac_white_macs)" ]; then
|
||
ip6tables -t mangle -A openclash -m set ! --match-set lan_ac_white_ipv6s src -m set ! --match-set lan_ac_white_macs src -j RETURN >/dev/null 2>&1
|
||
else
|
||
ip6tables -t mangle -A openclash -m set ! --match-set lan_ac_white_ipv6s src -j RETURN >/dev/null 2>&1
|
||
ip6tables -t mangle -A openclash -m set ! --match-set lan_ac_white_macs src -j RETURN >/dev/null 2>&1
|
||
fi
|
||
|
||
if [ "$en_mode" == "redir-host" ]; then
|
||
ip6tables -t mangle -A openclash -m set ! --match-set common_ports dst -j RETURN >/dev/null 2>&1
|
||
fi
|
||
|
||
if [ "$china_ip6_route" != "0" ]; then
|
||
if [ "$china_ip6_route" = "1" ]; then
|
||
rule="-m set --match-set china_ip6_route dst"
|
||
elif [ "$china_ip6_route" = "2" ]; then
|
||
rule="-m set ! --match-set china_ip6_route dst"
|
||
fi
|
||
[ "$enable_redirect_dns" != "2" ] && rule="$rule -m set ! --match-set china_ip6_route_pass dst"
|
||
ip6tables -t mangle -A openclash $rule -j RETURN >/dev/null 2>&1
|
||
fi
|
||
fi
|
||
|
||
#tcp Tproxy && TUN
|
||
if [ "$ipv6_mode" -ne 1 ] && [ "$ipv6_mode" -ne 3 ]; then
|
||
if [ "$ipv6_mode" -eq 0 ]; then
|
||
ip6tables -t mangle -A openclash -p tcp -m comment --comment "OpenClash TCP Tproxy" -j TPROXY --on-port "$tproxy_port" --tproxy-mark "$PROXY_FWMARK"
|
||
else
|
||
ip6tables -t mangle -A openclash -p tcp -j MARK --set-mark "$PROXY_FWMARK"
|
||
fi
|
||
fi
|
||
|
||
#udp
|
||
if [ "$ipv6_mode" -eq 2 ] || [ "$ipv6_mode" -eq 3 ]; then
|
||
ip6tables -t mangle -A openclash -p udp -m comment --comment "OpenClash UDP TUN" -j MARK --set-xmark "$PROXY_FWMARK"
|
||
else
|
||
if [ "$enable_v6_udp_proxy" -eq 1 ]; then
|
||
ip6tables -t mangle -A openclash -p udp -m comment --comment "OpenClash UDP Tproxy" -j TPROXY --on-port "$tproxy_port" --tproxy-mark "$PROXY_FWMARK"
|
||
fi
|
||
fi
|
||
|
||
ip6tables -t mangle -A PREROUTING -j openclash
|
||
|
||
#router self proxy
|
||
if [ "$router_self_proxy" = "1" ]; then
|
||
if [ "$ipv6_mode" -eq 1 ] || [ "$ipv6_mode" -eq 3 ]; then
|
||
#tcp Redirect Mode
|
||
ip6tables -t nat -N openclash_output
|
||
ip6tables -t nat -F openclash_output
|
||
ip6tables -t nat -A openclash_output $owner -j RETURN
|
||
ip6tables -t nat -A openclash_output -m set --match-set localnetwork6 dst -j RETURN
|
||
ip6tables -t nat -A openclash_output -m conntrack --ctdir REPLY -j RETURN
|
||
ip6tables -t nat -A openclash_output -m set --match-set wan_ac_black_ipv6s dst -j RETURN >/dev/null 2>&1
|
||
if [ "$en_mode" = "redir-host" ]; then
|
||
ip6tables -t nat -A openclash_output -m set ! --match-set common_ports dst -j RETURN >/dev/null 2>&1
|
||
fi
|
||
if [ "$china_ip6_route" != "0" ]; then
|
||
if [ "$china_ip6_route" = "1" ]; then
|
||
rule="-m set --match-set china_ip6_route dst"
|
||
elif [ "$china_ip6_route" = "2" ]; then
|
||
rule="-m set ! --match-set china_ip6_route dst"
|
||
fi
|
||
[ "$enable_redirect_dns" != "2" ] && rule="$rule -m set ! --match-set china_ip6_route_pass dst"
|
||
ip6tables -t nat -A openclash_output $rule -j RETURN >/dev/null 2>&1
|
||
fi
|
||
ip6tables -t nat -A openclash_output -p tcp -j REDIRECT --to-ports "$proxy_port"
|
||
ip6tables -t nat -A OUTPUT -j openclash_output >/dev/null 2>&1
|
||
fi
|
||
|
||
#other mode and Redirect Mode udp
|
||
ip6tables -t mangle -N openclash_output
|
||
ip6tables -t mangle -F openclash_output
|
||
ip6tables -t mangle -A openclash_output $owner -j RETURN
|
||
ip6tables -t mangle -A openclash_output -m set --match-set localnetwork6 dst -j RETURN
|
||
ip6tables -t mangle -A openclash_output -m conntrack --ctdir REPLY -j RETURN
|
||
ip6tables -t mangle -A openclash_output -m set --match-set wan_ac_black_ipv6s dst -j RETURN >/dev/null 2>&1
|
||
if [ "$en_mode" = "redir-host" ]; then
|
||
ip6tables -t mangle -A openclash_output -m set ! --match-set common_ports dst -j RETURN >/dev/null 2>&1
|
||
fi
|
||
if [ "$china_ip6_route" != "0" ]; then
|
||
if [ "$china_ip6_route" = "1" ]; then
|
||
rule="-m set --match-set china_ip6_route dst"
|
||
elif [ "$china_ip6_route" = "2" ]; then
|
||
rule="-m set ! --match-set china_ip6_route dst"
|
||
fi
|
||
[ "$enable_redirect_dns" != "2" ] && rule="$rule -m set ! --match-set china_ip6_route_pass dst"
|
||
ip6tables -t mangle -A openclash_output $rule -j RETURN >/dev/null 2>&1
|
||
fi
|
||
|
||
if ([ "$ipv6_mode" -eq 1 ] && [ "$enable_v6_udp_proxy" -eq 1 ]) || [ "$ipv6_mode" -eq 3 ]; then
|
||
ip6tables -t mangle -A openclash_output -p udp -j MARK --set-xmark "$PROXY_FWMARK"
|
||
fi
|
||
if ([ "$ipv6_mode" -eq 0 ] && [ "$enable_v6_udp_proxy" -eq 1 ]) || [ "$ipv6_mode" -eq 2 ]; then
|
||
ip6tables -t mangle -A openclash_output -j MARK --set-xmark "$PROXY_FWMARK"
|
||
fi
|
||
if [ "$ipv6_mode" -eq 0 ] && [ "$enable_v6_udp_proxy" -ne 1 ]; then
|
||
ip6tables -t mangle -A openclash_output -p tcp -j MARK --set-xmark "$PROXY_FWMARK"
|
||
fi
|
||
ip6tables -t mangle -A OUTPUT -j openclash_output
|
||
fi
|
||
|
||
#route
|
||
if [ "$ipv6_mode" -ne 2 ] && [ "$ipv6_mode" -ne 3 ]; then
|
||
if [ "$enable_v6_udp_proxy" -eq 1 ] || [ "$ipv6_mode" -eq 0 ]; then
|
||
modprobe xt_TPROXY >/dev/null 2>&1
|
||
ip -6 rule add fwmark "$PROXY_FWMARK" table "$PROXY_ROUTE_TABLE"
|
||
ip -6 route add local ::/0 dev lo table "$PROXY_ROUTE_TABLE"
|
||
fi
|
||
fi
|
||
|
||
#TUN FORWORD
|
||
if [ "$ipv6_mode" -eq 2 ] || [ "$ipv6_mode" -eq 3 ]; then
|
||
ip6tables -I FORWARD -m comment --comment "OpenClash TUN Forward" -o utun -j ACCEPT >/dev/null 2>&1
|
||
ip6tables -I FORWARD -m comment --comment "OpenClash TUN Forward" -i utun -j ACCEPT >/dev/null 2>&1
|
||
ip6tables -I INPUT -m comment --comment "OpenClash TUN Input" -i utun -j ACCEPT >/dev/null 2>&1
|
||
ip6tables -t nat -I POSTROUTING -m comment --comment "OpenClash TUN Postrouting" -o utun -j RETURN >/dev/null 2>&1
|
||
fi
|
||
|
||
#quic
|
||
if [ "$disable_udp_quic" -eq 1 ]; then
|
||
if [ "$ipv6_mode" -eq 2 ] || [ "$ipv6_mode" -eq 3 ]; then
|
||
chain="FORWARD -o utun"
|
||
else
|
||
chain="INPUT"
|
||
fi
|
||
if [ "$china_ip6_route" = "2" ]; then
|
||
rule="-m set --match-set china_ip6_route dst"
|
||
else
|
||
rule="-m set ! --match-set china_ip6_route dst"
|
||
fi
|
||
ip6tables -I $chain -p udp --dport 443 -m comment --comment "OpenClash QUIC REJECT" $rule -j REJECT >/dev/null 2>&1
|
||
fi
|
||
|
||
#bypass gateway compatible
|
||
if [ "$bypass_gateway_compatible" -eq 1 ]; then
|
||
ip6tables -t nat -N openclash_post
|
||
ip6tables -t nat -F openclash_post
|
||
ip6tables -t nat -A openclash_post $owner -j RETURN
|
||
ip6tables -t nat -A openclash_post -m mark --mark "$PROXY_FWMARK" -j ACCEPT
|
||
ip6tables -t nat -A openclash_post -m set --match-set localnetwork6 dst -j RETURN
|
||
ip6tables -t nat -A openclash_post -m conntrack --ctdir REPLY -j RETURN
|
||
ip6tables -t nat -A openclash_post $addr_local -j MASQUERADE
|
||
ip6tables -t nat -A POSTROUTING -m comment --comment "OpenClash Bypass Gateway Compatible" -j openclash_post
|
||
fi
|
||
|
||
#intranet allowed
|
||
if [ "$intranet_allowed" -eq 1 ]; then
|
||
if [ -n "$intranet_allowed_wan_name" ] && [ "$intranet_allowed_wan_name" != "0" ]; then
|
||
config_load "openclash"
|
||
config_list_foreach "config" "intranet_allowed_wan_name" wan6_name_add
|
||
else
|
||
wan6_ints=$(ip6tables-save -t filter |grep -e "-j zone_wan_input" 2>/dev/null |awk '{for (i=1;i<=NF;i++) {if ($i ~ /-i/) {print $(i+1)}}}' 2>/dev/null)
|
||
fi
|
||
if [ -n "$wan6_ints" ]; then
|
||
ip6tables -t filter -N openclash_wan_input
|
||
ip6tables -t filter -F openclash_wan_input
|
||
for wan6_int in $wan6_ints; do
|
||
ip6tables -t filter -I INPUT -i "$wan6_int" -m set ! --match-set localnetwork6 src -j openclash_wan_input
|
||
done
|
||
ip6tables -t filter -A openclash_wan_input -p udp -m multiport --dport "$proxy_port,$tproxy_port,$cn_port,$http_port,$socks_port,$mixed_port,$dns_port" -j REJECT >/dev/null 2>&1
|
||
ip6tables -t filter -A openclash_wan_input -p tcp -m multiport --dport "$proxy_port,$tproxy_port,$cn_port,$http_port,$socks_port,$mixed_port,$dns_port" -j REJECT >/dev/null 2>&1
|
||
else
|
||
LOG_OUT "Warning: Can't Settting Only Intranet Allowed Function, Get IPv6 WAN Interfaces error, Please Verify The Firewall's WAN Zone Name is wan, Ignore This IF The Device Does not Have a WAN Interfaces..."
|
||
fi
|
||
fi
|
||
fi
|
||
fi 2>/dev/null
|
||
|
||
#端口转发
|
||
LOG_OUT "Tip: Start Add Port Bypassing Rules For Firewall Redirect and Firewall Rules..."
|
||
config_load "firewall"
|
||
config_foreach firewall_redirect_exclude "redirect"
|
||
config_foreach firewall_rule_exclude "rule"
|
||
config_load "openclash"
|
||
config_foreach firewall_lan_ac_traffic "lan_ac_traffic"
|
||
|
||
#Custom
|
||
|
||
if [ -f "/etc/openclash/custom/openclash_custom_firewall_rules.sh" ]; then
|
||
chmod +x /etc/openclash/custom/openclash_custom_firewall_rules.sh >/dev/null 2>&1
|
||
/etc/openclash/custom/openclash_custom_firewall_rules.sh >/dev/null 2>&1
|
||
fi
|
||
|
||
}
|
||
|
||
revert_firewall()
|
||
{
|
||
rm -rf /var/etc/openclash.include >/dev/null 2>&1
|
||
|
||
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
|
||
|
||
ip -6 rule del fwmark "$PROXY_FWMARK" table "$PROXY_ROUTE_TABLE" >/dev/null 2>&1
|
||
ip -6 route del local ::/0 dev lo table "$PROXY_ROUTE_TABLE" >/dev/null 2>&1
|
||
|
||
#TUN
|
||
ip rule del fwmark "$PROXY_FWMARK" table "$PROXY_ROUTE_TABLE" >/dev/null 2>&1
|
||
ip rule del fwmark "$PROXY_FWMARK" ipproto icmp table main >/dev/null 2>&1
|
||
ip route del default dev utun table "$PROXY_ROUTE_TABLE" >/dev/null 2>&1
|
||
ip -6 rule del fwmark "$PROXY_FWMARK" table "$PROXY_ROUTE_TABLE" >/dev/null 2>&1
|
||
ip -6 rule del fwmark "$PROXY_FWMARK" ipproto icmp table main >/dev/null 2>&1
|
||
ip -6 route del default dev utun table "$PROXY_ROUTE_TABLE" >/dev/null 2>&1
|
||
|
||
if [ -n "$FW4" ]; then
|
||
for nft in "input" "forward" "dstnat" "srcnat" "nat_output" "mangle_prerouting" "mangle_output"; do
|
||
local handles=$(nft -a list chain inet fw4 ${nft} |grep -E "openclash|OpenClash" |awk -F '# handle ' '{print$2}')
|
||
for handle in $handles; do
|
||
nft delete rule inet fw4 ${nft} handle ${handle}
|
||
done
|
||
done >/dev/null 2>&1
|
||
|
||
for handle in $(nft -a list chains |grep -E "chain openclash|OpenClash" |awk -F '# handle ' '{print$2}'); do
|
||
nft delete chain inet fw4 handle ${handle}
|
||
done >/dev/null 2>&1
|
||
|
||
for handle in $(nft -a list sets |grep -E "set localnetwork|china_ip|lan_ac_|wan_ac_black_|_google_dns_|common_ports" |awk -F '# handle ' '{print$2}'); do
|
||
nft delete set inet fw4 handle ${handle}
|
||
done >/dev/null 2>&1
|
||
else
|
||
for ipt in "iptables -nvL INPUT" "iptables -nvL FORWARD" "iptables -nvL POSTROUTING -t nat" "iptables -nvL OUTPUT -t nat" "iptables -nvL OUTPUT -t mangle" "iptables -nvL PREROUTING -t nat" "iptables -nvL PREROUTING -t mangle" "ip6tables -nvL PREROUTING -t mangle" "ip6tables -nvL OUTPUT -t mangle" "ip6tables -nvL PREROUTING -t nat" "ip6tables -nvL INPUT" "ip6tables -nvL POSTROUTING -t nat" "ip6tables -nvL FORWARD" "ip6tables -nvL OUTPUT -t nat"; do
|
||
for comment in "openclash" "OpenClash"; do
|
||
local lines=$($ipt |sed 1,2d |sed -n "/${comment}/=" 2>/dev/null |sort -rn)
|
||
if [ -n "$lines" ]; then
|
||
for line in $lines; do
|
||
$(echo "$ipt" |awk -v OFS=" " '{print $1,$4,$5}' |sed 's/[ ]*$//g') -D $(echo "$ipt" |awk '{print $3}') $line
|
||
done
|
||
fi
|
||
done
|
||
done >/dev/null 2>&1
|
||
|
||
for chain in "openclash" "openclash_output" "openclash_post" "openclash_wan_input" "openclash_dns_redirect" "openclash_upnp"; do
|
||
iptables -t nat -F $chain
|
||
iptables -t nat -X $chain
|
||
iptables -t mangle -F $chain
|
||
iptables -t mangle -X $chain
|
||
iptables -t filter -F $chain
|
||
iptables -t filter -X $chain
|
||
ip6tables -t nat -F $chain
|
||
ip6tables -t nat -X $chain
|
||
ip6tables -t mangle -F $chain
|
||
ip6tables -t mangle -X $chain
|
||
ip6tables -t filter -F $chain
|
||
ip6tables -t filter -X $chain
|
||
done >/dev/null 2>&1
|
||
|
||
ipset destroy localnetwork6 >/dev/null 2>&1
|
||
ipset destroy china_ip6_route >/dev/null 2>&1
|
||
ipset destroy china_ip6_route_pass >/dev/null 2>&1
|
||
ipset destroy lan_ac_white_ipv6s >/dev/null 2>&1
|
||
ipset destroy lan_ac_black_ipv6s >/dev/null 2>&1
|
||
ipset destroy wan_ac_black_ipv6s >/dev/null 2>&1
|
||
ipset destroy localnetwork >/dev/null 2>&1
|
||
ipset destroy china_ip_route >/dev/null 2>&1
|
||
ipset destroy china_ip_route_pass >/dev/null 2>&1
|
||
ipset destroy lan_ac_white_ips >/dev/null 2>&1
|
||
ipset destroy lan_ac_black_ips >/dev/null 2>&1
|
||
ipset destroy lan_ac_white_macs >/dev/null 2>&1
|
||
ipset destroy lan_ac_black_macs >/dev/null 2>&1
|
||
ipset destroy wan_ac_black_ips >/dev/null 2>&1
|
||
ipset destroy common_ports >/dev/null 2>&1
|
||
fi
|
||
}
|
||
|
||
get_config()
|
||
{
|
||
enable=$(uci -q get openclash.config.enable)
|
||
rule_source=$(uci -q get openclash.config.rule_source)
|
||
enable_custom_clash_rules=$(uci -q get openclash.config.enable_custom_clash_rules)
|
||
da_password=$(uci -q get openclash.config.dashboard_password)
|
||
cn_port=$(uci -q get openclash.config.cn_port)
|
||
proxy_port=$(uci -q get openclash.config.proxy_port)
|
||
tproxy_port=$(uci -q get openclash.config.tproxy_port || echo 7895)
|
||
proxy_mode=$(uci -q get openclash.config.proxy_mode)
|
||
ipv6_enable=$(uci -q get openclash.config.ipv6_enable)
|
||
ipv6_dns=$(uci -q get openclash.config.ipv6_dns || echo 0)
|
||
ipv6_mode=$(uci -q get openclash.config.ipv6_mode || echo 0)
|
||
enable_v6_udp_proxy=$(uci -q get openclash.config.enable_v6_udp_proxy || echo 0)
|
||
http_port=$(uci -q get openclash.config.http_port)
|
||
socks_port=$(uci -q get openclash.config.socks_port)
|
||
enable_redirect_dns=$(uci -q get openclash.config.enable_redirect_dns || echo 1)
|
||
if [ "$(uci -q get openclash.config.fakeip_range)" == "0" ]; then
|
||
fakeip_range=$(ruby_read "$CONFIG_FILE" "['dns']['fake-ip-range']")
|
||
else
|
||
fakeip_range=$(uci -q get openclash.config.fakeip_range)
|
||
fi
|
||
[ -z "$fakeip_range" ] && fakeip_range="198.18.0.1/16"
|
||
|
||
lan_interface_name=$(uci -q get openclash.config.lan_interface_name || echo 0)
|
||
if [ "$lan_interface_name" = "0" ]; then
|
||
lan_ip=$(uci -q get network.lan.ipaddr 2>/dev/null | awk -F '/' '{print $1}' 2>/dev/null | tr -d '\n' || ip address show $(uci -q -p /tmp/state get network.lan.ifname || uci -q -p /tmp/state get network.lan.device) | grep -w "inet" 2>/dev/null |grep -Eo 'inet [0-9\.]+' | awk '{print $2}' | head -1 | tr -d '\n' || ip addr show 2>/dev/null | grep -w 'inet' | grep 'global' | grep 'brd' | grep -Eo 'inet [0-9\.]+' | awk '{print $2}' | head -n 1 | tr -d '\n')
|
||
else
|
||
lan_ip=$(ip address show $lan_interface_name 2>/dev/null | grep -w "inet" 2>/dev/null | grep -Eo 'inet [0-9\.]+' | awk '{print $2}' | head -1 | tr -d '\n')
|
||
fi
|
||
|
||
wan_ip4s=$(/usr/share/openclash/openclash_get_network.lua "wanip" 2>/dev/null)
|
||
wan_ip6s=$(ifconfig | grep 'inet6 addr' | awk '{print $3}' 2>/dev/null)
|
||
log_level=$(uci -q get openclash.config.log_level)
|
||
intranet_allowed=$(uci -q get openclash.config.intranet_allowed)
|
||
enable_udp_proxy=$(uci -q get openclash.config.enable_udp_proxy || echo 1)
|
||
disable_udp_quic=$(uci -q get openclash.config.disable_udp_quic)
|
||
operation_mode=$(uci -q get openclash.config.operation_mode)
|
||
lan_ac_mode=$(uci -q get openclash.config.lan_ac_mode)
|
||
enable_rule_proxy=$(uci -q get openclash.config.enable_rule_proxy)
|
||
stack_type=$(uci -q get openclash.config.stack_type)
|
||
stack_type_v6=$(uci -q get openclash.config.stack_type_v6 || echo "system")
|
||
china_ip_route=$(uci -q get openclash.config.china_ip_route); [[ "$china_ip_route" != "0" && "$china_ip_route" != "1" && "$china_ip_route" != "2" ]] && china_ip_route=0
|
||
china_ip6_route=$(uci -q get openclash.config.china_ip6_route); [[ "$china_ip6_route" != "0" && "$china_ip6_route" != "1" && "$china_ip6_route" != "2" ]] && china_ip6_route=0
|
||
small_flash_memory=$(uci -q get openclash.config.small_flash_memory)
|
||
mixed_port=$(uci -q get openclash.config.mixed_port)
|
||
interface_name=$(uci -q get openclash.config.interface_name || echo 0)
|
||
common_ports=$(uci -q get openclash.config.common_ports)
|
||
dns_port=$(uci -q get openclash.config.dns_port)
|
||
store_fakeip=$(uci -q get openclash.config.store_fakeip || echo 0)
|
||
bypass_gateway_compatible=$(uci -q get openclash.config.bypass_gateway_compatible || echo 0)
|
||
core_version=$(uci -q get openclash.config.core_version || echo 0)
|
||
router_self_proxy=$(uci -q get openclash.config.router_self_proxy || echo 1)
|
||
enable_meta_sniffer=$(uci -q get openclash.config.enable_meta_sniffer || echo 0)
|
||
enable_meta_sniffer_custom=$(uci -q get openclash.config.enable_meta_sniffer_custom || echo 0)
|
||
geodata_loader=$(uci -q get openclash.config.geodata_loader || echo 0)
|
||
enable_geoip_dat=$(uci -q get openclash.config.enable_geoip_dat || echo 0)
|
||
enable_tcp_concurrent=$(uci -q get openclash.config.enable_tcp_concurrent || echo 0)
|
||
append_default_dns=$(uci -q get openclash.config.append_default_dns || echo 0)
|
||
enable_meta_sniffer_pure_ip=$(uci -q get openclash.config.enable_meta_sniffer_pure_ip || echo 0)
|
||
find_process_mode=$(uci -q get openclash.config.find_process_mode || echo 0)
|
||
upnp_lease_file=$(uci -q get upnpd.config.upnp_lease_file)
|
||
global_client_fingerprint=$(uci -q get openclash.config.global_client_fingerprint || echo 0)
|
||
enable_unified_delay=$(uci -q get openclash.config.enable_unified_delay || echo 0)
|
||
enable_respect_rules=$(uci -q get openclash.config.enable_respect_rules || echo 0)
|
||
intranet_allowed_wan_name=$(uci -q get openclash.config.intranet_allowed_wan_name || echo 0)
|
||
custom_fakeip_filter_mode=$(uci -q get openclash.config.custom_fakeip_filter_mode || echo "blacklist")
|
||
iptables_compat=$(iptables -m owner -h 2>/dev/null | grep "owner match options" || command -v fw4 || echo 0)
|
||
disable_quic_go_gso=$(uci -q get openclash.config.disable_quic_go_gso || echo 0)
|
||
[ -z "$dns_port" ] && dns_port=7874 && uci -q set openclash.config.dns_port=7874
|
||
uci -q commit openclash
|
||
}
|
||
|
||
start_service()
|
||
{
|
||
|
||
enable=$(uci -q get openclash.config.enable)
|
||
[ "$enable" != "1" ] && LOG_OUT "Warning: OpenClash Now Disabled, Need Start From Luci Page, Exit..." && SLOG_CLEAN && exit 0
|
||
|
||
LOG_OUT "OpenClash Start Running..."
|
||
|
||
config_choose
|
||
do_run_mode
|
||
|
||
LOG_OUT "Step 1: Get The Configuration..."
|
||
get_config
|
||
|
||
LOG_OUT "Step 2: Check The Components..."
|
||
#检查文件是否存在
|
||
do_run_file "$RAW_CONFIG_FILE" "$BACKUP_FILE"
|
||
|
||
if ! $quick_start; then
|
||
LOG_OUT "Step 3: Modify The Config File..."
|
||
config_check
|
||
/usr/share/openclash/yml_change.sh 2>/dev/null "$en_mode" "$da_password" "$cn_port" "$proxy_port" "$TMP_CONFIG_FILE" "$ipv6_enable" "$http_port" "$socks_port" "$log_level" "$proxy_mode" "$en_mode_tun" "$stack_type" "$dns_port" "$mixed_port" "$tproxy_port" "$ipv6_dns" "$store_fakeip" "$enable_meta_sniffer" "$enable_geoip_dat" "$geodata_loader" "$enable_meta_sniffer_custom" "$interface_name" "$enable_tcp_concurrent" "$core_type" "$append_default_dns" "$enable_meta_sniffer_pure_ip" "$find_process_mode" "$fakeip_range" "$global_client_fingerprint" "$ipv6_mode" "$stack_type_v6" "$enable_unified_delay" "$enable_respect_rules" "$custom_fakeip_filter_mode" "$iptables_compat" "$disable_quic_go_gso"
|
||
/usr/share/openclash/yml_rules_change.sh 2>/dev/null "$rule_source" "$enable_custom_clash_rules" "$TMP_CONFIG_FILE" "$enable_rule_proxy" "$CONFIG_NAME" "$router_self_proxy" "$lan_ip" "$enable_redirect_dns" "$en_mode"
|
||
#Custom overwrite
|
||
if [ -f "/etc/openclash/custom/openclash_custom_overwrite.sh" ]; then
|
||
chmod +x /etc/openclash/custom/openclash_custom_overwrite.sh >/dev/null 2>&1
|
||
/etc/openclash/custom/openclash_custom_overwrite.sh 2>/dev/null "$TMP_CONFIG_FILE"
|
||
fi
|
||
else
|
||
LOG_OUT "Step 3: Quick Start Mode, Skip Modify The Config File..."
|
||
fi
|
||
|
||
LOG_OUT "Step 4: Start Running The Clash Core..."
|
||
start_run_core
|
||
|
||
LOG_OUT "Step 5: Set Dnsmasq..."
|
||
change_dns "$enable_redirect_dns"
|
||
|
||
LOG_OUT "Step 6: Set Firewall Rules..."
|
||
set_firewall
|
||
check_core_status &
|
||
|
||
LOG_OUT "Step 7: Add Cron Rules, Start Daemons..."
|
||
add_cron
|
||
if [ -z "$(uci -q get dhcp.lan.dhcpv6)" ] || [ "$(uci -q get dhcp.lan.dhcpv6)" == "disabled" ]; then
|
||
LOG_OUT "OpenClash Start Successful!"
|
||
elif [ "$ipv6_enable" -eq 0 ]; then
|
||
LOG_OUT "Warning: OpenClash Start Successful, Please Note That Network May Abnormal With IPv6's DHCP Server"
|
||
else
|
||
LOG_OUT "OpenClash Start Successful!"
|
||
fi
|
||
echo "OpenClash Already Start!"
|
||
write_run_quick
|
||
SLOG_CLEAN
|
||
rm -rf /tmp/yaml_*
|
||
}
|
||
|
||
stop_service()
|
||
{
|
||
|
||
enable=$(uci -q get openclash.config.enable)
|
||
|
||
LOG_OUT "OpenClash Stoping..."
|
||
LOG_OUT "Step 1: Backup The Current Groups State..."
|
||
/usr/share/openclash/openclash_history_get.sh 2>/dev/null
|
||
|
||
LOG_OUT "Step 2: Delete OpenClash Firewall Rules..."
|
||
revert_firewall
|
||
|
||
LOG_OUT "Step 3: Close The OpenClash Daemons..."
|
||
watchdog_pids=$(unify_ps_pids "openclash_watchdog.sh")
|
||
for watchdog_pid in $watchdog_pids; do
|
||
kill -9 "$watchdog_pid" >/dev/null 2>&1
|
||
done >/dev/null 2>&1
|
||
|
||
streaming_unlock_pids=$(unify_ps_pids "openclash_streaming_unlock.lua")
|
||
for streaming_unlock_pid in $streaming_unlock_pids; do
|
||
kill -9 "$streaming_unlock_pid" >/dev/null 2>&1
|
||
done >/dev/null 2>&1
|
||
|
||
LOG_OUT "Step 4: Close The Clash Core Process..."
|
||
if [ "$enable" != "1" ]; then
|
||
kill_clash
|
||
fi
|
||
|
||
LOG_OUT "Step 5: Restart Dnsmasq..."
|
||
revert_dnsmasq
|
||
|
||
LOG_OUT "Step 6: Delete OpenClash Residue File..."
|
||
if [ "$enable" != "1" ]; then
|
||
|
||
rm -rf /tmp/clash_last_version >/dev/null 2>&1
|
||
rm -rf /tmp/Proxy_Group >/dev/null 2>&1
|
||
rm -rf /tmp/rules_name >/dev/null 2>&1
|
||
rm -rf /tmp/rule_providers_name >/dev/null 2>&1
|
||
rm -rf /tmp/openclash_last_version >/dev/null 2>&1
|
||
rm -rf /tmp/openclash_config.tmp >/dev/null 2>&1
|
||
rm -rf /tmp/openclash.change >/dev/null 2>&1
|
||
rm -rf /tmp/openclash_debug.log >/dev/null 2>&1
|
||
rm -rf /tmp/openclash_edit_file_name >/dev/null 2>&1
|
||
rm -rf ${DNSMASQ_CONF_DIR}/dnsmasq_openclash_chnroute_pass.conf >/dev/null 2>&1
|
||
rm -rf ${DNSMASQ_CONF_DIR}/dnsmasq_openclash_chnroute6_pass.conf >/dev/null 2>&1
|
||
rm -rf ${DNSMASQ_CONF_DIR}/dnsmasq_openclash_custom_domain.conf >/dev/null 2>&1
|
||
LOG_OUT "OpenClash Already Stop!"
|
||
else
|
||
LOG_OUT "OpenClash Already Stop!"
|
||
fi
|
||
|
||
del_cron
|
||
rm -rf /tmp/yaml_* >/dev/null 2>&1
|
||
rm -rf $START_LOG >/dev/null 2>&1
|
||
echo "OpenClash Already Stop!"
|
||
}
|
||
|
||
revert_dnsmasq()
|
||
{
|
||
get_config
|
||
redirect_dns=$(uci -q get openclash.config.redirect_dns)
|
||
dnsmasq_server=$(uci -q get openclash.config.dnsmasq_server)
|
||
dnsmasq_noresolv=$(uci -q get openclash.config.dnsmasq_noresolv)
|
||
dnsmasq_resolvfile=$(uci -q get openclash.config.dnsmasq_resolvfile)
|
||
cachesize_dns=$(uci -q get openclash.config.cachesize_dns)
|
||
dnsmasq_cachesize=$(uci -q get openclash.config.dnsmasq_cachesize)
|
||
filter_aaaa_dns=$(uci -q get openclash.config.filter_aaaa_dns)
|
||
dnsmasq_filter_aaaa=$(uci -q get openclash.config.dnsmasq_filter_aaaa)
|
||
default_resolvfile=$(uci -q get openclash.config.default_resolvfile)
|
||
revert_dns "$redirect_dns" "$enable" "$default_resolvfile" "$dnsmasq_noresolv" "$dnsmasq_resolvfile" "$cachesize_dns" "$dnsmasq_cachesize" "$filter_aaaa_dns" "$dnsmasq_filter_aaaa" "$dnsmasq_server"
|
||
/etc/init.d/dnsmasq restart >/dev/null 2>&1
|
||
}
|
||
|
||
restart()
|
||
{
|
||
echo "OpenClash Restart..."
|
||
LOG_OUT "OpenClash Restart..."
|
||
#快速启动判断
|
||
check_run_quick
|
||
stop
|
||
start
|
||
}
|
||
|
||
start_watchdog()
|
||
{
|
||
procd_open_instance "openclash-watchdog"
|
||
procd_set_param command "/usr/share/openclash/openclash_watchdog.sh"
|
||
procd_close_instance
|
||
}
|
||
|
||
reload_service()
|
||
{
|
||
enable=$(uci -q get openclash.config.enable)
|
||
if pidof clash >/dev/null && [ "$enable" == "1" ] && [ "$1" == "firewall" ]; then
|
||
LOG_OUT "Reload OpenClash Firewall Rules..."
|
||
revert_firewall 2>/dev/null
|
||
do_run_mode 2>/dev/null
|
||
get_config 2>/dev/null
|
||
set_firewall 2>/dev/null
|
||
check_core_status & 2>/dev/null
|
||
SLOG_CLEAN
|
||
fi
|
||
if pidof clash >/dev/null && [ "$enable" == "1" ] && [ "$1" == "revert" ]; then
|
||
revert_firewall 2>/dev/null
|
||
revert_dnsmasq 2>/dev/null
|
||
SLOG_CLEAN
|
||
fi
|
||
if pidof clash >/dev/null && [ "$enable" == "1" ] && [ "$1" == "restore" ]; then
|
||
do_run_mode 2>/dev/null
|
||
get_config 2>/dev/null
|
||
change_dns "$enable_redirect_dns"
|
||
set_firewall 2>/dev/null
|
||
check_core_status & 2>/dev/null
|
||
SLOG_CLEAN
|
||
fi
|
||
if [ "$enable" == "1" ] && [ "$1" == "core" ]; then
|
||
check_run_quick 2>/dev/null
|
||
do_run_mode 2>/dev/null
|
||
get_config 2>/dev/null
|
||
start_run_core 2>/dev/null
|
||
check_core_status 2>/dev/null
|
||
write_run_quick 2>/dev/null
|
||
SLOG_CLEAN
|
||
fi
|
||
}
|
||
|
||
boot()
|
||
{
|
||
delay_start=$(uci -q get openclash.config.delay_start || echo 0)
|
||
enable=$(uci -q get openclash.config.enable)
|
||
if [ "$delay_start" -gt 0 ] && [ "$enable" == "1" ]; then
|
||
LOG_OUT "Enable Delay Start, OpenClash Will Start After【$delay_start】Seconds..."
|
||
sleep "$delay_start"
|
||
fi
|
||
restart
|
||
}
|
||
|