Forum Discussion

F5_Jeff's avatar
F5_Jeff
Icon for Cirrus rankCirrus
Nov 28, 2018

irule for SMTP

Hi Everyone,

 

we have an ongoing testing and this is the irule that we currently have.

 

when CLIENT_ACCEPTED { log local0. "Client_ACCEPTED_HIT: IP address:[IP::client_addr]" TCP::respond "220\r\n" TCP::collect }

 

when CLIENT_DATA { log local0. "Client_DATA_HIT: IP address:[IP::client_addr] Data: [TCP::payload]" if { [TCP::payload] contains "gmail.com" or [TCP::payload] contains "google.com" } { pool testtesttest log local0. "cdata_FOUND: IP address:[IP::client_addr] Dest IP:[server_addr]:[server_port] Data: [TCP::payload]" } TCP::release TCP::collect }

 

the scenario is, when an email is sent using gmail, the traffic should go to testtesttest pool however, this does not work as based on the statistics, testtesttest statistics does not increase. It seems that the traffic goes to the default pool. Upon checking the /var/log/ltm directory, we can see this error:

 

CLIENT_DATA> - no serverside connection established (line 4) invoked from within "server_addr"

 

is this related to the irule why the traffic is not directed to the specified pool? are there any error with the script in the iRule?

 

Any help will be very much appreaciated.

 

Thank you.

 

  • Hi Jeff,

    It may be easier for people to review your iRule if you format it, using the preformatted code option.

    Ideally you should be using $1. But the error you are seeing is because you are using $1 in a client side context before the connection to the server has been made, so the address unknown at this stage.

    You should also try to capture an email using tcpdump/wireshark and calculate how many bytes into the payload the google.com and gmail.com are. That way you only need to collect the number of bytes needed.

    Lee

  • Hi

     

    your irule will work only if the first payload matches conditions..

     

    after first TCP::release, the connection is opened to the backend server...

     

    if you want to search in any other packets, you must collect, store in a buffer (list variable for example) without releasing to backend until the expected string is found...

     

    then you must to send on serverside the same dialog values...

     

  • for better viewing of the iRule:

    when CLIENT_ACCEPTED {
      log local0. "Client_ACCEPTED_HIT: IP address:[IP::client_addr]"
      TCP::respond "220\r\n" 
      TCP::collect
    } 
    
    when CLIENT_DATA { 
      log local0. "Client_DATA_HIT: IP address:[IP::client_addr] Data: [TCP::payload]"
      if { [TCP::payload] contains "gmail.com" } {
          pool testtesttest
          log local0. "cdata_FOUND: IP address:[IP::client_addr] Dest IP:[server_addr]:[server_port] Data: [TCP::payload]"
       }
      TCP::release
      TCP::collect
    }