DNS Flood Protection v3

Problem this snippet solves:

This iRule may provide basic idea to protect against dns flood protection per source ip address. The "maxquery" is number of query allowed per second. The "holdtime" is the period that bad client will be blocked. Different in this version of the rule is the use of the static namespace for the variables in the RULE_INIT to prevent demotion, and the use of the table command to make the rule cleaner and simpler. DNS Flood Protection V3.1, which adds the ability to limit amount of memory used by blacklist and tracking table, is also available.

Code :

when RULE_INIT {
  set static::maxquery 100
  set static::holdtime 600
}
when CLIENT_DATA {
    set srcip [IP::remote_addr]
    # If there is a match, drop the request and exit the event
    if { [table lookup -subtable "blacklist" $srcip] != "" } {
        drop
        return
    }
    # set key to the sourceIP and current time
    set curtime [clock second]
    set key "count:$srcip:$curtime"

    # Keep a count of the entries in the table for this IP in the current second (ie 12
    set count [table incr $key]

    # Time significance is 1s, so expire any entries after 2s (fudge factor) to conserve memory
    table lifetime $key 2

    if { $count > $static::maxquery } {
        # Add IP to the blacklist and set the lifetime to the holdtime variable 
        # so entry will automatically expire when desired.  The lifetime is used
        # instead of the timeout because the first thing the iRule does is lookup
        # the IP in the blacklist table, which would keep the timeout from expiring
        # the blacklist entry.
        table add -subtable "blacklist" $srcip "blocked" indef $static::holdtime

        # Since IP is on blacklist now, the count doesn't matter.  Delete to clean up.
        table delete $key
        drop
        return
    }
}
Published Mar 17, 2015
Version 1.0
No CommentsBe the first to comment