Linux透明网关、nftables+xray tproxy代理
•默认分类
5237
2
作为旁路由、透明代理(网关),大多数人可以选择opewnrt+科学插件,可视化及快速上手。
但我的想法是折腾更多的玩法,最终形成了这篇帖子,希望可以帮到其他爱好者--少踩坑
2025年了,之前很纳闷为什么xray tproxy之后,产生了大量的未关闭udp链接,直到我尝试在nft提前放行国内直连IP,
这个问题解决了。当下在用的方案是mosdns(dns分流)+xraytproxy(透明网关)+nftables
小白入门:TProxy 透明代理(ipv4 and ipv6)配置教程
可以参阅上面的文档之后再参考我的方案。
mosdns国内外分流配置:
log:
level: error
plugins:
- tag: cache
type: cache
args:
size: 2048
lazy_cache_ttl: 86400
- tag: forward_local
type: forward
args:
concurrent: 2
upstreams:
- addr: "tls://dot.pub"
dial_addr: "120.53.53.53"
enable_pipeline: true
- addr: "tls://dns.alidns.com"
dial_addr: "223.5.5.5"
enable_pipeline: true
- tag: forward_remote
type: forward
args:
concurrent: 1
upstreams:
- addr: "tls://dns.google"
dial_addr: "8.8.4.4"
enable_pipeline: true
- tag: gfw_list # 代理域名
type: domain_set
args:
files:
- /usr/local/share/v2ray/proxy-list.txt
- /usr/local/share/v2ray/gfw.txt
- tag: ad_list # 广告域名
type: domain_set
args:
files:
- /usr/local/share/v2ray/reject-list.txt
- tag: main_sequence
type: sequence
args:
- matches: qtype 12 65
exec: reject 0
- matches: qname $ad_list
exec: reject 3
- exec: $cache
- matches: has_resp
exec: accept
- matches: qname $gfw_list
exec: prefer_ipv4 $forward_remote
- matches: has_resp
exec: accept
- exec: $forward_local
- matches: has_resp
exec: accept
- tag: udp_server
type: udp_server
args:
entry: main_sequence
listen: :53
- tag: tcp_server
type: tcp_server
args:
entry: main_sequence
listen: :53
nftables配置:
#!/usr/sbin/nft -f
# 清空所有规则
flush ruleset
table inet xray {
# 本地/私有IPv4地址集合
set local_ips {
type ipv4_addr
flags interval
elements = {
127.0.0.0/8, # 本地回环
10.0.0.0/8, # RFC1918私有网络
172.16.0.0/12, # RFC1918私有网络(包含172.17.0.0/16)
192.168.0.0/16, # RFC1918私有网络
169.254.0.0/16, # 链路本地地址
224.0.0.0/4, # 组播地址
240.0.0.0/4, # 保留地址
100.64.0.0/10, # CGNAT地址
192.0.0.0/24, # IETF协议分配
198.51.100.0/24 # 文档示例地址
}
}
# 本地/私有IPv6地址集合
set local_ips6 {
type ipv6_addr
flags interval
elements = {
::1/128, # 本地回环
fc00::/7, # 唯一本地地址
fe80::/10, # 链路本地地址
ff00::/8, # 组播地址
::ffff:0:0/96, # IPv4映射地址
::/128, # 未指定地址
2001:db8::/32, # 文档示例地址
2002::/16, # 6to4地址
100::/64 # 保留地址
}
}
# 中国IP地址集合 - 由更新脚本动态填充
set cnip_v4 {
type ipv4_addr
flags interval
auto-merge
}
set cnip_v6 {
type ipv6_addr
flags interval
auto-merge
}
# 预路由链 - 处理进入系统的包
chain prerouting {
type filter hook prerouting priority filter
policy accept
# 跳过本地、中国IP的流量以及已标记的流量
ip daddr @local_ips return
ip6 daddr @local_ips6 return
ip daddr @cnip_v4 return
ip6 daddr @cnip_v6 return
meta mark 2 return
# 将TCP和UDP流量重定向到Xray的TPROXY端口
meta l4proto { tcp, udp } meta mark set 1 tproxy to :12345 accept
}
# 输出链 - 处理从本机发出的包
chain output {
type route hook output priority filter
policy accept
# 跳过本地、中国IP的流量以及已标记的流量
ip daddr @local_ips return
ip6 daddr @local_ips6 return
ip daddr @cnip_v4 return
ip6 daddr @cnip_v6 return
meta mark 2 return
# 标记非直连流量
meta l4proto { tcp, udp } meta mark set 1 accept
}
# 分流链 - 用于处理本地发起但由透明代理接管的连接
chain divert {
type filter hook prerouting priority mangle
policy accept
# 检测到已建立的TCP连接,设置标记以便重用相同的路径
meta l4proto tcp socket transparent 1 meta mark set 1 accept
}
}
# NAT表 - 用于网络地址转换
table inet nat {
chain postrouting {
type nat hook postrouting priority 100
policy accept
# 将Docker容器网络流量进行源地址转换
ip saddr 172.17.0.0/16 oif "enp1s0" masquerade
}
}
策略路由:
ip rule add fwmark 1 table 100
ip -6 rule add fwmark 1 table 106
ip route add local 0.0.0.0/0 dev lo table 100
ip -6 route add local ::/0 dev lo table 106
一些域名IP文件资源
["geosite.dat"]="https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat"
["geoip.dat"]="https://raw.githubusercontent.com/Loyalsoldier/geoip/release/geoip-only-cn-private.dat"
["geoip-asn.dat"]="https://raw.githubusercontent.com/Loyalsoldier/geoip/release/geoip-asn.dat"
["direct-list.txt"]="https://raw.githubusercontent.com/Loyalsoldier/v2ray-rules-dat/release/direct-list.txt"
["proxy-list.txt"]="https://raw.githubusercontent.com/Loyalsoldier/v2ray-rules-dat/release/proxy-list.txt"
["reject-list.txt"]="https://raw.githubusercontent.com/Loyalsoldier/v2ray-rules-dat/release/reject-list.txt"
["apple-cn.txt"]="https://raw.githubusercontent.com/Loyalsoldier/v2ray-rules-dat/release/apple-cn.txt"
["google-cn.txt"]="https://raw.githubusercontent.com/Loyalsoldier/v2ray-rules-dat/release/google-cn.txt"
["gfw.txt"]="https://raw.githubusercontent.com/Loyalsoldier/v2ray-rules-dat/release/gfw.txt"
["cn-ip.txt"]="https://github.com/Loyalsoldier/geoip/raw/refs/heads/release/text/cn.txt"
["private.txt"]="https://github.com/Loyalsoldier/geoip/raw/refs/heads/release/text/private.txt"
分离cnip的脚本
#!/bin/bash
# --- 配置 ---
CNIP_FILE="/usr/local/share/v2ray/cn-ip.txt"
IPV4_FILE="/usr/local/share/v2ray/china_ipv4.txt"
IPV6_FILE="/usr/local/share/v2ray/china_ipv6.txt"
NFT_TABLE="inet xray"
NFT_SET_V4="cnip_v4"
NFT_SET_V6="cnip_v6"
# --- 配置结束 ---
# 错误处理函数
error_exit() {
echo "❌ 错误: $1" >&2
exit 1
}
# 检查必要的文件和命令是否存在
[ -f "$CNIP_FILE" ] || error_exit "$CNIP_FILE 文件不存在"
command -v nft >/dev/null 2>&1 || error_exit "nft 命令未找到,请安装 nftables"
command -v awk >/dev/null 2>&1 || error_exit "awk 命令未找到"
echo "🔄 开始更新 nftables 直连IP..."
# 创建临时文件
TEMP_FILE_V4=$(mktemp) || error_exit "无法创建临时文件"
TEMP_FILE_V6=$(mktemp) || error_exit "无法创建临时文件"
# 确保脚本退出时删除临时文件
trap 'rm -f "$TEMP_FILE_V4" "$TEMP_FILE_V6"; echo "🧹 清理临时文件"; exit' EXIT INT TERM
# 分离IPv4和IPv6地址
echo "🔍 分离IPv4和IPv6地址..."
> "$IPV4_FILE" # 清空文件
> "$IPV6_FILE" # 清空文件
awk -v ipv4_file="$IPV4_FILE" -v ipv6_file="$IPV6_FILE" '{
if ($1 ~ /^[0-9]+\./)
print $1 > ipv4_file;
else if ($1 ~ /^[0-9a-fA-F:]+/)
print $1 > ipv6_file;
}' "$CNIP_FILE" || error_exit "地址分离失败"
# 检查分离后的文件是否为空
[ -s "$IPV4_FILE" ] || echo "⚠️ 警告: 未找到IPv4地址"
[ -s "$IPV6_FILE" ] || echo "⚠️ 警告: 未找到IPv6地址"
# 准备 IPv4 批量添加命令
echo "📝 准备IPv4规则..."
{
echo "flush set $NFT_TABLE $NFT_SET_V4"
echo "add element $NFT_TABLE $NFT_SET_V4 {"
awk '{printf "%s,\n", $1}' "$IPV4_FILE" | sed '$ s/,$//'
echo "}"
} > "$TEMP_FILE_V4"
# 准备 IPv6 批量添加命令
echo "📝 准备IPv6规则..."
{
echo "flush set $NFT_TABLE $NFT_SET_V6"
echo "add element $NFT_TABLE $NFT_SET_V6 {"
awk '{printf "%s,\n", $1}' "$IPV6_FILE" | sed '$ s/,$//'
echo "}"
} > "$TEMP_FILE_V6"
# 执行批量更新
echo "🔄 正在应用 IPv4 地址..."
nft -f "$TEMP_FILE_V4" || error_exit "应用IPv4规则失败"
echo "🔄 正在应用 IPv6 地址..."
nft -f "$TEMP_FILE_V6" || error_exit "应用IPv6规则失败"
# 验证规则是否成功应用
IPV4_COUNT=$(wc -l < "$IPV4_FILE")
IPV6_COUNT=$(wc -l < "$IPV6_FILE")
echo "✅ nftables 规则更新成功!IPv4地址: $IPV4_COUNT 条, IPv6地址: $IPV6_COUNT 条"
请问一下dae+sing-box该怎么用debian配置
101.6.6.6被ban了,方便出个VPS版本的Linux旁路由方案不?