公司的服务器遭受了攻击,某些人不停调用公司服务器发送短信的api,真是有够无聊的。
由于我们的架构是前面F5-Big-ip,后面接了N个Tomcat,那就直接写个F5的irule来阻止它。
阻止GET请求的频率,30秒只允许单个ip发5次
假设GET的模式是
GET /seendsms.do?mobile=13800000000&msg=aaaaaaaa
irule里有个非常神奇的东西,table,大家可以理解为是一个会话表,基本操作是key-value型,有生存时间,这点最重要。
详细的大家可以去看:
https://devcentral.f5.com/wiki/iRules.table.ashx
阻止GET的irule:
when RULE_INIT {
set static::windowSecs 30
}
when HTTP_REQUEST {
if { ( [HTTP::method] equals "GET" ) && ( [HTTP::uri] starts_with "/sendsms.do" ) } {
set myUserId [IP::client_addr]
set myMaxRate 5
if { $myMaxRate ne "" } {
set reqnum [table incr "req:$myUserId"]
set tbl "countpost:$myUserId"
table set -subtable $tbl $reqnum "ignored" indef $static::windowSecs
if { [table keys -subtable $tbl -count] > $myMaxRate } {
HTTP::respond 403 "Block"
return
}
}
}
}
来个复杂的例子:
假如POST的请求如下:
POST /api/sendMessage.htm HTTP/1.1
Content-Length: 203
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Host: 172.8.2.23
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.5 (Java/1.7.0_51)
Accept-Encoding: gzip,deflate
action=order.sumit.order&jsonData=%7B%22channelCode%22%3A%22%22%2C%22mobiles%22%3A%5B%2215176989787%22%5D%2C%22source%22%3A%22pop%22%2C%22tempParameters%22%3A%5B%22480827%22%2C%2291%22%5D%2C%22templateId%22%3A2%7D
如果我们要组织post /api/sendMessage.htm,action=sendmsg的话,就比较复杂一些,我们判断uri满足条件后,还要进一步判断content的内容:
when RULE_INIT {
set static::windowSecs 10
}
when HTTP_REQUEST {
if { ( [HTTP::method] equals "POST" ) && ( [HTTP::uri] equals "/api/sendMessage.htm" ) && ([HTTP::header "Content-Length"] <= 2048) } {
HTTP::collect [HTTP::header Content-Length]
}
}
when HTTP_REQUEST_DATA {
set myUserId [IP::client_addr]
set mymethod "unknown"
foreach x [split [string tolower [HTTP::payload]] "&"] {
if { $x starts_with "action=" } {
set mymethod [lindex [split $x "="] 1]
}
}
if { $mymethod equals "order.submit.order" }
{
set myMaxRate 5
if { $myMaxRate ne "" } {
set reqnum [table incr "req:$myUserId"]
set tbl "countpost:$myUserId"
table set -subtable $tbl $reqnum "ignored" indef $static::windowSecs
if { [table keys -subtable $tbl -count] > $myMaxRate } {
HTTP::respond 403 "Block"
return
}
}
}
}