From 7b08547f161a8e07c75acab4bb21d1784bf52cbe Mon Sep 17 00:00:00 2001 From: juewuy Date: Thu, 3 Nov 2022 16:12:43 +0800 Subject: [PATCH] =?UTF-8?q?v1.6.6=20~=E6=96=B0=E5=A2=9ETproxy=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F=20~=E6=96=B0=E5=A2=9ENftables=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/clash.sh | 81 +++++++++++++++----------------- scripts/start.sh | 118 ++++++++++++++++++++++++++++++++++------------- 2 files changed, 122 insertions(+), 77 deletions(-) diff --git a/scripts/clash.sh b/scripts/clash.sh index 8fff09f..424060c 100644 --- a/scripts/clash.sh +++ b/scripts/clash.sh @@ -593,23 +593,21 @@ clashcfg(){ echo ----------------------------------------------- echo -e "\033[36m已设为 $redir_mod !!\033[0m" } + [ -n "$(iptables -j TPROXY 2>&1 | grep 'on-port')" ] && sup_tp=1 + ip tuntap >/dev/null 2>&1 && sup_tun=1 + type nftables >/dev/null 2>&1 && sup_nft=1 echo ----------------------------------------------- echo -e "当前代理模式为:\033[47;30m $redir_mod \033[0m;Clash核心为:\033[47;30m $clashcore \033[0m" echo -e "\033[33m切换模式后需要手动重启clash服务以生效!\033[0m" - echo -e "\033[36mTun及混合模式必须使用clashpre核心!\033[0m" echo ----------------------------------------------- - echo -e " 1 Redir模式:CPU以及内存\033[33m占用较低\033[0m" - echo -e " 但\033[31m不支持UDP\033[0m" - echo -e " 适合\033[32m非外服游戏用户\033[0m使用" - echo -e " 2 混合模式: 使用redir转发TCP,Tun转发UDP流量" - echo -e " \033[33m速度较快\033[0m,\033[31m内存占用略高\033[0m" - echo -e " 适合\033[32m游戏用户、综合用户\033[0m" - echo -e " 3 Tun模式: \033[33m支持UDP转发\033[0m且延迟最低" - echo -e " \033[31mCPU占用极高\033[0m,只支持fake-ip模式" - echo -e " \033[33m如非必要不推荐使用\033[0m" - echo -e " 4 纯净模式: 不设置iptables静态路由" - echo -e " 必须\033[33m手动配置\033[0mhttp/sock5代理" - echo -e " 或使用内置的PAC文件配置代理" + echo -e " 1 Redir模式: Redir转发TCP,不转发UDP" + [ -n "$sup_tun" ] && echo -e " 2 混合模式: Redir转发TCP,Tun转发UDP" + [ -n "$sup_tp" ] && echo -e " 3 Tproxy混合: Redir转发TCP,Tproxy转发UDP" + [ -n "$sup_tun" ] && echo -e " 4 Tun模式: 使用Tun转发TCP&UDP(占用高)" + [ -n "$sup_tp" ] && echo -e " 5 Tproxy模式: 使用Tproxy转发TCP&UDP" + [ -n "$sup_nft" ] && echo -e " 6 Nft模式1: 使用nftables转发TCP,不转发UDP" + [ -n "$sup_nft" ] && echo -e " 7 Nft模式2: 使用nftables转发TCP&UDP" + echo -e " 8 纯净模式: 不设置流量转发" echo " 0 返回上级菜单" read -p "请输入对应数字 > " num if [ -z "$num" ]; then @@ -620,40 +618,33 @@ clashcfg(){ redir_mod=Redir模式 dns_mod=redir_host set_redir_config - elif [ "$num" = 3 ]; then - ip tuntap >/dev/null 2>&1 - if [ "$?" != 0 ];then - echo ----------------------------------------------- - echo -e "\033[31m当前设备内核可能不支持开启Tun/混合模式!\033[0m" - read -p "是否强制开启?可能无法正常使用!(1/0) > " res - if [ "$res" = 1 ];then - redir_mod=Tun模式 - dns_mod=fake-ip - set_redir_config - else - set_redir_mod - fi - else - redir_mod=Tun模式 - dns_mod=fake-ip - set_redir_config - fi + elif [ "$num" = 2 ]; then - ip tuntap >/dev/null 2>&1 - if [ "$?" != 0 ];then - echo -e "\033[31m当前设备内核可能不支持开启Tun/混合模式!\033[0m" - read -p "是否强制开启?可能无法正常使用!(1/0) > " res - if [ "$res" = 1 ];then - redir_mod=混合模式 - set_redir_config - else - set_redir_mod - fi - else - redir_mod=混合模式 - set_redir_config - fi + redir_mod=混合模式 + set_redir_config + + elif [ "$num" = 3 ]; then + redir_mod=Tproxy混合 + set_redir_config + elif [ "$num" = 4 ]; then + redir_mod=Tun模式 + dns_mod=fake-ip + set_redir_config + + elif [ "$num" = 5 ]; then + redir_mod=Tproxy模式 + set_redir_config + + elif [ "$num" = 6 ]; then + redir_mod=Nft模式1 + set_redir_config + + elif [ "$num" = 7 ]; then + redir_mod=Nft模式2 + set_redir_config + + elif [ "$num" = 8 ]; then redir_mod=纯净模式 set_redir_config echo ----------------------------------------------- diff --git a/scripts/start.sh b/scripts/start.sh index f75bc93..97bcc73 100644 --- a/scripts/start.sh +++ b/scripts/start.sh @@ -437,16 +437,9 @@ cn_ip_route(){ else logger "未找到cn_ip列表,正在下载!" 33 $0 webget $bindir/cn_ip.txt "$update_url/bin/china_ip_list.txt" - [ "$?" = "1" ] && rm -rf $bindir/cn_ip.txt && logger "列表下载失败,已退出!" 31 && exit 1 + [ "$?" = "1" ] && rm -rf $bindir/cn_ip.txt && logger "列表下载失败!" 31 fi fi - if [ -f $bindir/cn_ip.txt ];then - echo "create cn_ip hash:net family inet hashsize 1024 maxelem 65536" > /tmp/cn_$USER.ipset - awk '!/^$/&&!/^#/{printf("add cn_ip %s'" "'\n",$0)}' $bindir/cn_ip.txt >> /tmp/cn_$USER.ipset - ipset -! flush cn_ip 2>/dev/null - ipset -! restore < /tmp/cn_$USER.ipset - rm -rf cn_$USER.ipset - fi } start_redir(){ #获取局域网host地址 @@ -463,7 +456,15 @@ start_redir(){ iptables -t nat -A clash -d 224.0.0.0/4 -j RETURN iptables -t nat -A clash -d 240.0.0.0/4 -j RETURN [ -n "$host_lan" ] && iptables -t nat -A clash -d $host_lan -j RETURN - [ "$dns_mod" = "redir_host" -a "$cn_ip_route" = "已开启" ] && iptables -t nat -A clash -m set --match-set cn_ip dst -j RETURN >/dev/null 2>&1 #绕过大陆IP + #绕过CN_IP + [ "$dns_mod" = "redir_host" -a "$cn_ip_route" = "已开启" -a -f $bindir/cn_ip.txt ] && { + echo "create cn_ip hash:net family inet hashsize 1024 maxelem 65536" > /tmp/cn_$USER.ipset + awk '!/^$/&&!/^#/{printf("add cn_ip %s'" "'\n",$0)}' $bindir/cn_ip.txt >> /tmp/cn_$USER.ipset + ipset -! flush cn_ip 2>/dev/null + ipset -! restore < /tmp/cn_$USER.ipset + rm -rf cn_$USER.ipset + iptables -t nat -A clash -m set --match-set cn_ip dst -j RETURN >/dev/null 2>&1 + } if [ "$macfilter_type" = "白名单" -a -n "$(cat $clashdir/mac)" ];then #mac白名单 for mac in $(cat $clashdir/mac); do @@ -504,7 +505,7 @@ start_redir(){ ip6tables -t nat -A PREROUTING -p tcp -j clashv6 fi } -start_dns(){ +start_dns_redir(){ #屏蔽OpenWrt内置53端口转发 iptables -t nat -D PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 53 2> /dev/null iptables -t nat -D PREROUTING -p tcp --dport 53 -j REDIRECT --to-ports 53 2> /dev/null @@ -547,7 +548,7 @@ start_dns(){ fi } -start_udp(){ +start_tproxy(){ #获取局域网host地址 host_lan ip rule add fwmark 1 table 100 @@ -568,18 +569,18 @@ start_udp(){ if [ "$macfilter_type" = "白名单" -a -n "$(cat $clashdir/mac)" ];then #mac白名单 for mac in $(cat $clashdir/mac); do - iptables -t mangle -A clash -p udp -m mac --mac-source $mac -j TPROXY --on-port $redir_port --tproxy-mark 1 + iptables -t mangle -A clash -p $1 -m mac --mac-source $mac -j TPROXY --on-port $redir_port --tproxy-mark 1 done else #mac黑名单 for mac in $(cat $clashdir/mac); do iptables -t mangle -A clash -m mac --mac-source $mac -j RETURN done - iptables -t mangle -A clash -p udp -s 192.168.0.0/16 -j TPROXY --on-port $redir_port --tproxy-mark 1 - iptables -t mangle -A clash -p udp -s 10.0.0.0/8 -j TPROXY --on-port $redir_port --tproxy-mark 1 - [ -n "$host_lan" ] && iptables -t mangle -A clash -p udp -s $host_lan -j TPROXY --on-port $redir_port --tproxy-mark 1 + iptables -t mangle -A clash -p $1 -s 192.168.0.0/16 -j TPROXY --on-port $redir_port --tproxy-mark 1 + iptables -t mangle -A clash -p $1 -s 10.0.0.0/8 -j TPROXY --on-port $redir_port --tproxy-mark 1 + [ -n "$host_lan" ] && iptables -t mangle -A clash -p $1 -s $host_lan -j TPROXY --on-port $redir_port --tproxy-mark 1 fi - iptables -t mangle -A PREROUTING -p udp -j clash + iptables -t mangle -A PREROUTING -p $1 -j clash } start_output(){ #流量过滤 @@ -625,6 +626,53 @@ start_tun(){ iptables -A FORWARD -o utun -j ACCEPT #ip6tables -A FORWARD -o utun -j ACCEPT > /dev/null 2>&1 } +start_nft(){ + #设置策略路由 + ip rule add fwmark 1 table 100 + ip route add local 0.0.0.0/0 dev lo table 100 + #IPV6 + [ "$ipv6_support" = "已开启" ] && { + ip -6 rule add fwmark 1 table 101 + ip -6 route add local ::/0 dev lo table 101 + } + nft add table shellclash + nft add chain shellclash prerouting { type filter hook prerouting priority 0 \; } + #保留地址 + nft define RESERVED_IP = {0.0.0.0/8, 10.0.0.0/8, 127.0.0.0/8, 100.64.0.0/10, 169.254.0.0/16, 172.16.0.0/12, 192.168.0.0/16, 224.0.0.0/4, 240.0.0.0/4} + #创建nft表和链 + nft add chain shellclash prerouting { type filter hook prerouting priority 0 \; } + nft add rule shellclash prerouting ip daddr $RESERVED_IP return + #过滤CN-IP + [ "$dns_mod" = "redir_host" -a "$cn_ip_route" = "已开启" -a -f $bindir/cn_ip.txt ] && { + CN_IP=$(awk '{printf "%s, ",$1}' $bindir/cn_ip.txt) + nft define CN_IP = $CN_IP + nft add rule shellclash prerouting ip daddr $CN_IP return + } + #过滤常用端口 + [ "$common_ports" = "已开启" ] && { + ports=$(echo $multiport | sed 's/,/, /g') + nft add rule shellclash prerouting tcp dport != {$ports} return + } + #过滤局域网设备 ether saddr + [ -n "$(cat $clashdir/mac)" ] && { + MAC=$(awk '{printf "%s, ",$1}' $clashdir/mac) + nft define MAC = $MAC + [ "$macfilter_type" = "黑名单" ] && nft add rule shellclash prerouting ether saddr {$MAC} return + [ "$macfilter_type" = "白名单" ] && nft add rule shellclash prerouting ether saddr != {$MAC} return + } + #代理局域网设备 + nft add rule shellclash prerouting udp dport 53 redirect to :$dns_port accept + nft add rule shellclash prerouting tcp dport 53 redirect to :$dns_port accept + nft add rule shellclash prerouting meta l4proto {$1} mark set 1 tproxy to :$redir_port accept + #代理本机 + [ "$local_proxy" = "已开启" ] && [ "$local_type" = "nftables增强模式" ] && { + nft add chain shellclash output { type filter hook prerouting priority 0 \; } + nft add rule shellclash output meta skuid clash return + [ "$common_ports" = "已开启" ] && nft add rule shellclash output tcp dport != {$ports} return + nft add rule shellclash output ip daddr $RESERVED_IP return + nft add rule shellclash output meta l4proto {$1} mark set 1 accept # 重路由至 prerouting + } +} start_wan(){ [ "$mix_port" = "7890" -o -z "$authentication" ] && { iptables -A INPUT -p tcp -s 10.0.0.0/8 --dport $mix_port -j ACCEPT @@ -882,24 +930,30 @@ afstart(){ $bindir/clash -t -d $bindir >/dev/null if [ "$?" = 0 ];then #设置iptables转发规则 - [ "$dns_mod" = "redir_host" ] && [ "$cn_ip_route" = "已开启" ] && cn_ip_route - if [ "$redir_mod" != "纯净模式" ] && [ "$dns_no" != "已禁用" ];then - if [ "$dns_redir" != "已开启" ];then - start_dns - else - #openwrt使用dnsmasq转发 - uci del dhcp.@dnsmasq[-1].server >/dev/null 2>&1 - uci delete dhcp.@dnsmasq[0].resolvfile 2>/dev/null - uci add_list dhcp.@dnsmasq[0].server=127.0.0.1#$dns_port > /dev/null 2>&1 - uci set dhcp.@dnsmasq[0].noresolv=1 2>/dev/null - uci commit dhcp >/dev/null 2>&1 - /etc/init.d/dnsmasq restart >/dev/null 2>&1 + start_dns(){ + [ "$dns_mod" = "redir_host" ] && [ "$cn_ip_route" = "已开启" ] && cn_ip_route + if [ "$dns_no" != "已禁用" ];then + if [ "$dns_redir" != "已开启" ];then + start_dns_redir + else + #openwrt使用dnsmasq转发 + uci del dhcp.@dnsmasq[-1].server >/dev/null 2>&1 + uci delete dhcp.@dnsmasq[0].resolvfile 2>/dev/null + uci add_list dhcp.@dnsmasq[0].server=127.0.0.1#$dns_port > /dev/null 2>&1 + uci set dhcp.@dnsmasq[0].noresolv=1 2>/dev/null + uci commit dhcp >/dev/null 2>&1 + /etc/init.d/dnsmasq restart >/dev/null 2>&1 + fi fi - fi - [ "$redir_mod" != "纯净模式" ] && [ "$redir_mod" != "Tun模式" ] && start_redir - [ "$redir_mod" = "Redir模式" ] && [ "$tproxy_mod" = "已开启" ] && start_udp + } + [ "$redir_mod" = "Redir模式" ] && start_dns && start_redir + [ "$redir_mod" = "混合模式" ] && start_dns && start_redir && start_tun + [ "$redir_mod" = "Tproxy混合" ] && start_dns && start_redir && start_tproxy udp + [ "$redir_mod" = "Tun模式" ] && start_dns && start_tun + [ "$redir_mod" = "Tproxy模式" ] && start_dns && start_tproxy all + [ "$redir_mod" = "Nft模式1" ] && start_nft 'tcp, icmp' + [ "$redir_mod" = "Nft模式2" ] && start_nft 'tcp, udp, icmp' [ "$local_proxy" = "已开启" ] && [ "$local_type" = "iptables增强模式" ] && start_output - [ "$redir_mod" = "Tun模式" -o "$redir_mod" = "混合模式" ] && start_tun type iptables >/dev/null 2>&1 && start_wan #标记启动时间 mark_time