Youtube已经全面普及AV1了, 然而有部分"极其先进"的OTT平台还在用H264. 30M的带宽Youtube可以看到8K30, 而H264编码的就只能看到1080P60...想要流畅播放4K30的H264需要50M的带宽, 每个月也要花费比AV1更多的流量.
云计算大厂为了防止自家VPS被用来开"国际机场", 推出了一系列上行带宽只有30M的轻量云服务.
其中阿里云是30M对等一点都不给大家薅, Ucloud 50M/30M, 腾讯云 100M/30M...
价格便宜, 稳定性超强, 就是连流畅看个高清视频的带宽都不够.
传统的PCC负载均衡, 单个线程无法切割只能通过其中一条线路送到对面. 出现一条线路满载, 另一条线路空载是日常.
而MPTCP可以均匀分配单个线程的数据, 完美解决了PCC在流媒体收看与推流无法平分流量的痛点.
只要轻量云下行比上行带宽大, 同区域虚拟机内网可互联且流量不计费, 那我们就可以用MPTCP愉快的叠加上行带宽, 将其中一台作为出口即可. 反正那些轻量云都是单向流量计费, 只算入网部分.
本案例虚拟机配置方式如下
国内部分采用RouterOS作为主路由, 同一个二层内有一台Debian 12 6.10内核已编译BBRv3, VPS作为 Xray 客户端(旁路由).
海外部分采用2台surfercloud(Ucloud)轻量云VPS, 带宽均为50/30M, 系统Debian 11.7.
Part 1 - 配置系统环境
首先进控制面板开2台Debian虚拟机, 其中一台内核用xanmod 升级到 6.10, 并开启BBRv3+fq.
推荐这个一键脚本
wget -O tcpx.sh "https://github.com/ylx2016/Linux-NetSpeed/raw/master/tcpx.sh" && chmod +x tcpx.sh && ./tcpx.sh
先选32 安装核心, 重启后选11 或者 12 启动 BBRv3+FQ.
另一台直接DD成RouterOS方便起隧道:
wget --no-check-certificate https://download.mikrotik.com/routeros/6.45.8/chr-6.45.8.img.zip -O chr.img.zip && \
gunzip -c chr.img.zip > chr.img && \
mount -o loop,offset=512 chr.img /mnt && \
ADDRESS=`ip addr show eth0 | grep global | cut -d' ' -f 6 | head -n 1` && \
GATEWAY=`ip route list | grep default | cut -d' ' -f 3` && \
echo "/ip address add address=$ADDRESS interface=[/interface ethernet find where name=ether1]
/ip route add gateway=$GATEWAY
" > /mnt/rw/autorun.scr && \
umount /mnt && \
echo u > /proc/sysrq-trigger && \
dd if=chr.img bs=9216 of=/dev/vda && \
reboot
DD 完成后把RouterOS 更新到6.49最新版, 别忘了登录Mikrotik账号配置License.
Part 2 : 配置网络环境
三台虚拟机GRE隧道互连打通内网.
GRE1 : 国内RouterOS动态IP - 海外Debian VPS
RouterOS侧需关闭KeepAlive功能.
海外Debian 使用这样的命令起GRE:
ip tunnel add gre1 mode gre remote 58.32.32.1 local 10.41.120.57 ttl 255
ip addr add 10.13.2.1/24 dev gre1
ip link set gre1 up
ip link set gre1 mtu 1418
Remote Address 先根据实际填写, 第二行 10.13.2.1/24 改成自己喜欢的内网IP段.
需要注意的是 MTU不会自动协商, 取国内PPPoe后的MTU 手动设定.
互ping一下 , 通了之后我们配置ssh-exec通过RouterOS 遥控Linux修改GRE隧道的 Remote Address.
先在Debian下生成密钥对:
ssh-keygen -t rsa -m PEM
目录就用默认的, 然后自己设个喜欢的密码.
编辑 /etc/ssh/sshd_config
AuthorizedKeysFile .ssh/id_rsa.pub
PubkeyAuthentication yes
完事后service ssh restart, 这台VPS就开启了密钥登录, 此类教程网上很多, 根据系统不同方法略有差异.
把刚才生成的 id_rsa 和 id_rsa.pub 通过自己喜欢的方式下载到本地, 用Winbox上传到RouterOS:
System - Users 菜单里导入私钥用户名这里写RouterOS的管理员账号, 一般默认admin不用改.
Winbox 里开个Terminal使用以下命令进行测试:
/system ssh-exec address=DebianVPS的IP user=root command="ifconfig"
Terminal里返回对端的网卡配置那说明ssh服务端配置正确, 开始配置RouterOS脚本:
:global ipaddr [/ip address get [/ip address find interface=PPPoe名称] address]
:set ipaddr [:pick $ipaddr 0 ([len $ipaddr] -3)]
/system ssh-exec address=对端IP user=root command="ip tunnel change gre1 remote $ipaddr"
这个脚本的工作流程详细为大家讲解一下:
第一步 : 找到PPPoe拨号的公网IP
第二步 : 把那个IP地址定义为$ipaddr
第三步 : 通过ssh-exec 发送修改隧道对端IP的指令
脚本根据自己的实际情况编辑一下放到 System - Script里:
你可以把这个脚本用Scheduler几分钟执行一次, 也可以在PPPoe Profile里, 每次拨号成功后执行.
我这里用了delay, 8秒后重新执行一次, 确保指令发到对面.
修改相同的IP地址, 系统自动判定无须修改, 网络不中断, 所以我们可以放心的重复执行.
/system script run RemoteGRE
:delay 8000ms;
/system script run RemoteGRE
先把最复杂的一条GRE隧道配好了, 接下来的2条很简单.
GRE2 : 国内RouterOS动态IP - 海外RouterOS VPS
两头RouterOS, 这是最简单的, 用DDNS做Remote Address即可:
使用DDNS的方法有很多, 自行参考网络教程即可. 或者可以硬核一些, 采用与GRE相同的ssh-exec遥控方式.
两头分别给一个内网IP地址:
互ping一下, 通了就配下一条~
GRE3 : 最后还有一条2台VPS之间内网互联的GRE隧道(可根据实际情况省略)
有群友反馈, Ucloud可以2层直接 next-hop 另一个内网IP(设为网关).
不一定每家IDC都能二层互联, 大家可以先尝试, 不通的话再打一条GRE隧道也让费不了多少系统资源.
RouterOS那一头直接写Debian VPS的内网IP, 关闭KeepAlive, 别忘了配个内网地址~
Debian 那头通过命令行配置:
ip tunnel add gre3 mode gre remote 10.41.126.91 local 10.41.120.57 ttl 255
ip addr add 10.13.1.1/24 dev gre3
ip link set gre3 up
互ping一下 , 通了之后GRE隧道配置工作结束.
Part 3 : 配置静态路由
很多人都注
海外Debian那台修改loopback地址. 大家都是127.0.0.1, 当然要换一个识别度比较高的地址:
ifconfig lo 11.4.5.14 up
我们要让国内的那台RouterOS分别经由GRE1访问这个IP, 在另一张路由表中经由GRE2-GRE3访问这个IP~
先到IP-Route建路由表(以tw1 和 tw2 两张路由表为例):
分别为2个GRE隧道配置SRC-NAT:
接下来要配置国内作为MPTCP客户端的Debian虚拟机~
这里需要2个网络出口, 以eth0 和 eth0.235为例.
首先配置一个VLAN interface, 编辑 /etc/network/interfaces . 这一步根据系统不同方法会有区别, 请自行查找网络教程. 在eth0上配VLAN 235:
auto eth0.235
iface eth0.235 inet static
address 192.168.235.112/24
RouterOS在与Debian虚拟机同一个二层下的接口创建相同的VLAN接口, 再分配一个IP地址:
互ping一下, 通了之后配路由规则:
这样从eth0访问11.4.5.14走tw1, 从eth0.235(vlan235)访问11.4.5.14走tw2.
配置海外RouterOS上到达11.4.5.14的路由:
先为GRE3配置SRC-NAT:
IP - Route, 在Main 表里直创建路由, Gateway即GRE3对端IP:
本地分别通过 eth0 与 eth0.35 MTR一下~
直达海外Debian VPS的那个出口只有一跳:
绕行RouterOS的那个出口会多一跳:
Part 4 : 配置MPTCP
服务端(海外Debian VPS)这头的规则:
ip mptcp limits set subflows 8
ip mptcp limits set add_addr_accepted 8
limits 无脑全部调到最大值8,与性能无关。MPTCPv1规定最大8个子流。1个出口一个subflow,这是固定的,并不是说这个参数越大同一个出口可以生成的子流更多。
国内这头稍微复杂那么一点点, 先要配置一条路由规则:
ip route add 11.4.5.14 metric 1 nexthop via eth0对端IP dev eth0 weight 1 nexthop via vlan235对端IP dev eth0.235 weight 33
众所周知, 有了路由才能通TCP/UDP/MPTCP...以上这是一整条命令, weight 参数随意写, 不影响MPTCP的带宽的分配比例.
分别配置2个出口的subflow, 这里的IP即本地网卡IP:
ip mptcp endpoint add id 1 subflow fullmesh eth0IP dev eth0
ip mptcp endpoint add id 2 subflow fullmesh vlan235IP dev eth0.235
ip mptcp limits set subflows 8
ip mptcp limits set add_addr_accepted 8
Part 5 : 配置Xray-Core
节约时间, 服务端直接用一键脚本:
bash <(wget -qO- -o- https://github.com/233boy/Xray/raw/main/install.sh)
编辑配置文件 /etc/xray/config.json, listen地址自己修改后的loopback地址:
"inbounds": [
{
"tag": "api",
"port": 56359,
"listen": "11.4.5.14",
"protocol": "dokodemo-door",
"settings": {
"address": "11.4.5.14"
}
}
],
再修改脚本自动创建的出网配置文件, 在/etc/xray/conf文件夹中 ~
"streamSettings": 这一段里加上mptcp相关配置 :
"sockopt": {
"tcpMptcp": true
},
之后service xray restart, 成功运行的话, 服务端配置工作已经全部结束.
客户端的选择就多了, 可以用Clash.meta, Sing-box,未来还可以用dae. 只要你的系统支持MPTCP这些Socks类代理服务端就可以用. 比如你用的OpenWRT配的OpenClash, 系统把mptcp模块给阉割了, 就算OpenClash支持了MPTCP那也是毫无卵用的.
或者同样用 Xray做客户端, 方法和服务端一样, "streamSettings"添加和上面一摸一样的MPTCP参数即可.
这里还是提供一个参考配置, 自行根据Xray文档调成自己最喜欢的协议:
"outbounds": [
{
"tag": "VLESS-REALITY-52372.json",
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "11.4.5.14",
"port": 52372,
"users": [
{
"id": "7a504caf-06f7-425b-94f0-7f6d6e114514",
"encryption": "none",
"flow": "xtls-rprx-vision"
}
]
}
]
},
"streamSettings": {
"network": "tcp",
"security": "reality",
"realitySettings": {
"serverName": "www.amazon.com",
"fingerprint": "chrome",
"publicKey": "Nl1atxBfJlCecC8Z3vr6oeTK8ZEc_ogxOwQ2I114514",
"shortId": "",
"spiderX": "/"
},
"sockopt": {
"tcpMptcp": true
}
}
},
{
"tag": "direct",
"protocol": "freedom"
}
]
Part 6 : 验证并保存配置
我这里采用的是不改变原有网络结构的方式, 通过原有的OpenClash旁路由下, 连接那台Debian VPS.
在作为Xray Client的那台VPS上再配一个 inbound 给OpenClash接入 :
"inbounds": [
{
"port": 2333,
"listen": "192.168.1.12",
"protocol": "shadowsocks",
"settings": {
"network": "tcp,udp",
"method": "none",
"password": "114514"
},
"sniffing": {
"enabled": true,
"destOverride": [
"http",
"tls"
]
}
}
],
在Clash里选择这条线路, 访问一下fast.com进行验证测试.
测速开始前在国内那台Debian上使用 ip mptcp monitor 命令:
看到 saddr4= 后面有2个不同的IP, MTCP的状态有 CREATED ESTABLISHED ANNOUNCED SF_ESTABLISHED, 那基本OK了.
本来应该在作为服务端的VPS上查看更直观, 然而Debian 11 没有 ip mptcp monitor这个命令, 要升级到Debian 12才有.
故障排查 :
全部是 CLOSED状态 : 说明Xray-Core 客户端或服务端参数不对.
SF_ESTABLISHED 状态没有 : 说明 MPTCP subflow的 endpoint配置错误, 或者这条线路的路由不通.
什么都没有 : 说明没有数据使用MPTCP. 可能是数据根本没发到这台VPS, 检查Xray的 Inbound参数,也有可能是Outbound部分的MPTCP参数配置错误.
再进RouterOS, 看一下流量是否平分到2条GRE隧道:
最后我们需要将一切参数保存并在开机时自动添加运行, 可以写在很多不同的地方, 自行参考网络教程.
海外Debian服务端 :
PostUp = ifconfig lo 11.4.5.14 up
PostUp = ip tunnel add gre3 mode gre remote 10.41.126.91 local 10.41.120.57 ttl 255
PostUp = ip addr add 10.13.1.1/24 dev gre3
PostUp = ip link set gre3 up
PostUp = ip tunnel add gre1 mode gre remote 58.32.32.1 local 10.41.120.57 ttl 255
PostUp = ip addr add 10.13.2.1/24 dev gre1
PostUp = ip link set gre1 up
PostUp = ip link set gre1 mtu 1418
PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostUp = ip mptcp limits set subflows 8
PostUp = ip mptcp limits set add_addr_accepted 8
PostUp = service xray restart
国内Debian客户端 :
PostUp = ip route add 11.4.5.14 metric 1 nexthop via eth0对端IP dev eth0 weight 1 nexthop via vlan235对端IP dev eth0.235 weight 33
PostUp = ip mptcp endpoint add id 1 subflow fullmesh eth0IP dev eth0
PostUp = ip mptcp endpoint add id 2 subflow fullmesh vlan235IP dev eth0.235
PostUp = ip mptcp limits set subflows 8
PostUp = ip mptcp limits set add_addr_accepted 8
PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostUp = iptables -t nat -A POSTROUTING -o eth0.235 -j MASQUERADE
网络配置sysctl 必要参数 :
net.ipv4.ip_forward=1
net.core.default_qdisc=fq
net.ipv4.tcp_congestion_control=bbr
恭喜你完成了地狱般最简单的MPTCP实例配置~