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