家里入网是 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/metarules-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
对网络这块确实不太熟悉,麻烦大家给指点指点,谢谢