V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
erguotou521
V2EX  ›  路由器

sing-box 作为旁路由导致无法 dig 通网关服务器

  •  
  •   erguotou521 · 2 天前 · 201 次点击

    家里入网是 ROS 硬路由(称之为 A ),下面有一个 pve 上创建了基于 Debian 的服务器(称之为 B ),在上面跑了 sing-box 客户端,使用 tproxy 模式配合 nftables 搭建,然后家里主机将网关和 DNS 都指向 B 后能 ping 通 A ,但是 dig 不通,导致 winbox 无法连接上 A 。

    下面是我的 sing-box 配置

    {
      "dns": {
        "servers": [
          {"tag": "dns_direct", "address": "223.5.5.5", "address_strategy": "ipv4_only", "strategy": "ipv4_only", "detour": "🎯 全球直连"},
          {"tag": "dns_proxy", "address": "tls://8.8.8.8", "address_strategy": "ipv4_only", "strategy": "ipv4_only", "detour": "🚀 节点选择"},
          {"tag":"block", "address": "rcode://refused"}
        ],
        "rules": [
          {"outbound": "any", "server": "dns_direct", "disable_cache": true},
          {"clash_mode": "Direct", "server": "dns_direct"},
          {"clash_mode": "Global", "server": "dns_proxy"},
          {"rule_set": "geosite-cn", "server": "dns_direct"},
          {"rule_set": "geosite-geolocation-!cn", "server": "dns_proxy"},
          {"rule_set": "geosite-category-ads-all", "server": "block"}
        ],
        "final": "dns_proxy",
        "strategy": "ipv4_only",
        "disable_cache": true,
        "disable_expire": true
      },
      "inbounds": [
        {
          "type": "tproxy",
          "tag": "tproxy-in",
          "listen": "0.0.0.0",
          "listen_port": 7895
        }
      ],
      "outbounds": [
        { "tag": "🚀 节点选择", "type": "selector", "outbounds": ["🔯 香港自动", "🇭🇰 香港节点", "🇯🇵 日本节点", "🇺🇲 美国节点", "🐸 手动切换", "♻️ 自动选择", "🎯 全球直连"] },
        { "tag": "📹 YouTube", "type": "selector", "outbounds": ["🚀 节点选择", "♻️ 自动选择", "🔯 香港自动", "🇭🇰 香港节点", "🇯🇵 日本节点", "🇺🇲 美国节点", "🐸 手动切换"] },
        { "tag": "🤖 OpenAI", "type": "selector", "outbounds": ["🚀 节点选择", "♻️ 自动选择", "🔯 香港自动", "🇭🇰 香港节点", "🇯🇵 日本节点", "🇺🇲 美国节点", "🐸 手动切换"] },
        { "tag": "🍀 Google", "type": "selector", "outbounds": ["🚀 节点选择", "♻️ 自动选择", "🔯 香港自动", "🇭🇰 香港节点", "🇯🇵 日本节点", "🇺🇲 美国节点", "🐸 手动切换"] },
        { "tag": "👨‍💻 Github", "type": "selector", "outbounds": ["🚀 节点选择", "♻️ 自动选择", "🔯 香港自动", "🇭🇰 香港节点", "🇯🇵 日本节点", "🇺🇲 美国节点", "🐸 手动切换"] },
        { "tag": "🪟 Microsoft", "type": "selector", "outbounds": ["🚀 节点选择", "♻️ 自动选择", "🔯 香港自动", "🇭🇰 香港节点", "🇯🇵 日本节点", "🇺🇲 美国节点", "🎯 全球直连"] },
        { "tag": "🐬 OneDrive", "type": "selector", "outbounds": ["🚀 节点选择", "♻️ 自动选择", "🔯 香港自动", "🇭🇰 香港节点", "🇯🇵 日本节点", "🇺🇲 美国节点", "🐸 手动切换"] },
        { "tag": "🎵 TikTok", "type": "selector", "outbounds": ["🚀 节点选择", "♻️ 自动选择", "🔯 香港自动", "🇭🇰 香港节点", "🇯🇵 日本节点", "🇺🇲 美国节点", "🐸 手动切换"] },
        { "tag": "🎥 Netflix", "type": "selector", "outbounds": ["🚀 节点选择", "♻️ 自动选择", "🔯 香港自动", "🇭🇰 香港节点", "🇯🇵 日本节点", "🇺🇲 美国节点", "🐸 手动切换"] },
        { "tag": "📲 Telegram", "type": "selector", "outbounds": ["🚀 节点选择", "♻️ 自动选择", "🔯 香港自动", "🇭🇰 香港节点", "🇯🇵 日本节点", "🇺🇲 美国节点", "🐸 手动切换"] },
        { "tag": "🍏 Apple", "type": "selector", "outbounds": ["🎯 全球直连", "🇭🇰 香港节点", "🇯🇵 日本节点", "🇺🇲 美国节点"] },
        { "tag": "🐠 漏网之鱼", "type": "selector", "outbounds": ["🚀 节点选择","🎯 全球直连"] },
        { "tag": "🐸 手动切换", "type": "selector", "outbounds": ["{all}"]},
        { "tag": "🇭🇰 香港节点", "type": "selector", "outbounds": ["{all}"], "filter": [{ "action": "include", "keywords": ["🇭🇰|HK|hk|香港|港|HongKong"] }] },
        { "tag": "🇯🇵 日本节点", "type": "selector", "outbounds": ["{all}"], "filter": [{ "action": "include", "keywords": ["🇯🇵|JP|jp|日本|日|Japan"] }] },
        { "tag": "🇺🇲 美国节点", "type": "selector", "outbounds": ["{all}"], "filter": [{ "action": "include", "keywords": ["🇺🇸|US|us|美国|美|United States"] }, { "action": "exclude", "keywords": ["香港|港|HK|hk|HongKong"] }] },
        { "tag": "🔯 香港自动", "type": "urltest", "outbounds": ["{all}"], "filter": [{ "action": "include", "keywords": ["🇭🇰|HK|hk|香港|港|HongKong"] }], "url": "http://www.gstatic.com/generate_204", "interval": "10m", "tolerance": 50 },
        { "tag": "♻️ 自动选择", "type": "urltest", "outbounds": ["{all}"], "filter": [{ "action": "exclude", "keywords": ["网站|地址|剩余|过期|时间|有效"] }], "url": "http://www.gstatic.com/generate_204", "interval": "10m", "tolerance": 50 },
        { "tag": "GLOBAL", "type": "selector", "outbounds": ["{all}"]},
        { "tag": "🎯 全球直连", "type": "direct" }
      ],
      "route": {
        "rules": [
          {"action": "sniff"},
          {"protocol": "dns", "action": "hijack-dns"},
          {"clash_mode": "direct", "outbound": "🎯 全球直连"},
          {"clash_mode": "global", "outbound": "GLOBAL"},
          {"rule_set": "geosite-private", "outbound": "🎯 全球直连"},
          {"rule_set": "geosite-chat", "outbound": "🤖 OpenAI"},
          {"rule_set": "geosite-youtube", "outbound": "📹 YouTube"},
          {"rule_set": "geosite-github", "outbound": "👨‍💻 Github"},
          {"rule_set": ["geosite-google", "geoip-google"], "outbound": "🍀 Google"},
          {"rule_set": ["geosite-telegram", "geoip-telegram"], "outbound": "📲 Telegram"},
          {"rule_set": "geosite-tiktok", "outbound": "🎵 TikTok"},
          {"rule_set": ["geosite-netflix", "geoip-netflix"], "outbound": "🎥 Netflix"},
          {"rule_set": ["geosite-apple", "geoip-apple"], "outbound": "🍏 Apple"},
          {"rule_set": "geosite-onedrive", "outbound": "🐬 OneDrive"},
          {"rule_set": "geosite-microsoft", "outbound": "🪟 Microsoft"},
          {"rule_set": "geosite-geolocation-!cn", "outbound": "🚀 节点选择"},
          {"rule_set": ["geoip-cn", "geosite-cn"], "outbound": "🎯 全球直连"}
        ],
        "rule_set": [
          { "tag": "geosite-category-ads-all", "type": "remote", "format": "binary", "url": "https://ghproxy.cc/https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-category-ads-all.srs", "download_detour": "🎯 全球直连" },
          { "tag": "geosite-chat", "type": "remote", "format": "binary", "url": "https://ghproxy.cc/https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/sing/geo/geosite/category-ai-chat-!cn.srs", "download_detour": "🎯 全球直连" },
          { "tag": "geosite-youtube", "type": "remote", "format": "binary", "url": "https://ghproxy.cc/https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/sing/geo/geosite/youtube.srs", "download_detour": "🎯 全球直连" },
          { "tag": "geosite-google", "type": "remote", "format": "binary", "url": "https://ghproxy.cc/https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/sing/geo/geosite/google.srs", "download_detour": "🎯 全球直连" },
          { "tag": "geosite-github", "type": "remote", "format": "binary", "url": "https://ghproxy.cc/https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/sing/geo/geosite/github.srs", "download_detour": "🎯 全球直连" },
          { "tag": "geosite-telegram", "type": "remote", "format": "binary", "url": "https://ghproxy.cc/https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/sing/geo/geosite/telegram.srs", "download_detour": "🎯 全球直连" },
          { "tag": "geosite-tiktok", "type": "remote", "format": "binary", "url": "https://ghproxy.cc/https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/sing/geo/geosite/tiktok.srs", "download_detour": "🎯 全球直连" },
          { "tag": "geosite-netflix", "type": "remote", "format": "binary", "url": "https://ghproxy.cc/https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/sing/geo/geosite/netflix.srs", "download_detour": "🎯 全球直连" },
          { "tag": "geosite-apple", "type": "remote", "format": "binary", "url": "https://ghproxy.cc/https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/sing/geo/geosite/apple.srs", "download_detour": "🎯 全球直连" },
          { "tag": "geosite-microsoft", "type": "remote", "format": "binary", "url": "https://ghproxy.cc/https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/sing/geo/geosite/microsoft.srs", "download_detour": "🎯 全球直连" },
          { "tag": "geosite-onedrive", "type": "remote", "format": "binary", "url": "https://ghproxy.cc/https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/sing/geo/geosite/onedrive.srs", "download_detour": "🎯 全球直连" },
          { "tag": "geosite-geolocation-!cn", "type": "remote", "format": "binary", "url": "https://ghproxy.cc/https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/sing/geo/geosite/geolocation-!cn.srs", "download_detour": "🎯 全球直连" },
          { "tag": "geosite-cn", "type": "remote", "format": "binary", "url": "https://ghproxy.cc/https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/sing/geo/geosite/cn.srs", "download_detour": "🎯 全球直连" },
          { "tag": "geosite-private", "type": "remote", "format": "binary", "url": "https://ghproxy.cc/https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/sing/geo/geosite/private.srs", "download_detour": "🎯 全球直连" },
                
          { "tag": "geoip-google", "type": "remote", "format": "binary", "url": "https://ghproxy.cc/https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/sing/geo/geoip/google.srs", "download_detour": "🎯 全球直连" },
          { "tag": "geoip-telegram", "type": "remote", "format": "binary", "url": "https://ghproxy.cc/https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/sing/geo/geoip/telegram.srs", "download_detour": "🎯 全球直连" },     
          { "tag": "geoip-netflix", "type": "remote", "format": "binary", "url": "https://ghproxy.cc/https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/sing/geo/geoip/netflix.srs", "download_detour": "🎯 全球直连" },     
          { "tag": "geoip-apple", "type": "remote", "format": "binary", "url": "https://ghproxy.cc/https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/sing/geo-lite/geoip/apple.srs", "download_detour": "🎯 全球直连" },
          { "tag": "geoip-cn", "type": "remote", "format": "binary", "url": "https://ghproxy.cc/https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/sing/geo/geoip/cn.srs", "download_detour": "🎯 全球直连" },
          { "tag": "geoip-private", "type": "remote", "format": "binary", "url": "https://ghproxy.cc/https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/sing/geo/geoip/private.srs", "download_detour": "🎯 全球直连" }
        ],
        "final": "🐠 漏网之鱼",
        "default_mark": 666,
        "auto_detect_interface": true
      },
      "ntp": {
        "enabled": true,
        "server": "time.windows.com",
        "server_port": 123,
        "interval": "30m"
      },
      "experimental": {
        "cache_file": {
          "enabled": true,
          "path": "/etc/sing-box/cache.db",
          "store_fakeip": false
        },
        "clash_api": {
          "external_controller": "0.0.0.0:9090",
          "external_ui": "/etc/sing-box/ui",
          "external_ui_download_url": "https://ghproxy.cc/https://github.com/Zephyruso/zashboard/archive/refs/heads/gh-pages.zip",
          "external_ui_download_detour": "🎯 全球直连",
          "default_mode": "rule"
        }
      }
    }
    

    其中{all}filter已被替换成可用的节点列表。 然后下面是 nftables 的脚本,我是参考了七尺宇的sbshell项目里的

    #!/bin/sh
    
    # 配置参数
    TPROXY_PORT=7895
    ROUTING_MARK=666
    PROXY_FWMARK=1
    PROXY_ROUTE_TABLE=100
    INTERFACE=$(ip route show default | awk '/default/ {print $5}')
    
    # 保留 IP 地址集合
    
    ReservedIP4='{ 127.0.0.0/8, 10.0.0.0/8, 100.64.0.0/10, 169.254.0.0/16, 172.16.0.0/12, 192.0.0.0/24, 192.0.2.0/24, 198.18.0.0/15, 198.51.100.0/24, 192.88.99.0/24, 192.168.0.0/16, 203.0.113.0/24, 224.0.0.0/4, 240.0.0.0/4, 255.255.255.255/32 }'
    
    CustomBypassIP='{ 192.168.0.0/16 }' # 自定义绕过的 IP 地址集合
    
    # 检查指定路由表是否存在
    check_route_exists() {
        ip route show table "$1" >/dev/null 2>&1
        return $?
    }
    
    # 创建路由表,如果不存在的话
    create_route_table_if_not_exists() {
        if ! check_route_exists "$PROXY_ROUTE_TABLE"; then
            echo "路由表不存在,正在创建..."
            ip route add local default dev "$INTERFACE" table "$PROXY_ROUTE_TABLE" || { echo "创建路由表失败"; exit 1; }
        fi
    }
    
    # 等待 FIB 表加载完成
    wait_for_fib_table() {
        i=1
        while [ $i -le 10 ]; do
            if ip route show table "$PROXY_ROUTE_TABLE" >/dev/null 2>&1; then
                return 0
            fi
            echo "等待 FIB 表加载中,等待 $i 秒..."
            i=$((i + 1))
        done
        echo "FIB 表加载失败,超出最大重试次数"
        return 1
    }
    
    # 清理现有 sing-box 防火墙规则
    clearSingboxRules() {
        nft list table inet sing-box >/dev/null 2>&1 && nft delete table inet sing-box
        ip rule del fwmark $PROXY_FWMARK lookup $PROXY_ROUTE_TABLE 2>/dev/null
        ip route del local default dev "${INTERFACE}" table $PROXY_ROUTE_TABLE 2>/dev/null
        echo "清理 sing-box 相关的防火墙规则"
    }
    
    tproxy_setup() {
        # 创建并确保路由表存在
        create_route_table_if_not_exists
        
        # 等待 FIB 表加载完成
        if ! wait_for_fib_table; then
            echo "FIB 表准备失败,退出脚本。"
            exit 1
        fi
        
        # 清理现有规则
        clearSingboxRules
      
        # 设置 IP 规则和路由
        ip -f inet rule add fwmark $PROXY_FWMARK lookup $PROXY_ROUTE_TABLE
        ip -f inet route add local default dev "${INTERFACE}" table $PROXY_ROUTE_TABLE
        sysctl -w net.ipv4.ip_forward=1 > /dev/null
    
        # 确保目录存在
        sudo mkdir -p /etc/sing-box/nft
        # 设置 TProxy 模式下的 nftables 规则
        cat > /etc/sing-box/nft/nftables.conf <<EOF
    table inet sing-box {
        set RESERVED_IPSET {
            type ipv4_addr
            flags interval
            auto-merge
            elements = $ReservedIP4
        }
      
        chain prerouting_tproxy {
            type filter hook prerouting priority mangle; policy accept;
            # DNS 请求重定向到本地 TProxy 端口
            meta l4proto { tcp, udp } th dport 53 tproxy to :$TPROXY_PORT accept
            # 自定义绕过地址
            ip daddr $CustomBypassIP accept
            # 保留地址绕过
            ip daddr @RESERVED_IPSET accept
            # 拒绝访问本地 TProxy 端口
            fib daddr type local meta l4proto { tcp, udp } th dport $TPROXY_PORT reject with icmpx type host-unreachable
            # 本地地址绕过
            fib daddr type local accept
            # 优化已建立的 TCP 连接
            meta l4proto tcp socket transparent 1 meta mark set $PROXY_FWMARK accept
            # 重定向剩余流量到 TProxy 端口并设置标记
            meta l4proto { tcp, udp } tproxy to :$TPROXY_PORT meta mark set $PROXY_FWMARK
        }
      
        chain output_tproxy {
            type route hook output priority mangle; policy accept;
            # 放行本地回环接口流量
            meta oifname "lo" accept
            # 本地 sing-box 发出的流量绕过
            meta mark $ROUTING_MARK accept
            # DNS 请求标记
            meta l4proto { tcp, udp } th dport 53 meta mark set $PROXY_FWMARK
            # 绕过 NBNS 流量
            udp dport { netbios-ns, netbios-dgm, netbios-ssn } accept
            # 自定义绕过地址
            ip daddr $CustomBypassIP accept
            # 本地地址绕过
            fib daddr type local accept
            # 标记并重定向剩余流量
            meta l4proto { tcp, udp } meta mark set $PROXY_FWMARK
        }
    }
    EOF
      
        # 应用防火墙规则和 IP 路由
        nft -f /etc/sing-box/nft/nftables.conf
      
        # 持久化防火墙规则
        nft list ruleset > /etc/nftables.conf
      
        echo "TProxy 模式的防火墙规则已应用。"
    }
    
    tproxy_setup
    

    这样一套配置可以让 PC 访问互联网也能访问家里的局域网( 192.168.5.0/24 )服务,但是局域网的 DNS 都不通了。

    还有一个延伸问题,我在工作环境也有一套一样的服务,也是一样的问题,但是当我使用 WireGuard 连回家后,家里的 ip 服务是都可以访问了,但是百度/谷歌都访问不了了,可是我的 wg 配置的 [Interface] Address = 192.168.10.3/32 DNS = 114.114.114.114 [Peer] AllowedIPs = 192.168.10.0/24, 192.168.8.0/24

    对网络这块确实不太熟悉,麻烦大家给指点指点,谢谢

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5338 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 07:41 · PVG 15:41 · LAX 23:41 · JFK 02:41
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.