前言
众所周知,wireguard工作在IP层,直接转发IP数据包。网络上的wireguard部署教程通常基于iptables的nat功能,但这样部署的服务器在网络质量较差时无法达到较快的TCP连接速度:因为直接转发IP数据包的工作模式下,tcp拥塞控制是源服务器和客户端控制的,wireguard只扮演数据包转发角色。
找遍了全网也没找到怎么解决,于是动脑尝试解决一下。
透明代理
https://en.wikipedia.org/wiki/Proxy_server#Transparent_proxy
透明代理是一种简单拦截应用层数据的方式。在本文中,我使用透明代理拦截经过wireguard的tcp数据包,使他通过系统TCP协议栈,从而可以获得BBR拥塞控制的好处。
配置路由表和iptables
以下是根据V2ray中透明代理教程修改而来的配置:
# 将进入透明代理的流量转发到lo
ip rule add fwmark 1 table 100
ip route add local 0.0.0.0/0 dev lo table 100
ip -6 rule add fwmark 1 table 100
ip -6 route add local ::/0 dev lo table 100
iptables -t mangle -N V2RAY
ip6tables -t mangle -N V2RAY
# 设置透明代理
ip6tables -t mangle -A V2RAY -s fc00:ffff::/64 -p tcp -j TPROXY --on-port 12345 --tproxy-mark 1
iptables -t mangle -A V2RAY -s 192.168.254.0/24 -p tcp -j TPROXY --on-port 12345 --tproxy-mark 1
iptables -t mangle -A PREROUTING -j V2RAY
ip6tables -t mangle -A PREROUTING -j V2RAY
其中fc00:ffff::/64和192.168.254.0/24是wireguard客户端的子网;只有从wireguard客户端发出的流量经过透明代理;UDP不需要透明代理来获得加速。
可以直接使用V2ray的透明代理功能,但截至本文发出时V2ray的这个功能存在内存泄露问题:
{
"inbounds": [
{
"port": 12345,
"protocol": "dokodemo-door",
"settings": {
"network": "tcp,udp",
"followRedirect": true
},
"streamSettings": {
"sockopt": {
"tproxy": "tproxy",
"mark":255
}
}
}
],
"outbounds": [
{
"protocol": "freedom",
"streamSettings": {
"sockopt": {
"mark": 255
}
}
}
]
}