之所以选用ShadowsocksR,而不是V2ray,是因为V2ray的UDP协议是UDP over TCP,就是讲UDP数据包转换成TCP再进行传送,主要的问题是在Nat Full Cone表现上极为不好,无法穿透内网,也就无法实现多人联机。
在我测试的结果来看,给我的感觉是UDP数据包通过远端传送出去之后,并没有接到其他服务器响应回来的数据包,也没把数据包带回来,导致只会有去无返的数据包。
当然udp测试是通过的,因为数据包可以正常发出。又有其他人说是是因为多路数据包回应时,v2ray只能记住前一个的数据包的源地址,导致后面的错误返回属于无效包。
这是V2实现NAT穿透的技术讨论页,有兴趣可以自行关注:https://github.com/v2ray/v2ray-core/issues/1429#issuecomment-549667805
虽然V2ray在实际使用过程中TCP性能要比SSR要好很多,但是无法达成我们今天这个场景,所以我们还是选择SSR。
本文的内容主要讲网游加速器的原理和实际遇到的问题以及解决具体问题。
TG技术扯谈群组:https://t.me/EllerCN
一步到位教程
不想看细节的可以看这个一步到位教程,很简单。需要了解过程的查看下文。
注:将你的SSR端口配置为8388
下载通用(服务端/客户端):
mkdir /home/udp2raw-tunnel
cd /home/udp2raw-tunnel
wget https://github.com/wangyu-/udp2raw-tunnel/releases/download/20190716.test.0/udp2raw_binaries.tar.gz
tar -xzf udp2raw_binaries.tar.gz
mkdir /home/speederv2
cd /home/speederv2
wget https://github.com/wangyu-/UDPspeeder/releases/download/20190121.0/speederv2_binaries.tar.gz
tar -xzf speederv2_binaries.tar.gz
mkdir /home/kcptun
cd /home/kcptun
wget https://github.com/xtaci/kcptun/releases/download/v20191127/kcptun-linux-amd64-20191127.tar.gz
tar -zxf kcptun-linux-amd64-*.tar.gz
服务端运行脚本:
若服务端端口无冲突的情况下,该脚本不必修改可直接使用。
local_proxy
为代理加速的端口,如SSR的监听端口8388,也可以是其他你需要加速的端口。
cat >/home/jiasu_run.sh <<\EOF
#!/bin/bash
echo "KCP/SpeederV2/Udp2raw一键启动脚本[服务端]"
cd `dirname $0`
publish_ip="0.0.0.0" #服务端IP地址
publish_kcp=29900 #KCP对外端口
publish_udp2raw=6002 #UDP2RAW监听端口
local_proxy=8388 #加速的代理端口,如SSR的8388
local_speederv2=6001 #speederv2本地服务端口
param=$1
if [ ! -d "./pid" ];then
mkdir ./pid
fi
pid_kcptun=./pid/kcptun_$0.pid
pid_speederv2=./pid/speederv2_$0.pid
pid_udp2raw=./pid/udp2raw_$0.pid
function pid_exists(){
local exists=`ps aux | awk '{print $2}'| grep -w $1`
if [[ ! $exists ]]
then
return 0;
else
return 1;
fi
}
function pid_status(){
if [[ -f $1 ]];then
pid_exists `cat $1`
if [[ $? == 1 ]];then
echo -e "\t $2: \033[32m运行中\033[0m"
else
echo -e "\t $2: \033[31m已停止\033[0m"
fi
else
echo -e "\t $2: \033[31m已停止\033[0m"
fi
}
function stop(){
local pid=`cat $1`
kill -9 $pid
pid_exists $pid
if [[ $pid == 1 ]]
then
echo "停止任务失败"
fi
}
function start(){
./kcptun/server_linux_amd64 -l $publish_ip:$publish_kcp -t 127.0.0.1:$local_proxy -key "eller" -mtu 1400 -sndwnd 2048 -rcvwnd 2048 -mode fast2 >/dev/null 2>&1 &
pid=$!
echo $pid >$pid_kcptun
sleep 2
pid_exists $pid
if [ $? == 1 ];then
echo -e "KCP \033[32m启动成功\033[0m,对接端口:$publish_ip:$publish_kcp"
#echo "KCP 启动成功,对接端口:$remote_ip:$remote_kcp"
else
echo -e "KCP \033[33m启动失败\033[0m"
fi
./speederv2/speederv2_amd64 -s -l127.0.0.1:$local_speederv2 -r127.0.0.1:$local_proxy -k "eller" -f20:40 --timeout 1 >/dev/null 2>&1 &
pid=$!
echo $pid >$pid_speederv2
sleep 2
pid_exists $pid
if [ $? == 1 ];then
echo -e "SpeedV2 \033[32m启动成功\033[0m"
else
echo -e "SpeedV2 \033[33m启动失败\033[0m"
fi
./udp2raw-tunnel/udp2raw_amd64 -s -l$publish_ip:$publish_udp2raw -r 127.0.0.1:$local_speederv2 -a -k "eller" --raw-mode faketcp >/dev/null 2>&1 &
pid=$!
echo $pid >$pid_udp2raw
sleep 2
pid_exists $pid
if [ $? == 1 ];then
echo -e "UDP2RAW \033[32m启动成功\033[0m"
else
echo -e "UDP2RAW \033[33m启动失败\033[0m"
fi
}
function stop_proces(){
stop $pid_kcptun
stop $pid_speederv2
stop $pid_udp2raw
}
if [[ "start" == $param ]];then
echo "即将:启动脚本";
start
elif [[ "stop" == $param ]];then
echo "即将:停止脚本";
stop_proces;
elif [[ "restart" == $param ]];then
stop_proces
start
else
echo "当前配置(如不正确,请编辑脚本进行修改):"
echo -e "\t 服务端IP:$publish_ip"
echo -e "\t 服务端KCP端口: $publish_kcp"
echo -e "\t 服务端UDP2RAW端口: $publish_udp2raw"
echo -e "\t 本地加速端口: $local_proxy"
echo -e "\t 本地udp2raw端口:$local_speederv2"
echo "服务状态:"
pid_status $pid_kcptun "KCP"
pid_status $pid_speederv2 "speederv2"
pid_status $pid_udp2raw "udp2raw"
echo "使用方式: "
echo -e "\t运行服务:bash $0 start "
echo -e "\t停止服务:bash $0 stop "
echo -e "\t重启服务:bash $0 restart "
fi
EOF
客户端运行脚本:
这里的客户端一般为中继服务器,你也可以通过虚拟机来创建此服务,windows端连接这个"中继"服务器IP,即代理加速的端口即可,如:8388
注意修改脚本中的 “55.66.77.88
”为自己的服务器IP
cat >/home/jiasu_run.sh <<\EOF
#!/bin/bash
echo "KCP/SpeederV2/Udp2raw一键启动脚本[客户端]"
cd `dirname $0`
remote_ip="55.66.77.88" #远端IP地址
remote_kcp=29900 #远端KCP端口
remote_udp2raw=6002 #远端UDP2RAW端口
local_publish=8388 #本地公开端口,建议和服务端SSR一致便于理解
local_udp2raw=7004 #udp2raw本地服务端口
param=$1
if [ ! -d "./pid" ];then
mkdir ./pid
fi
pid_kcptun=./pid/kcptun_$0.pid
pid_speederv2=./pid/speederv2_$0.pid
pid_udp2raw=./pid/udp2raw_$0.pid
function pid_exists(){
local exists=`ps aux | awk '{print $2}'| grep -w $1`
if [[ ! $exists ]]
then
return 0;
else
return 1;
fi
}
function pid_status(){
if [[ -f $1 ]];then
pid_exists `cat $1`
if [[ $? == 1 ]];then
echo -e "\t $2: \033[32m运行中\033[0m"
else
echo -e "\t $2: \033[31m已停止\033[0m"
fi
else
echo -e "\t $2: \033[31m已停止\033[0m"
fi
}
function stop(){
local pid=`cat $1`
kill -9 $pid
pid_exists $pid
if [[ $pid == 1 ]]
then
echo "停止任务失败"
fi
}
function start(){
./kcptun/client_linux_amd64 -l :$local_publish -r $remote_ip:$remote_kcp -key eller -mtu 1400 -sndwnd 256 -rcvwnd 2048 -mode fast2 -conn 4 > /dev/null 2>&1 &
pid=$!
echo $pid >$pid_kcptun
sleep 2
pid_exists $pid
if [ $? == 1 ];then
echo -e "KCP \033[32m启动成功\033[0m,对接端口:$remote_ip:$remote_kcp"
#echo "KCP 启动成功,对接端口:$remote_ip:$remote_kcp"
else
echo -e "KCP \033[33m启动失败\033[0m"
fi
./speederv2/speederv2_amd64 -c -l0.0.0.0:$local_publish -r127.0.0.1:$local_udp2raw -f20:40 -k "eller" --mode 0 > /dev/null 2>&1 &
pid=$!
echo $pid >$pid_speederv2
sleep 2
pid_exists $pid
if [ $? == 1 ];then
echo -e "SpeedV2 \033[32m启动成功\033[0m"
else
echo -e "SpeedV2 \033[33m启动失败\033[0m"
fi
./udp2raw-tunnel/udp2raw_amd64 -c -l127.0.0.1:$local_udp2raw -r$remote_ip:$remote_udp2raw -k "eller" --raw-mode faketcp >/dev/null 2>&1 &
pid=$!
echo $pid >$pid_udp2raw
sleep 2
pid_exists $pid
if [ $? == 1 ];then
echo -e "UDP2RAW \033[32m启动成功\033[0m"
else
echo -e "UDP2RAW \033[33m启动失败\033[0m"
fi
}
function stop_proces(){
stop $pid_kcptun
stop $pid_speederv2
stop $pid_udp2raw
}
if [[ "start" == $param ]];then
echo "即将:启动脚本";
start
elif [[ "stop" == $param ]];then
echo "即将:停止脚本";
stop_proces;
elif [[ "restart" == $param ]];then
stop_proces
start
else
echo "当前配置(如不正确,请编辑脚本进行修改):"
echo -e "\t 远端IP:$remote_ip"
echo -e "\t 远端KCP端口: $remote_kcp"
echo -e "\t 远端UDP2RAW端口: $remote_udp2raw"
echo -e "\t 本地发布端口: $local_publish"
echo -e "\t 本地udp2raw端口:$local_udp2raw"
echo "服务状态:"
pid_status $pid_kcptun "KCP"
pid_status $pid_speederv2 "speederv2"
pid_status $pid_udp2raw "udp2raw"
echo "使用方式: "
echo -e "\t运行服务:bash $0 start "
echo -e "\t停止服务:bash $0 stop "
echo -e "\t重启服务:bash $0 restart "
fi
EOF
运行
服务端/客户端
chmod x /home/jiasu_run.sh
# 启动
bash /home/jiasu_run.sh start
# 停止
bash /home/jiasu_run.sh stop
# 重启
bash /home/jiasu_run.sh restart
使用截图
防火墙:
开放脚本中的:6002、29900端口。
SSTap连通性测试:
成功运行之后就可以通过,中继服务器IP:端口
来连接自己加速后的服务。
加速后的UDP服务,能有效减少丢包的情况。
下文为原始内容
网游加速器
一般网游加速器核心是将用户与游戏服务器的距离拉短,或经过稳定的中继服务器,优化路由提高连接稳定性。
即在选择服务器线路上,最好针对你所玩的游戏来选择合适的服务器。
以GTAV游戏举例,可以通过抓包获取到游戏的服务器地址。
conductor-prod.ros.rockstargames.com
patches.rockstargames.com
prod.cloud.rockstargames.com
prod.cs.ros.rockstargames.com
prod.p01sjc.pod.rockstargames.com
prod.p02sjc.pod.rockstargames.com
prod.ros.rockstargames.com
prod.ros.rockstargames.com
prod.telemetry.ros.rockstargames.com
prod.anticheat.ros.rockstargames.com
prod.badsport.ros.rockstargames.com
prod.modders.ros.rockstargames.com
prod.bans.ros.rockstargames.com
prod.report.ros.rockstargames.com
prod.reports.ros.rockstargames.com
prod.modder.ros.rockstargames.com
经过测试,无论你在世界何地,连接GTAV的服务器都需要连接telemetry服务器,我们通过全球ping获取这个服务器的IP地址。
推荐使用站长工具:
http://ping.chinaz.com/prod.telemetry.ros.rockstargames.com
发现服务器目的地都在西雅图或者波特兰两地,而这两地的实际位置也是很相近。
整理拿到服务器的IP地址列表
34.210.149.250
35.215.105.43
34.210.149.250
34.209.49.245
34.215.105.43
还有一个很重要的服务器,我们也进行全球ping尝试。
http://ping.chinaz.com/prod.ros.rockstargames.com
我们测出只有一个IP地址,也就是GTAV中最慢的 192.81.241.100
查看本地到该IP的路由跃点
可见,延迟有273以上,是非常高了(因为服务器禁ping,所以只参考最后一个可见跃点IP的延迟)
其实,我在此之前,测试尾号100的IP地址时,服务器所在地也是在西雅图/波特兰两地的,所以本教程依然以波特兰/西雅图为目的地说明。
所以我们需要解决的问题就是跳过中间这些默认的路由节点,直连到游戏服务器。那么可以采用西雅图或者波特兰的服务器,尽量保障本地到服务器之间是直连。
如果本地到波特兰是160ms的延迟,波特兰同市机房到GTAV服务器延迟为10ms。大致可以理解,延迟从274ms降到了170ms。
如果你选用亚马逊的服务器,且你有亚马逊内网专线的话,那么你可以得到更好的体验,毕竟可以看到最终路由到了亚马逊的机房中。
参照上文,我们可以选用洛杉矶/圣何塞的服务器,即广州-洛杉矶的服务器延迟 洛杉矶-西雅图的延迟。
在实际使用中我们还会遇到各种各样的网络拥堵情况,比如丢包严重,线路QOS,出口干扰等。
为了解决这些外界干扰情况,我们将使用一些其他工具将所需的数据包封装起来进行传输,从而减少外界对链接传输的干扰。
ShadowsocksR
SSR的配置教程有很多,本文不再多说,可以自行搜寻。
服务器信息
文中远端服务器IP:10.10.10.10
SSR端口:8388
KCP
kcp是一款TCP双端网络加速神器,可以有效将极差的网络环境改善,从而提升网络畅通率和链接速度。
该工具大致是开放一个端口将数据通过封装,经过UDP传输到达目的地,回路也是反向UDP回应。
具体参见开源项目:
https://github.com/xtaci/kcptun
由于是双端加速,我们需要在客户端和服务器分别部署,对于客户端还是推荐中转服务器,省去游戏机的繁琐配置。
KCP二进制文件:
https://github.com/xtaci/kcptun/releases
KCP安装方式服务器和客户端一样,区别于配置和启动方式不同,故下载安装如下:
mkdir /home/kcptun
cd /home/kcptun
wget https://github.com/xtaci/kcptun/releases/download/v20191127/kcptun-linux-amd64-20191127.tar.gz
tar -zxf kcptun-linux-amd64-*.tar.gz
服务器端:
cd /home/kcptun
cat > run.sh <<EOF
./server_linux_amd64 -l :29900 -t 127.0.0.1:8388 -key eller -mtu 1400 -sndwnd 2048 -rcvwnd 2048 -mode fast2 > kcptun.log 2>&1 &
EOF
cat > stop.sh <<EOF
PID=`ps -ef | grep server_linux_amd64 | grep -v grep | awk '{print $2}'`
if [[ "" != "$PID" ]]; then
echo "killing $PID"
kill -9 $PID
fi
EOF
KCP监听29900端口,并将数据转发给8388端口,eller是密匙需要和客户端一致,mode是加速模式,其他参数参见KCP官方介绍。
响应速度:
fast3 > [fast2] > fast > normal > default
有效载荷比:
default > normal > fast > [fast2] > fast3
中间 mode 参数比较均衡,总之就是越快越浪费带宽,推荐模式 fast2。
其他参数,请使用 ./server_linux_amd64 -h 查看,更深层次的参数调整需要理解 KCP 协议,并通过“隐藏参数”调整。
下面是作者给的配置样例,适用大部分ADSL接入(非对称上下行)的参数(实验环境电信100M ADSL)。其它带宽请按比例调整,比如 50M ADSL,把 CLIENT 的 -sndwnd -rcvwnd 减掉一半,SERVER 不变。
客户端:
cd /home/kcptun
cat > run.sh <<EOF
./client_linux_amd64 -l :12948 -r 10.10.10.10:29900 -key eller -mtu 1400 -sndwnd 256 -rcvwnd 2048 -mode fast2 -conn 4
EOF
cat > stop.sh <<EOF
PID=`ps -ef | grep client_linux_amd64 | grep -v grep | awk '{print $2}'`
if [[ "" != "$PID" ]]; then
echo "killing $PID"
kill -9 $PID
fi
EOF
其中10.10.10.10位服务器IP地址,需要将其更换掉。
启动
sh ./run.sh
停止
sh ./stop.sh
UDPSpeeder
UDPSpeeder是一款加速UDP流量的工具,上面那个KCP虽然是UDP传输但也只能传输TCP流量,所以我们需要这款工具将UDP流量也一并加速。
具体参见开源项目:
https://github.com/wangyu-/UDPspeeder
二进制文件下载:
https://github.com/wangyu-/UDPspeeder/releases
在安装部署方面,服务端和客户端也基本一致,只需要区别于启动参数即可。
mkdir /home/speederv2
cd /home/speederv2
wget https://github.com/wangyu-/UDPspeeder/releases/download/20190121.0/speederv2_binaries.tar.gz
tar -xzf speederv2_binaries.tar.gz
服务端:
cd /home/speederv2
cat > run.sh <<EOF
./speederv2_amd64 -s -l0.0.0.0:6001 -r127.0.0.1:8388 -k "passwd" -f2:4 --timeout 1 >error.txt 2>&1 &
EOF
其中的passwd可自行更改,需要保持客户端一致。
客户端:
cd /home/speederv2
cat > run.sh <<EOF
speederv2_amd64 -c -l0.0.0.0:7001 -r10.10.10.10:6001 -k "passwd" -f2:4 --timeout 1 >error.txt 2>&1 &
EOF
设监听本地7001端口作为UDP数据入口,本地连接远端服务器(10.10.10.10)的6001端口(speederv2端口)进行传送数据。
启动
sh ./run.sh
Udp2raw
Udp2raw是一款将UDP流量伪装工具,本身并没有加速功能,但在复杂的网络环境中,经过将UDP流量伪装改善成TCP流量(实际还是UDP传输)可以达到更稳定的传输。
具体参见开源项目:
https://github.com/wangyu-/udp2raw-tunnel
二进制文件下载:
https://github.com/wangyu-/udp2raw-tunnel/releases
通过上文,我们在成功配置了UDPSpeeder和KCP的基础上,我们再加上Udp2raw,将UDPSpeeder的流量混淆成TCP流量。
也可以一并将KCP也混淆了,但我不太推荐再混淆一层。因为本身KCP的速度就已经比较快了,再包一层会导致性能下降,网络也得不到好的提升,除非确实UDP QOS严重,可以尝试将KCP一并混淆。
mkdir /home/udp2raw-tunnel
cd /home/udp2raw-tunnel
wget https://github.com/wangyu-/udp2raw-tunnel/releases/download/20190716.test.0/udp2raw_binaries.tar.gz
tar -xzf udp2raw_binaries.tar.gz
服务端:
cd /home/udp2raw-tunnel
cat > run.sh <<EOF
./udp2raw_amd64 -s -l0.0.0.0:6002 -r 127.0.0.1:6001 -a -k "passwd" --raw-mode faketcp >error.txt 2>&1 &
EOF
需要说明下,在服务器端,6001端口为speederv2的监听端口,而speederv2连接的是SSR的8388端口。
如果要混淆KCP,那么可以使用这个配置:
cd /home/udp2raw-tunnel
cat > run.sh <<EOF
./udp2raw_amd64 -s -l0.0.0.0:6002 -r 127.0.0.1:6001 -a -k "passwd" --raw-mode faketcp >error.txt 2>&1 &
./udp2raw_amd64 -s -l0.0.0.0:6003 -r 127.0.0.1:29900 -a -k "passwd" --raw-mode faketcp >error.txt 2>&1 &
EOF
对外端口:6002为混淆过的Speederv2端口,6003为混淆过的KCP端口。
客户端:
cd /home/udp2raw-tunnel
cat > run.sh <<EOF
./udp2raw_amd64 -l127.0.0.1:70002 -r10.10.10.10:6002 -k "passwd" --raw-mode faketcp >error.txt 2>&1 &
EOF
如果需要混淆KCP:
cd /home/udp2raw-tunnel
cat > run.sh <<EOF
./udp2raw_amd64 -l127.0.0.1:70002 -r10.10.10.10:6002 -k "passwd" --raw-mode faketcp >error.txt 2>&1 &
./udp2raw_amd64 -l127.0.0.1:70003 -r10.10.10.10:6003 -k "passwd" --raw-mode faketcp >error.txt 2>&1 &
EOF
本地127的7002端口对接远端的6002端口(udp2raw转Speederv2),7003端口对接远端的6003端口(udp2raw转KCP)。
如果我们使用了udp2raw,客户端对应的speederv2和kcp连接地址需要更改为udp2raw混淆后的服务器端口,修改如下:
speederv2
cd /home/speederv2
cat > run.sh <<EOF
speederv2_amd64 -c -l0.0.0.0:8388 -r127.0.0.1:7002 -k "passwd" -f2:4 --timeout 1 >error.txt 2>&1 &
EOF
kcp
cd /home/kcptun
cat > run.sh <<EOF
./client_linux_amd64 -l :8388 -r 1127.0.0.1:7003 -key eller -mtu 1400 -sndwnd 256 -rcvwnd 2048 -mode fast2 -conn 4 >error.txt 2>&1 &
EOF
简单说明下,最后这里修改了前面的配置,修改后的目的是:
将speederv2的监听8388的UDP数据,将其传送给本地7002端口(udp2raw入口),而远端7002端口连接的是远端6002端口(udp2raw),远端6002端口再转发到6001(speeder),6001再转发给8388端口给SSR。
将kcp的监听8388的TCP数据,将其传送给本地7003端口(udp2raw入口),而远端7003端口连接的是远端6003端口(udp2raw),远端6003端口再转发到29900(kcp),29900再转发给8388端口给SSR。
因为KCP和speederv2是分别监听TCP和UDP协议,所以不会端口冲突。
listen udp [local:8388] =udp=> [local:7002] =udp fake tcp=> [remote:7002] =udp=> [remote:6002] =udp=> [remote:8388] SSR
listen tcp[local:8388] =udp=> [local:7003] =udp fake tcp=> [remote:6003] =udp=> [remote:29900] =tcp=> [remote:8388] SSR
此时连接客户端的8388端口就相当于连接服务器的8388端口,期间还经过了一系列的转换。
最终可以用SSR连接127.0.0.1:8388,如果文中提到的客户端为中转服务器,可省去在windows上配置的麻烦过程,以上的speederv2、udp2raw、kcp均支持windows。
服务器端SSR端口:8388
服务器端KCP原生端口:29900
服务器端KCP混淆端口:6003
服务器端Speederv2原生端口:6001
服务器端Speederv2混淆端口:6002
启动
客户端/服务端均适用
/home/kcptun/run.sh
/home/speederv2/run.sh
/home/udp2raw-tunnel/run.sh
停止
客户端/服务端均适用
pkill -9 client_linux_amd64
pkill -9 speederv2_amd64
pkill -9 udp2raw_amd64
客户端
针对于windows上的加速器客户端,推荐采用SSTAP。因SSTAP已经不再维护更新,更推荐Netch。
SSTAP:
https://www.sockscap64.com/changelog-of-sstap/
Netch:
https://github.com/NetchX/Netch/releases
参考链接:
https://home4love.com/3154.html