armbian 部署sing-box实现整个局域网透明tproxy模式配置方法

sing-box安装

  1. 下载主程序:Releases · sing-box
  2. 新建一个文件夹 mkdir -p /mnt/singbox/
  3. 将下载的 sing-box-1.12.12-darwin-amd64.tar.gz解压
  4. 将解压后中的**sing-box**上传到上面创建的/mnt/singbox/文件夹中
  5. 创建服务启动文件:nano singbox.service,在其中粘贴如下内容:
[Unit]
Description=singbox
After=network.target

[Service]
Type=simple
Restart=on-failure
RestartSec=1800s
ExecStartPre=/bin/sleep 2
LimitNOFILE=infinity
ExecStart=/mnt/singbox/sing-box run -c /mnt/singbox/config.json
ExecStop= /bin/bash -c "lsof -i :2080 -t | xargs kill"

[Install]
WantedBy=multi-user.target
# [ctrl+x,输入 y;【回车】,退出 nano 文本编辑器]
  1. singbox.service建立软连接到/etc/systemd/system/
ln -s "/mnt/singbox/singbox.service" "/etc/systemd/system/"
  1. sing-box增加执行权限: chmod a+x ./singbox

所有代码如下:

root@uefi-x86:~# mkdir -p /mnt/singbox/
root@uefi-x86:~# cd /mnt/singbox/
root@uefi-x86:/mnt/singbox# nano singbox.service
root@uefi-x86:/mnt/singbox# chmod a+x ./singbox
root@uefi-x86:/mnt/singbox#
  1. 在sing-box文件同一位置建立配置文件config.json,模板config.json下载,中间的节点信息需要自行修改
  2. 启动服务、查看服务状态、停止服务、重启服务:
# 启动服务
root@uefi-x86:~# systemctl start singbox
#查看服务状态
root@uefi-x86:~# systemctl status singbox
● singbox.service - singbox
Loaded: loaded (/etc/systemd/system/singbox.service; linked; preset: enabled)
Active: active (running) since Mon 2025-11-17 12:09:53 CST; 16s ago
Invocation: f540e84457e5470b8be4622a9b9639f8
Process: 1983 ExecStartPre=/bin/sleep 2 (code=exited, status=0/SUCCESS)
Main PID: 1985 (sing-box)
Tasks: 9 (limit: 2155)
Memory: 52.6M (peak: 52.9M)
CPU: 387ms
CGroup: /system.slice/singbox.service
└─1985 /bash/singbox/sing-box run -c /bash/singbox/config.json

11月 17 12:09:51 uefi-x86 systemd[1]: Starting singbox.service - singbox...
11月 17 12:09:53 uefi-x86 systemd[1]: Started singbox.service - singbox.
11月 17 12:09:53 uefi-x86 sing-box[1985]: WARN[0000] legacy DNS servers is deprecated in sing-bo>
11月 17 12:09:53 uefi-x86 sing-box[1985]: WARN[0000] outbound DNS rule item is deprecated in sin>
lines 1-16/16 (END)
#停止服务
root@uefi-x86:~# systemctl stop singbox
#重启服务
root@uefi-x86:~# systemctl restart singbox

singbox订阅转换

官方API

https://sing-box-subscribe.vercel.app/config/订阅

晓风foke:

http://singbox.byxiao.top/config/订阅

自建:

https://singsub.bere.top/config/订阅

指定配置文件URL:

https://singsub.bere.top/config/订阅/&file=https://github.com/Toperlock/sing-box-subscribe/raw/main/config_template/config_template_groups_tun.json

自建订阅方法:

docker run -d --name sing-box-subscribe -p 5000:5000 jwy8645/sing-box-subscribe:amd64

DNS配置示例

"servers": [
{
"tag": "dns-aliyun",
"type": "https",
"server": "dns.alidns.com",
"domain_resolver": "dns-resolver-aliyun"
},
{
"type": "udp",
"tag": "dns-resolver-aliyun",
"server": "223.5.5.5"
},
{
"type": "https",
"tag": "dns-google",
"server": "dns.google",
"domain_resolver": "dns-resolver-google"
},
{
"type": "udp",
"tag": "dns-resolver-google",
"server": "8.8.8.8"
},
{
"type": "fakeip",
"tag": "fakeip",
"inet4_range": "198.18.0.0/15"
}
]

singbox 软网关篇

下面假设主路由的 ip 为 192.168.31.1,旁路由的 ip 为 192.168.31.6,你应该根据你的情况,在下面的的配置中将它们替换成你自己的。

  • 首先你要确保旁路由本身已经可以科学上网,sing-box 的配置可以参考我的,重点在 inbounds:
# 配置一:
"inbounds": [
{
"type": "tproxy",
"tag": "tproxy-in",
"listen": "::",
"listen_port": 12345,
"tcp_fast_open": true,
"udp_fragment": true
}
],
# 配置二:
"inbounds": [
{
"type": "tun",
"inet4_address": "172.19.0.1/30",
"auto_route": true,
"strict_route": false,
"sniff": true,
"sniff_override_destination": true
}
],
"outbounds": [
{
"tag": "direct",
"type": "direct"
},
{
"tag": "block",
"type": "block"
},
{
"tag": "dns-out",
"type": "dns"
}
// 添加你自己的节点
],
"route": {
  • 修改旁路由的 ip 获取方式为手动。

地址:192.168.31.6

子网掩码:255.255.255.0

网关:192.168.31.1

DNS:192.168.31.1

  • 修改主路由的 DHCP。

网关:192.168.31.6

DNS:192.168.31.6

以上是大多数旁路由或者透明代理教程会说到的。

相信很多人这些都做完了,但是局域网设备完全不能上网,下面是重点。

  • 开启IPv4转发。

使用以下命令检查IPv4转发是否已启用

sysctl net.ipv4.ip_forward

如果输出为 net.ipv4.ip_forward = 1,则表示IPv4转发已启用。

否则开启它: 在/etc/sysctl.conf文件里添加一行net.ipv4.ip_forward = 1,保存之后运行:

sudo sysctl -p
  • 在旁路由上修改转发规则。

修改/etc/nftables.conf,添加以下规则

# 定义表
table ip nat {
chain postrouting {
type nat hook postrouting priority 100; policy accept;

# 对192.168.31.0/24网段(除了192.168.31.1)的流量进行NAT
ip saddr 192.168.31.0/24 ip saddr != 192.168.31.1 oif "tun0" masquerade
}
}

让它生效

sudo nft -f /etc/nftables.conf
  • 在旁路由上修改 DNS 监听规则。

修改/etc/systemd/resolved.conf,添加以下规则

DNSStubListenerExtra=0.0.0.0
DNSStubListenerExtra=::

让它生效

sudo systemctl restart systemd-resolved

好了,恭喜你 🎉🎉🎉,现在你局域网的设备都可以科学上网了。

帮到你的话,请点点右上角的 ⭐Star⭐。

  • 设置开机生效

新建/etc/systemd/system/nftables-post-tun0.service文件,添加以下内容:

[Unit]
Description=Apply nftables rules after tun0 is up
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/bin/bash -c 'until ip link show tun0 &>/dev/null; do sleep 1; done; nft -f /etc/nftables.conf'
RemainAfterExit=true

[Install]
WantedBy=multi-user.target

运行

sudo systemctl daemon-reload
sudo systemctl enable nftables-post-tun0.service

nftables(新版)防火墙配置

先设置路由表(命名为100)

ip route add local default dev lo table 100
ip rule add fwmark 1 table 100

ip route add local default dev lo table 100 的作用是:

  • 在路由表 100 中添加一条路由。
  • local default 表示匹配所有目标地址。
  • dev lo 指定使用环回接口 lo。 这条命令通常用于将发往本机的数据包通过环回接口进行处理,例如,用于透明代理,将发往代理服务的数据包路由到代理服务监听的地址。

ip rule add fwmark 1 table 100 的作用是:

  • 创建一条策略路由规则。
  • fwmark 1 匹配所有 fwmark 值为 1 的数据包。fwmark 通常由 iptablesnft 设置。
  • table 100 指定匹配的数据包使用路由表 100 进行路由。

结合起来,这两条命令通常一起使用,用于将带有特定 fwmark 的流量通过环回接口发送到本地进程。

更改nftables默认配置

文件路径:/etc/nftables.conf

#!/usr/sbin/nft -f

flush ruleset

table inet filter {
chain input {
type filter hook input priority filter;
}
chain forward {
type filter hook forward priority filter;
}
chain output {
type filter hook output priority filter;
}
}

更改配置如下

#!/usr/sbin/nft -f

flush ruleset

define RESERVED_IP = {
100.64.0.0/10,
127.0.0.0/8,
169.254.0.0/16,
172.16.0.0/12,
192.0.0.0/24,
224.0.0.0/4,
240.0.0.0/4,
255.255.255.255/32
}

table ip sing-box {
chain prerouting {
type filter hook prerouting priority mangle; policy accept;
ip daddr $RESERVED_IP return
# 192.168.1.0修改为你的内网网段
ip daddr 192.168.1.0/24 tcp dport != 53 return
ip daddr 192.168.1.0/24 udp dport != 53 return
# 12345修改为你的透明代理程序的端口
ip protocol tcp tproxy to :12345 meta mark set 1
ip protocol udp tproxy to :12345 meta mark set 1
}
chain output {
type route hook output priority mangle; policy accept;
ip daddr $RESERVED_IP return
# 192.168.1.0修改为你的内网网段
ip daddr 192.168.1.0/24 tcp dport != 53 return
ip daddr 192.168.1.0/24 udp dport != 53 return
ip protocol tcp meta mark set 1
ip protocol udp meta mark set 1
}
}

刷新配置

nft -f /etc/nftables.conf

持久化路由表(开机自启)

文件路径:/etc/network/interfaces

auto enp1s0             #enp1s0改为自己的网卡
iface enp1s0 inet static
address 192.168.1.8 #静态ip
netmask 255.255.255.0 #子网掩码
gateway 192.168.1.1 #网关
dns-nameservers 192.168.1.1 #dns

post-up ip route add local default dev lo table 100
post-up ip rule add fwmark 1 table 100

重启网络服务

systemctl restart networking.service

或者重启系统

验证配置

重启后,使用以下命令验证路由和规则是否已成功添加

ip route show table 100

ip rule show

你应该能看到你配置的路由和规则。

一些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
}
}

收藏二:

define RESERVED_IP = {
10.0.0.0/8,
100.64.0.0/10,
127.0.0.0/8,
169.254.0.0/16,
172.16.0.0/12,
192.0.0.0/24,
224.0.0.0/4,
240.0.0.0/4,
255.255.255.255/32
}
define LAN_IP = {
192.168.10.0/24,
192.168.20.0/24
}
chain mangle_xray_prerouting {
type filter hook prerouting priority mangle; policy accept;
ip saddr != $LAN_IP return
ip daddr $RESERVED_IP return
#ip daddr 192.168.0.0/16 tcp dport != 53 return #由代理接管DNS解析
#ip daddr 192.168.0.0/16 udp dport != 53 return #由代理接管DNS解析
ip daddr 192.168.0.0/16 return #代理不接管DNS解析
meta nfproto ipv4 udp dport { 123 } return #ntp对时,直通。有这一行就不用写xray规则。
ip protocol { tcp,udp } tproxy ip to 127.0.0.1:12345 meta mark set 0x10 #匹配ip rule规则的fwmark
}
chain mangle_xray_output {
type route hook output priority mangle; policy accept;
ip daddr $RESERVED_IP return
#ip daddr 192.168.0.0/16 tcp dport != 53 return #由代理接管DNS解析
#ip daddr 192.168.0.0/16 udp dport != 53 return #由代理接管DNS解析
ip daddr 192.168.0.0/16 return #代理不接管DNS解析
meta nfproto ipv4 udp dport { 123 } return #ntp对时,直通。有这一行就不用写xray规则。
meta mark 0x12 return #匹配xray中outbounds的mark
ip protocol { tcp,udp } meta mark set 0x10 #匹配ip rule规则的fwmark
}
# 或者用 $LAN_IP 替换所有的 192.168.0.0/16 也可以。

nftables 透明拦截流量 | Kubernetes 实践指南

分类: singbox | 马斯克的赛博空间

mario-huang/sing-box-bypass-router-transparent-proxy-configuration: sing-box 旁路由 透明代理 配置

8.3. 使用 nftables 配置 NAT | 安全网络 | Red Hat Enterprise Linux | 8 | Red Hat Documentation

sing-box tproxy - 心底的河流

TProxy 透明代理 | Project X