一种基于抄袭配置文件的透明代理配置方式 & 近况汇报

一种基于抄袭配置文件的透明代理配置方式 & 近况汇报

RayAlto OP

1. 《一种基于照搬配置文件的透明代理配置方式》

碧蓝档案国际服 5 周年

最近几个月在玩 Steam 平台的碧蓝档案,一开始用传统的 *_proxy 环境变量是可以正常运行的,但最近登陆越来越卡,最近几天要重试好几次才能登陆进去,我怀疑是(最后也确实是)一些组件封装了自己的网络层,没有读环境变量,所以没走代理。我寻思透明代理这一块是绕不过去了。

1.1. 背景

之前用透明代理是 Shadowsocks 时代给树莓派刷了 OpenWRT ,里面有开箱即用的透明代理,确实方便,后来自己用 ArchLinux DIY 路由器就没搞过透明代理,因为我完全不了解 iptables 啥的,看别人的博客都是需要一大堆 iptables 指令,每一条我都不知道什么意思,所以没敢搞,但现在不一样了, AI 太好用了你们知道吗, ChatGPT 能帮我给每一行指令写出注释,所以我大胆地抄了 XTLS 的教程,最终是 works 的,所以想分享一下

我家里的网络大概是这样的:

网络拓扑

关于我的 NAS 的信息可以在这里这里这里看到。

1.2. Xray 客户端配置

Xray 服务端不需要变动,新增一份用于透明代理的客户端配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
{
"dns": {
"hosts": {
"你的 VPS 的域名": "你的 VPS 的 IP",
"可以有很多": "可以有很多"
},
"servers": [
{ // 国内 DNS
"address": "223.5.5.5",
"domains": ["geosite:cn"],
"expectIPs": ["geoip:cn"]
},
{ // 境外 DNS
"address": "8.8.8.8",
"domains": ["geosite:geolocation-!cn"]
}
]
},

"inbounds": [
{ // TProxy
"tag": "tproxy",
"port": 12345, // 这里选了 12345 端口
"protocol": "dokodemo-door",
"settings": {
"network": "tcp,udp",
"followRedirect": true
},
"sniffing": {
"enabled": true,
"destOverride": ["http", "tls"]
},
"streamSettings": {
"sockopt": {
"tproxy": "tproxy"
}
}
}
],

"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [

{ // 劫持所有 DNS 流量走 dns-out 出口
"ruleTag": "tproxy-dns",
"inboundTag": ["tproxy"],
"outboundTag": "dns-out",
"port": 53
},

{ // 境外 DNS 走代理
"ruleTag": "DNS-8-8-8-8",
"outboundTag": "proxy",
"ip": ["8.8.8.8"],
"port": "53"
},
{ // 境内 DNS 直连
"ruleTag": "DNS-223-5-5-5",
"outboundTag": "direct",
"ip": ["223.5.5.5"],
"port": "53"
},

{
"ruleTag": "Block",
"outboundTag": "block",
"domain": [
"geosite:category-ads-all"
]
},

{
"ruleTag": "Direct-Domain",
"outboundTag": "direct",
"domain": [
"geosite:cn",
"geosite:private",
"domain:可以加上你的 VPS 域名"
]
},
{
"ruleTag": "Direct-IP",
"outboundTag": "direct",
"ip": [
"geoip:cn",
"geoip:private",
"可以加上你的 VPS IP"
]
},

]
},

"outbounds": [

{ // 出口第一个条目,如果流量没有命中上面任何 rule ,则默认走这个
"tag": "proxy",
"protocol": "vless",
"settings": {
// ...
},
"streamSettings": {
// ...
"sockopt": {
"mark": 2 // 打上 2 标记出口流量,避免又被发回 Xray
}
}
},

{
"tag": "direct",
"protocol": "freedom",
"settings": {
"domainStrategy": "UseIPv4"
},
"streamSettings": {
"sockopt": {
"mark": 2 // 打上 2 标记出口流量,避免又被发回 Xray
}
}
},

{
"tag": "block",
"protocol": "blackhole",
"response": {
"type": "http"
}
},

{ // 这里没太搞懂,按理来说这么设置会导致所有 DNS 请求都走下面的 8.8.8.8 ,但实测 DNS 请求貌似是有国内/境外的分流的
"tag": "dns-out",
"protocol": "dns",
"settings": {
"address": "8.8.8.8"
},
"streamSettings": {
"sockopt": {
"mark": 2 // 打上 2 标记出口流量,避免又被发回 Xray
}
}
}

]
}

保存到 xray 配置目录,比如我保存到了 /etc/xray/tproxy.json

1.3. 路由配置

1
2
3
4
# 给路由表 100 添加一条默认本地路由,所有目标地址都走本地回环
ip route add local default dev lo table 100
# 添加一条规则:所有标记为 1 的数据包都走路由表 100
ip rule add fwmark 1 table 100

现在所有打上标记 1 的数据包都会走本地回环,而不是外部网关,以便后续 Xray 接收。

1.4. 配置 Netfilter

配置 Netfilter ,我用 nftables :

注意:我家路由用的是 192.168.1.0/24 子网,所以下面 nftables 配置 24-25, 33-34 行写了 192.168.0.0/16 是可以正常工作的,如果你的路由使用其他子网,就可能需要改一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#!/usr/bin/nft -f

flush ruleset

# 保留 IP 段(不走代理)
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
}

table ip xray { # IPv4 表,名为 xray
chain prerouting { # prerouting 链(所有入口流量)
type filter hook prerouting priority mangle; policy accept;
# 排除保留 IP 段
ip daddr $RESERVED_IP return
# 排除目标地址为 192.168.0.0/16 且端口并非 53 的流量(劫持 DNS 流量)
ip daddr 192.168.0.0/16 tcp dport != 53 return
ip daddr 192.168.0.0/16 udp dport != 53 return
# 所有其他流量 tproxy 到 127.0.0.1:12345 ,设置标记 1 (后续会根据上面添加的路由规则进入路由表 100 进入本地回环)
ip protocol tcp tproxy to 127.0.0.1:12345 meta mark set 1
ip protocol udp tproxy to 127.0.0.1:12345 meta mark set 1
}
chain output { # 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
ip daddr 192.168.0.0/16 udp dport != 53 return
# 排除标记为 2 的
meta mark 2 return
ip protocol tcp meta mark set 1
ip protocol udp meta mark set 1
}
}

1.5. 透明代理客户端

这样就完成了透明代理配置,需要科学上网的设备只需要配置这台机器为网关 & DNS即可,如我的台式机用 netctl ,我的 NAS 使用 192.168.1.222 :

1
2
3
# ...
Gateway='192.168.1.222'
DNS=('192.168.1.222')

1.6. 持久化

把上面的 nftable 保存成一个文件,比如我保存到了 xray 配置目录里 /etc/xray/nft.conf ,然后搞一个 systemd unit

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[Unit]
Description=xray-nftables
Documentation=man:nft(8) http://wiki.nftables.org
Wants=network-pre.target
Before=network-pre.target shutdown.target
Conflicts=shutdown.target
DefaultDependencies=no

[Service]
Type=oneshot
RemainAfterExit=yes
StandardInput=null
ProtectSystem=full
ProtectHome=true
ExecStart=/usr/bin/nft -f /etc/xray/nft.conf ; /usr/bin/ip route add local default dev lo table 100 ; /usr/bin/ip rule add fwmark 1 table 100
ExecReload=/usr/bin/nft -f /etc/xray/nft.conf
ExecStop=/usr/bin/nft flush ruleset ; /usr/bin/ip route del local default dev lo table 100 ; /usr/bin/ip rule del table 100

[Install]
WantedBy=sysinit.target

设置成自动运行

1
2
systemctl enable xray@tproxy
systemctl enable xray-nftables

2. 近况汇报

变身 995 社畜快一年了

TODO