Source Engine Query泛洪是使用Source引擎游戏服务器的查询协议来进行的攻击,攻击者只需要发送一小段数据包,服务端会返回几倍的数据,形成反射性攻击。由于正常玩家在查询服务器时也会使用到此协议,因此不能直接封禁,否则将影响正常玩家。我的策略是对数据包进行限流,若超出阈值则拉黑,使用linux iptables来实现,主要用到以下几个模块:
- string(对数据包内容进行匹配)
- hashlimit(对请求限流)
- recent(记录攻击信息)
-
首先匹配数据,查询Valve的开发文档,由于我目前遇到的攻击只是使用
A2S_INFO
的攻击,因此拿到这个Request header和payload信息。
-
构造过滤规则,这里只匹配到
Source
,已经能够有足够把握是Source Engine Query的数据包,当然如果怕影响其它业务,也可以继续匹配。
-m string --hex-string '|ff ff ff ff 54 53 6f 75 72 63 65 20|' --algo kmp
- 然后设置限流,设置每秒10次请求。同时把mode设置为根据原ip、目标ip、目标端口进行保存,以确保运行多个服务端时互相不会受到影响。
-m hashlimit --hashlimit-name SourceEngineQuery --hashlimit-mode srcip,dstip,dstport --hashlimit-above 10/second --hashlimit-burst 1 --hashlimit-htable-expire 30000
- 然后增加对黑名单IP的保存,此模块默认一个表只能保存100个IP数据,因此如果需要防御更大的攻击,还需要修改ip_list_tot参数,可见另一篇文章:https://devsdawn.com/2020/01/changing-ip_list_tot-parameter-of-linux-iptables-recent-module/
-m recent --set
- 现在,这条规则应该是这样。
iptables -I INPUT -p udp -m string --hex-string '|ff ff ff ff 54 53 6f 75 72 63 65 20|' --algo kmp -m hashlimit --hashlimit-name SourceEngineQuery --hashlimit-mode srcip,dstip,dstport --hashlimit-above 10/second --hashlimit-burst 1 --hashlimit-htable-expire 30000 -m recent --set -j DROP
- 最后,我们还需要对黑名单的IP进行判断并屏蔽,屏蔽时间为60秒,同时清除超过60秒的屏蔽数据。
iptables -I INPUT -m recent --rcheck --seconds 60 --reap -j DROP
发表回复