重写nftables防火墙

This commit is contained in:
juewuy
2024-03-03 19:12:31 +08:00
parent bbd3ed85c6
commit a2621a01b8
4 changed files with 369 additions and 278 deletions

View File

@@ -2142,10 +2142,6 @@ userguide(){
elif [ "$num" = 1 ];then elif [ "$num" = 1 ];then
#设置运行模式 #设置运行模式
redir_mod="Redir模式" redir_mod="Redir模式"
ckcmd nft && {
redir_mod="Nft基础"
modprobe nft_tproxy >/dev/null 2>&1 && redir_mod="Nft混合"
}
setconfig redir_mod "$redir_mod" setconfig redir_mod "$redir_mod"
#自动识别IPV6 #自动识别IPV6
[ -n "$(ip a 2>&1 | grep -w 'inet6' | grep -E 'global' | sed 's/.*inet6.//g' | sed 's/scope.*$//g')" ] && { [ -n "$(ip a 2>&1 | grep -w 'inet6' | grep -E 'global' | sed 's/.*inet6.//g' | sed 's/scope.*$//g')" ] && {
@@ -2386,7 +2382,7 @@ testcommand(){
exit; exit;
elif [ "$num" = 4 ]; then elif [ "$num" = 4 ]; then
if [ -n "$(echo $redir_mod | grep 'Nft')" -o "$local_type" = "nftables增强模式" ];then if [ "$firewall_mod" = "nftables" ];then
nft list table inet shellcrash nft list table inet shellcrash
else else
echo -------------------Redir--------------------- echo -------------------Redir---------------------

View File

@@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
# Copyright (C) Juewuy # Copyright (C) Juewuy
version=1.9.0pre13 version=test
setdir(){ setdir(){
dir_avail(){ dir_avail(){
@@ -201,6 +201,12 @@ else
COMMAND='"$TMPDIR/CrashCore -d $BINDIR -f $TMPDIR/config.yaml"' COMMAND='"$TMPDIR/CrashCore -d $BINDIR -f $TMPDIR/config.yaml"'
fi fi
setconfig COMMAND "$COMMAND" ${CRASHDIR}/configs/command.env setconfig COMMAND "$COMMAND" ${CRASHDIR}/configs/command.env
#设置防火墙执行模式
[ -z "$(grep firewall_mod $CRASHDIR/configs/ShellClash.cfg 2>/dev/null)" ] && {
ckcmd iptables && firewall_mod=iptables
nft add table inet shellcrash 2>/dev/null && firewall_mod=nftables
setconfig firewall_mod $firewall_mod
}
#设置更新地址 #设置更新地址
[ -n "$url" ] && setconfig update_url $url [ -n "$url" ] && setconfig update_url $url
#设置环境变量 #设置环境变量
@@ -307,5 +313,7 @@ sed -i "s/clash_v/core_v/g" $configpath
sed -i "s/clash.meta/meta/g" $configpath sed -i "s/clash.meta/meta/g" $configpath
sed -i "s/ShellClash/ShellCrash/g" $configpath sed -i "s/ShellClash/ShellCrash/g" $configpath
sed -i "s/cpucore=armv8/cpucore=arm64/g" $configpath sed -i "s/cpucore=armv8/cpucore=arm64/g" $configpath
sed -i "s/redir_mod=Nft基础/redir_mod=Redir模式/g" $configpath
sed -i "s/redir_mod=Nft混合/redir_mod=Tproxy模式/g" $configpath
echo -e "\033[32m脚本初始化完成,请输入\033[30;47m crash \033[0;33m命令开始使用\033[0m" echo -e "\033[32m脚本初始化完成,请输入\033[30;47m crash \033[0;33m命令开始使用\033[0m"

View File

@@ -1115,188 +1115,243 @@ setboot(){ #启动相关设置
esac esac
} }
metacfg(){ set_redir_mod(){
set_redir_config(){
setconfig redir_mod $redir_mod
setconfig dns_mod $dns_mod
echo -----------------------------------------------
echo -e "\033[36m已设为 $redir_mod \033[0m"
}
[ -n "$(ls /dev/net/tun 2>/dev/null)" ] || ip tuntap >/dev/null 2>&1 && sup_tun=1
[ -z "$firewall_area" ] && firewall_area=1
firewall_area_dsc=$(echo "仅局域网 仅本机 局域网+本机 已禁用 主-旁转发($bypass_host)" | cut -d' ' -f$firewall_area)
echo ----------------------------------------------- echo -----------------------------------------------
echo -e "当前代理模式为:\033[47;30m$redir_mod\033[0mShellCrash核心为\033[47;30m $crashcore \033[0m"
echo -e "\033[33m切换模式后需要手动重启服务以生效\033[0m"
echo -----------------------------------------------
[ -n "$firewall_mod" ] && {
if [ $firewall_area -le 4 ];then
echo -e " 1 \033[32mRedir模式\033[0m Redir转发TCP不转发UDP"
echo -e " 2 \033[36m混合模式\033[0m Redir转发TCPTun转发UDP"
echo -e " 3 \033[32mTproxy模式\033[0m Tproxy转发TCP&UDP"
echo -e " 4 \033[33mTun模式\033[0m Tun转发TCP&UDP(占用高不推荐)"
else
echo -e " 5 \033[32mTCP旁路转发\033[0m 仅转发TCP流量至旁路由"
echo -e " 6 \033[36mT&U旁路转发\033[0m 转发TCP&UDP流量至旁路由"
fi
echo -----------------------------------------------
echo -e " 7 设置劫持范围:\033[47;30m$firewall_area_dsc\033[0m"
echo -e " 8 切换防火墙应用:\033[47;30m$firewall_mod\033[0m"
}
} echo " 0 返回上级菜单"
normal_set(){ #基础设置 read -p "请输入对应数字 > " num
set_redir_mod(){ case $num in
set_redir_config(){ 0) ;;
setconfig redir_mod $redir_mod 1)
setconfig dns_mod $dns_mod redir_mod=Redir模式
if [ "$redir_mod" = "混合模式" -o "$redir_mod" = "Tun模式" ] && [ "$crashcore" = "clash" ];then set_redir_config
rm -rf ${BINDIR}/clash set_redir_mod
rm -rf ${CRASHDIR}/clash ;;
setconfig crashcore meta 2)
fi if [ -n "$sup_tun" ];then
echo ----------------------------------------------- redir_mod=混合模式
echo -e "\033[36m已设为 $redir_mod \033[0m"
}
[ -n "$(iptables -j TPROXY 2>&1 | grep 'on-port')" ] && sup_tp=1
[ -n "$(ls /dev/net/tun 2>/dev/null)" ] || ip tuntap >/dev/null 2>&1 && sup_tun=1
nft add table inet shellcrash 2>/dev/null && sup_nft=1 && modprobe nft_tproxy >/dev/null 2>&1 && sup_nft=2
echo -----------------------------------------------
echo -e "当前代理模式为:\033[47;30m $redir_mod \033[0mShellCrash核心为\033[47;30m $crashcore \033[0m"
echo -e "\033[33m切换模式后需要手动重启服务以生效\033[0m"
echo -----------------------------------------------
ckcmd iptables && echo -e " 1 \033[32mRedir模式\033[0m Redir转发TCP不转发UDP"
[ -n "$sup_tun" ] && echo -e " 2 \033[36m混合模式\033[0m Redir转发TCPTun转发UDP"
[ -n "$sup_tun" ] && echo -e " 4 \033[33mTun模式\033[0m 使用Tun转发TCP&UDP(占用高)"
[ -n "$sup_tp" ] && echo -e " 5 \033[32mTproxy模式\033[0m 使用Tproxy转发TCP&UDP"
[ -n "$sup_nft" ] && echo -e " 6 \033[36mNft基础\033[0m 使用nftables转发TCP不转发UDP"
[ "$sup_nft" = 2 ] && echo -e " 7 \033[32mNft混合\033[0m 使用nft_tproxy转发TCP&UDP"
echo -e " 8 \033[36m纯净模式\033[0m 不设置流量转发"
echo " 0 返回上级菜单"
read -p "请输入对应数字 > " num
if [ -z "$num" ]; then
errornum
elif [ "$num" = 0 ]; then
i=
elif [ "$num" = 1 ]; then
redir_mod=Redir模式
dns_mod=redir_host
set_redir_config set_redir_config
else
elif [ "$num" = 2 ]; then echo -e "\033[31m设备未检测到Tun内核模块请尝试其他模式或者安装相关依赖\033[0m"
[ -n "$sup_tun" ] || { sleep 1
echo -e "\033[32m设备未检测到Tun内核模块可能无法代理UDP流量\033[0m" fi
sleep 1 set_redir_mod
} ;;
redir_mod=混合模式 3)
set_redir_config if [ "$firewall_mod" = "iptables" ] ;then
elif [ "$num" = 3 ]; then
if [ -f /etc/init.d/qca-nss-ecm -a "$systype" = "mi_snapshot" ] ;then if [ -f /etc/init.d/qca-nss-ecm -a "$systype" = "mi_snapshot" ] ;then
read -p "当前设备的QOS服务与本模式冲突是否禁用相关功能(1/0) > " res read -p "xiaomi设备的QOS服务与本模式冲突是否禁用相关功能(1/0) > " res
[ "$res" = '1' ] && ${CRASHDIR}/misnap_init.sh tproxyfix && redir_mod=Tproxy混合 [ "$res" = '1' ] && ${CRASHDIR}/misnap_init.sh tproxyfix && redir_mod=Tproxy模式
elif [ -n "$(iptables -j TPROXY 2>&1 | grep 'on-port')" ] ;then
redir_mod=Tproxy模式
set_redir_config
else else
redir_mod=Tproxy混合 echo -e "\033[31m设备未检测到iptables-mod-tproxy模块请尝试其他模式或者安装相关依赖\033[0m"
sleep 1
fi fi
set_redir_config elif [ "$firewall_mod" = "nftables" ] ;then
if modprobe nft_tproxy >/dev/null 2>&1;then
elif [ "$num" = 4 ]; then redir_mod=Tproxy模式
set_redir_config
else
echo -e "\033[31m设备未检测到nft_tproxy内核模块请尝试其他模式或者安装相关依赖\033[0m"
sleep 1
fi
fi
set_redir_mod
;;
4)
if [ -n "$sup_tun" ];then
redir_mod=Tun模式 redir_mod=Tun模式
set_redir_config set_redir_config
else
elif [ "$num" = 5 ]; then echo -e "\033[31m设备未检测到Tun内核模块请尝试其他模式或者安装相关依赖\033[0m"
if [ -f /etc/init.d/qca-nss-ecm -a "$systype" = "mi_snapshot" ] ;then sleep 1
read -p "当前设备的QOS服务与本模式冲突是否禁用相关功能(1/0) > " res fi
[ "$res" = '1' ] && ${CRASHDIR}/misnap_init.sh tproxyfix && redir_mod=Tproxy模式 set_redir_mod
else ;;
redir_mod=Tproxy模式 5)
fi redir_mod=TCP旁路转发
set_redir_config set_redir_config
set_redir_mod
elif [ "$num" = 6 ]; then ;;
if ckcmd opkg && [ -z "$(opkg list-installed | grep firewall4)" ];then 6)
read -p "检测到缺少firewall4依赖是否自动安装(1/0) > " res redir_mod=T&U旁路转发
[ "$res" = '1' ] && opkg install firewall4 && redir_mod=Nft基础 set_redir_config
else set_redir_mod
redir_mod=Nft基础 ;;
fi 7)
set_redir_config echo -----------------------------------------------
echo -e "\033[31m注意\033[0m基于桥接网卡的Docker/虚拟机流量请使用1或3"
elif [ "$num" = 7 ]; then echo -----------------------------------------------
if ckcmd opkg && [ -z "$(opkg list-installed | grep kmod-nft-tproxy)" ];then echo -e " 1 \033[32m仅劫持局域网流量\033[0m"
read -p "检测到缺少kmod-nft-tproxy依赖是否自动安装(1/0) > " res echo -e " 2 \033[36m仅劫持本机流量\033[0m"
[ "$res" = '1' ] && opkg install kmod-nft-tproxy && redir_mod=Nft混合 echo -e " 3 \033[32m劫持局域网+本机流量\033[0m"
else echo -e " 4 不配置流量劫持(纯净模式)\033[0m"
redir_mod=Nft混合 echo -e " 5 \033[33m转发局域网流量到旁路由设备\033[0m"
fi echo -----------------------------------------------
set_redir_config read -p "请输入对应数字 > " num
case $num in
elif [ "$num" = 8 ]; then [1-4])
redir_mod=纯净模式 [ "$firewall_area" = 5 ] && {
set_redir_config redir_mod=Redir模式
setconfig redir_mod $redir_mod
}
firewall_area=$num
setconfig firewall_area $firewall_area
;;
5)
echo ----------------------------------------------- echo -----------------------------------------------
echo -e "\033[33m当前模式需要手动在设备WiFi或应用中配置HTTP或sock5代理\033[0m" echo -e "\033[31m注意\033[0m此功能存在多种风险如无网络基础请勿尝试"
echo -e "HTTP/SOCK5代理服务器地址\033[30;47m$host\033[0m;端口均为:\033[30;47m$mix_port\033[0m" echo -e "\033[33m说明\033[0m此功能不启动内核仅配置防火墙转发且子设备无需额外设置网关DNS"
echo -e "也可以使用更便捷的PAC自动代理PAC代理链接为" echo -e "\033[33m说明\033[0支持防火墙分流及设备过滤支持部分定时任务但不支持ipv6"
echo -e "\033[30;47m http://$host:$db_port/ui/pac \033[0m" echo -e "\033[31m注意\033[0如需代理UDP请确保旁路由运行了支持UDP代理的模式"
echo -e "PAC的使用教程请参考\033[4;32mhttps://juewuy.github.io/ehRUeewcv\033[0m" echo -----------------------------------------------
sleep 2 read -p "请输入旁路由IPV4地址 > " bypass_host
else [ -n "$bypass_host" ] && {
errornum firewall_area=$num
fi setconfig firewall_area $firewall_area
setconfig bypass_host $bypass_host
} redir_mod=TCP旁路转发
set_dns_mod(){ setconfig redir_mod $redir_mod
echo ----------------------------------------------- }
echo -e "当前DNS运行模式为\033[47;30m $dns_mod \033[0m" ;;
echo -e "\033[33m切换模式后需要手动重启服务以生效\033[0m" *) errornum ;;
echo ----------------------------------------------- esac
echo -e " 1 fake-ip模式 \033[32m响应速度更快\033[0m" sleep 1
echo -e " 不支持绕过CN-IP功能" set_redir_mod
if [ "$crashcore" = singbox -o "$crashcore" = singboxp ];then ;;
echo -e " 3 mix混合模式 \033[32m内部realip外部fakeip\033[0m" 8)
echo -e " 依赖geosite-cn.(db/srs)数据库" if [ "$firewall_mod" = 'iptables' ];then
else if nft add table inet shellcrash 2>/dev/null;then
echo -e " 2 redir_host模式\033[32m兼容性更好\033[0m" firewall_mod=nftables
echo -e " 需搭配加密DNS使用" redir_mod=Redir模式
fi setconfig redir_mod $redir_mod
echo " 0 返回上级菜单"
read -p "请输入对应数字 > " num
if [ -z "$num" ]; then
errornum
elif [ "$num" = 0 ]; then
i=
elif [ "$num" = 1 ]; then
dns_mod=fake-ip
setconfig dns_mod $dns_mod
echo -----------------------------------------------
echo -e "\033[36m已设为 $dns_mod 模式!!\033[0m"
elif [ "$num" = 2 ]; then
dns_mod=redir_host
setconfig dns_mod $dns_mod
echo -----------------------------------------------
echo -e "\033[36m已设为 $dns_mod 模式!!\033[0m"
elif [ "$num" = 3 ]; then
if [ "$crashcore" = singbox -o "$crashcore" = singboxp ];then
dns_mod=mix
setconfig dns_mod $dns_mod
echo -----------------------------------------------
echo -e "\033[36m已设为 $dns_mod 模式!!\033[0m"
else else
echo -e "\033[31m当前内核不支持的功能!!\033[0m" echo -e "\033[31m当前设备未安装nftables或者nftables版本过低(<1.0.2),无法切换\033[0m"
sleep 1
fi fi
else else
errornum if ckcmd iptables;then
firewall_mod=iptables
redir_mod=Redir模式
setconfig redir_mod $redir_mod
else
echo -e "\033[31m当前设备未安装iptables,无法切换!\033[0m"
fi
fi fi
} sleep 1
fake_ip_filter(){ setconfig firewall_mod $firewall_mod
echo -e "\033[32m用于解决Fake-ip模式下部分地址或应用无法连接的问题\033[0m" set_redir_mod
echo -e "\033[31m脚本已经内置了大量地址你只需要添加出现问题的地址\033[0m" ;;
echo -e "\033[36m示例a.b.com" *)
echo -e "示例:*.b.com" errornum
echo -e "示例:*.*.b.com\033[0m" ;;
echo ----------------------------------------------- esac
if [ -s ${CRASHDIR}/configs/fake_ip_filter ];then }
echo -e "\033[33m已添加Fake-ip过滤地址\033[0m" set_dns_mod(){
cat ${CRASHDIR}/configs/fake_ip_filter | awk '{print NR" "$1}' echo -----------------------------------------------
echo -e "当前DNS运行模式为\033[47;30m $dns_mod \033[0m"
echo -e "\033[33m切换模式后需要手动重启服务以生效\033[0m"
echo -----------------------------------------------
echo -e " 1 fake-ip模式 \033[32m响应速度更快\033[0m"
echo -e " 不支持绕过CN-IP功能"
if [ "$crashcore" = singbox -o "$crashcore" = singboxp ];then
echo -e " 3 mix混合模式 \033[32m内部realip外部fakeip\033[0m"
echo -e " 依赖geosite-cn.(db/srs)数据库"
else
echo -e " 2 redir_host模式\033[32m兼容性更好\033[0m"
echo -e " 需搭配加密DNS使用"
fi
echo " 0 返回上级菜单"
read -p "请输入对应数字 > " num
if [ -z "$num" ]; then
errornum
elif [ "$num" = 0 ]; then
i=
elif [ "$num" = 1 ]; then
dns_mod=fake-ip
setconfig dns_mod $dns_mod
echo -----------------------------------------------
echo -e "\033[36m已设为 $dns_mod 模式!!\033[0m"
elif [ "$num" = 2 ]; then
dns_mod=redir_host
setconfig dns_mod $dns_mod
echo -----------------------------------------------
echo -e "\033[36m已设为 $dns_mod 模式!!\033[0m"
elif [ "$num" = 3 ]; then
if [ "$crashcore" = singbox -o "$crashcore" = singboxp ];then
dns_mod=mix
setconfig dns_mod $dns_mod
echo -----------------------------------------------
echo -e "\033[36m已设为 $dns_mod 模式!!\033[0m"
else else
echo -e "\033[33m你还未添加Fake-ip过滤地址\033[0m" echo -e "\033[31m当前内核不支持的功能\033[0m"
sleep 1
fi fi
echo ----------------------------------------------- else
echo -e "\033[32m输入数字直接移除对应地址输入地址直接添加\033[0m" errornum
read -p "请输入数字或地址 > " input fi
case $input in }
0) ;; fake_ip_filter(){
'') ;; echo -e "\033[32m用于解决Fake-ip模式下部分地址或应用无法连接的问题\033[0m"
[0-99]) echo -e "\033[31m脚本已经内置了大量地址你只需要添加出现问题的地址\033[0m"
sed -i "${input}d" ${CRASHDIR}/configs/fake_ip_filter 2>/dev/null echo -e "\033[36m示例a.b.com"
echo -e "\033[32m移除成功\033[0m" echo -e "示例:*.b.com"
fake_ip_filter echo -e "示例:*.*.b.com\033[0m"
;; echo -----------------------------------------------
*) if [ -s ${CRASHDIR}/configs/fake_ip_filter ];then
echo -e "你输入的地址是:\033[32m$input\033[0m" echo -e "\033[33m已添加Fake-ip过滤地址\033[0m"
read -p "确认添加?(1/0) > " res cat ${CRASHDIR}/configs/fake_ip_filter | awk '{print NR" "$1}'
[ "$res" = 1 ] && echo $input >> ${CRASHDIR}/configs/fake_ip_filter else
fake_ip_filter echo -e "\033[33m你还未添加Fake-ip过滤地址\033[0m"
;; fi
esac echo -----------------------------------------------
} echo -e "\033[32m输入数字直接移除对应地址输入地址直接添加\033[0m"
read -p "请输入数字或地址 > " input
case $input in
0) ;;
'') ;;
[0-99])
sed -i "${input}d" ${CRASHDIR}/configs/fake_ip_filter 2>/dev/null
echo -e "\033[32m移除成功\033[0m"
fake_ip_filter
;;
*)
echo -e "你输入的地址是:\033[32m$input\033[0m"
read -p "确认添加?(1/0) > " res
[ "$res" = 1 ] && echo $input >> ${CRASHDIR}/configs/fake_ip_filter
fake_ip_filter
;;
esac
}
normal_set(){ #基础设置
#获取设置默认显示 #获取设置默认显示
[ -z "$skip_cert" ] && skip_cert=已开启 [ -z "$skip_cert" ] && skip_cert=已开启
[ -z "$common_ports" ] && common_ports=已开启 [ -z "$common_ports" ] && common_ports=已开启

View File

@@ -1,4 +1,4 @@
#!/bin/sh #!/bin/bash
# Copyright (C) Juewuy # Copyright (C) Juewuy
#初始化目录 #初始化目录
@@ -1168,107 +1168,110 @@ start_tun(){ #iptables-tun
fi fi
} }
start_nft(){ #nftables-allinone start_nft(){ #nftables-allinone
#获取局域网host地址 table_type=$1
getlanip [ -n "$2" ] && table=$2 || table=$1
[ "$common_ports" = "已开启" ] && PORTS=$(echo $multiport | sed 's/,/, /g') [ "$common_ports" = "已开启" ] && PORTS=$(echo $multiport | sed 's/,/, /g')
RESERVED_IP=$(echo $reserve_ipv4 | sed 's/ /, /g') RESERVED_IP=$(echo $reserve_ipv4 | sed 's/ /, /g')
LOCAL_IP="127.0.0.0/8, $(echo $local_ipv4 | sed 's/ /, /g')" if [ "$1" = 'output' ];then
HOST_IP=$(echo $host_ipv4 | sed 's/ /, /g') HOST_IP="127.0.0.0/8, $(echo $local_ipv4 | sed 's/ /, /g')"
#设置策略路由 chain_type=route
ip rule add fwmark $fwmark table 100 else
ip route add local default dev lo table 100 HOST_IP=$(echo $host_ipv4 | sed 's/ /, /g')
[ "$redir_mod" = "Nft基础" ] && \ chain_type=nat
nft add chain inet shellcrash prerouting { type nat hook prerouting priority -100 \; } fi
[ "$redir_mod" = "Nft混合" ] && { #不同模式调整
[ "$redir_mod" = "Redir模式" ] && \
nft add chain inet shellcrash $table { type nat hook $table_type priority -100 \; }
[ "$redir_mod" = "Tproxy模式" ] && {
modprobe nft_tproxy >/dev/null 2>&1 modprobe nft_tproxy >/dev/null 2>&1
nft add chain inet shellcrash prerouting { type filter hook prerouting priority 0 \; } nft add chain inet shellcrash $table { type $chain_type hook $table_type priority mangle \; }
} }
[ -n "$(echo $redir_mod|grep Nft)" ] && { [ "$redir_mod" = "Tun模式" -o "$redir_mod" = "混合模式" ] && {
#过滤局域网设备 modprobe tun >/dev/null 2>&1
[ -n "$(cat ${CRASHDIR}/configs/mac)" ] && { i=1
MAC=$(awk '{printf "%s, ",$1}' ${CRASHDIR}/configs/mac) while [ -z "$(ip route list |grep utun)" -a "$i" -le 29 ];do
[ "$macfilter_type" = "黑名单" ] && \ sleep 1
nft add rule inet shellcrash prerouting ether saddr {$MAC} return || \ i=$((i+1))
nft add rule inet shellcrash prerouting ether saddr != {$MAC} return done
} if [ -z "$(ip route list |grep utun)" ];then
#过滤保留地址 logger "找不到tun模块放弃启动tun相关防火墙规则" 31
nft add rule inet shellcrash prerouting ip daddr {$RESERVED_IP} return exit 1
#仅代理本机局域网网段流量
nft add rule inet shellcrash prerouting ip saddr != {$HOST_IP} return
#绕过CN-IP
[ "$dns_mod" != "fake-ip" -a "$cn_ip_route" = "已开启" -a -f ${BINDIR}/cn_ip.txt ] && {
CN_IP=$(awk '{printf "%s, ",$1}' ${BINDIR}/cn_ip.txt)
[ -n "$CN_IP" ] && nft add rule inet shellcrash prerouting ip daddr {$CN_IP} return
}
#过滤常用端口
[ -n "$PORTS" ] && nft add rule inet shellcrash prerouting tcp dport != {$PORTS} ip daddr != {198.18.0.0/16} return
#ipv6支持
if [ "$ipv6_redir" = "已开启" ];then
RESERVED_IP6="$(echo "$reserve_ipv6 $host_ipv6" | sed 's/ /, /g')"
HOST_IP6="$(echo $host_ipv6 | sed 's/ /, /g')"
ip -6 rule add fwmark $fwmark table 101 2> /dev/null
ip -6 route add local ::/0 dev lo table 101 2> /dev/null
#过滤保留地址及本机地址
nft add rule inet shellcrash prerouting ip6 daddr {$RESERVED_IP6} return
#仅代理本机局域网网段流量
nft add rule inet shellcrash prerouting ip6 saddr != {$HOST_IP6} return
#绕过CN_IPV6
[ "$dns_mod" != "fake-ip" -a "$cn_ipv6_route" = "已开启" -a -f ${BINDIR}/cn_ipv6.txt ] && {
CN_IP6=$(awk '{printf "%s, ",$1}' ${BINDIR}/cn_ipv6.txt)
[ -n "$CN_IP6" ] && nft add rule inet shellcrash prerouting ip6 daddr {$CN_IP6} return
}
else else
nft add rule inet shellcrash prerouting meta nfproto ipv6 return nft add chain inet shellcrash $table { type $chain_type hook $table_type priority mangle \; }
fi fi
#透明路由
[ "$redir_mod" = "Nft基础" ] && nft add rule inet shellcrash prerouting meta l4proto tcp mark set $fwmark redirect to $redir_port
[ "$redir_mod" = "Nft混合" ] && nft add rule inet shellcrash prerouting meta l4proto {tcp, udp} mark set $fwmark tproxy to :$tproxy_port
} }
#屏蔽QUIC [ "$firewall_area" = 5 ] && {
[ "$quic_rj" = 已启用 ] && { nft add chain inet shellcrash $table { type $chain_type hook $table_type priority mangle \; }
nft add chain inet shellcrash input { type filter hook input priority 0 \; } nft add rule inet shellcrash $table ip daddr {$bypass_host} return
[ -n "$CN_IP" ] && nft add rule inet shellcrash input ip daddr {$CN_IP} return
[ -n "$CN_IP6" ] && nft add rule inet shellcrash input ip6 daddr {$CN_IP6} return
nft add rule inet shellcrash input udp dport 443 reject comment 'ShellCrash-QUIC-REJECT'
} }
#代理本机(仅TCP)
[ "$local_proxy" = "已开启" ] && [ "$local_type" = "nftables增强模式" ] && {
#dns
[ "$dns_no" != "已禁用" ] && {
[ -z "$(grep 'nameserver 127.0.0.1' /etc/resolv.conf 2>/dev/null)" ] && echo 'nameserver 127.0.0.1' >> /etc/resolv.conf #修复部分虚拟机dns查询失败的问题
nft add chain inet shellcrash dns_out { type nat hook output priority -100 \; }
nft add rule inet shellcrash dns_out meta skgid { 453, 7890 } return && \
nft add rule inet shellcrash dns_out udp dport 53 redirect to $dns_port
}
#output
nft add chain inet shellcrash output { type nat hook output priority -100 \; }
nft add rule inet shellcrash output meta skgid 7890 return && {
[ -n "$PORTS" ] && nft add rule inet shellcrash output tcp dport != {$PORTS} return
nft add rule inet shellcrash output ip daddr {$RESERVED_IP} return
nft add rule inet shellcrash output ip saddr != {$LOCAL_IP} return
nft add rule inet shellcrash output meta l4proto tcp mark set $fwmark redirect to $redir_port
}
#Docker
type docker >/dev/null 2>&1 && {
nft add chain inet shellcrash docker { type nat hook prerouting priority -100 \; }
nft add rule inet shellcrash docker ip saddr != {172.16.0.0/12} return #进代理docker网段
nft add rule inet shellcrash docker ip daddr {$RESERVED_IP} return #过滤保留地址
nft add rule inet shellcrash docker udp dport 53 redirect to $dns_port
nft add rule inet shellcrash docker meta l4proto tcp mark set $fwmark redirect to $redir_port
}
}
}
start_nft_dns(){ #nftables-dns
nft add chain inet shellcrash dns { type nat hook prerouting priority -100 \; }
#过滤局域网设备 #过滤局域网设备
[ -n "$(cat ${CRASHDIR}/configs/mac)" ] && { [ -n "$(cat ${CRASHDIR}/configs/mac)" ] && {
MAC=$(awk '{printf "%s, ",$1}' ${CRASHDIR}/configs/mac) MAC=$(awk '{printf "%s, ",$1}' ${CRASHDIR}/configs/mac)
[ "$macfilter_type" = "黑名单" ] && \ [ "$macfilter_type" = "黑名单" ] && \
nft add rule inet shellcrash dns ether saddr {$MAC} return || \ nft add rule inet shellcrash $table ether saddr {$MAC} return || \
nft add rule inet shellcrash dns ether saddr != {$MAC} return nft add rule inet shellcrash $table ether saddr != {$MAC} return
} }
nft add rule inet shellcrash dns udp dport 53 redirect to ${dns_port} #过滤保留地址
nft add rule inet shellcrash dns tcp dport 53 redirect to ${dns_port} nft add rule inet shellcrash $table ip daddr {$RESERVED_IP} return
#仅代理本机局域网网段流量
nft add rule inet shellcrash $table ip saddr != {$HOST_IP} return
#绕过CN-IP
[ "$dns_mod" != "fake-ip" -a "$cn_ip_route" = "已开启" -a -f ${BINDIR}/cn_ip.txt ] && {
CN_IP=$(awk '{printf "%s, ",$1}' ${BINDIR}/cn_ip.txt)
[ -n "$CN_IP" ] && nft add rule inet shellcrash $table ip daddr {$CN_IP} return
}
#过滤常用端口
[ -n "$PORTS" ] && nft add rule inet shellcrash $table tcp dport != {$PORTS} ip daddr != {198.18.0.0/16} return
#局域网ipv6支持
if [ "$ipv6_redir" = "已开启" -a "$table_type" = 'prerouting' -a "$firewall_area" != 5 ];then
RESERVED_IP6="$(echo "$reserve_ipv6 $host_ipv6" | sed 's/ /, /g')"
HOST_IP6="$(echo $host_ipv6 | sed 's/ /, /g')"
ip -6 rule add fwmark $fwmark table 101 2> /dev/null
ip -6 route add local ::/0 dev lo table 101 2> /dev/null
#过滤保留地址及本机地址
nft add rule inet shellcrash $table ip6 daddr {$RESERVED_IP6} return
#仅代理本机局域网网段流量
nft add rule inet shellcrash $table ip6 saddr != {$HOST_IP6} return
#绕过CN_IPV6
[ "$dns_mod" != "fake-ip" -a "$cn_ipv6_route" = "已开启" -a -f ${BINDIR}/cn_ipv6.txt ] && {
CN_IP6=$(awk '{printf "%s, ",$1}' ${BINDIR}/cn_ipv6.txt)
[ -n "$CN_IP6" ] && nft add rule inet shellcrash $table ip6 daddr {$CN_IP6} return
}
else
nft add rule inet shellcrash $table meta nfproto ipv6 return
fi
# nft add rule inet shellcrash local_tproxy log prefix \"pre\" level debug
[ "$table_type" = 'output' ] && nft add rule inet shellcrash $table meta skgid 7890 return #本机流量防回环
[ "$redir_mod" = "Redir模式" ] && nft add rule inet shellcrash $table meta l4proto tcp redirect to $redir_port
[ "$redir_mod" = "混合模式" ] && {
nft add rule inet shellcrash $table meta l4proto udp mark set $fwmark
nft add rule inet shellcrash $table meta l4proto tcp mark set $((fwmark + 1))
nft add chain inet shellcrash ${table}_mixtcp { type nat hook $table_type priority -100 \; }
nft add rule inet shellcrash ${table}_mixtcp mark == $((fwmark + 1)) meta l4proto tcp redirect to $redir_port
}
[ "$redir_mod" = "Tproxy模式" ] && {
nft add rule inet shellcrash $table meta l4proto {tcp, udp} mark set $fwmark
nft add chain inet shellcrash ${table}_tproxy { type filter hook $table_type priority -100 \; }
nft add rule inet shellcrash ${table}_tproxy meta mark == $fwmark meta l4proto {tcp, udp} tproxy to :$tproxy_port
}
[ "$redir_mod" = "Tun模式" ] && nft add rule inet shellcrash $table meta l4proto {tcp, udp} mark set $fwmark
[ "$redir_mod" = "TCP旁路转发" ] && nft add rule inet shellcrash $table meta l4proto tcp mark set $fwmark
[ "$redir_mod" = "T&U旁路转发" ] && nft add rule inet shellcrash $table meta l4proto {tcp, udp} mark set $fwmark
}
start_nft_dns(){ #nftables-dns
nft add chain inet shellcrash ${1}_dns { type nat hook $1 priority -100 \; }
#过滤局域网设备
[ -n "$(cat ${CRASHDIR}/configs/mac)" ] && {
MAC=$(awk '{printf "%s, ",$1}' ${CRASHDIR}/configs/mac)
[ "$macfilter_type" = "黑名单" ] && \
nft add rule inet shellcrash ${1}_dns ether saddr {$MAC} return || \
nft add rule inet shellcrash ${1}_dns ether saddr != {$MAC} return
}
[ "$1" = 'output' ] && {
nft add rule inet shellcrash ${1}_dns meta skgid { 453, 7890 } return
}
nft add rule inet shellcrash ${1}_dns udp dport 53 redirect to ${dns_port}
nft add rule inet shellcrash ${1}_dns tcp dport 53 redirect to ${dns_port}
} }
start_wan(){ #iptables公网访问防火墙 start_wan(){ #iptables公网访问防火墙
#获取局域网host地址 #获取局域网host地址
@@ -1403,6 +1406,8 @@ stop_firewall(){ #还原防火墙配置
} }
#还原防火墙文件 #还原防火墙文件
[ -s /etc/init.d/firewall.bak ] && mv -f /etc/init.d/firewall.bak /etc/init.d/firewall [ -s /etc/init.d/firewall.bak ] && mv -f /etc/init.d/firewall.bak /etc/init.d/firewall
#others
sed -i '/shellcrash-dns-repair/d' /etc/resolv.conf
} }
#启动相关 #启动相关
web_save(){ #最小化保存面板节点选择 web_save(){ #最小化保存面板节点选择
@@ -1664,6 +1669,7 @@ afstart(){ #启动后
#读取配置文件 #读取配置文件
getconfig getconfig
[ -z "$firewall_area" ] && firewall_area=1
#延迟启动 #延迟启动
[ ! -f ${TMPDIR}/crash_start_time ] && [ -n "$start_delay" ] && [ "$start_delay" -gt 0 ] && { [ ! -f ${TMPDIR}/crash_start_time ] && [ -n "$start_delay" ] && [ "$start_delay" -gt 0 ] && {
logger "ShellCrash将延迟$start_delay秒启动" 31 pushoff logger "ShellCrash将延迟$start_delay秒启动" 31 pushoff
@@ -1686,7 +1692,8 @@ afstart(){ #启动后
start_dns(){ start_dns(){
if [ "$dns_no" != "已禁用" ];then if [ "$dns_no" != "已禁用" ];then
if [ "$dns_redir" != "已开启" ];then if [ "$dns_redir" != "已开启" ];then
[ -n "$(echo $redir_mod|grep Nft)" ] && start_nft_dns || start_ipt_dns [ "$firewall_mod" = 'iptables' ] && start_ipt_dns
[ "$firewall_mod" = 'nftables' ] && start_nft_dns prerouting
else else
#openwrt使用dnsmasq转发 #openwrt使用dnsmasq转发
uci del dhcp.@dnsmasq[-1].server >/dev/null 2>&1 uci del dhcp.@dnsmasq[-1].server >/dev/null 2>&1
@@ -1700,21 +1707,46 @@ afstart(){ #启动后
return 0 return 0
} }
#设置路由规则 #设置路由规则
[ "$redir_mod" = "Redir模式" ] && start_dns && start_redir [ "$firewall_area" != 4 ] && {
[ "$redir_mod" = "混合模式" ] && start_dns && start_redir && start_tun udp getlanip #获取局域网host地址
[ "$redir_mod" = "Tproxy混合" ] && start_dns && start_redir && start_tproxy udp #设置策略路由
[ "$redir_mod" = "Tun模式" ] && start_dns && start_tun all [ "$redir_mod" = "Tproxy模式" ] && ip route add local default dev lo table 100
[ "$redir_mod" = "Tproxy模式" ] && start_dns && start_tproxy all [ "$redir_mod" = "Tun模式" -o "$redir_mod" = "混合模式" ] && ip route add default dev utun table 100
[ -n "$(echo $redir_mod|grep Nft)" -o "$local_type" = "nftables增强模式" ] && { [ "$firewall_area" = 5 ] && ip route add default via $bypass_host table 100
nft add table inet shellcrash #初始化nftables [ "$redir_mod" != "纯净模式" -a "$redir_mod" != "Redir模式" ] && ip rule add fwmark $fwmark table 100
nft flush table inet shellcrash [ "$firewall_mod" = 'iptables' ] && {
} [ "$redir_mod" = "Redir模式" ] && start_dns && start_redir
[ -n "$(echo $redir_mod|grep Nft)" ] && start_dns && start_nft [ "$redir_mod" = "混合模式" ] && start_dns && start_redir && start_tun udp
#设置本机代理 [ "$redir_mod" = "Tun模式" ] && start_dns && start_tun all
[ "$local_proxy" = "已开启" ] && { [ "$redir_mod" = "Tproxy模式" ] && start_dns && start_tproxy all
[ "$local_type" = "环境变量" ] && $0 set_proxy $mix_port $db_port [ "$firewall_area" = 2 -o "$firewall_area" = 3 ] && [ -n "$(grep '0:7890' /etc/passwd)" ] && start_output #设置本机代理
[ "$local_type" = "iptables增强模式" ] && [ -n "$(grep '0:7890' /etc/passwd)" ] && start_output }
[ "$local_type" = "nftables增强模式" ] && [ -n "$(grep '0:7890' /etc/passwd)" ] && [ "$redir_mod" = "纯净模式" ] && start_nft [ "$firewall_mod" = 'nftables' ] && {
nft add table inet shellcrash #初始化nftables
nft flush table inet shellcrash
#局域网代理
[ "$firewall_area" = 1 -o "$firewall_area" = 3 -o "$firewall_area" = 5 ] && {
start_dns
start_nft prerouting
#屏蔽QUIC
[ "$quic_rj" = 已启用 ] && {
nft add chain inet shellcrash input { type filter hook input priority 0 \; }
[ -n "$CN_IP" ] && nft add rule inet shellcrash input ip daddr {$CN_IP} return
[ -n "$CN_IP6" ] && nft add rule inet shellcrash input ip6 daddr {$CN_IP6} return
nft add rule inet shellcrash input udp dport 443 reject comment 'ShellCrash-QUIC-REJECT'
}
}
#设置本机代理
[ "$firewall_area" = 2 -o "$firewall_area" = 3 ] && [ -n "$(grep '0:7890' /etc/passwd)" ] && {
start_nft_dns output
start_nft output
#修复部分虚拟机dns查询失败的问题
[ -z "$(grep 'nameserver 127.0.0.1' /etc/resolv.conf 2>/dev/null)" ] && {
line=$(grep -n 'nameserver' /etc/resolv.conf | awk -F: 'FNR==1{print $1}')
sed -i "$line i\nameserver 127.0.0.1 #shellcrash-dns-repair" /etc/resolv.conf
}
}
}
} }
ckcmd iptables && start_wan #本地防火墙 ckcmd iptables && start_wan #本地防火墙
mark_time #标记启动时间 mark_time #标记启动时间