介绍

  • 如果你不知道V2Ray是什么,欢迎移步至官网学习:Project V
  • 本文重点在软路由设备上部署时遇到的一些配置,特此记录,方便以后使用
  • 配置涉及防火墙的操作,请务必明确你执行的防火墙命令的效果,别搞得自己无法登陆设备
  • 这里不讨论安装软件的细节,只记录相关配置,默认读者知晓如何安装V2Ray
  • 此教程不使用ssl证书来做安全验证

服务端配置

这里的服务端是一个VPS,服务端配置非常简单
服务端配置文件config.json如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
"inbounds": [
{
"port": 1088, # 这里配置端口号
"protocol": "vmess",
"settings": {
"clients": [
{
"id": "xxx", # 这里可以使用标准UUID,通过 cat /proc/sys/kernel/random/uuid 生成一个即可
"alterId": 0
}
]
}
}
],
"outbounds": [
{
"protocol": "freedom",
"settings": {}
}
]
}

客户端配置

客户端配置是在软路由上进行配置,所以有两块内容

  1. 配置V2Ray客户端
  2. 配置全局透明代理

配置V2Ray客户端

客户端配置文件config.json如下

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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
{
"log": {
"loglevel": "warning"
},
"inbounds": [
{
"tag":"transparent",
"port": 12345,
"protocol": "dokodemo-door",
"settings": {
"network": "tcp,udp",
"followRedirect": true
},
"sniffing": {
"enabled": true,
"destOverride": [
"http",
"tls"
]
},
"streamSettings": {
"sockopt": {
"tproxy": "tproxy",
"mark":255
}
}
},
{
"port": 1080,
"protocol": "socks",
"sniffing": {
"enabled": true,
"destOverride": ["http", "tls"]
},
"settings": {
"auth": "noauth"
}
}
],
"outbounds": [
{
"tag": "proxy",
"protocol": "vmess",
"settings": {
"vnext": [
{
"address": "xxxxx", # 服务端的IP,这里就是VPS的IP
"port": 1088, # 服务端配置的端口号
"users": [
{
"id": "xxxxx", # 这里的id和服务端配置文件中的必须相同
"alterId": 0, # 这个值不要修改
"security": "auto"
}
]
}
]
},
"streamSettings": {
"sockopt": {
"mark": 255
}
},
"mux": {
"enabled": true
}
},
{
"tag": "direct",
"protocol": "freedom",
"settings": {
"domainStrategy": "UseIP"
},
"streamSettings": {
"sockopt": {
"mark": 255
}
}
},
{
"tag": "block",
"protocol": "blackhole",
"settings": {
"response": {
"type": "http"
}
}
},
{
"tag": "dns-out",
"protocol": "dns",
"streamSettings": {
"sockopt": {
"mark": 255
}
}
}
],
"dns": {
"hosts": { # 这里配置dns的本地解析,如果不需要,删除hosts块即可
"xxxx": "ip"
},
"servers": [
{
"address": "223.5.5.5",
"port": 53,
"domains": [
"geosite:cn",
"ntp.org"
]
},
{
"address": "114.114.114.114",
"port": 53,
"domains": [
"geosite:cn",
"ntp.org"
]
},
{
"address": "8.8.8.8",
"port": 53,
"domains": [
"geosite:geolocation-!cn"
]
},
{
"address": "1.1.1.1",
"port": 53,
"domains": [
"geosite:geolocation-!cn"
]
}
]
},
"routing": {
"domainStrategy": "IPIfNonMatch",
"domainMatcher": "mph",
"rules": [
{
"type": "field",
"inboundTag": [
"transparent"
],
"port": 53,
"network": "udp",
"outboundTag": "dns-out"
},
{
"type": "field",
"inboundTag": [
"transparent"
],
"port": 123,
"network": "udp",
"outboundTag": "direct"
},
{
"type": "field",
"ip": [ # 这里添加不走代理的IP
"223.5.5.5",
"114.114.114.114",
],
"outboundTag": "direct"
},
{
"type": "field",
"ip": [ # 这里添加走代理的IP
"8.8.8.8",
"1.1.1.1"
],
"outboundTag": "proxy"
},
{
"type": "field",
"domain": [ # 这里用来过滤广告,如果不想内网打开某个网页,可以添加域名到这里
"geosite:category-ads-all"
],
"outboundTag": "block"
},
{
"type": "field",
"protocol":["bittorrent"],
"outboundTag": "direct"
},
{
"type": "field",
"outboundTag": "Proxy",
"domain": [ # 这里添加走代理的域名
"full:www.icloud.com",
"domain:icloud-content.com",
"geosite:geolocation-!cn",
"geosite:google"
]
},
{
"type": "field",
"ip": [ # 这里添加不走代理的IP
"geoip:private",
"geoip:cn",
"2.2.2.2"
],
"outboundTag": "direct"
},
{
"type": "field",
"domain": [ # 这里添加不走代理的域名
"geosite:cn",
"geosite:private",
"geosite:tld-cn",
"geosite:icloud",
"geosite:category-games@cn",
"v2ray_server.com"
],
"outboundTag": "direct"
},
{
"type": "field",
"outboundTag": "proxy",
"network": "tcp,udp"
}
]
}
}

这份配置文件实现的功能:

  • 监听本地1080端口,将访问1080口的流量进行过滤和转发,没有全局代理的情况下,设备可以单独配置代理使用
  • 设置透明代理TPROXY方式和监听12345端口
  • 设置DNS转发
  • 通过路由规则文件进行分发国内域名和ip直连,国外转发,广告阻塞

配置文件中使用的路由规则文件是加强版,具体内容见V2Ray 路由规则文件加强版

配置全局透明代理

配置全局代理的思路是将所有UDP和TCP报文全部交给V2Ray进行处理,通过iptables来实现
写一个脚本统一实现,可以代理ipv4,也可以代理ipv6,自行决定:

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
#!/bin/bash

TEMPFILE="/run/iptrestorebak"

SetIpv4Rules() {
# 设置策略路由 v4
ip rule add fwmark 1 table 100
ip route add local 0.0.0.0/0 dev lo table 100

# 代理局域网设备 v4
iptables -t mangle -N V2RAY
iptables -t mangle -A V2RAY -d 127.0.0.1/32 -j RETURN
iptables -t mangle -A V2RAY -d 224.0.0.0/4 -j RETURN
iptables -t mangle -A V2RAY -d 255.255.255.255/32 -j RETURN
iptables -t mangle -A V2RAY -d 192.168.0.0/16 -p tcp -j RETURN # 这一条和下一条规则用来过滤掉本地局域网服务,不需要走代理。如果有多个网段,都进行配置
iptables -t mangle -A V2RAY -d 192.168.0.0/16 -p udp ! --dport 53 -j RETURN
iptables -t mangle -A V2RAY -j RETURN -m mark --mark 0xff
iptables -t mangle -A V2RAY -p udp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1
iptables -t mangle -A V2RAY -p tcp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1
iptables -t mangle -A PREROUTING -j V2RAY

# 代理网关本机 v4
iptables -t mangle -N V2RAY_MASK
iptables -t mangle -A V2RAY_MASK -d 224.0.0.0/4 -j RETURN
iptables -t mangle -A V2RAY_MASK -d 255.255.255.255/32 -j RETURN
iptables -t mangle -A V2RAY_MASK -d 192.168.0.0/16 -p tcp -j RETURN # 这一条和下一条规则用来过滤掉本地局域网服务,不需要走代理。如果有多个网段,都进行配置
iptables -t mangle -A V2RAY_MASK -d 192.168.0.0/16 -p udp ! --dport 53 -j RETURN
iptables -t mangle -A V2RAY_MASK -j RETURN -m mark --mark 0xff
iptables -t mangle -A V2RAY_MASK -p udp -j MARK --set-mark 1
iptables -t mangle -A V2RAY_MASK -p tcp -j MARK --set-mark 1
iptables -t mangle -A OUTPUT -j V2RAY_MASK

# 新建 DIVERT 规则,避免已有连接的包二次通过 TPROXY,理论上有一定的性能提升 v4
iptables -t mangle -N DIVERT
iptables -t mangle -A DIVERT -j MARK --set-mark 1
iptables -t mangle -A DIVERT -j ACCEPT
iptables -t mangle -I PREROUTING -p tcp -m socket -j DIVERT
}

CleanIpv4Rules() {
ip route del local 0.0.0.0/0 dev lo table 100
ip rule del fwmark 1 table 100
iptables-save | grep -vE 'V2RAY|DIVERT' > ${TEMPFILE}
iptables-restore < ${TEMPFILE}
rm -f ${TEMPFILE}
}

SetIpv6Rules() {
# 设置策略路由 v6
ip -6 rule add fwmark 1 table 106
ip -6 route add local ::/0 dev lo table 106

# 代理局域网设备 v6
ip6tables -t mangle -N V2RAY6
ip6tables -t mangle -A V2RAY6 -d ::1/128 -j RETURN
ip6tables -t mangle -A V2RAY6 -d fe80::/10 -j RETURN
ip6tables -t mangle -A V2RAY6 -d fd00::/8 -p tcp -j RETURN # 这一条和下一条规则用来过滤掉本地局域网服务,不需要走代理。如果有多个网段,都进行配置
ip6tables -t mangle -A V2RAY6 -d fd00::/8 -p udp ! --dport 53 -j RETURN
ip6tables -t mangle -A V2RAY6 -j RETURN -m mark --mark 0xff
ip6tables -t mangle -A V2RAY6 -p udp -j TPROXY --on-ip ::1 --on-port 12345 --tproxy-mark 1
ip6tables -t mangle -A V2RAY6 -p tcp -j TPROXY --on-ip ::1 --on-port 12345 --tproxy-mark 1
ip6tables -t mangle -A PREROUTING -j V2RAY6

# 代理网关本机 v6
ip6tables -t mangle -N V2RAY6_MASK
ip6tables -t mangle -A V2RAY6_MASK -d fe80::/10 -j RETURN
ip6tables -t mangle -A V2RAY6_MASK -d fd00::/8 -p tcp -j RETURN # 这一条和下一条规则用来过滤掉本地局域网服务,不需要走代理。如果有多个网段,都进行配置
ip6tables -t mangle -A V2RAY6_MASK -d fd00::/8 -p udp ! --dport 53 -j RETURN
ip6tables -t mangle -A V2RAY6_MASK -j RETURN -m mark --mark 0xff
ip6tables -t mangle -A V2RAY6_MASK -p udp -j MARK --set-mark 1
ip6tables -t mangle -A V2RAY6_MASK -p tcp -j MARK --set-mark 1
ip6tables -t mangle -A OUTPUT -j V2RAY6_MASK

# 新建 DIVERT 规则,避免已有连接的包二次通过 TPROXY,理论上有一定的性能提升 v6
ip6tables -t mangle -N DIVERT
ip6tables -t mangle -A DIVERT -j MARK --set-mark 1
ip6tables -t mangle -A DIVERT -j ACCEPT
ip6tables -t mangle -I PREROUTING -p tcp -m socket -j DIVERT
}

CleanIpv6Rules() {
ip -6 route del local ::/0 dev lo table 106
ip -6 rule del fwmark 1 table 106
ip6tables-save | grep -vE 'V2RAY|DIVERT' > ${TEMPFILE}
ip6tables-restore < ${TEMPFILE}
rm -f ${TEMPFILE}
}

CleanProxyRules() {
CleanIpv4Rules
CleanIpv6Rules
}

SetProxyRules() {
# 检查防止重复配置
if iptables-save | grep V2RAY > /dev/null 2>&1; then
exit 0
fi
SetIpv4Rules
SetIpv6Rules
}

case "$1" in
on)
SetProxyRules
;;
off)
CleanProxyRules
;;
*)
echo "Wrong para, only on or off"
exit 1
;;
esac

该配置脚本和V2Ray客户端配套使用,一定注意!

执行脚本命令进行添加和删除对应的规则:

1
2
3
4
5
# 添加规则
bash tproxy.sh on

# 删除规则
bash tproxy.sh off

systemd管理全局代理

使用systemd的服务进行管理,参考配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[Unit]
Description=V2Ray Service
Documentation=https://www.v2fly.org/
After=network.target nss-lookup.target

[Service]
User=nobody
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
NoNewPrivileges=true
ExecStartPre=/usr/local/etc/v2ray/tproxy.sh on
ExecStart=/usr/local/bin/v2ray run -config /usr/local/etc/v2ray/config.json
ExecStopPost=/usr/local/etc/v2ray/tproxy.sh off
RestartSec=30
Restart=on-failure
RestartPreventExitStatus=23

[Install]
WantedBy=multi-user.target

防火墙配置

如果存在防火墙,可先将防火墙关闭,等V2Ray调试完成后再打开
在UFW防火墙中,需要去掉部分规则,否则会存在部分网络无法访问:
/etc/ufw/before.rules配置中注释掉所有ufw-not-local规则
接着重新加载即可ufw reload

参考