Forum Discussion

Charlie__14964's avatar
Charlie__14964
Icon for Nimbostratus rankNimbostratus
Dec 05, 2008

spam defender Maxxonnect

Hallo guy’s

 

We have a need for E-Mail security as a .

 

I’m trying to write an iRule for “friend mail” which you can send from our web page,

 

(send these page to my friend) the user can write E-Mail addressee from friend and some text in addition.

 

We’d like to be able block access for 1 hours based of source IP-Addresses

 

if they send more then 10 E-Mail per hours.

 

URL will be https://www.hostname.com/mail

 

My idea is, if someone gets /friendmail.jsp then put/cache source_ip in a time/session table.

 

With each renewed call of the /friendmail.jsp left a Counter is increased by one.

 

If the value 10 is reached, is the time differentiated over one hour to lie,

 

otherwise the Client SOURCE IP becomes closed for e.g. at least 1 hours

 

The iRule below I have got the Error:

 

HTTP_REQUEST - cant use empty string as operand of - while executing expr { $now - $usertime }

 

I’m for each proposal grateful.

 

Regards

 

-------------------------------------------------------

 

when RULE_INIT {

 

set ::maxconnect 10

 

set ::blocktime 3600

 

array set ::users { }

 

array set ::spammers { }

 

}

 

when HTTP_REQUEST {

 

if { [string tolower [HTTP::uri]] equals "/mail"} {

 

set clientip [IP::remote_addr]

 

set now [clock second]

 

log local0. "User is analyzed - $clientip"

 

if { [ info exists ::spammers($clientip) ] } {

 

if { $::blocktime > [expr { $now - $::spammers($clientip)} ] } {

 

the user tries to connect in the blocktime period

 

set ::spammers($clientip) $now

 

TCP::respond "550 Message Rejected - Too Much spam/r/n"

 

log local0. "The user tries to send while in the block period - $clientip"

 

drop

 

return

 

}

 

else

 

{

 

the timeout has expired free the user from the list

 

unset ::spammers($clientip)

 

log local0. "The user has been removed from the list - $clientip"

 

}

 

}

 

end of exist ::spammer Line

 

if { [info exists ::users($clientip)] } {

 

set usertime [getfield $::users($clientip) ":" 2]

 

log local0. "the user time is $usertime and now is $now - $clientip"

 

if { [expr { $now - $usertime } ] > $::blocktime } {

 

the last connection was before the timeout period

 

set ::users($clientip) "1:$now"

 

return

 

}

 

else {

 

the connection was in the timeout

 

set t [getfield $::users($clientip) ":" 1]

 

set ::users($clientip) "[incr [getfield $::users($clientip) ":" 1]]:$now"

 

log local0. "the user - $clientip - has been connected $t times before"

 

incr t

 

set ::users($clientip) "$t,$now"

 

log local0. "the user - $clientip - has been connected $t times after"

 

if { [getfield $::users($clientip) ":" 1] > $::maxconnect } {

 

the user has exceeded the max no of connections

 

add him to the spam list

 

set ::spammers($clientip) $now

 

set ::users($clientip) "1:$now"

 

TCP::respond "550 Message Rejected - Too much spam\r\n"

 

log local0. "this user has started spamming us - $clientip "

 

drop

 

return

 

end of Max connections

 

}

 

}

 

end of else

 

}

 

else {

 

new client not if exists ::users

 

set ::users($clientip) "1:$now"

 

log local0. "this is user has just connected - $clientip"

 

}

 

}

 

}

 

3 Replies

  • Can you log the values for now and usertime before trying to subtract them? Does this error happen on every request? You could also write out the values in the array to help debug this.

     

     

    Aaron
  • Hi Charlie,

     

     

    Can you post the updated rule which shows the log statements? You can use the code tags to preserve the spacing in the iRule: [ code ] irule text [ /code ], without the spaces.

     

     

    Aaron
  • Colin_Walker_12's avatar
    Colin_Walker_12
    Historic F5 Account
    It looks like this has something to do with the way TCL is trying to interpret your array call within the expr command context. You might try either adding some quotes or brackets around the actual array call itself, or perhaps setting a local variable to the value of the array call before comparing the values with expr.

     
     set tempVal [$::spammers($clientip)] 
     if { $::blocktime > [expr { $now - $tempVal } ] } { 
     

    Something like that, perhaps. The syntax you're using looks correct, and the data is obviously there if it's passing the if exists call, so it's got to be an interpreter oddity within the expr command string itself.

    Colin

    Colin