#!/bin/sh /etc/rc.common # Copyright (c) 2019 vernesong START=99 STOP=15 . $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_CONF_DIR=$(uci -q get dhcp.@dnsmasq[0].confdir || echo '/tmp/dnsmasq.d') DNSMASQ_CONF_DIR=${DNSMASQ_CONF_DIR%*/} } LOGTIME=$(echo $(date "+%Y-%m-%d %H:%M:%S")) 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" LOCK_FILE=/tmp/lock/openclash.lock PROXY_FWMARK="0x162" PROXY_ROUTE_TABLE="0x162" set_lock() { exec 888>"$LOCK_FILE" 2>/dev/null flock -x 888 2>/dev/null } del_lock() { flock -u 888 2>/dev/null rm -rf "$LOCK_FILE" } 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 nohup /usr/share/openclash/openclash_watchdog.sh & } del_cron() { sed -i '/openclash.sh/d' $CRON_FILE 2>/dev/null sed -i '/openclash_rule.sh/d' $CRON_FILE 2>/dev/null 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() { if [ "$1" -eq 1 ]; then uci -q del openclash.config.dnsmasq_server config_load "dhcp" config_list_foreach "$(uci 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 openclash.config.redirect_dns=1 else uci -q set openclash.config.redirect_dns=0 fi if [ "$1" -eq 1 ] && [ "$2" -eq 1 ]; then 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.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() { [ "$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" ]; then uci -q set dhcp.@dnsmasq[0].resolvfile="$5" elif [ -n "$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 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 else rm -rf /tmp/resolv.conf.auto touch /tmp/resolv.conf.auto 2>/dev/null cat >> "/tmp/resolv.conf.auto" <<-EOF # Interface lan nameserver 114.114.114.114 nameserver 119.29.29.29 EOF uci -q set dhcp.@dnsmasq[0].resolvfile=/tmp/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 rm -rf ${DNSMASQ_CONF_DIR}/dnsmasq_openclash_custom_domain.conf >/dev/null 2>&1 } kill_clash() { clash_pids=$(pidof clash |sed 's/$//g') for clash_pid in $clash_pids; do kill -9 "$clash_pid" 2>/dev/null done >/dev/null 2>&1 sleep 1 } start_fail() { kill_clash stop del_lock exit 0 } #检查集文件防止启动失败 yml_provider_check() { provider_path_line=$(ruby_read "$1" ".key?('$2')") local provider_path_check if "$provider_path_line"; then while :; do provider_path_check=$(ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e " Value = YAML.load_file('$1'); Value['$2'].values.each{|x,v| if not x['path'].empty? then if x['path'].split('/')[0] == '.' then v = '/etc/openclash/'+x['path'].split('./')[1] else v = x['path'] end end; if File::exist?(v) then if not YAML.load_file(v).key?('$3') then puts false break end else puts false break end } " 2>/dev/null) if [ "$provider_path_check" == "false" ] && [ -n "$(pidof clash)" ]; then sleep 2 else break fi done fi if [ -z "$(pidof clash)" ] && [ "$provider_path_check" == "false" ]; then if [ "$2" = "proxy-providers" ]; then LOG_OUT "Error: Failed To Download Proxy-providers, Please Check The Log Page For Detailed error information!" else LOG_OUT "Error: Failed To Download Rule-providers, Please Check The Log Page For Detailed error information!" fi LOG_ALERT LOG_OUT "Tip: You Can Try to Restart With Meta Core" start_fail fi } #获取订阅配置 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 RAW_CONFIG_FILE="/etc/openclash/config/config.yaml" else RAW_CONFIG_FILE="/etc/openclash/config/$name.yaml" fi uci -q set openclash.config.config_path="$RAW_CONFIG_FILE" uci -q commit openclash subscribe_enable=1 } #配置文件选择 config_choose() { if [ -z "$RAW_CONFIG_FILE" ] || [ ! -f "$RAW_CONFIG_FILE" ]; then CONFIG_NAME=$(ls -lt /etc/openclash/config/ | grep -E '.yaml|.yml' | head -n 1 |awk '{print $9}') if [ -n "$CONFIG_NAME" ]; then 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" fi fi 2>/dev/null 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" if [ ! -f "$RAW_CONFIG_FILE" ]; then config_load "openclash" config_foreach sub_info_get "config_subscribe" if [ "$subscribe_enable" = "1" ]; then LOG_OUT "Config File Does Not Exist, You Have Set Subscription Information, Ready To Download..." nohup /usr/share/openclash/openclash.sh & del_lock exit 0 else LOG_OUT "Error: Config Not Found" sleep 3 del_lock exit 0 fi fi } 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 puts '${LOGTIME} 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!" sleep 3 start_fail elif [ ! -f "$TMP_CONFIG_FILE" ] || [ ! -s "$TMP_CONFIG_FILE" ]; then LOG_OUT "Error: Config File Format Validation Failed..." sleep 3 start_fail fi } yml_other_rules_get() { local section="$1" local enabled config config_get_bool "enabled" "$section" "enabled" "1" config_get "config" "$section" "config" "" if [ "$enabled" = "0" ] || [ "$config" != "$2" ]; then return fi if [ -n "$rule_name" ]; then return fi config_get "rule_name" "$section" "rule_name" "" } check_run_quick() { quick_start=true check_file="$(echo $RAW_CONFIG_FILE | tr " " "?") /etc/openclash/custom/openclash_custom_domain_dns.list /etc/openclash/custom/openclash_custom_domain_dns_policy.list /etc/openclash/custom/openclash_custom_fake_filter.list /etc/openclash/custom/openclash_custom_fallback_filter.yaml /etc/openclash/custom/openclash_custom_hosts.list /etc/openclash/custom/openclash_custom_rules.list /etc/openclash/custom/openclash_custom_rules_2.list $dev_core_path $tun_core_path $meta_core_path $ipdb_path $geosite_path $geoip_path $chnr_path $chnr6_path /usr/share/openclash/res/ConnersHua.yaml /usr/share/openclash/res/ConnersHua_return.yaml /usr/share/openclash/res/lhie1.yaml /etc/openclash/custom/openclash_force_sniffing_domain.yaml /etc/openclash/custom/openclash_sniffing_domain_filter.yaml /etc/openclash/custom/openclash_sniffing_ports_filter.yaml /etc/openclash/custom/openclash_custom_localnetwork_ipv4.list /etc/openclash/custom/openclash_custom_localnetwork_ipv6.list /etc/openclash/custom/openclash_custom_chnroute_pass.list /etc/openclash/custom/openclash_custom_chnroute6_pass.list $cndomain_path" if [ ! -f "$CONFIG_FILE" ] || [ ! -f "/tmp/openclash_config.tmp" ] || [ ! -f "/tmp/openclash.change" ]; 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() { 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 } custom_rule_provider() { local section="$1" local enabled config config_get "config" "$section" "config" "" config_get_bool "enabled" "$section" "enabled" "1" if [ "$enabled" = "0" ]; then return fi if [ "$config" = "all" ] || [ "$config" = "$CONFIG_NAME" ]; then config_set_custom_rule_provider=1 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)" ] && 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 dev_core_path="/etc/openclash/core/clash" tun_core_path="/etc/openclash/core/clash_tun" 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" cndomain_path="/etc/openclash/accelerated-domains.china.conf" 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/accelerated-domains.china.conf" "$cndomain_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 dev_core_path="/tmp/etc/openclash/core/clash" tun_core_path="/tmp/etc/openclash/core/clash_tun" 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" cndomain_path="/tmp/etc/openclash/accelerated-domains.china.conf" [ ! -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 [ ! -h "/etc/openclash/accelerated-domains.china.conf" ] && mv "/etc/openclash/accelerated-domains.china.conf" "$cndomain_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 if [ "$enable_meta_core" != "1" ]; then if [ -n "$en_mode_tun" ]; then ln -s "$tun_core_path" /etc/openclash/clash 2>/dev/null core_type="TUN" core_start_log="Tip: Detected The Exclusive Function of The TUN Core, Use TUN Core to Start..." fi if [ "$rule_source" != "0" ]; then config_load "openclash" config_foreach yml_other_rules_get "other_rules" "$CONFIG_NAME" fi config_load "openclash" config_set_custom_rule_provider=0 for i in "rule_provider_config" "rule_provider_config" "rule_providers" "game_config"; do config_foreach custom_rule_provider "$i" if [ "$config_set_custom_rule_provider" -eq 1 ]; then break fi done 2>/dev/null if [ "$proxy_mode" = "script" ] || [ "$config_set_custom_rule_provider" -eq 1 ] || [ "$rule_name" = "ConnersHua" ] || [ "$rule_name" = "lhie1" ] || [ -n "$(ruby_read "$RAW_CONFIG_FILE" "['rules'].grep(/(^RULE-SET,|^SCRIPT,)/)")" ] || [ -n "$(ruby_read "/etc/openclash/custom/openclash_custom_rules.list" "['rules'].grep(/(^RULE-SET,|^SCRIPT,)/)")" ] || [ -n "$(ruby_read "/etc/openclash/custom/openclash_custom_rules_2.list" "['rules'].grep(/(^RULE-SET,|^SCRIPT,)/)")" ]; then if [ -z "$en_mode_tun" ]; then ln -s "$tun_core_path" /etc/openclash/clash 2>/dev/null core_type="TUN" core_start_log="Tip: Detected The Exclusive Function of The TUN Core, Use TUN Core to Start..." fi fi else ln -s "$meta_core_path" /etc/openclash/clash 2>/dev/null core_type="Meta" core_start_log="Tip: Detected The Exclusive Function of The Meta Core, Use Meta Core to Start..." fi if [ ! -f "/etc/openclash/clash" ] && [ -f "$dev_core_path" ] && [ -z "$core_type" ]; then ln -s "$dev_core_path" /etc/openclash/clash 2>/dev/null core_start_log="Tip: No Special Configuration Detected, Use Dev Core to Start..." fi if [ ! -f "/etc/openclash/clash" ] && [ -f "$tun_core_path" ] && [ -z "$core_type" ]; then ln -s "$tun_core_path" /etc/openclash/clash 2>/dev/null core_type="TUN" core_start_log="Tip: Detected that the Dev Core is not Installed, Use TUN Core to Start..." fi if [ ! -f "/etc/openclash/clash" ] && [ -f "$meta_core_path" ] && [ -z "$core_type" ]; then ln -s "$meta_core_path" /etc/openclash/clash 2>/dev/null core_type="Meta" core_start_log="Tip: Detected that the Dev Core is not Installed, Use Meta Core to Start..." fi [ ! -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 [ "$core_type" == "TUN" ] && [ ! -f "$tun_core_path" ]; then start_fail elif [ "$core_type" == "Meta" ] && [ ! -f "$meta_core_path" ]; then start_fail elif [ -z "$core_type" ] && [ ! -f "$dev_core_path" ]; then start_fail else del_lock stop exit 0 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" ] && [ "$enable_meta_core" = "1" ] && { 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" = "1" ] || [ "$china_ip6_route" = "1" ] || [ "$disable_udp_quic" = "1" ]; then if [ ! -f "$chnr_path" ] || [ ! -f "$chnr6_path" ]; then LOG_OUT "Tip: Detected that the Chnroute Cidr or CN Domains List is not Installed, Ready to Download..." /usr/share/openclash/openclash_chnroute.sh fi if [ ! -f "$cndomain_path" ] && [ "$en_mode" = "fake-ip" ] && [ "$china_ip_route" = "1" ]; then LOG_OUT "Tip: Detected that the Chnroute Cidr or CN Domains List 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 if [ ! -f "$cndomain_path" ] && [ "$en_mode" = "fake-ip" ] && [ "$china_ip_route" = "1" ]; then start_fail fi fi [ ! -x "$tun_core_path" ] && chmod 4755 "$tun_core_path" 2>/dev/null [ ! -x "$dev_core_path" ] && chmod 4755 "$dev_core_path" 2>/dev/null [ ! -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 } [ -f "$cndomain_path" ] && [ "$small_flash_memory" = "1" ] && { ln -s "$cndomain_path" /etc/openclash/accelerated-domains.china.conf 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 ! capsh --is-uid=0 >/dev/null || ! capsh --has-ambient >/dev/null; then LOG_OUT "Error: Could Not Load The Capsh Library, Please Verify The Capsh Shell Library Work Well..." LOG_OUT "Tip: You Could Download And Re-Install The libcap & libcap-bin Library From The Address Give" echo "" >> $LOG_FILE echo "---------- https://mirrors.cloud.tencent.com/lede/snapshots/packages/ ----------" >> $LOG_FILE echo "" >> $LOG_FILE sleep 3 start_fail 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() { LOG_OUT "$core_start_log" ulimit -SHn 65535 2>/dev/null ulimit -v 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 config_reload=$(uci -q get openclash.config.config_reload) if [ -n "$(pidof clash)" ] && [ "$core_type" != "TUN" ] && [ "$core_type" != "Meta" ] && [ "$config_reload" != "0" ]; then curl -s --connect-timeout 5 -m 5 -H 'Content-Type: application/json' -H "Authorization: Bearer ${da_password}" -XPUT http://"$lan_ip":"$cn_port"/configs?force=true -d "{\"path\": \"$CONFIG_FILE\"}" 2>/dev/null else kill_clash #防止赋权失败 touch "/tmp/openclash.log" 2>/dev/null chmod o+w /etc/openclash/proxy_provider/* 2>/dev/null chmod o+w /etc/openclash/rule_provider/* 2>/dev/null chmod o+w /etc/openclash/history/* 2>/dev/null chmod o+w /etc/openclash/cache.db 2>/dev/null chmod o+w /tmp/openclash.log 2>/dev/null chown nobody:nogroup /etc/openclash/core/* 2>/dev/null #使用nobody启动内核方便代理路由自身流量 capabilties="cap_sys_resource,cap_dac_override,cap_net_raw,cap_net_bind_service,cap_net_admin,cap_sys_ptrace" capsh --caps="${capabilties}+eip" -- -c "capsh --user=nobody --addamb='${capabilties}' -- -c 'nohup $CLASH -d $CLASH_CONFIG -f \"$CONFIG_FILE\" >> $LOG_FILE 2>&1 &'" >> $LOG_FILE 2>&1 fi uci -q set openclash.config.config_reload=1 uci -q commit openclash } check_core_status() { check_time=1 while ( [ "$check_time" -le 3 ] && [ -n "$(pidof clash)" ] ) do sleep 1 let check_time++ done if [ -z "$(pidof clash)" ]; then LOG_ALERT fi } #不修改配置文件启动 raw_config_start() { cp "$RAW_CONFIG_FILE" "$CONFIG_FILE" dns_port=$(ruby_read "$CONFIG_FILE" "['dns']['listen'].split(':')[1]") en_mode=$(ruby_read "$CONFIG_FILE" "['dns']['enhanced-mode']") proxy_port=$(ruby_read "$CONFIG_FILE" "['redir-port']") if [ -z "$dns_port" ] || [ -z "$en_mode" ] || [ -z "$proxy_port" ]; then if [ -z "$dns_port" ]; then LOG_OUT "Error: Get DNS 'listen' Option Error, OpenClash Can Not Start With Raw Config File" sleep 2 fi if [ -z "$en_mode" ]; then LOG_OUT "Error: Get DNS 'enhanced-mode' Option Error, OpenClash Can Not Start With Raw Config File" sleep 2 fi if [ -z "$proxy_port" ]; then LOG_OUT "Error: Get General 'redir-port' Option Error, OpenClash Can Not Start With Raw Config File" sleep 2 fi start_fail fi start_run_core check_core_status if ! pidof clash >/dev/null; then LOG_OUT "Error: OpenClash Can Not Start, Please Check The Error Info And Try Again!" sleep 3 start_fail fi if [ "$en_mode" = "redir-host" ]; then case $en_mode_tun in "1") uci -q set openclash.config.en_mode=redir-host-tun ;; "2") uci -q set openclash.config.en_mode=redir-host-mix ;; *) uci -q set openclash.config.en_mode=redir-host esac elif [ "$en_mode" = "fake-ip" ]; then case $en_mode_tun in "1") uci -q set openclash.config.en_mode=fake-ip-tun ;; "2") uci -q set openclash.config.en_mode=fake-ip-mix ;; *) uci -q set openclash.config.en_mode=fake-ip esac fi dase=$(ruby_read "$CONFIG_FILE" "['secret']") uci -q set openclash.config.dashboard_password="$dase" cn_port=$(ruby_read "$CONFIG_FILE" "['external-controller'].split(':')[1]") uci -q set openclash.config.cn_port="$cn_port" uci -q set openclash.config.proxy_port="$proxy_port" uci -q set openclash.config.restricted_mode=1 uci commit openclash } try_restore_start() { if [ -z "$(pidof clash)" ]; then if [ "$rule_source" = 0 ] && [ "$enable_custom_clash_rules" = 0 ]; then LOG_OUT "Error: OpenClash Can Not Start, Try Use Raw Config Restart Again..." raw_config_start else LOG_OUT "Error: OpenClash Can Not Start, Try Use Backup Rules Start Again..." ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e " begin Value = YAML.load_file('$RAW_CONFIG_FILE'); Value_1 = YAML.load_file('$CONFIG_FILE'); if Value.has_key?('rule-providers') then Value_1['rule-providers'] = Value.select {|x| 'rule-providers' == x}['rule-providers']; end; if Value.has_key?('script') then Value_1['script'] = Value.select {|x| 'script' == x}['script']; end; if Value.has_key?('rules') then Value_1['rules'] = Value.select {|x| 'rules' == x}['rules']; end; File.open('$CONFIG_FILE','w') {|f| YAML.dump(Value_1, f)}; rescue Exception => e puts '${LOGTIME} Error: Restore Backup Rules Failed,【' + e.message + '】'; end " 2>/dev/null >> $LOG_FILE start_run_core check_core_status if ! pidof clash >/dev/null; then LOG_OUT "Error: OpenClash Can Not Start, Try Use Raw Config Restart Again..." raw_config_start fi fi fi } #防火墙设置部分 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 } 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}') if [ -n "$upnp_ip" ] && [ -n "$upnp_dp" ]; then if [ -n "$FW4" ]; then if [ -z "$(nft list chain inet fw4 openclash_upnp |grep "$upnp_ip" |grep "$upnp_dp")" ]; then nft add rule inet fw4 openclash_upnp ip saddr { "$upnp_ip" } udp sport "$upnp_dp" counter return 2>/dev/null fi else if [ -z "$(iptables -t mangle -nL openclash_upnp |grep "$upnp_ip" |grep "$upnp_dp")" ]; then iptables -t mangle -A openclash_upnp -p udp -s "$upnp_ip" --sport "$upnp_dp" -j RETURN 2>/dev/null fi fi fi fi done >/dev/null 2>&1 fi } firewall_rule_exclude() { local section="$1" local name src dest dest_port 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" "" 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 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 else nft insert rule inet fw4 openclash_mangle_v6 position 0 ip6 saddr { "$dest_ip" } tcp sport "$i" counter return >/dev/null 2>&1 fi nft insert rule inet fw4 openclash_mangle_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 nft insert rule inet fw4 openclash_mangle_v6 position 0 ip6 saddr { "$dest_ip" } udp sport "$i" counter return >/dev/null 2>&1 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 ] && [ -n "$(ip6tables -t mangle -L 2>&1 | grep -o 'Chain')" ]; 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 else ip6tables -t mangle -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 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 nft insert rule inet fw4 openclash_mangle_v6 position 0 ip6 saddr { "$dest_ip" } tcp sport "$dest_port" counter return >/dev/null 2>&1 fi 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 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 fi 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 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 ip6tables -t mangle -I openclash -p tcp "$dest_ip" --sport "$dest_port" -j RETURN >/dev/null 2>&1 fi ip6tables -t mangle -I openclash_output -p tcp "$dest_ip" --sport "$dest_port" -j RETURN >/dev/null 2>&1 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 fi ip6tables -t mangle -I openclash_output -p udp "$dest_ip" --sport "$dest_port" -j RETURN >/dev/null 2>&1 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 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 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 [ -n "$FW4" ]; then LOG_OUT "Tip: Firewall4 was Detected, Use NFTABLE Rules..." if [ "$china_ip_route" = "1" ] || [ "$disable_udp_quic" = "1" ]; then nft 'flush set inet fw4 china_ip_route' nft -f '/etc/openclash/china_ip_route.ipset' 2>/dev/null 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' 2>/dev/null done if [ "$enable_redirect_dns" = "1" ]; then mkdir -p ${DNSMASQ_CONF_DIR} 2>/dev/null 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 '!/^$/&&!/^#/&&/(^([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(" %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 '!/^$/&&!/^#/&&/(^([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(" %s,'" "'\n",$0)}' /etc/openclash/custom/openclash_custom_chnroute_pass.list >>/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 } 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 nft 'flush set inet fw4 china_ip_route_pass' 2>/dev/null nft -f '/tmp/openclash_china_ip_route_pass.list' 2>/dev/null rm -rf /tmp/openclash_china_ip_route_pass.list 2>/dev/null if [ "$en_mode" = "fake-ip" ] && [ "$china_ip_route" = "1" ]; then cat "/etc/openclash/accelerated-domains.china.conf" |awk -v dns="${custom_china_domain_dns_server}" -F '/' '!/^$/&&!/^#/{print $1"/"$2"/"dns}' >${DNSMASQ_CONF_DIR}/dnsmasq_accelerated-domains.china.conf 2>/dev/null for i in `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("%s\n",$0)}' /etc/openclash/custom/openclash_custom_chnroute_pass.list` do sed -i "/server=\/${i}\//d" ${DNSMASQ_CONF_DIR}/dnsmasq_accelerated-domains.china.conf 2>/dev/null done 2>/dev/null fi fi fi if [ "$enable_redirect_dns" -eq 1 ]; then 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 [ -z "$(nft list chain inet fw4 dstnat |grep 'OpenClash DNS Hijack')"]; then nft insert rule inet fw4 dstnat position 0 tcp dport 53 counter redirect to "$DNSPORT" comment \"OpenClash DNS Hijack\" 2>/dev/null nft insert rule inet fw4 dstnat position 0 udp dport 53 counter redirect to "$DNSPORT" comment \"OpenClash DNS Hijack\" 2>/dev/null fi elif [ "$enable_redirect_dns" -eq 2 ]; then nft 'add chain inet fw4 openclash_dns_redirect' 2>/dev/null nft add rule inet fw4 openclash_dns_redirect tcp dport 53 counter redirect to "$dns_port" comment \"OpenClash DNS Hijack\" 2>/dev/null nft add rule inet fw4 openclash_dns_redirect udp dport 53 counter redirect to "$dns_port" comment \"OpenClash DNS Hijack\" 2>/dev/null nft 'add rule inet fw4 dstnat position 0 tcp dport 53 counter jump openclash_dns_redirect' 2>/dev/null nft 'add rule inet fw4 dstnat position 0 udp dport 53 counter jump openclash_dns_redirect' 2>/dev/null if [ "$router_self_proxy" = 1 ]; then nft 'add chain inet fw4 nat_output { type nat hook output priority -1; }' 2>/dev/null nft add rule inet fw4 nat_output position 0 tcp dport 53 ip daddr {127.0.0.1} meta skuid != 65534 counter redirect to "$dns_port" comment \"OpenClash DNS Hijack\" 2>/dev/null nft add rule inet fw4 nat_output position 0 udp dport 53 ip daddr {127.0.0.1} meta skuid != 65534 counter redirect to "$dns_port" comment \"OpenClash DNS Hijack\" 2>/dev/null fi fi if [ "$en_mode" = "fake-ip" ] && [ "$china_ip_route" = "1" ] && [ "$enable_redirect_dns" = "1" ]; then LOG_OUT "Tip: Bypass the China IP May Cause the Dnsmasq Load For a Long Time After Restart in FAKE-IP Mode, Hijack the DNS to Core Untill the Dnsmasq Works Well..." nft insert rule inet fw4 dstnat position 0 tcp dport 53 counter redirect to "$dns_port" comment \"OpenClash DNS Hijack\" 2>/dev/null nft insert rule inet fw4 dstnat position 0 udp dport 53 counter redirect to "$dns_port" comment \"OpenClash DNS Hijack\" 2>/dev/null nft 'add chain inet fw4 nat_output { type nat hook output priority -1; }' 2>/dev/null nft add rule inet fw4 nat_output position 0 tcp dport 53 meta skuid != 65534 counter redirect to "$dns_port" comment \"OpenClash DNS Hijack\" 2>/dev/null nft add rule inet fw4 nat_output position 0 udp dport 53 meta skuid != 65534 counter redirect to "$dns_port" comment \"OpenClash DNS Hijack\" 2>/dev/null nft add rule inet fw4 nat_output position 0 tcp dport 12353 meta skuid != 65534 counter redirect to "$DNSPORT" comment \"OpenClash DNS Hijack\" 2>/dev/null nft add rule inet fw4 nat_output position 0 udp dport 12353 meta skuid != 65534 counter redirect to "$DNSPORT" comment \"OpenClash DNS Hijack\" 2>/dev/null fi #lan_google_dns_ac if [ -n "$(uci -q get openclash.config.lan_block_google_dns_ips)" ]; then nft 'add set inet fw4 lan_block_google_dns_ips { type ipv4_addr; flags interval; auto-merge; }' 2>/dev/null nft 'add set inet fw4 lan_block_google_dns_ipv6s { type ipv6_addr; flags interval; auto-merge; }' 2>/dev/null config_load "openclash" config_list_foreach "config" "lan_block_google_dns_ips" nft_ac_add "lan_block_google_dns_ips" "lan_block_google_dns_ipv6s" fi if [ -n "$(uci -q get openclash.config.lan_block_google_dns_macs)" ]; then nft 'add set inet fw4 lan_block_google_dns_macs { type ether_addr; }' 2>/dev/null config_load "openclash" config_list_foreach "config" "lan_block_google_dns_macs" nft_ac_add "lan_block_google_dns_macs" 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; }' 2>/dev/null nft 'add set inet fw4 lan_ac_black_ipv6s { type ipv6_addr; flags interval; auto-merge; }' 2>/dev/null 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; }' 2>/dev/null 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; }' 2>/dev/null nft 'add set inet fw4 lan_ac_white_ipv6s { type ipv6_addr; flags interval; auto-merge; }' 2>/dev/null 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; }' 2>/dev/null 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; }' 2>/dev/null nft 'add set inet fw4 wan_ac_black_ipv6s { type ipv6_addr; flags interval; auto-merge; }' 2>/dev/null config_load "openclash" config_list_foreach "config" "wan_ac_black_ips" nft_ac_add "wan_ac_black_ips" "wan_ac_black_ipv6s" fi #lan port ac if [ -n "$(uci -q get openclash.config.lan_ac_black_ports)" ]; then nft 'add set inet fw4 lan_ac_black_ports { type inet_service; }' 2>/dev/null config_load "openclash" config_list_foreach "config" "lan_ac_black_ports" nft_ac_add "lan_ac_black_ports" 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" } 2>/dev/null done 2>/dev/null 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 "$lan_ip_cidrs" ]; then for lan_ip_cidr in $lan_ip_cidrs; do nft add element inet fw4 localnetwork { "$lan_ip_cidr" } 2>/dev/null done fi if [ -n "$wan_ip4s" ]; then for wan_ip4 in $wan_ip4s; do nft add element inet fw4 localnetwork { "$wan_ip4" } 2>/dev/null done fi #common ports 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" nft 'add set inet fw4 common_ports { type inet_service; }' 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' 2>/dev/null nft 'add chain inet fw4 openclash_post' 2>/dev/null nft 'flush chain inet fw4 openclash_post' 2>/dev/null nft 'add rule inet fw4 openclash_post ip saddr @localnetwork tcp sport @lan_ac_black_ports counter return' 2>/dev/null nft add rule inet fw4 openclash_post meta mark "$PROXY_FWMARK" counter accept 2>/dev/null nft 'add rule inet fw4 openclash_post ip daddr @localnetwork counter return' 2>/dev/null nft 'add rule inet fw4 openclash_post meta nfproto {ipv4} fib saddr type != { local } meta skuid != 65534 counter masquerade' 2>/dev/null nft add rule inet fw4 srcnat meta nfproto {ipv4} counter jump openclash_post comment \"OpenClash Bypass Gateway Compatible\" 2>/dev/null fi #intranet allowed if [ "$intranet_allowed" -eq 1 ]; then 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/) {print $(i+1)}}}' 2>/dev/null |sed 's/"//g') if [ -n "$wan_ints" ]; then nft 'add chain inet fw4 openclash_wan_input' 2>/dev/null nft 'flush chain inet fw4 openclash_wan_input' 2>/dev/null 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 2>/dev/null done nft add rule inet fw4 openclash_wan_input udp dport {$proxy_port,$tproxy_port,$cn_port,$http_port,$socks_port,$mixed_port,$dns_port} counter reject nft add rule inet fw4 openclash_wan_input tcp dport {$proxy_port,$tproxy_port,$cn_port,$http_port,$socks_port,$mixed_port,$dns_port} counter reject fi fi if [ -z "$en_mode_tun" ] || [ "$en_mode_tun" -eq 2 ]; then #tcp nft 'add chain inet fw4 openclash' 2>/dev/null nft 'flush chain inet fw4 openclash' 2>/dev/null nft 'add rule inet fw4 openclash ip daddr @localnetwork counter return' 2>/dev/null 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" 2>/dev/null fi nft 'add rule inet fw4 openclash ip saddr @localnetwork tcp sport @lan_ac_black_ports counter return' 2>/dev/null nft 'add rule inet fw4 openclash ip daddr @wan_ac_black_ips counter return' 2>/dev/null nft 'add rule inet fw4 openclash ip saddr @lan_ac_black_ips counter return' 2>/dev/null nft 'add rule inet fw4 openclash ether saddr @lan_ac_black_macs counter return' 2>/dev/null 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' 2>/dev/null else nft 'add rule inet fw4 openclash ether saddr != @lan_ac_white_macs counter return' 2>/dev/null nft 'add rule inet fw4 openclash ip saddr != @lan_ac_white_ips counter return' 2>/dev/null fi if [ "$en_mode" = "redir-host" ]; then nft 'add rule inet fw4 openclash tcp dport != @common_ports counter return' 2>/dev/null fi if [ "$china_ip_route" = "1" ]; then if [ "$enable_redirect_dns" = "1" ]; then nft 'add rule inet fw4 openclash ip daddr @china_ip_route ip daddr != @china_ip_route_pass counter return' 2>/dev/null else nft 'add rule inet fw4 openclash ip daddr @china_ip_route counter return' 2>/dev/null fi fi nft add rule inet fw4 openclash ip protocol tcp counter redirect to "$proxy_port" 2>/dev/null nft 'add rule inet fw4 dstnat ip protocol tcp counter jump openclash' 2>/dev/null if [ -z "$en_mode_tun" ]; then #Google dns nft insert rule inet fw4 dstnat position 0 ip daddr { 8.8.8.8, 8.8.4.4 } tcp dport 53 counter redirect to "$proxy_port" comment \"OpenClash Google DNS Hijack\" 2>/dev/null #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' 2>/dev/null nft 'flush chain inet fw4 openclash_mangle' 2>/dev/null nft 'add chain inet fw4 openclash_upnp' 2>/dev/null nft 'flush chain inet fw4 openclash_upnp' 2>/dev/null upnp_exclude nft 'add rule inet fw4 openclash_mangle ip daddr @localnetwork counter return' 2>/dev/null nft 'add rule inet fw4 openclash_mangle udp dport 53 counter return' 2>/dev/null 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 2>/dev/null fi nft 'add rule inet fw4 openclash_mangle ip saddr @localnetwork udp sport @lan_ac_black_ports counter return' 2>/dev/null nft 'add rule inet fw4 openclash_mangle ip daddr @wan_ac_black_ips counter return' 2>/dev/null nft 'add rule inet fw4 openclash_mangle ip saddr @lan_ac_black_ips counter return' 2>/dev/null nft 'add rule inet fw4 openclash_mangle ether saddr @lan_ac_black_macs counter return' 2>/dev/null 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' 2>/dev/null else nft 'add rule inet fw4 openclash_mangle ether saddr != @lan_ac_white_macs counter return' 2>/dev/null nft 'add rule inet fw4 openclash_mangle ip saddr != @lan_ac_white_ips counter return' 2>/dev/null fi if [ "$en_mode" = "redir-host" ]; then nft 'add rule inet fw4 openclash_mangle udp dport != @common_ports counter return' 2>/dev/null fi if [ "$china_ip_route" = "1" ]; then if [ "$enable_redirect_dns" = "1" ]; then nft 'add rule inet fw4 openclash_mangle ip daddr @china_ip_route ip daddr != @china_ip_route_pass counter return' 2>/dev/null else nft 'add rule inet fw4 openclash_mangle ip daddr @china_ip_route counter return' 2>/dev/null fi fi nft 'add rule inet fw4 openclash_mangle ip protocol udp counter jump openclash_upnp' 2>/dev/null 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 2>/dev/null nft 'add rule inet fw4 mangle_prerouting ip protocol udp counter jump openclash_mangle' 2>/dev/null elif [ "$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' 2>/dev/null nft 'flush chain inet fw4 openclash_mangle' 2>/dev/null 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 ip protocol udp counter jump openclash_mangle' 2>/dev/null if [ "$enable_redirect_dns" != "2" ] || [ "$router_self_proxy" = "1" ]; then nft 'add chain inet fw4 openclash_mangle_output' 2>/dev/null nft 'flush chain inet fw4 openclash_mangle_output' 2>/dev/null nft add rule inet fw4 openclash_mangle_output meta l4proto { udp } ip daddr { "$fakeip_range" } mark set "$PROXY_FWMARK" 2>/dev/null nft 'add rule inet fw4 mangle_output ip protocol udp counter jump openclash_mangle_output' 2>/dev/null fi fi #quic if [ "$disable_udp_quic" -eq 1 ]; then nft insert rule inet fw4 input position 0 udp dport 443 ip daddr != @china_ip_route counter reject comment \"OpenClash QUIC REJECT\" 2>/dev/null fi fi if [ "$enable_redirect_dns" != "2" ] || [ "$router_self_proxy" = "1" ]; then nft 'add chain inet fw4 openclash_output' 2>/dev/null nft 'flush chain inet fw4 openclash_output' 2>/dev/null nft 'add rule inet fw4 openclash_output ip daddr @localnetwork counter return' 2>/dev/null nft 'add rule inet fw4 openclash_output ip saddr @localnetwork tcp sport @lan_ac_black_ports counter return' 2>/dev/null if [ "$en_mode" = "fake-ip" ]; then nft add rule inet fw4 openclash_output ip protocol tcp ip daddr { "$fakeip_range" } skuid != 65534 counter redirect to "$proxy_port" 2>/dev/null fi nft 'add rule inet fw4 openclash_output skuid != 65534 ip daddr @wan_ac_black_ips counter return' 2>/dev/null if [ "$en_mode" = "redir-host" ]; then nft add rule inet fw4 openclash_output tcp dport != @common_ports skuid != 65534 counter return 2>/dev/null fi if [ "$china_ip_route" = "1" ]; then if [ "$enable_redirect_dns" = "1" ]; then nft 'add rule inet fw4 openclash_output skuid != 65534 ip daddr @china_ip_route ip daddr != @china_ip_route_pass counter return' 2>/dev/null else nft 'add rule inet fw4 openclash_output skuid != 65534 ip daddr @china_ip_route counter return' 2>/dev/null fi fi nft add rule inet fw4 openclash_output ip protocol tcp skuid != 65534 counter redirect to "$proxy_port" 2>/dev/null nft 'add chain inet fw4 nat_output { type nat hook output priority -1; }' 2>/dev/null nft 'add rule inet fw4 nat_output ip protocol tcp counter jump openclash_output' 2>/dev/null fi fi if [ -n "$en_mode_tun" ]; then #TUN模式 #启动TUN TUN_WAIT=0 TUN_RESTART=1 ip link set utun up LOG_OUT "Tip: Waiting for TUN Interface Start..." while ( [ -n "$(pidof clash)" ] && [ -z "$(ip route list |grep utun)" ] && [ "$TUN_WAIT" -le 30 ] ) do ip link set utun up let TUN_WAIT++ sleep 2 done if [ -n "$(pidof clash)" ] && [ -z "$(ip route list |grep utun)" ] && [ "$TUN_WAIT" -gt 10 ]; 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 sleep 3 start_run_core check_core_status sleep 10 let TUN_RESTART++ done 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 ip route replace default dev utun table "$PROXY_ROUTE_TABLE" ip rule add fwmark "$PROXY_FWMARK" table "$PROXY_ROUTE_TABLE" #设置防火墙 if [ "$enable_redirect_dns" != "2" ] || [ "$router_self_proxy" = "1" ]; then nft 'add chain inet fw4 openclash_mangle_output' 2>/dev/null nft 'flush chain inet fw4 openclash_mangle_output' 2>/dev/null nft 'add rule inet fw4 openclash_mangle_output ip daddr @localnetwork counter return' 2>/dev/null nft 'add rule inet fw4 openclash_mangle_output ip saddr @localnetwork meta l4proto {tcp,udp} th sport @lan_ac_black_ports counter return' 2>/dev/null if [ "$en_mode" = "fake-ip" ]; then if [ "$en_mode_tun" -eq 1 ]; then nft add rule inet fw4 openclash_mangle_output meta l4proto {tcp,udp} th dport { 0-65535 } ip daddr { "$fakeip_range" } mark set "$PROXY_FWMARK" 2>/dev/null if [ "$china_ip_route" = "1" ]; then if [ "$enable_redirect_dns" = "1" ]; then nft 'add rule inet fw4 openclash_mangle_output skuid != 65534 ip daddr @china_ip_route ip daddr != @china_ip_route_pass counter return' 2>/dev/null else nft 'add rule inet fw4 openclash_mangle_output skuid != 65534 ip daddr @china_ip_route counter return' 2>/dev/null fi fi nft add rule inet fw4 openclash_mangle_output tcp dport { 0-65535 } skuid != 65534 meta mark set "$PROXY_FWMARK" 2>/dev/null else if [ "$china_ip_route" = "1" ]; then if [ "$enable_redirect_dns" = "1" ]; then nft 'add rule inet fw4 openclash_mangle_output skuid != 65534 ip daddr @china_ip_route ip daddr != @china_ip_route_pass counter return' 2>/dev/null else nft 'add rule inet fw4 openclash_mangle_output skuid != 65534 ip daddr @china_ip_route counter return' 2>/dev/null fi fi nft add rule inet fw4 openclash_mangle_output skuid != 65534 udp dport { 0-65535 } ip daddr { "$fakeip_range" } meta mark set "$PROXY_FWMARK" 2>/dev/null fi elif [ "$en_mode" = "redir-host" ] && [ "$en_mode_tun" -eq 1 ]; then nft 'add rule inet fw4 openclash_mangle_output skuid != 65534 ip daddr @wan_ac_black_ips counter return' 2>/dev/null nft 'add rule inet fw4 openclash_mangle_output meta l4proto {tcp,udp} th dport != @common_ports skuid != 65534 counter return' 2>/dev/null if [ "$china_ip_route" = "1" ]; then if [ "$enable_redirect_dns" = "1" ]; then nft 'add rule inet fw4 openclash_mangle_output skuid != 65534 ip daddr @china_ip_route ip daddr != @china_ip_route_pass counter return' 2>/dev/null else nft 'add rule inet fw4 openclash_mangle_output skuid != 65534 ip daddr @china_ip_route counter return' 2>/dev/null fi fi nft add rule inet fw4 openclash_mangle_output tcp dport { 0-65535 } skuid != 65534 meta mark set "$PROXY_FWMARK" 2>/dev/null fi nft 'add rule inet fw4 mangle_output meta l4proto {tcp,udp} counter jump openclash_mangle_output' 2>/dev/null fi nft 'add chain inet fw4 openclash_mangle' 2>/dev/null nft 'flush chain inet fw4 openclash_mangle' 2>/dev/null nft 'add chain inet fw4 openclash_dns_hijack' 2>/dev/null nft 'flush chain inet fw4 openclash_dns_hijack' 2>/dev/null nft 'add chain inet fw4 openclash_upnp' 2>/dev/null nft 'flush chain inet fw4 openclash_upnp' 2>/dev/null upnp_exclude #其他流量 nft 'add rule inet fw4 openclash_mangle meta l4proto {tcp,udp} iifname utun counter return' 2>/dev/null nft 'add rule inet fw4 openclash_mangle ip daddr @localnetwork counter return' 2>/dev/null nft 'add rule inet fw4 openclash_mangle ip saddr @localnetwork meta l4proto {tcp,udp} th sport @lan_ac_black_ports counter return' 2>/dev/null nft 'add rule inet fw4 openclash_mangle ip daddr @wan_ac_black_ips counter return' 2>/dev/null nft 'add rule inet fw4 openclash_mangle ip saddr @lan_ac_black_ips counter return' 2>/dev/null nft 'add rule inet fw4 openclash_mangle ether saddr @lan_ac_black_macs counter return' 2>/dev/null 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' 2>/dev/null else nft 'add rule inet fw4 openclash_mangle ether saddr != @lan_ac_white_macs counter return' 2>/dev/null nft 'add rule inet fw4 openclash_mangle ip saddr != @lan_ac_white_ips counter return' 2>/dev/null fi if [ "$en_mode" = "redir-host" ]; then nft 'add rule inet fw4 openclash_mangle meta l4proto {tcp,udp} th dport != @common_ports counter return' 2>/dev/null fi if [ "$china_ip_route" = "1" ]; then if [ "$enable_redirect_dns" = "1" ]; then nft 'add rule inet fw4 openclash_mangle ip daddr @china_ip_route ip daddr != @china_ip_route_pass counter return' 2>/dev/null else nft 'add rule inet fw4 openclash_mangle ip daddr @china_ip_route counter return' 2>/dev/null fi fi nft 'add rule inet fw4 openclash_mangle ip protocol udp counter jump openclash_upnp' 2>/dev/null nft add rule inet fw4 openclash_mangle meta l4proto {tcp,udp} th dport { 0-65535 } mark set "$PROXY_FWMARK" 2>/dev/null if [ "$en_mode_tun" -eq 1 ]; then nft 'insert rule inet fw4 mangle_prerouting position 0 meta l4proto {tcp,udp} counter jump openclash_mangle' 2>/dev/null else nft 'insert rule inet fw4 mangle_prerouting position 0 meta nfproto {ipv4} tcp dport 53 counter jump openclash_dns_hijack' 2>/dev/null nft 'add rule inet fw4 openclash_dns_hijack ip saddr @lan_ac_black_ips counter return' 2>/dev/null nft 'add rule inet fw4 openclash_dns_hijack ether saddr @lan_ac_black_macs counter return' 2>/dev/null 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_dns_hijack ether saddr != @lan_ac_white_macs ip saddr != @lan_ac_white_ips counter return' 2>/dev/null else nft 'add rule inet fw4 openclash_dns_hijack ether saddr != @lan_ac_white_macs counter return' 2>/dev/null nft 'add rule inet fw4 openclash_dns_hijack ip saddr != @lan_ac_white_ips counter return' 2>/dev/null fi nft add rule inet fw4 openclash_dns_hijack meta nfproto {ipv4} tcp dport 53 mark set "$PROXY_FWMARK" comment \"OpenClash TCP DNS Hijack\" 2>/dev/null nft 'insert rule inet fw4 mangle_prerouting position 0 ip protocol udp counter jump openclash_mangle' 2>/dev/null fi if [ "$enable_redirect_dns" -eq 2 ]; then local position=$(nft list chain inet fw4 openclash_dns_redirect |grep "DNS" |grep -v "REDIRECT" |awk -F '# handle ' '{print$2}' |sort -rn |head -1 || ehco 0) nft insert rule inet fw4 openclash_dns_redirect "$position" meta nfproto {ipv4} tcp dport 53 counter accept comment \"OpenClash TCP DNS Hijack\" 2>/dev/null else nft insert rule inet fw4 dstnat position 0 meta nfproto {ipv4} tcp dport 53 counter accept comment \"OpenClash TCP DNS Hijack\" 2>/dev/null fi #TUN FORWORD nft insert rule inet fw4 forward position 0 meta l4proto {tcp,udp} oifname utun counter accept comment \"OpenClash TUN Forward\" 2>/dev/null #quic if [ "$disable_udp_quic" -eq 1 ]; 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\" 2>/dev/null fi fi #dns if [ "$enable_redirect_dns" -eq 2 ]; then nft 'insert rule inet fw4 openclash_dns_redirect position 0 ip saddr @lan_ac_black_ips counter return' 2>/dev/null nft 'insert rule inet fw4 openclash_dns_redirect position 0 ether saddr @lan_ac_black_macs counter return' 2>/dev/null 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 'insert rule inet fw4 openclash_dns_redirect position 0 ether saddr != @lan_ac_white_macs ip saddr != @lan_ac_white_ips counter return' 2>/dev/null else nft 'insert rule inet fw4 openclash_dns_redirect position 0 ether saddr != @lan_ac_white_macs counter return' 2>/dev/null nft 'insert rule inet fw4 openclash_dns_redirect position 0 ip saddr != @lan_ac_white_ips counter return' 2>/dev/null fi fi #google_dns_block if [ -n "$(uci -q get openclash.config.lan_block_google_dns_ips)" ] || [ -n "$(uci -q get openclash.config.lan_block_google_dns_macs)" ]; then nft 'add set inet fw4 openclash_google_dns_ips { type ipv4_addr; flags interval; auto-merge; }' nft 'add element inet fw4 openclash_google_dns_ips { 8.8.8.8, 8.8.4.4 }' if [ -z "$en_mode_tun" ] || [ "$en_mode_tun" -eq 2 ]; then nft insert rule inet fw4 dstnat position 0 ip saddr @lan_block_google_dns_ips ip daddr @openclash_google_dns_ips counter accept comment \"OpenClash Google DNS Block\" 2>/dev/null nft insert rule inet fw4 dstnat position 0 ether saddr @lan_block_google_dns_macs ip daddr @openclash_google_dns_ips counter accept comment \"OpenClash Google DNS Block\" 2>/dev/null fi nft insert rule inet fw4 forward position 0 ip saddr @lan_block_google_dns_ips ip daddr @openclash_google_dns_ips counter reject comment \"OpenClash Google DNS Block\" 2>/dev/null nft insert rule inet fw4 forward position 0 ether saddr @lan_block_google_dns_macs ip daddr @openclash_google_dns_ips counter reject comment \"OpenClash Google DNS Block\" 2>/dev/null fi #ipv6 if [ "$ipv6_enable" -eq 1 ]; then if [ -z "$(nft list chain inet fw4 dstnat |grep 'OpenClash DNS Hijack')"]; then if [ "$enable_redirect_dns" -eq 1 ]; then nft insert rule inet fw4 dstnat position 0 meta nfproto {ipv6} tcp dport 53 counter redirect to "$DNSPORT" comment \"OpenClash DNS Hijack\" 2>/dev/null nft insert rule inet fw4 dstnat position 0 meta nfproto {ipv6} udp dport 53 counter redirect to "$DNSPORT" comment \"OpenClash DNS Hijack\" 2>/dev/null elif [ "$enable_redirect_dns" -eq 2 ]; then nft insert rule inet fw4 openclash_dns_redirect position 0 meta nfproto {ipv6} tcp dport 53 counter redirect to "$dns_port" comment \"OpenClash DNS Hijack\" 2>/dev/null nft insert rule inet fw4 openclash_dns_redirect position 0 meta nfproto {ipv6} udp dport 53 counter redirect to "$dns_port" comment \"OpenClash DNS Hijack\" 2>/dev/null if [ "$router_self_proxy" = 1 ]; then nft 'add chain inet fw4 nat_output { type nat hook output priority -1; }' 2>/dev/null nft add rule inet fw4 nat_output position 0 meta nfproto {ipv6} tcp dport 53 ip daddr {::/0} meta skuid != 65534 counter redirect to "$dns_port" comment \"OpenClash DNS Hijack\" 2>/dev/null nft add rule inet fw4 nat_output position 0 meta nfproto {ipv6} udp dport 53 ip daddr {::/0} meta skuid != 65534 counter redirect to "$dns_port" comment \"OpenClash DNS Hijack\" 2>/dev/null fi fi fi if [ "$en_mode" = "fake-ip" ] && [ "$china_ip_route" = "1" ] && [ "$enable_redirect_dns" = "1" ]; then nft insert rule inet fw4 dstnat position 0 meta nfproto {ipv6} tcp dport 53 counter redirect to "$dns_port" comment \"OpenClash DNS Hijack\" 2>/dev/null nft insert rule inet fw4 dstnat position 0 meta nfproto {ipv6} udp dport 53 counter redirect to "$dns_port" comment \"OpenClash DNS Hijack\" 2>/dev/null nft 'add chain inet fw4 nat_output { type nat hook output priority -1; }' 2>/dev/null nft add rule inet fw4 nat_output position 0 meta nfproto {ipv6} tcp dport 53 meta skuid != 65534 counter redirect to "$dns_port" comment \"OpenClash DNS Hijack\" 2>/dev/null nft add rule inet fw4 nat_output position 0 meta nfproto {ipv6} udp dport 53 meta skuid != 65534 counter redirect to "$dns_port" comment \"OpenClash DNS Hijack\" 2>/dev/null nft add rule inet fw4 nat_output position 0 meta nfproto {ipv6} tcp dport 12353 meta skuid != 65534 counter redirect to "$DNSPORT" comment \"OpenClash DNS Hijack\" 2>/dev/null nft add rule inet fw4 nat_output position 0 meta nfproto {ipv6} udp dport 12353 meta skuid != 65534 counter redirect to "$DNSPORT" comment \"OpenClash DNS Hijack\" 2>/dev/null fi if [ "$china_ip6_route" = "1" ] || [ "$disable_udp_quic" = "1" ]; then nft 'flush set inet fw4 china_ip6_route' nft -f '/etc/openclash/china_ip6_route.ipset' 2>/dev/null 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' 2>/dev/null done if [ "$enable_redirect_dns" = "1" ]; then mkdir -p ${DNSMASQ_CONF_DIR} 2>/dev/null 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 '!/^$/&&!/^#/&&!/^(\*?\.?)*[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})*$/{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 '!/^$/&&!/^#/&&!/^(\*?\.?)*[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})*$/{printf(" %s,'" "'\n",$0)}' /etc/openclash/custom/openclash_custom_chnroute6_pass.list >>/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 } awk '!/^$/&&!/^#/&&/^(\*?\.?)*[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})*$/{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 nft 'flush set inet fw4 china_ip6_route_pass' 2>/dev/null nft -f '/tmp/openclash_china_ip6_route_pass.list' 2>/dev/null rm -rf /tmp/openclash_china_ip6_route_pass.list 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 2>/dev/null if [ -n "$nftflag" ]; then sed -i "s/\/${nftflag}/\/4#${nftflag}/g" ${DNSMASQ_CONF_DIR}/dnsmasq_openclash_chnroute_pass.conf 2>/dev/null sed -i "s/${nftflag}china_ip_route_pass/6#${nftflag}china_ip6_route_pass/g" ${DNSMASQ_CONF_DIR}/dnsmasq_openclash_chnroute6_pass.conf 2>/dev/null else sed -i "s/china_ip_route_pass/china_ip6_route_pass/g" ${DNSMASQ_CONF_DIR}/dnsmasq_openclash_chnroute6_pass.conf 2>/dev/null 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" } 2>/dev/null done 2>/dev/null 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 "$lan_ip6_cidrs" ]; then for lan_ip6_cidr in $lan_ip6_cidrs; do nft add element inet fw4 localnetwork6 { "$lan_ip6_cidr" } 2>/dev/null done fi if [ -n "$wan_ip6s" ]; then for wan_ip6 in $wan_ip6s; do nft add element inet fw4 localnetwork6 { "$wan_ip6" } 2>/dev/null done fi 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" #Google dns nft insert rule inet fw4 dstnat position 0 ip6 daddr { 2001:4860:4860::8888, 2001:4860:4860::8844 } tcp dport 53 counter accept comment \"OpenClash Google DNS Hijack\" 2>/dev/null nft 'add chain inet fw4 openclash_mangle_v6' 2>/dev/null nft 'flush chain inet fw4 openclash_mangle_v6' 2>/dev/null nft 'add rule inet fw4 openclash_mangle_v6 ip6 daddr @localnetwork6 counter return' 2>/dev/null nft 'add rule inet fw4 openclash_mangle_v6 meta nfproto {ipv6} udp dport 53 counter return' 2>/dev/null nft 'add rule inet fw4 openclash_mangle_v6 ip6 saddr @localnetwork6 meta nfproto {ipv6} sport @lan_ac_black_ports counter return' 2>/dev/null nft 'add rule inet fw4 openclash_mangle_v6 ip6 daddr @wan_ac_black_ipv6s counter return' 2>/dev/null if [ "$en_mode" == "redir-host" ]; then nft 'add rule inet fw4 openclash_mangle_v6 meta nfproto {ipv6} th dport != @common_ports counter return' 2>/dev/null fi nft 'add rule inet fw4 openclash_mangle_v6 ip6 saddr @lan_ac_black_ipv6s counter return' 2>/dev/null nft 'add rule inet fw4 openclash_mangle_v6 ether saddr @lan_ac_black_macs counter return' 2>/dev/null 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' 2>/dev/null else nft 'add rule inet fw4 openclash_mangle_v6 ether saddr != @lan_ac_white_macs counter return' 2>/dev/null nft 'add rule inet fw4 openclash_mangle_v6 ip6 saddr != @lan_ac_white_ipv6s counter return' 2>/dev/null fi if [ "$china_ip6_route" = "1" ]; then if [ "$enable_redirect_dns" = "1" ]; then nft 'add rule inet fw4 openclash_mangle_v6 ip6 daddr @china_ip6_route ip6 daddr != @china_ip6_route_pass counter return' 2>/dev/null else nft 'add rule inet fw4 openclash_mangle_v6 ip6 daddr @china_ip6_route counter return' 2>/dev/null fi fi nft add rule inet fw4 openclash_mangle_v6 meta nfproto {ipv6} tcp dport { 0-65535 } mark set "$PROXY_FWMARK" tproxy ip6 to :"$tproxy_port" counter accept comment \"OpenClash TCP Tproxy\" 2>/dev/null nft 'add rule inet fw4 mangle_prerouting meta nfproto {ipv6} jump openclash_mangle_v6' 2>/dev/null #dns if [ "$enable_redirect_dns" -eq 2 ]; then nft 'insert rule inet fw4 openclash_dns_redirect position 0 ip6 saddr @lan_ac_black_ipv6s counter return' 2>/dev/null nft 'insert rule inet fw4 openclash_dns_redirect position 0 ether saddr @lan_ac_black_macs counter return' 2>/dev/null 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 'insert rule inet fw4 openclash_dns_redirect position 0 ether saddr != @lan_ac_white_macs ip6 saddr != @lan_ac_white_ipv6s counter return' 2>/dev/null else nft 'insert rule inet fw4 openclash_dns_redirect position 0 ether saddr != @lan_ac_white_macs counter return' 2>/dev/null nft 'insert rule inet fw4 openclash_dns_redirect position 0 ip6 saddr != @lan_ac_white_ipv6s counter return' 2>/dev/null fi fi if [ "$enable_redirect_dns" != "2" ] || [ "$router_self_proxy" = 1 ]; then nft 'add chain inet fw4 openclash_mangle_output_v6' 2>/dev/null nft 'flush chain inet fw4 openclash_mangle_output_v6' 2>/dev/null nft 'add rule inet fw4 openclash_mangle_output_v6 ip6 daddr @localnetwork6 counter return' 2>/dev/null nft 'add rule inet fw4 openclash_mangle_output_v6 ip6 saddr @localnetwork6 meta nfproto {ipv6} sport @lan_ac_black_ports counter return' 2>/dev/null nft 'add rule inet fw4 openclash_mangle_output_v6 skuid != 65534 ip6 daddr @wan_ac_black_ipv6s counter return' 2>/dev/null nft 'add rule inet fw4 openclash_mangle_output_v6 meta nfproto {ipv6} th dport != @common_ports skuid != 65534 counter return' 2>/dev/null if [ "$china_ip6_route" = "1" ]; then if [ "$enable_redirect_dns" = "1" ]; then nft 'add rule inet fw4 openclash_mangle_output_v6 skuid != 65534 ip6 daddr @china_ip6_route ip6 daddr != @china_ip6_route_pass counter return' 2>/dev/null else nft 'add rule inet fw4 openclash_mangle_output_v6 skuid != 65534 ip6 daddr @china_ip6_route counter return' 2>/dev/null fi fi nft add rule inet fw4 openclash_mangle_output_v6 meta nfproto {ipv6} skuid != 65534 tcp dport { 0-65535 } mark set "$PROXY_FWMARK" 2>/dev/null nft 'add rule inet fw4 mangle_output meta nfproto {ipv6} counter jump openclash_mangle_output_v6' 2>/dev/null fi #udp if [ "$enable_udp_proxy" -eq 1 ] || [ -n "$en_mode_tun" ]; then nft add rule inet fw4 openclash_mangle_v6 meta nfproto {ipv6} udp dport { 0-65535 } mark set "$PROXY_FWMARK" tproxy ip6 to :"$tproxy_port" counter accept comment \"OpenClash UDP Tproxy\" 2>/dev/null fi #quic if [ "$disable_udp_quic" -eq 1 ]; then nft insert rule inet fw4 input position 0 udp dport 443 ip6 daddr != @china_ip6_route counter reject comment \"OpenClash QUIC REJECT\" 2>/dev/null fi #bypass gateway compatible if [ "$bypass_gateway_compatible" -eq 1 ]; then #nft 'delete chain inet fw4 openclash_post_v6' 2>/dev/null nft 'add chain inet fw4 openclash_post_v6' 2>/dev/null nft 'flush chain inet fw4 openclash_post_v6' 2>/dev/null nft 'add rule inet fw4 openclash_post_v6 ip6 saddr @localnetwork6 meta nfproto {ipv6} sport @lan_ac_black_ports counter return' 2>/dev/null nft add rule inet fw4 openclash_post_v6 meta nfproto {ipv6} meta mark "$PROXY_FWMARK" counter accept 2>/dev/null nft 'add rule inet fw4 openclash_post_v6 ip6 daddr @localnetwork6 counter return' 2>/dev/null nft 'add rule inet fw4 openclash_post_v6 meta nfproto {ipv6} fib saddr type != { local } meta skuid != 65534 counter masquerade' 2>/dev/null nft add rule inet fw4 srcnat meta nfproto {ipv6} counter jump openclash_post_v6 comment \"OpenClash Bypass Gateway Compatible\" 2>/dev/null fi #google_dns_block if [ -n "$(uci -q get openclash.config.lan_block_google_dns_ips)" ] || [ -n "$(uci -q get openclash.config.lan_block_google_dns_macs)" ]; then nft 'add set inet fw4 openclash_google_dns_ipv6s { type ipv6_addr; flags interval; auto-merge; }' nft 'add element inet fw4 openclash_google_dns_ipv6s { 2001:4860:4860::8888, 2001:4860:4860::8844, 2001:4860:4860::6464, 2001:4860:4860::64 }' nft insert rule inet fw4 dstnat position 0 ip6 saddr @lan_block_google_dns_ipv6s ip6 daddr @openclash_google_dns_ipv6s counter accept comment \"OpenClash Google DNS Block\" 2>/dev/null nft insert rule inet fw4 dstnat position 0 ether saddr @lan_block_google_dns_macs ip6 daddr @openclash_google_dns_ipv6s counter accept comment \"OpenClash Google DNS Block\" 2>/dev/null nft insert rule inet fw4 forward position 0 ip6 saddr @lan_block_google_dns_ipv6s ip6 daddr @openclash_google_dns_ipv6s counter reject comment \"OpenClash Google DNS Block\" 2>/dev/null nft insert rule inet fw4 forward position 0 ether saddr @lan_block_google_dns_macs ip6 daddr @openclash_google_dns_ipv6s counter reject comment \"OpenClash Google DNS Block\" 2>/dev/null fi #intranet allowed if [ "$intranet_allowed" -eq 1 ]; then 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/) {print $(i+1)}}}' 2>/dev/null |sed 's/"//g') if [ -n "$wan6_ints" ]; then nft 'add chain inet fw4 openclash_wan6_input' 2>/dev/null nft 'flush chain inet fw4 openclash_wan6_input' 2>/dev/null 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 2>/dev/null done nft add rule inet fw4 openclash_wan6_input udp dport {$proxy_port,$tproxy_port,$cn_port,$http_port,$socks_port,$mixed_port,$dns_port} counter reject 2>/dev/null nft add rule inet fw4 openclash_wan6_input tcp dport {$proxy_port,$tproxy_port,$cn_port,$http_port,$socks_port,$mixed_port,$dns_port} counter reject 2>/dev/null fi fi fi 2>/dev/null else if [ "$china_ip_route" = "1" ] || [ "$disable_udp_quic" = "1" ]; then ipset -! flush china_ip_route 2>/dev/null ipset -! restore /dev/null if [ "$enable_redirect_dns" = "1" ]; then mkdir -p ${DNSMASQ_CONF_DIR} 2>/dev/null 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 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 ipset -! flush china_ip_route_pass 2>/dev/null ipset -! restore /dev/null rm -rf /tmp/openclash_china_ip_route_pass.list 2>/dev/null if [ "$en_mode" = "fake-ip" ] && [ "$china_ip_route" = "1" ]; then cat "/etc/openclash/accelerated-domains.china.conf" |awk -v dns="${custom_china_domain_dns_server}" -F '/' '!/^$/&&!/^#/{print $1"/"$2"/"dns}' >${DNSMASQ_CONF_DIR}/dnsmasq_accelerated-domains.china.conf 2>/dev/null for i in `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("%s\n",$0)}' /etc/openclash/custom/openclash_custom_chnroute_pass.list` do sed -i "/server=\/${i}\//d" ${DNSMASQ_CONF_DIR}/dnsmasq_accelerated-domains.china.conf 2>/dev/null done 2>/dev/null fi fi fi if [ "$enable_redirect_dns" -eq 1 ]; then 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 [ -z "$(iptables -t nat -nL PREROUTING --line-number |grep 'OpenClash DNS Hijack')"]; then iptables -t nat -I PREROUTING -p udp --dport 53 -j REDIRECT --to-ports "$DNSPORT" -m comment --comment "OpenClash DNS Hijack" 2>/dev/null iptables -t nat -I PREROUTING -p tcp --dport 53 -j REDIRECT --to-ports "$DNSPORT" -m comment --comment "OpenClash DNS Hijack" 2>/dev/null fi elif [ "$enable_redirect_dns" -eq 2 ]; then iptables -t nat -N openclash_dns_redirect iptables -t nat -F openclash_dns_redirect iptables -t nat -A openclash_dns_redirect -p udp --dport 53 -j REDIRECT --to-ports "$dns_port" -m comment --comment "OpenClash DNS Hijack" 2>/dev/null iptables -t nat -A openclash_dns_redirect -p tcp --dport 53 -j REDIRECT --to-ports "$dns_port" -m comment --comment "OpenClash DNS Hijack" 2>/dev/null iptables -t nat -I PREROUTING -p udp --dport 53 -j openclash_dns_redirect 2>/dev/null iptables -t nat -I PREROUTING -p tcp --dport 53 -j openclash_dns_redirect 2>/dev/null if [ "$router_self_proxy" = 1 ]; then iptables -t nat -I OUTPUT -p udp --dport 53 -d 127.0.0.1 -m owner ! --uid-owner 65534 -j REDIRECT --to-ports "$dns_port" -m comment --comment "OpenClash DNS Hijack" 2>/dev/null iptables -t nat -I OUTPUT -p tcp --dport 53 -d 127.0.0.1 -m owner ! --uid-owner 65534 -j REDIRECT --to-ports "$dns_port" -m comment --comment "OpenClash DNS Hijack" 2>/dev/null fi fi if [ "$en_mode" = "fake-ip" ] && [ "$china_ip_route" = "1" ] && [ "$enable_redirect_dns" = "1" ]; then LOG_OUT "Tip: Bypass the China IP May Cause the Dnsmasq Load For a Long Time After Restart in FAKE-IP Mode, Hijack the DNS to Core Untill the Dnsmasq Works Well..." iptables -t nat -I PREROUTING -p udp --dport 53 -j REDIRECT --to-ports "$dns_port" -m comment --comment "OpenClash DNS Hijack" 2>/dev/null iptables -t nat -I PREROUTING -p tcp --dport 53 -j REDIRECT --to-ports "$dns_port" -m comment --comment "OpenClash DNS Hijack" 2>/dev/null iptables -t nat -I OUTPUT -p udp --dport 53 -m owner ! --uid-owner 65534 -j REDIRECT --to-ports "$dns_port" -m comment --comment "OpenClash DNS Hijack" 2>/dev/null iptables -t nat -I OUTPUT -p tcp --dport 53 -m owner ! --uid-owner 65534 -j REDIRECT --to-ports "$dns_port" -m comment --comment "OpenClash DNS Hijack" 2>/dev/null iptables -t nat -I OUTPUT -p udp --dport 12353 -m owner ! --uid-owner 65534 -j REDIRECT --to-ports "$DNSPORT" -m comment --comment "OpenClash DNS Hijack" 2>/dev/null iptables -t nat -I OUTPUT -p tcp --dport 12353 -m owner ! --uid-owner 65534 -j REDIRECT --to-ports "$DNSPORT" -m comment --comment "OpenClash DNS Hijack" 2>/dev/null fi #lan_google_dns_ac if [ -n "$(uci -q get openclash.config.lan_block_google_dns_ips)" ]; then ipset create lan_block_google_dns_ips hash:net ipset create lan_block_google_dns_ipv6s hash:net family inet6 config_load "openclash" config_list_foreach "config" "lan_block_google_dns_ips" ac_add "lan_block_google_dns_ips" "lan_block_google_dns_ipv6s" fi if [ -n "$(uci -q get openclash.config.lan_block_google_dns_macs)" ]; then ipset create lan_block_google_dns_macs hash:mac config_load "openclash" config_list_foreach "config" "lan_block_google_dns_macs" ac_add "lan_block_google_dns_macs" 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 #lan port ac if [ -n "$(uci -q get openclash.config.lan_ac_black_ports)" ]; then ipset create lan_ac_black_ports bitmap:port range 0-65535 config_load "openclash" config_list_foreach "config" "lan_ac_black_ports" ac_add "lan_ac_black_ports" 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 2>/dev/null 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 "$lan_ip_cidrs" ]; then for lan_ip_cidr in $lan_ip_cidrs; do ipset add localnetwork "$lan_ip_cidr" 2>/dev/null done fi if [ -n "$wan_ip4s" ]; then for wan_ip4 in $wan_ip4s; do ipset add localnetwork "$wan_ip4" 2>/dev/null done fi #common ports 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" 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 -m set --match-set localnetwork src -m set --match-set lan_ac_black_ports src -j RETURN >/dev/null 2>&1 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 addrtype ! --src-type LOCAL -m owner ! --uid-owner 65534 -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 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) 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 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 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 localnetwork src -m set --match-set lan_ac_black_ports src -j RETURN >/dev/null 2>&1 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" = "1" ]; then if [ "$enable_redirect_dns" = "1" ]; then iptables -t nat -A openclash -m set --match-set china_ip_route dst -m set ! --match-set china_ip_route_pass dst -j RETURN >/dev/null 2>&1 else iptables -t nat -A openclash -m set --match-set china_ip_route dst -j RETURN >/dev/null 2>&1 fi 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 #Google dns iptables -t nat -I PREROUTING -m comment --comment "OpenClash Google DNS Hijack" -p tcp -d 8.8.8.8 --dport 53 -j REDIRECT --to-ports "$proxy_port" iptables -t nat -I PREROUTING -m comment --comment "OpenClash Google DNS Hijack" -p tcp -d 8.8.4.4 --dport 53 -j REDIRECT --to-ports "$proxy_port" #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 -p udp --dport 53 -j RETURN >/dev/null 2>&1 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 localnetwork src -m set --match-set lan_ac_black_ports src -j RETURN >/dev/null 2>&1 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" = "1" ]; then if [ "$enable_redirect_dns" = "1" ]; then iptables -t mangle -A openclash -m set --match-set china_ip_route dst -m set ! --match-set china_ip_route_pass dst -j RETURN >/dev/null 2>&1 else iptables -t mangle -A openclash -m set --match-set china_ip_route dst -j RETURN >/dev/null 2>&1 fi 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 elif [ "$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 if [ "$enable_redirect_dns" != "2" ] || [ "$router_self_proxy" = 1 ]; then iptables -t mangle -N openclash_output iptables -t mangle -F openclash_output iptables -t mangle -A openclash_output -m owner ! --uid-owner 65534 -p udp -d "$fakeip_range" -j MARK --set-mark "$PROXY_FWMARK" iptables -t mangle -A OUTPUT -p udp -j openclash_output fi fi #quic if [ "$disable_udp_quic" -eq 1 ]; 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 fi fi if [ "$enable_redirect_dns" != "2" ] || [ "$router_self_proxy" = 1 ]; then iptables -t nat -N openclash_output iptables -t nat -F openclash_output if [ "$en_mode" = "fake-ip" ] && [ -z "$en_mode_tun" ]; then iptables -t nat -A openclash_output -m owner ! --uid-owner 65534 -p tcp -d "$fakeip_range" -j REDIRECT --to-ports "$proxy_port" fi iptables -t nat -A openclash_output -m set --match-set localnetwork dst -j RETURN iptables -t nat -A openclash_output -m set --match-set localnetwork src -m set --match-set lan_ac_black_ports src -j RETURN >/dev/null 2>&1 iptables -t nat -A openclash_output -m owner ! --uid-owner 65534 -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 owner ! --uid-owner 65534 -m set ! --match-set common_ports dst -j RETURN >/dev/null 2>&1 fi if [ "$china_ip_route" = "1" ]; then if [ "$enable_redirect_dns" = "1" ]; then iptables -t nat -A openclash_output -m owner ! --uid-owner 65534 -m set --match-set china_ip_route dst -m set ! --match-set china_ip_route_pass dst -j RETURN >/dev/null 2>&1 else iptables -t nat -A openclash_output -m owner ! --uid-owner 65534 -m set --match-set china_ip_route dst -j RETURN >/dev/null 2>&1 fi fi iptables -t nat -A openclash_output -m owner ! --uid-owner 65534 -p tcp -j REDIRECT --to-ports "$proxy_port" iptables -t nat -A OUTPUT -j openclash_output >/dev/null 2>&1 fi fi if [ -n "$en_mode_tun" ]; then #TUN模式 #启动TUN TUN_WAIT=0 TUN_RESTART=1 ip link set utun up LOG_OUT "Tip: Waiting for TUN Interface Start..." while ( [ -n "$(pidof clash)" ] && [ -z "$(ip route list |grep utun)" ] && [ "$TUN_WAIT" -le 30 ] ) do ip link set utun up let TUN_WAIT++ sleep 2 done if [ -n "$(pidof clash)" ] && [ -z "$(ip route list |grep utun)" ] && [ "$TUN_WAIT" -gt 10 ]; 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 sleep 3 start_run_core check_core_status sleep 10 let TUN_RESTART++ done 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 ip route replace default dev utun table "$PROXY_ROUTE_TABLE" ip rule add fwmark "$PROXY_FWMARK" table "$PROXY_ROUTE_TABLE" #设置防火墙 if [ "$enable_redirect_dns" != "2" ] || [ "$router_self_proxy" = 1 ]; then if [ "$en_mode" = "fake-ip" ]; then iptables -t mangle -N openclash_output iptables -t mangle -F openclash_output iptables -t mangle -A openclash_output -m set --match-set localnetwork dst -j RETURN iptables -t mangle -A openclash_output -m set --match-set localnetwork src -m set --match-set lan_ac_black_ports src -j RETURN >/dev/null 2>&1 if [ "$en_mode_tun" -eq 1 ]; then iptables -t mangle -A openclash_output -m owner ! --uid-owner 65534 -d "$fakeip_range" -j MARK --set-mark "$PROXY_FWMARK" iptables -t mangle -A openclash_output -m owner ! --uid-owner 65534 -m set --match-set wan_ac_black_ips dst -j RETURN >/dev/null 2>&1 if [ "$china_ip_route" = "1" ]; then if [ "$enable_redirect_dns" = "1" ]; then iptables -t mangle -A openclash_output -m owner ! --uid-owner 65534 -m set --match-set china_ip_route dst -m set ! --match-set china_ip_route_pass dst -j RETURN >/dev/null 2>&1 else iptables -t mangle -A openclash_output -m owner ! --uid-owner 65534 -m set --match-set china_ip_route dst -j RETURN >/dev/null 2>&1 fi fi iptables -t mangle -A openclash_output -m owner ! --uid-owner 65534 -p tcp -j MARK --set-mark "$PROXY_FWMARK" else if [ "$china_ip_route" = "1" ]; then if [ "$enable_redirect_dns" = "1" ]; then iptables -t mangle -A openclash_output -m owner ! --uid-owner 65534 -m set --match-set china_ip_route dst -m set ! --match-set china_ip_route_pass dst -j RETURN >/dev/null 2>&1 else iptables -t mangle -A openclash_output -m owner ! --uid-owner 65534 -m set --match-set china_ip_route dst -j RETURN >/dev/null 2>&1 fi fi iptables -t mangle -A openclash_output -m owner ! --uid-owner 65534 -p udp -d "$fakeip_range" -j MARK --set-mark "$PROXY_FWMARK" fi iptables -t mangle -A OUTPUT -j openclash_output elif [ "$en_mode" = "redir-host" ] && [ "$en_mode_tun" -eq 1 ]; then iptables -t mangle -N openclash_output iptables -t mangle -F openclash_output iptables -t mangle -A openclash_output -m set --match-set localnetwork dst -j RETURN iptables -t mangle -A openclash_output -m set --match-set localnetwork src -m set --match-set lan_ac_black_ports src -j RETURN >/dev/null 2>&1 iptables -t mangle -A openclash_output -m owner ! --uid-owner 65534 -m set --match-set wan_ac_black_ips dst -j RETURN >/dev/null 2>&1 iptables -t mangle -A openclash_output -m owner ! --uid-owner 65534 -m set ! --match-set common_ports dst -j RETURN >/dev/null 2>&1 if [ "$china_ip_route" = "1" ]; then if [ "$enable_redirect_dns" = "1" ]; then iptables -t mangle -A openclash_output -m owner ! --uid-owner 65534 -m set --match-set china_ip_route dst -m set ! --match-set china_ip_route_pass dst -j RETURN >/dev/null 2>&1 else iptables -t mangle -A openclash_output -m owner ! --uid-owner 65534 -m set --match-set china_ip_route dst -j RETURN >/dev/null 2>&1 fi fi iptables -t mangle -A openclash_output -m owner ! --uid-owner 65534 -p tcp -j MARK --set-mark "$PROXY_FWMARK" iptables -t mangle -A OUTPUT -j openclash_output fi fi iptables -t mangle -N openclash iptables -t mangle -F openclash iptables -t mangle -N openclash_dns_hijack iptables -t mangle -F openclash_dns_hijack iptables -t mangle -N openclash_upnp iptables -t mangle -F openclash_upnp upnp_exclude #其他流量 iptables -t mangle -A openclash -i utun -j RETURN >/dev/null 2>&1 iptables -t mangle -A openclash -m set --match-set localnetwork dst -j RETURN >/dev/null 2>&1 iptables -t mangle -A openclash -m set --match-set localnetwork src -m set --match-set lan_ac_black_ports src -j RETURN >/dev/null 2>&1 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" = "1" ]; then if [ "$enable_redirect_dns" = "1" ]; then iptables -t mangle -A openclash -m set --match-set china_ip_route dst -m set ! --match-set china_ip_route_pass dst -j RETURN >/dev/null 2>&1 else iptables -t mangle -A openclash -m set --match-set china_ip_route dst -j RETURN >/dev/null 2>&1 fi 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 -I PREROUTING -j openclash else iptables -t mangle -I PREROUTING -p tcp --dport 53 -j openclash_dns_hijack iptables -t mangle -A openclash_dns_hijack -m set --match-set lan_ac_black_ips src -j RETURN >/dev/null 2>&1 iptables -t mangle -A openclash_dns_hijack -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_dns_hijack -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_dns_hijack -m set ! --match-set lan_ac_white_ips src -j RETURN >/dev/null 2>&1 iptables -t mangle -A openclash_dns_hijack -m set ! --match-set lan_ac_white_macs src -j RETURN >/dev/null 2>&1 fi iptables -t mangle -A openclash_dns_hijack -m comment --comment "OpenClash TCP DNS Hijack" -p tcp --dport 53 -j MARK --set-mark "$PROXY_FWMARK" iptables -t mangle -I PREROUTING -p udp -j openclash fi if [ "$enable_redirect_dns" -eq 2 ]; then local position=$(iptables -nvL openclash_dns_redirect -t nat|grep "DNS" |grep -v "REDIRECT" |wc -l) let position++ iptables -t nat -I openclash_dns_redirect "$position" -m comment --comment "OpenClash TCP DNS Hijack" -p tcp --dport 53 -j ACCEPT else iptables -t nat -I PREROUTING -m comment --comment "OpenClash TCP DNS Hijack" -p tcp --dport 53 -j ACCEPT fi #TUN FORWORD iptables -I FORWARD -m comment --comment "OpenClash TUN Forward" -o utun -j ACCEPT #quic if [ "$disable_udp_quic" -eq 1 ]; 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 fi fi #dns if [ "$enable_redirect_dns" -eq 2 ]; then iptables -t nat -I openclash_dns_redirect -m set --match-set lan_ac_black_ips src -j RETURN >/dev/null 2>&1 iptables -t nat -I openclash_dns_redirect -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 -I openclash_dns_redirect -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 -I openclash_dns_redirect -m set ! --match-set lan_ac_white_ips src -j RETURN >/dev/null 2>&1 iptables -t nat -I openclash_dns_redirect -m set ! --match-set lan_ac_white_macs src -j RETURN >/dev/null 2>&1 fi fi #google_dns_block if [ -n "$(uci -q get openclash.config.lan_block_google_dns_ips)" ] || [ -n "$(uci -q get openclash.config.lan_block_google_dns_macs)" ]; then ipset create openclash_google_dns_ips hash:net ipset add openclash_google_dns_ips 8.8.8.8 ipset add openclash_google_dns_ips 8.8.4.4 if [ -z "$en_mode_tun" ] || [ "$en_mode_tun" -eq 2 ]; then iptables -t nat -I PREROUTING -m comment --comment "OpenClash Google DNS Block" -m set --match-set lan_block_google_dns_ips src -m set --match-set openclash_google_dns_ips dst -j ACCEPT >/dev/null 2>&1 iptables -t nat -I PREROUTING -m comment --comment "OpenClash Google DNS Block" -m set --match-set lan_block_google_dns_macs src -m set --match-set openclash_google_dns_ips dst -j ACCEPT >/dev/null 2>&1 fi iptables -t filter -I FORWARD -m set --match-set lan_block_google_dns_ips src -m set --match-set openclash_google_dns_ips dst -j REJECT >/dev/null 2>&1 iptables -t filter -I FORWARD -m set --match-set lan_block_google_dns_macs src -m set --match-set openclash_google_dns_ips dst -j REJECT >/dev/null 2>&1 fi #ipv6 if [ "$ipv6_enable" -eq 1 ] && [ -n "$(ip6tables -t mangle -L 2>&1 | grep -o 'Chain')" ]; then if [ -z "$(ip6tables -t nat -nL PREROUTING --line-number |grep 'DNS Hijack')"]; then if [ "$enable_redirect_dns" -eq 1 ]; then ip6tables -t nat -I PREROUTING -p udp --dport 53 -j REDIRECT --to-ports "$DNSPORT" -m comment --comment "OpenClash DNS Hijack" 2>/dev/null ip6tables -t nat -I PREROUTING -p tcp --dport 53 -j REDIRECT --to-ports "$DNSPORT" -m comment --comment "OpenClash DNS Hijack" 2>/dev/null elif [ "$enable_redirect_dns" -eq 2 ]; then ip6tables -t nat -N openclash_dns_redirect ip6tables -t nat -F openclash_dns_redirect ip6tables -t nat -A openclash_dns_redirect -p udp --dport 53 -j REDIRECT --to-ports "$dns_port" -m comment --comment "OpenClash DNS Hijack" 2>/dev/null ip6tables -t nat -A openclash_dns_redirect -p tcp --dport 53 -j REDIRECT --to-ports "$dns_port" -m comment --comment "OpenClash DNS Hijack" 2>/dev/null ip6tables -t nat -I PREROUTING -p udp --dport 53 -j openclash_dns_redirect 2>/dev/null ip6tables -t nat -I PREROUTING -p tcp --dport 53 -j openclash_dns_redirect 2>/dev/null if [ "$router_self_proxy" = 1 ]; then ip6tables -t nat -I OUTPUT -p udp --dport 53 -d ::/0 -m owner ! --uid-owner 65534 -j REDIRECT --to-ports "$dns_port" -m comment --comment "OpenClash DNS Hijack" 2>/dev/null ip6tables -t nat -I OUTPUT -p tcp --dport 53 -d ::/0 -m owner ! --uid-owner 65534 -j REDIRECT --to-ports "$dns_port" -m comment --comment "OpenClash DNS Hijack" 2>/dev/null fi fi fi if [ "$en_mode" = "fake-ip" ] && [ "$china_ip_route" = "1" ] && [ "$enable_redirect_dns" = "1" ]; then ip6tables -t nat -I PREROUTING -p udp --dport 53 -j REDIRECT --to-ports "$dns_port" -m comment --comment "OpenClash DNS Hijack" 2>/dev/null ip6tables -t nat -I PREROUTING -p tcp --dport 53 -j REDIRECT --to-ports "$dns_port" -m comment --comment "OpenClash DNS Hijack" 2>/dev/null ip6tables -t nat -I OUTPUT -p udp --dport 53 -m owner ! --uid-owner 65534 -j REDIRECT --to-ports "$dns_port" -m comment --comment "OpenClash DNS Hijack" 2>/dev/null ip6tables -t nat -I OUTPUT -p tcp --dport 53 -m owner ! --uid-owner 65534 -j REDIRECT --to-ports "$dns_port" -m comment --comment "OpenClash DNS Hijack" 2>/dev/null ip6tables -t nat -I OUTPUT -p udp --dport 12353 -m owner ! --uid-owner 65534 -j REDIRECT --to-ports "$DNSPORT" -m comment --comment "OpenClash DNS Hijack" 2>/dev/null ip6tables -t nat -I OUTPUT -p tcp --dport 12353 -m owner ! --uid-owner 65534 -j REDIRECT --to-ports "$DNSPORT" -m comment --comment "OpenClash DNS Hijack" 2>/dev/null fi if [ "$china_ip6_route" = "1" ] || [ "$disable_udp_quic" = "1" ]; then ipset -! flush china_ip6_route 2>/dev/null ipset -! restore /dev/null if [ "$enable_redirect_dns" = "1" ]; then mkdir -p ${DNSMASQ_CONF_DIR} 2>/dev/null echo "create china_ip6_route_pass hash:net family inet6 hashsize 1024 maxelem 1000000" >/tmp/openclash_china_ip6_route_pass.list awk '!/^$/&&!/^#/&&!/^(\*?\.?)*[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})*$/{printf("add china_ip6_route_pass %s'" "'\n",$0)}' /etc/openclash/custom/openclash_custom_chnroute6_pass.list >>/tmp/openclash_china_ip6_route_pass.list 2>/dev/null awk '!/^$/&&!/^#/&&/^(\*?\.?)*[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})*$/{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 2>/dev/null ipset -! flush china_ip6_route_pass 2>/dev/null ipset -! restore /dev/null rm -rf /tmp/openclash_china_ip6_route_pass.list 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 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 2>/dev/null sed -i "s/china_ip_route_pass/china_ip6_route_pass/g" ${DNSMASQ_CONF_DIR}/dnsmasq_openclash_chnroute6_pass.conf 2>/dev/null 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 2>/dev/null 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 "$lan_ip6_cidrs" ]; then for lan_ip6_cidr in $lan_ip6_cidrs; do ipset add localnetwork6 "$lan_ip6_cidr" 2>/dev/null done fi if [ -n "$wan_ip6s" ]; then for wan_ip6 in $wan_ip6s; do ipset add localnetwork6 "$wan_ip6" done fi 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" #Google dns ip6tables -t nat -I PREROUTING -m comment --comment "OpenClash Google DNS Hijack" -p tcp -d 2001:4860:4860::8888 --dport 53 -j ACCEPT ip6tables -t nat -I PREROUTING -m comment --comment "OpenClash Google DNS Hijack" -p tcp -d 2001:4860:4860::8844 --dport 53 -j ACCEPT 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 -p udp --dport 53 -j RETURN >/dev/null 2>&1 ip6tables -t mangle -A openclash -m set --match-set localnetwork6 src -m set --match-set lan_ac_black_ports src -j RETURN >/dev/null 2>&1 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" = "1" ]; then if [ "$enable_redirect_dns" = "1" ]; then ip6tables -t mangle -A openclash -m set --match-set china_ip6_route dst -m set ! --match-set china_ip6_route_pass dst -j RETURN >/dev/null 2>&1 else ip6tables -t mangle -A openclash -m set --match-set china_ip6_route dst -j RETURN >/dev/null 2>&1 fi fi ip6tables -t mangle -A openclash -p tcp -m comment --comment "OpenClash TCP Tproxy" -j TPROXY --on-port "$tproxy_port" --tproxy-mark "$PROXY_FWMARK" ip6tables -t mangle -A PREROUTING -j openclash #dns if [ "$enable_redirect_dns" -eq 2 ]; then ip6tables -t nat -I openclash_dns_redirect -m set --match-set lan_ac_black_ips src -j RETURN >/dev/null 2>&1 ip6tables -t nat -I openclash_dns_redirect -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 -I openclash_dns_redirect -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 ip6tables -t nat -I openclash_dns_redirect -m set ! --match-set lan_ac_white_ips src -j RETURN >/dev/null 2>&1 ip6tables -t nat -I openclash_dns_redirect -m set ! --match-set lan_ac_white_macs src -j RETURN >/dev/null 2>&1 fi fi if [ "$enable_redirect_dns" != "2" ] || [ "$router_self_proxy" = 1 ]; then ip6tables -t mangle -N openclash_output ip6tables -t mangle -F openclash_output ip6tables -t mangle -A openclash_output -m set --match-set localnetwork6 dst -j RETURN ip6tables -t mangle -A openclash_output -m set --match-set localnetwork6 src -m set --match-set lan_ac_black_ports src -j RETURN >/dev/null 2>&1 ip6tables -t mangle -A openclash_output -m owner ! --uid-owner 65534 -m set --match-set wan_ac_black_ipv6s dst -j RETURN >/dev/null 2>&1 ip6tables -t mangle -A openclash_output -m owner ! --uid-owner 65534 -m set ! --match-set common_ports dst -j RETURN >/dev/null 2>&1 if [ "$china_ip6_route" = "1" ]; then if [ "$enable_redirect_dns" = "1" ]; then ip6tables -t mangle -A openclash_output -m owner ! --uid-owner 65534 -m set --match-set china_ip6_route dst -m set ! --match-set china_ip6_route_pass dst -j RETURN >/dev/null 2>&1 else ip6tables -t mangle -A openclash_output -m owner ! --uid-owner 65534 -m set --match-set china_ip6_route dst -j RETURN >/dev/null 2>&1 fi fi ip6tables -t mangle -A openclash_output -p tcp -m owner ! --uid-owner 65534 -j MARK --set-xmark "$PROXY_FWMARK" ip6tables -t mangle -A OUTPUT -j openclash_output fi #udp if [ "$enable_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 #quic if [ "$disable_udp_quic" -eq 1 ]; then ip6tables -I INPUT -p udp --dport 443 -m comment --comment "OpenClash QUIC REJECT" -m set ! --match-set china_ip6_route dst -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 -m set --match-set localnetwork src -m set --match-set lan_ac_black_ports src -j RETURN >/dev/null 2>&1 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 addrtype ! --src-type LOCAL -m owner ! --uid-owner 65534 -j MASQUERADE ip6tables -t nat -A POSTROUTING -m comment --comment "OpenClash Bypass Gateway Compatible" -j openclash_post fi #google_dns_block if [ -n "$(uci -q get openclash.config.lan_block_google_dns_ips)" ] || [ -n "$(uci -q get openclash.config.lan_block_google_dns_macs)" ]; then ipset create openclash_google_dns_ipv6s hash:net family inet6 ipset add openclash_google_dns_ipv6s 2001:4860:4860::8888 ipset add openclash_google_dns_ipv6s 2001:4860:4860::8844 ipset add openclash_google_dns_ipv6s 2001:4860:4860::6464 ipset add openclash_google_dns_ipv6s 2001:4860:4860::64 ip6tables -t nat -I PREROUTING -m comment --comment "OpenClash Google DNS Block" -m set --match-set lan_block_google_dns_ipv6s src -m set --match-set openclash_google_dns_ipv6s dst -j ACCEPT ip6tables -t nat -I PREROUTING -m comment --comment "OpenClash Google DNS Block" -m set --match-set lan_block_google_dns_macs src -m set --match-set openclash_google_dns_ipv6s dst -j ACCEPT ip6tables -t filter -I FORWARD -m set --match-set lan_block_google_dns_ipv6s src -m set --match-set openclash_google_dns_ipv6s dst -j REJECT >/dev/null 2>&1 ip6tables -t filter -I FORWARD -m set --match-set lan_block_google_dns_macs src -m set --match-set openclash_google_dns_ipv6s dst -j REJECT >/dev/null 2>&1 fi #intranet allowed if [ "$intranet_allowed" -eq 1 ]; then 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) 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 fi fi fi 2>/dev/null fi #端口转发 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" #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 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_accelerated-domains.china.conf >/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 route del default dev utun table "$PROXY_ROUTE_TABLE" >/dev/null 2>&1 ip rule del fwmark "$PROXY_FWMARK" table "$PROXY_ROUTE_TABLE" >/dev/null 2>&1 route delete -net "$fakeip_range" dev utun >/dev/null 2>&1 ip link set dev utun down >/dev/null 2>&1 ip tuntap del utun mode tun >/dev/null 2>&1 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 link set dev utun down >/dev/null 2>&1 ip -6 tuntap del utun mode tun >/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_dns_hijack" "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 openclash_google_dns_ipv6s >/dev/null 2>&1 ipset destroy lan_block_google_dns_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 ipset destroy lan_block_google_dns_ips >/dev/null 2>&1 ipset destroy lan_block_google_dns_macs >/dev/null 2>&1 ipset destroy openclash_google_dns_ips >/dev/null 2>&1 ipset destroy lan_ac_black_ports >/dev/null 2>&1 fi } get_config() { 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) 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) fakeip_range=$(uci -q get openclash.config.fakeip_range || echo "198.18.0.1/16") lan_ip=$(uci -q get network.lan.ipaddr |awk -F '/' '{print $1}' 2>/dev/null || 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}' || ip addr show 2>/dev/null | grep -w 'inet' | grep 'global' | grep 'brd' | grep -Eo 'inet [0-9\.]+' | awk '{print $2}' | head -n 1) lan_ip_cidrs=$(ip route | grep "/" | awk '{print $1}' | grep -vE "^$(echo "$fakeip_range"|awk -F '.' '{print $1"."$2}')" 2>/dev/null) lan_ip6_cidrs=$(ip -6 route | grep "/" | awk '{print $1}' | grep -vE "^unreachable" 2>/dev/null) wan_ip4s=$(ifconfig | grep 'inet addr' | awk '{print $2}' | cut -d: -f2 | grep -vE "(^$(echo "$fakeip_range"|awk -F '.' '{print $1"."$2}')|^192.168|^127.0)" 2>/dev/null) wan_ip6s=$(ifconfig | grep 'inet6 addr' | awk '{print $3}' 2>/dev/null) disable_masq_cache=$(uci -q get openclash.config.disable_masq_cache) 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) china_ip_route=$(uci -q get openclash.config.china_ip_route) china_ip6_route=$(uci -q get openclash.config.china_ip6_route) 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) stream_domains_prefetch=$(uci -q get openclash.config.stream_domains_prefetch || echo 0) store_fakeip=$(uci -q get openclash.config.store_fakeip || echo 1) 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_core=$(uci -q get openclash.config.enable_meta_core || echo 0) 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 "memconservative") 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 1) enable_meta_sniffer_pure_ip=$(uci -q get openclash.config.enable_meta_sniffer_pure_ip || echo 1) custom_china_domain_dns_server=$(uci -q get openclash.config.custom_china_domain_dns_server || echo "114.114.114.114") find_process_mode=$(uci -q get openclash.config.find_process_mode || echo off) upnp_lease_file=$(uci -q get upnpd.config.upnp_lease_file) client_fingerprint=$(uci -q get openclash.config.client_fingerprint || echo 0) [ -z "$dns_port" ] && dns_port=7874 && uci -q set openclash.config.dns_port=7874 uci -q set openclash.config.restricted_mode=0 && uci -q commit openclash } start() { enable=$(uci -q get openclash.config.enable) [ "$enable" != "1" ] && LOG_OUT "Warning: OpenClash Now Disabled, Need Start From Luci Page, Exit..." && SLOG_CLEAN && del_lock && 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" #快速启动判断 check_run_quick 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" "$stream_domains_prefetch" "$enable_meta_core" "$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" "$client_fingerprint" /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" "$proxy_port" "$tproxy_port" "$enable_meta_core" "$enable_redirect_dns" "$fakeip_range" /usr/share/openclash/openclash_custom_domain_dns.sh >/dev/null 2>&1 fi LOG_OUT "Step 4: Start Running The Clash Core..." start_run_core LOG_OUT "Step 5: Check The Core Status..." check_core_status #检测proxy_provider配置文件状态 LOG_OUT "Step 6: Wait For The File Downloading..." if [ "$enable_meta_core" != "1" ]; then yml_provider_check "$CONFIG_FILE" "proxy-providers" "proxies" yml_provider_check "$CONFIG_FILE" "rule-providers" "payload" fi try_restore_start LOG_OUT "Step 7: Set Firewall Rules..." set_firewall LOG_OUT "Step 8: Restart Dnsmasq..." change_dns "$enable_redirect_dns" "$disable_masq_cache" LOG_OUT "Step 9: Add Cron Rules, Start Daemons..." add_cron if [ "$(uci -q get openclash.config.restricted_mode)" != "1" ]; then if [ -z "$(uci -q get dhcp.lan.dhcpv6)" ] || [ "$(uci -q get dhcp.lan.dhcpv6)" == "disabled" ]; then LOG_OUT "OpenClash Start Successful!" sleep 3 elif [ "$ipv6_enable" -eq 0 ]; then LOG_OUT "Warning: OpenClash Start Successful, Please Note That Network May Abnormal With IPv6's DHCP Server" sleep 3 else LOG_OUT "OpenClash Start Successful!" sleep 3 fi else LOG_OUT "Warning: OpenClash Start Successful With Raw Config File, Please Note That It's Restricted Mode Now" sleep 3 fi echo "OpenClash Already Start!" write_run_quick SLOG_CLEAN rm -rf /tmp/yaml_* } stop() { 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..." 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 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 ${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 rm -rf ${DNSMASQ_CONF_DIR}/dnsmasq_accelerated-domains.china.conf >/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/etc/openclash >/dev/null 2>&1 rm -rf /tmp/openclash_edit_file_name >/dev/null 2>&1 rm -rf /tmp/openclash_*_region>/dev/null 2>&1 del_lock LOG_OUT "OpenClash Already Stop!" sleep 3 fi del_cron rm -rf /tmp/yaml_* >/dev/null 2>&1 rm -rf $START_LOG >/dev/null 2>&1 echo "OpenClash Already Stop!" } restart() { [ -f "$LOCK_FILE" ] && LOG_OUT "Warning: Multiple Restart Scripts Running, Exit..." && SLOG_CLEAN && exit 0 mkdir -p /tmp/lock touch $LOCK_FILE set_lock stop start del_lock } reload() { enable=$(uci -q get openclash.config.enable) if pidof clash >/dev/null && [ "$enable" == "1" ] && [ "$1" == "firewall" ]; then LOG_OUT "Reload OpenClash Firewall Rules..." set_lock revert_firewall 2>/dev/null do_run_mode 2>/dev/null get_config 2>/dev/null start_run_core check_core_status set_firewall 2>/dev/null /etc/init.d/dnsmasq restart >/dev/null 2>&1 SLOG_CLEAN del_lock 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 }