Forum Discussion
mattias_56723
Nov 29, 2010Nimbostratus
Mitigating Slow HTTP Post DDoS Attacks With iRules
I have tried to implement the "slow http post ddos.." iRule, but I got some errors. http://devcentral.f5.com/Tutorials/...Rules.aspx
when HTTP_REQUEST {
if { [HTTP::method] equal...
hooleylist
Nov 29, 2010Cirrostratus
Hi Maddox,
I'm guessing you're hitting a case where there isn't a Content-Length header in a POST request. There should probably be more validation added to the example iRule to ensure more than 0 and less than 1Mb of data is collected. Here's an updated version you could try based on George's example. I haven't tested the default collection amount or timeouts, so you give this an extra review.
If you try this, could you let us know how it goes? You can use the R U Dead Yet tool to try this:
http://code.google.com/p/r-u-dead-yet/downloads/detail?name=R-U-Dead-Yet-v2.0.tar.gz&can=2&q=
Thanks, Aaron
Based on 'Mitigating Slow HTTP Post DDoS Attacks With iRules' from George Watkins
http://devcentral.f5.com/Tutorials/TechTips/tabid/63/articleType/ArticleView/articleId/1086402/Mitigating-Slow-HTTP-Post-DDoS-Attacks-With-iRules.aspx
Requires LTM v10.0+ for the after command
rule block_slow_post_requests {
when RULE_INIT {
Default amount of request payload to collect (in bytes)
set static::collect_length 2048
Default timeout for POST requests to send $collect_length bytes (in seconds)
set static::timeout 2
}
when HTTP_REQUEST {
Only check POOST requests
if { [HTTP::method] equals "POST"} {
Create a local variable copy of the static timeout
set timeout $static::timeout
Check for a non-existent Content-Length header
if {[HTTP::header Content-Length] eq ""}{
Use default collect length of 1k for POSTs without a Content-Length header
set collect_length $static::collect_length
} elseif {[HTTP::header Content-Length] == 0}{
Don't try collect a payload if there isn't one
unset collect_length
} elseif {[HTTP::header Content-Length] > $static::collect_length}{
Use default collect length
set collect_length $static::collect_length
} else {
Collect the actual payload length
set collect_length [HTTP::header Content-Length]
Calculate a custom timeout based on the same ratio we use for the default collect length and default timeout
set timeout [expr {[HTTP::header Content-Length] / $static::collect_length * $static::timeout}]
}
If the POST Content-Length isn't 0, collect (a portion of) the payload
if {[info exists collect_length]}{
If the entire request hasn't been received within X seconds, send a 408, and close the connection
set id [after $timeout {
HTTP::respond 408 content "Your POST request is not being received quickly enough. Please retry."
TCP::close
}]
Trigger collection of the request payload
HTTP::collect $collect_length
}
}
}
when HTTP_REQUEST_DATA {
Check if the 'after' ID exists
if {[info exists id]} {
If all the POST data has been received, cancel the connection closure
after cancel $id
}
}
Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects