Forum Discussion

rleclerc_120926's avatar
rleclerc_120926
Icon for Nimbostratus rankNimbostratus
Jan 08, 2013

iRule to drop or allow base on cookie value and date

I need to put together an iRule that either allows or drops traffic based on a cookie value and the day of the month. So if cookie value ends in 0,2,4,6,8 and day of the month is 2-30 (all even numbered days) then allow, else if cookie value ends in 1,3,5,7,9 and day of the month is 1-31 (all odd numbered days) then allow, else drop.

 

What we are doing is dropping or allowing based on a cookie value (well the last digit) and the date. Think gas rationing...

 

 

I have created iRules in the past that would allow or drop, the complexity of the logic with this is above my head.

 

1. Would using a datagroup would make sense based on what I read but I have never used one and am not sure where to start... Would it be a string or interger? and what would the string/interger and value be?

 

 

2. How do I reference the datagroup in the iRule? based on what I've done in the past I would write something like what is below, but that is a single value not a list of them.

 

when HTTP_REQUEST {

 

if { [HTTP::cookie exists "Cookie"] and [HTTP::cookie value "logininfo"] ends_with "X"} { and date ends_with "X"

 

use pool X

 

else drop

 

}

 

}

 

6 Replies

  • Hi,

    You can use modulus to check if a number is even:

    http://www.tcl.tk/man/tcl8.4/TclCmd/expr.htmM8

    You can use clock to get the current time and date of the month:

    http://www.tcl.tk/man/tcl8.4/TclCmd/clock.htmM6

    And string to parse the last character of the cookie value and check if it's an integer before checking if it's even:

    http://www.tcl.tk/man/tcl8.4/TclCmd/string.htmM23

    Here's an untested example:

    
    
    when HTTP_REQUEST {
    
     Get day of month:
     set day [clock format [clock seconds] -format {%d}]
     Check if it is even
    if {[clock format [clock seconds] -format {%d}] % 2 == 0 }{
    
     Check if the cookie value is not null: 
    [HTTP::cookie my_cookie] ne "" 
     
     Get the last char of the cookie value:
    [string range [HTTP::cookie my_cookie] end end]
    
     Assign the last character of the cookie value to a variable, last_char
    [set last_char [string range [HTTP::cookie my_cookie] end end]]
    
     Check if $last_char is an integer
    [string is integer ...
    
     Check if the last character is even using modulus %
     string is integer: http://www.tcl.tk/man/tcl8.4/TclCmd/string.htmM23
    if {[HTTP::cookie my_cookie] ne "" and [string is integer [set last_char [string range [HTTP::cookie my_cookie] end end]]] and $last_char % 2 == 0 }{
    
     Allow the request. Exit this event in this iRule so we do not block the request
    return
    }
    }
     Default action is to block the request
    HTTP::respond 403 content "you're blocked because you had cookie [HTTP::cookie my_cookie] and it is [clock format [clock seconds] -format {%d}] of the month"
    }
    

    Aaron
  • Actually, I missed that you want to allow odd numbered cookies on odd days. Can you try this?

    
    when HTTP_REQUEST {
    
     Get day of month:
     set day [clock format [clock seconds] -format {%d}]
     Check if it is even
    if {[clock format [clock seconds] -format {%d}] % 2 == 0 and }{
    
     Check if the cookie value is not null: 
    [HTTP::cookie my_cookie] ne "" 
     
     Get the last char of the cookie value:
    [string range [HTTP::cookie my_cookie] end end]
    
     Assign the last character of the cookie value to a variable, last_char
    [set last_char [string range [HTTP::cookie my_cookie] end end]]
    
     Check if $last_char is an integer
    [string is integer ...
    
     Check if the last character is even using modulus %
     string is integer: http://www.tcl.tk/man/tcl8.4/TclCmd/string.htmM23
    if {[HTTP::cookie my_cookie] ne "" and [string is integer [set last_char [string range [HTTP::cookie my_cookie] end end]]] and $last_char % 2 == 0 }{
    
     Allow the request. Exit this event in this iRule so we do not block the request
    return
    }
    } elseif {[HTTP::cookie my_cookie] ne "" and [string is integer [set last_char [string range [HTTP::cookie my_cookie] end end]]] and $last_char % 2 == 1}{
     Allow the request. Exit this event in this iRule so we do not block the request
    return
    }
     Default action is to block the request
    HTTP::respond 403 content "you're blocked because you had cookie [HTTP::cookie my_cookie] and it is [clock format [clock seconds] -format {%d}] of the month"
    }
    

    Aaron
  • Thanks Aaron, I am knee deep in a Production issue so I will try this in our Dev system later tonight.
  • just wondering if we can mod clock format value without converting to integer first.

    [root@ve11a:Active:Changes Pending] config  tclsh
    % put [clock format [clock seconds] -format {%d}]
    09
    % put [expr {[clock format [clock seconds] -format {%d}] % 2}]
    can't use invalid octal number as operand of "%"
    % scan [clock format [clock seconds] -format {%d}] {%d} dd
    1
    % put [expr {$dd % 2}]
    1
    
  • Good catch Nitass. We should use %e in the clock format command to get the day of month without 0 padding:

    
    %d
        Day of month (01 - 31).
    
    %e
        Day of month (1 - 31), no leading zeros.
    

    Aaron
  • ie, like this:

    
    when HTTP_REQUEST {
    
         Get day of month:
         set day [clock format [clock seconds] -format {%e}]
         Check if it is even
        if {[clock format [clock seconds] -format {%d}] % 2 == 0 and }{
    
             Check if the cookie value is not null: 
                [HTTP::cookie my_cookie] ne "" 
             
             Get the last char of the cookie value:
                [string range [HTTP::cookie my_cookie] end end]
            
             Assign the last character of the cookie value to a variable, last_char
                [set last_char [string range [HTTP::cookie my_cookie] end end]]
            
             Check if $last_char is an integer
                [string is integer ...
            
             Check if the last character is even using modulus %
             string is integer: http://www.tcl.tk/man/tcl8.4/TclCmd/string.htmM23
            if {[HTTP::cookie my_cookie] ne "" and [string is integer [set last_char [string range [HTTP::cookie my_cookie] end end]]] and $last_char % 2 == 0 }{
    
                 Allow the request. Exit this event in this iRule so we do not block the request
                return
            }
        } elseif {[HTTP::cookie my_cookie] ne "" and [string is integer [set last_char [string range [HTTP::cookie my_cookie] end end]]] and $last_char % 2 == 1}{
             Allow the request. Exit this event in this iRule so we do not block the request
            return
        }
         Default action is to block the request
        HTTP::respond 403 content "you're blocked because you had cookie [HTTP::cookie my_cookie] and it is [clock format [clock seconds] -format {%d}] of the month"
    }
    

    Aaron