Forum Discussion

Patti_G_72768's avatar
Patti_G_72768
Icon for Nimbostratus rankNimbostratus
Oct 28, 2013

iRule help needed - Need to meet three conditions

Hi all, I need to write an iRule that will will do the following:

 

  1. Detect if the Accept header is missing.

     

  2. The Connection for keep-alive is set to close.

     

  3. That there is a valid keep-alive value.

     

If all three conditions are met then I need to log and block the traffic. I bundled all three conditions into one statement because I wasn't sure if I needed an elseif statement or if there is a conditional statement I could use to check each one and then log and drop the traffic if all three are met. Here is my attempt at doing this:

 

when HTTP_REQUEST { if {([HTTP::header "Accept"] eq "" and [HTTP::header "Connection"] eq "close" and [HTTP::header "keep-alive"] matches_regex {([0-9]+)})} { log local0. "Invalid attempt." return } }

 

If possible, please help.

 

4 Replies

  • Patti, can I assume this is related to post: https://devcentral.f5.com/questions/irule-syntax-need-help-with-conditional-statementanswer82657?

    I wasn't sure where to go with that one based on the stated requirements, but it sounds like you've been able to define what the HULK HTTP DoS filters are doing.

    In any case, here's what that iRule might look like:

    when HTTP_REQUEST {
        if { not ( [HTTP::header exists Accept] ) and ( [string tolower [HTTP::header Connection]] equals "close" ) and ( [scan [HTTP::header Keep-Alive] %d data] > 0 ) } {
            log local0. "Invalid attempt"
            reject
        }
    }
    

    Might I also add that, based on what I've seen from the following:

    http://blog.spiderlabs.com/2012/05/hulk-vs-thor-application-dos-smackdown.html

    You can also detect Hulk based on the ordering of the HTTP headers:

    Accept-Encoding
    Host
    Keep-Alive
    User-Agent
    Accept-Charset
    Connection
    Referer
    Cache-Control
    

    So then the following might actually prove a more comprehensive filter:

    when HTTP_REQUEST {
        set header_list [list "Accept-Encoding" "Host" "Keep-Alive" "User-Agent" "Accept-Charset" "Connection" "Referer" "Cache-Control"]
    
        set match 1
        for { set i 0 } { $i < [llength $header_list] } { incr i } {
            if { not ( [lindex $header_list $i] equals [lindex [HTTP::header names] $i] ) } {
                set match 0
            }
        }
    
        if { $match == 1 } {
            log local0. "match"
        }   
    }
    
  • Hi Kevin, it is related to the previous post. I did some additional research to figure out what the filters were looking to do. Sorry for the confusion of the first post!

     

    Can I ask you to explain what the second iRule is doing? Would it be beneficial to create two separate iRules for this? One to look for the original filter and the second one to look for the ordering of HTTP headers?

     

    Thank you very much for your help!!!! I GREATLY appreciate it!!!!!

     

  • These are either/or iRule options. The first iRule above simply mimics the filter you're trying to replace. The second iRule steps through the defined list of headers (IN ORDER) to see if the incoming request matches this order. I'm basing the second iRule on the findings in the Spiderlabs URL.