我的服务器从2023年6月27日到8月20日遭到了近两个月的DDOS及BDS漏洞攻击。在应对的过程中,我积攒了一些经验,基于认真负责的态度和传播经验的目的,我将我的总结写到下面。我用家宽动态公网IP开服,以下经验适合家宽,云服务器也可适当参考。
如何抵挡大流量(几十Gbps的NTP、DNS反射放大攻击)?
方案一:高防转发
租一台高防云服务器,作为“挡箭牌”,将流量过滤后转发回源站。
Step 1:租高防服务器:云服务器无需太高配的CPU、内存、磁盘;只要上行带宽大,防御高就行。这里推荐:超享云的湖北、成都、鞍山机房;苏汇云的湖北机房。理由是便宜:同样100G防御,超享云和苏汇云的湖北机房60元/月可以买20mbps上行,而其他大部分云60元/月只能买10mbps。经过我的验证,10mbps无法满足玩家正常游玩需求,而20mbps可以。如果你找到了更便宜的高防服务器,可以在评论区留言。
Step 2:搭建流量转发。以下步骤是在Ubuntu 22.04系统里进行的。请确保你租的云服务器里,预装的系统尽量接近Ubuntu 22.04。依次输入以下命令:
将以下代码新增到nginx.conf的末尾新行。以下只是一个示例,请自行调整。你需要会使用vim编辑器,比如:按“i”进入插入模式,上下左右键移动光标到末尾,输入以下代码,之后按“esc”退出插入模式,进入普通模式;在普通模式输入“:wq”保存并退出。仍有疑问请自行查找教程。
以下是一个通用格式。假如你的源服务器域名是server.fun,基岩服端口是19132,Java服端口是25565,你买的高防服务器IP是114.514.19.810,可以这么填写:
下图是格式示例
之后输入以下命令:
之后,玩家通过地址114.514.19.810,端口19132可以进基岩服;通过地址114.514.19.810:25565可以进Java服。同时,如果攻击者流量小于100Gbps,就会被过滤而失效。另外,你需要避免server.fun这个域名泄露,否则他可以绕开转发服务器而直接攻击源站。
上面使用了proxy_upload_rate 100k。这里的目的在于:高防服务器的防火墙只能识别拦截NTP、DNS反射放大之类的大流量;如果攻击者手动编造大于20mbps看似正常的数据包,骗过防火墙,之后会被nginx转发,而占满高防为数不多20mbps的上行带宽,导致转发服务器带宽拥堵。通过proxy_upload_rate 100k将单个客户端对服务器的上传速度限制到0.1mb/s,可以防止他占满带宽,还不会影响玩家的正常交互;另外,此指令可能可以拦截BDS漏洞崩服包,会在下面讲到。
上面使用了proxy_download_rate 2m。这里目的在于:可以防止玩家进服或传送时占满带宽导致其他人卡。经过我的测量:视距20的玩家进BDS那一刻最高吃6mbps,平常跑图吃3mbps,而正常盖房子才0.2mbps;视距32的玩家进fabric(Java)服那一刻吃20~50mbps,平常跑图吃4mbps,正常盖房子才0.5mbps。这么设置可以给防止玩家进服或传送时一瞬间占满带宽导致其他人延迟高。
nginx官方文档对proxy_upload_rate的解释:
此外,如果你将动态解析IP的域名填入nginx.conf作为上游服务器时:nginx.conf只会在重启时解析域名的IP。因此,上游服务器IP变一次,你就要输一次sudo nginx -s reload。下面有自动化解决的两个办法:
①使用脚本,检测到上游服务器IP变化就自动重启nginx:
将以下代码修改后复制进去,然后“:wq”保存退出。
结合评论区Reiyans的建议,也可以多租几个转发节点服务器,让他们均衡负载,这样一个被打封了还能换另一个。
方案二:动态IP
家宽公网IP在被DDOS之后会自动更换新IP,可以好好利用这一点。
不要公开地将域名动态解析到IP,以免被持续攻击。可以开发一个网站,上面动态显示服务器IP,这样,等服务器被攻击10分钟以后IP变了,攻击者需要重新查询IP才能继续攻击,如果他要形成连续的攻击,就得一直上网站查IP(最好把ip地址画到图片里,并且加上人机验证才能查询,防止他用脚本自动爬取ip以跟踪攻击)。可以设置查IP需要登录,注册账号要求手机短信绑定、QQ绑定、玩家名绑定(也可采集其他信息,但注意保护玩家隐私),以保证账号的唯一性。如果哪个IP被攻击了,那么攻击者应该就在查了这个IP的人里面。可以将每次被攻击IP的查询者名单总结一下,哪些人经常出现在名单上,有可能攻击者就是他,可以暂时禁用他的查询,以观察是否会继续被攻击。查IP的系统如果是网站,需要有高防,以免被攻击导致无法查IP。也可以用QQ机器人代替(可以参考DDOSRUN插件)。
方案三:IPv6
开通并使用IPv6地址。在IPv6的环境下,应该没有那么多用于DDOS攻击的肉鸡资源(我猜的),因为我服务器没遭到一次IPv6条件下的DDOS。
目前大部分家用宽带都已接入ipv6网络,用不了可能只是因为路由器不支持或者没调好。点这里测试自己网络是否支持IPv6。攻击者依然可以通过IPv6发送漏洞崩服包,可以与下文对付漏洞包的方案(反作弊/限速/封IP)结合使用。将域名动态通过AAAA记录动态解析IPv6地址(动态解析IPv6的教程,此代码里的获取IP的接口不能用了,请替换为上面的接口)。部分玩家用IPv6玩可以为高防转发(方案一)分流(降低带宽压力),也可以为动态IP(方案二)降低嫌疑排查难度。
方案四:保密的域名
再购买一个域名,这个域名直接动态解析到源服务器,注意保密,只给熟人和自己用。此方案同样可以降低高防转发的压力和嫌疑排查的难度。
综上,建议四种方案结合使用。熟人用保密的域名;其他人能用IPv6用IPv6;再其他的人优先高防转发,转发体验不好就让他查IP。结合使用既可以让四种方案互相分流,又可以在某一方案被攻陷后有替代办法。
如何对付BDS漏洞攻击包?
方案一:社区反作弊
社区上存在一些能对付漏洞攻击包的插件,比如LLAC、FishingAC,但作用比较有限。因为攻击包多种多样,插件不一定能拦截全部,建议与其他方案搭配使用。另外,FishingAC的反崩服功能会封ip,不建议与高防转发搭配使用(高防转发的ip唯一)。因此我之前找他定制了一个只封端口的版本,可以找他问问。
方案二:nginx限速
我碰到的崩服包有一个共同特征,每次崩服都发送一组数据包,这组数据包在网速不受限的情况下传输速度为10mbps,会发送0.6秒,因此这组数据包的大小为0.8mb左右。一个玩家跟服务器交互时,对服务器的上传才10kbps左右,从服务器的下载才100kbps左右。如果把单个玩家对服务器的上传限速为20kbps,那么本来0.6秒就能发完的崩服包,就需要五分钟才能发完(也有可能在这期间他数据包的TTL到时间了,发不完),这样可能会影响他崩服的效果。
如果nginx会将没有及时传输的数据包延后传输,请尝试使用proxy_buffer_size指令来减少nginx的缓冲区,默认缓冲区为16k,无需修改。
方案三:使用Java版服务器核心开互通服
BDS的崩服包一定不会对fabric或spigot等服务端生效,但是需要换档、换核心之类的。
方案四:封IP
就是直接把攻击者的IP封了,BDS漏洞包的攻击IP较为单一。不过封了只能暂时解决,因为他还会换新的IP攻击。
如何抵挡大流量(几十Gbps的NTP、DNS反射放大攻击)?
方案一:高防转发
租一台高防云服务器,作为“挡箭牌”,将流量过滤后转发回源站。
Step 1:租高防服务器:云服务器无需太高配的CPU、内存、磁盘;只要上行带宽大,防御高就行。这里推荐:超享云的湖北、成都、鞍山机房;苏汇云的湖北机房。理由是便宜:同样100G防御,超享云和苏汇云的湖北机房60元/月可以买20mbps上行,而其他大部分云60元/月只能买10mbps。经过我的验证,10mbps无法满足玩家正常游玩需求,而20mbps可以。如果你找到了更便宜的高防服务器,可以在评论区留言。
Step 2:搭建流量转发。以下步骤是在Ubuntu 22.04系统里进行的。请确保你租的云服务器里,预装的系统尽量接近Ubuntu 22.04。依次输入以下命令:
Code:
sudo apt update #更新软件列表
sudo apt install nginx #安装流量转发工具nginx
sudo apt install vim #安装文本编辑器vim
sudo vim /etc/nginx/nginx.conf #打开nginx.conf配置文件
以下是一个通用格式。假如你的源服务器域名是server.fun,基岩服端口是19132,Java服端口是25565,你买的高防服务器IP是114.514.19.810,可以这么填写:
NGINX:
stream {
proxy_upload_rate 100k; #限制单个玩家对服务器的发送速度,100k=100kb/s=800kbps
proxy_download_rate 2m; #限制服务器对单个玩家的发送速度,2m=2mb/s=16mbps
server {
listen 25565; #玩家进Java服务器的端口
proxy_pass server.fun:25565; #源Java服务器的域名和端口
}
server {
listen 19132 udp; #玩家进基岩服务器的端口
proxy_pass server.fun:19132; #源基岩服务器的域名和端口
}
}
之后输入以下命令:
Code:
nginx -t #检查nginx.conf语法正确性
sudo nginx -s reload #重启nginx
上面使用了proxy_upload_rate 100k。这里的目的在于:高防服务器的防火墙只能识别拦截NTP、DNS反射放大之类的大流量;如果攻击者手动编造大于20mbps看似正常的数据包,骗过防火墙,之后会被nginx转发,而占满高防为数不多20mbps的上行带宽,导致转发服务器带宽拥堵。通过proxy_upload_rate 100k将单个客户端对服务器的上传速度限制到0.1mb/s,可以防止他占满带宽,还不会影响玩家的正常交互;另外,此指令可能可以拦截BDS漏洞崩服包,会在下面讲到。
上面使用了proxy_download_rate 2m。这里目的在于:可以防止玩家进服或传送时占满带宽导致其他人卡。经过我的测量:视距20的玩家进BDS那一刻最高吃6mbps,平常跑图吃3mbps,而正常盖房子才0.2mbps;视距32的玩家进fabric(Java)服那一刻吃20~50mbps,平常跑图吃4mbps,正常盖房子才0.5mbps。这么设置可以给防止玩家进服或传送时一瞬间占满带宽导致其他人延迟高。
nginx官方文档对proxy_upload_rate的解释:
此外,如果你将动态解析IP的域名填入nginx.conf作为上游服务器时:nginx.conf只会在重启时解析域名的IP。因此,上游服务器IP变一次,你就要输一次sudo nginx -s reload。下面有自动化解决的两个办法:
①使用脚本,检测到上游服务器IP变化就自动重启nginx:
Code:
sudo apt update #更新软件库
sudo apt install python3 python-is-python3 #安装python
sudo touch /home/restartnginx.py #新建脚本文件
sudo vim /home/restartnginx.py #编辑脚本文件
Python:
import socket
import time
import subprocess
UPSTREAM_SERVER = 'server.fun' # 更改为你的上游服务器域名
CHECK_INTERVAL = 60 # 检查间隔,单位:秒
def main():
last_ip = None
while True:
current_ip = socket.gethostbyname(UPSTREAM_SERVER)
if last_ip is not None and current_ip != last_ip:
print(f"IP address changed from {last_ip} to {current_ip}. Reloading nginx...")
subprocess.run(["nginx", "-s", "reload"])
last_ip = current_ip
time.sleep(CHECK_INTERVAL)
if __name__ == '__main__':
main()
Code:
nohup python /home/nginxrestart.py & #让这个Python脚本在后台运行
ps aux | grep nginxrestart #可选,检查脚本是否运行
黄色字为无法解决问题的讨论内容
②nginx自带resolver指令和resolver_timeout指令,用于解决上游服务器IP变化的问题。但是目前看来,这个办法只对http块有用,对stream块没用,即使stream块同样支持resolver指令和resolver_timeout指令,希望有懂nginx的大佬看到了来解决一下这个问题。根据查阅到的资料,nginx里stream块里虽然也支持resolver和resolver_timeout指令,但是这俩指令购买商业订阅才能用于四层转发。结合评论区Reiyans的建议,也可以多租几个转发节点服务器,让他们均衡负载,这样一个被打封了还能换另一个。
方案二:动态IP
家宽公网IP在被DDOS之后会自动更换新IP,可以好好利用这一点。
不要公开地将域名动态解析到IP,以免被持续攻击。可以开发一个网站,上面动态显示服务器IP,这样,等服务器被攻击10分钟以后IP变了,攻击者需要重新查询IP才能继续攻击,如果他要形成连续的攻击,就得一直上网站查IP(最好把ip地址画到图片里,并且加上人机验证才能查询,防止他用脚本自动爬取ip以跟踪攻击)。可以设置查IP需要登录,注册账号要求手机短信绑定、QQ绑定、玩家名绑定(也可采集其他信息,但注意保护玩家隐私),以保证账号的唯一性。如果哪个IP被攻击了,那么攻击者应该就在查了这个IP的人里面。可以将每次被攻击IP的查询者名单总结一下,哪些人经常出现在名单上,有可能攻击者就是他,可以暂时禁用他的查询,以观察是否会继续被攻击。查IP的系统如果是网站,需要有高防,以免被攻击导致无法查IP。也可以用QQ机器人代替(可以参考DDOSRUN插件)。
方案三:IPv6
开通并使用IPv6地址。在IPv6的环境下,应该没有那么多用于DDOS攻击的肉鸡资源(我猜的),因为我服务器没遭到一次IPv6条件下的DDOS。
目前大部分家用宽带都已接入ipv6网络,用不了可能只是因为路由器不支持或者没调好。点这里测试自己网络是否支持IPv6。攻击者依然可以通过IPv6发送漏洞崩服包,可以与下文对付漏洞包的方案(反作弊/限速/封IP)结合使用。将域名动态通过AAAA记录动态解析IPv6地址(动态解析IPv6的教程,此代码里的获取IP的接口不能用了,请替换为上面的接口)。部分玩家用IPv6玩可以为高防转发(方案一)分流(降低带宽压力),也可以为动态IP(方案二)降低嫌疑排查难度。
方案四:保密的域名
再购买一个域名,这个域名直接动态解析到源服务器,注意保密,只给熟人和自己用。此方案同样可以降低高防转发的压力和嫌疑排查的难度。
综上,建议四种方案结合使用。熟人用保密的域名;其他人能用IPv6用IPv6;再其他的人优先高防转发,转发体验不好就让他查IP。结合使用既可以让四种方案互相分流,又可以在某一方案被攻陷后有替代办法。
如何对付BDS漏洞攻击包?
方案一:社区反作弊
社区上存在一些能对付漏洞攻击包的插件,比如LLAC、FishingAC,但作用比较有限。因为攻击包多种多样,插件不一定能拦截全部,建议与其他方案搭配使用。另外,FishingAC的反崩服功能会封ip,不建议与高防转发搭配使用(高防转发的ip唯一)。因此我之前找他定制了一个只封端口的版本,可以找他问问。
方案二:nginx限速
此方案的有效性未经验证,但理论可行
可以用上文提到的nginx的proxy_upload_rate 100k。我碰到的崩服包有一个共同特征,每次崩服都发送一组数据包,这组数据包在网速不受限的情况下传输速度为10mbps,会发送0.6秒,因此这组数据包的大小为0.8mb左右。一个玩家跟服务器交互时,对服务器的上传才10kbps左右,从服务器的下载才100kbps左右。如果把单个玩家对服务器的上传限速为20kbps,那么本来0.6秒就能发完的崩服包,就需要五分钟才能发完(也有可能在这期间他数据包的TTL到时间了,发不完),这样可能会影响他崩服的效果。
如果nginx会将没有及时传输的数据包延后传输,请尝试使用proxy_buffer_size指令来减少nginx的缓冲区,默认缓冲区为16k,无需修改。
方案三:使用Java版服务器核心开互通服
BDS的崩服包一定不会对fabric或spigot等服务端生效,但是需要换档、换核心之类的。
方案四:封IP
就是直接把攻击者的IP封了,BDS漏洞包的攻击IP较为单一。不过封了只能暂时解决,因为他还会换新的IP攻击。
Last edited:
打赏用户