之前写过一篇搭建V2RAY透明代理的文章,那时候搭建在树莓派上,这个树莓派至今还在使用,并且至今这个透明代理还可以使用,但是树莓派有个问题就是作为单臂路由时单程最大只能跑到2MB/s(树莓派2B+,这是唯一一个可以通过USB口带动的设备)。今天决定使用虚拟机重新搭建一个透明代理,给本机的其他虚拟机使用,这样其他虚拟机在操作docker、k8s的时候就不必担心网络不通畅的问题了。
服务端
关于V2Ray的使用方式比较多样,这里我选择比较推荐的VLESS-TCP-TLS-WS,这种配置不需要额外的Nginx等软件,并且在TCP模式认证失败时会自动回落到WS模式。关于服务端的配置可以参考这个模板。服务端可选开启BBR阻塞控制。
客户端
客户端配置比较复杂,这里分部分说明。
V2Ray客户端配置
服务端跑起来之后就可以考虑客户端了,这里客户端是重头戏,因为它要负责作为其他使用仅主机网络的虚拟机的网关,提供上网与代理服务。这里我是用TPROXY的方式进行透明代理。客户端配置如下:
{
"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":{
"udp":true
}
},
{
"port":1081,
"protocol":"http",
"sniffing":{
"enabled":true,
"destOverride":[
"http",
"tls"
]
}
}
],
"outbounds":[
{ // 出口代理,对应服务器的配置
"tag":"proxy",
"protocol":"vless",
"settings":{
"vnext":[
{
"address":"example.com",
"port":443,
"users":[
{
"id":"",
"encryption":"none",
"level":0
}
]
}
]
},
"streamSettings":{
"network":"tcp",
"security":"tls",
"tlsSettings":{
"serverName":"example.com"
},
"sockopt":{
"mark":255
}
}
},
{
"tag":"direct",
"protocol":"freedom",
"settings":{
"domainStrategy":"UseIP"
},
"streamSettings":{
"sockopt":{
"mark":255
}
}
}
],
"routing":{
"domainStrategy":"IPOnDemand",
"rules":[
{ // udp53的DNS查询直连
"type":"field",
"inboundTag":[
"transparent"
],
"port":53,
"network":"udp",
"outboundTag":"direct"
},
{ // udp123的NTP校时直连
"type":"field",
"inboundTag":[
"transparent"
],
"port":123,
"network":"udp",
"outboundTag":"direct"
},
{ // bt流量直连
"type":"field",
"protocol":[
"bittorrent"
],
"outboundTag":"direct"
},
{ // 中国及局域网ip直连
"type":"field",
"ip":[
"geoip:private",
"geoip:cn"
],
"outboundTag":"direct"
},
{ // 中国网站直连
"type":"field",
"domain":[
"geosite:cn"
],
"outboundTag":"direct"
}
]
}
}
配置文件可以先留存备用,下面来说负责透明代理的虚拟机。
虚拟机配置
由于透明代理的虚拟机并不负责其他负载,因此只分配给他1C1G,分配20GB硬盘,有两块网卡,一个是NAT模式,用于连接互联网,另一个是VMnet2,配置为仅主机模式,用于向其他虚拟机提供服务。系统选择了openSUSE Leap 15.3,使用XFS作为文件系统,2GB的交换空间,安装时不额外创建用户,关闭防火墙,配置VMnet2的静态IP为10.172.1.1/16,启用v4和v6转发。
安装完成后进行一个系统更新,如果源特别慢的话可以考虑使用清华源。这里选用Leap的原因是它比较稳定,不需要风滚草那样有事儿没事儿滚一滚。更新完成之后安装V2Ray,将上面的配置文件应用过去,这时候可以通过10.172.1.1:1080
这个端口来检查我们的代理配置是否正确。我这边测试使用该端口进行大约5MB/s的传输时,V2Ray占用CPU大约10%,网卡软中断占用1%。
接下来即可配置网络过滤规则了。
Netfilter配置(nftables)
与较为熟悉的iptables不同,nftables是更为新颖的一款代替品。但是使用nftables要求内核中具备nft_tproxy
和nft_socket
,如果lsmod | grep nft
命令中不包含这两个模块,那么需要创建对应的配置文件以开机启动。配置文件/etc/modules-load.d/tproxy.conf
:
nft_tproxy
nft_socket
该配置文件将会在开机时无条件加载这两个模块。
使用以下命令配置nftables:
# 设置策略路由
ip rule add fwmark 1 table 100
ip route add local 0.0.0.0/0 dev lo table 100
#代理局域网设备
nft add table v2ray
nft add chain v2ray prerouting { type filter hook prerouting priority 0 \; }
nft add rule v2ray prerouting ip daddr {127.0.0.1/32, 10.0.0.0/8, 100.64.0.0/10, 172.16.0.0/12, 192.168.0.0/16, 224.0.0.0/4, 255.255.255.255/32} return # 前往这些地址的包不需要被代理,其中包括私有IP和TailScale
nft add rule v2ray prerouting ip saddr {100.64.0.0/10, 172.16.0.0/12} return # 来自Docker和TailScale的流量不被代理
nft add rule v2ray prerouting mark 0xff return # 直连 0xff 流量
nft add rule v2ray prerouting meta l4proto {tcp, udp} mark set 1 tproxy to 127.0.0.1:12345 accept # 转发至 V2Ray 12345 端口
# DIVERT 规则,避免已有连接的包二次通过 TPROXY,理论上有一定的性能提升
nft add table filter
nft add chain filter divert { type filter hook prerouting priority -150 \; }
nft add rule filter divert meta l4proto tcp socket transparent 1 meta mark set 1 accept
完成后可以开启一台虚拟机测试一下,只保留一张仅主机网卡,然后设置网关为10.172.1.1
。测试通过之后先别着急走,由于这些配置在重启后会丢失,因此还需要一些操作来将其持久化:
mkdir -p /etc/nftables && nft list ruleset > /etc/nftables/rules.v4
cat > /etc/systemd/system/tproxyrule.service <<EOF
[Unit]
Description=Tproxy rule
After=network.target
Wants=network.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/sbin/ip rule add fwmark 1 table 100 ; /sbin/ip route add local 0.0.0.0/0 dev lo table 100 ; /usr/sbin/nft -f /etc/nftables/rules.v4
ExecStop=/sbin/ip rule del fwmark 1 table 100 ; /sbin/ip route del local 0.0.0.0/0 dev lo table 100 ; /usr/sbin/nft flush ruleset
[Install]
WantedBy=multi-user.target
EOF
systemctl enable tproxyrule
另外由于TProxy支持UDP代理,而UDP经常会出现数量比较多的情况,这时候可以考虑允许V2Ray打开更多文件,以避免出现too many open files
的错误。修改/etc/systemd/system/v2ray.service
文件,在[Service]
下加入如下两行:
LimitNPROC=500
LimitNOFILE=1000000
随后刷新并重启V2Ray:
systemctl daemon-reload && systemctl restart v2ray
至此,其余的虚拟机都可以使用仅主机模式,通过将网关设置为10.172.1.1
来上网了,同时安装Docker和k8s等软件还不需要额外设置镜像仓库,方便又好用,岂不美哉?
-全文完-
【歪门邪道】2022年使用openSUSE搭建V2RAY透明代理 由 天空 Blond 采用 知识共享 署名 - 非商业性使用 - 相同方式共享 4.0 国际 许可协议进行许可。
本许可协议授权之外的使用权限可以从 https://skyblond.info/about.html 处获得。
只会用,看不懂啊
需要一些操作来将其持久化