Forum Discussion

FishNiX_29746's avatar
FishNiX_29746
Icon for Nimbostratus rankNimbostratus
Apr 15, 2010

Strange iRule behavoir v9.4.8

Greetings -

Recently we had some strange behavior and I'd like to get some opinions on the cause...

We have 3 iRules applied to a virtual server and one supporting class:


rule strip_xforwardedfor {
   when HTTP_REQUEST {
     while { [HTTP::header exists X-Forwarded-For] } {
       HTTP::header remove X-Forwarded-For
     }
  }
}
rule add_xforwardedfor {
  when HTTP_REQUEST {
    HTTP::header insert X-Forwarded-For [IP::client_addr]
  }
}
rule redirect_by_host_and_uri {
   when HTTP_REQUEST {
  foreach row [lsort -decreasing -index 1 $::host_uri_redirector_class] {
    if { [string tolower [HTTP::host]] equals [getfield $row " " 1] }{
      if { [string tolower [HTTP::uri]] starts_with [getfield $row " " 2] }{
        HTTP::redirect [getfield $row " " 3]
        break
      }
    }
  }
 }
}
class host_uri_redirector_class {
   "www.example.com /foobar http://foobar.example.com"
}

There are a whole host of reasons we use these rules, but we do use X-Forwarded-For to restrict access to some services, so it's necessary to remove existing and re-add them. We also have a lot of fingers in the LTM with varying degrees of experience, so it made sense for use to have people edit a class rather than develop iRules.

We have a standard http vserver with something special:


virtual test_vserver {
   snat automap
   destination 111.111.111.111:http
   ip protocol tcp
   rules
      strip_xforwardedfor
      add_xforwardedfor
      redirect_by_host_and_uri
   profiles
      http
      tcp
}

I originally had the rules in the order:

redirect_by_host_and_uri

strip_xforwardedfor

add_xforwardedfor

because it made sense to me that we wouldn't want to bother processing X-Forwarded-For if we were just going to redirect somewhere... This resulted in a connection reset from Windows (XP) only -- on many different workstations both internal and external with both Firefox and IE. It also resulted in these errors in /var/log/ltm


Apr 15 13:56:23 tmm tmm[1895]: 01220001:3: TCL error: strip_xforwardedfor  - Operation not supported (line 2)     invoked from within "HTTP::header remove X-Forwarded-For"
Apr 15 13:56:23 tmm tmm[1895]: 01220001:3: TCL error: strip_xforwardedfor  - Operation not supported (line 2)     invoked from within "HTTP::header remove X-Forwarded-For"
Apr 15 13:56:24 tmm tmm[1895]: 01220001:3: TCL error: strip_xforwardedfor  - Operation not supported (line 2)     invoked from within "HTTP::header remove X-Forwarded-For"
Apr 15 13:56:25 tmm tmm[1895]: 01220001:3: TCL error: strip_xforwardedfor  - Operation not supported (line 2)     invoked from within "HTTP::header remove X-Forwarded-For"
Apr 15 13:56:26 tmm tmm[1895]: 01220001:3: TCL error: strip_xforwardedfor  - Operation not supported (line 2)     invoked from within "HTTP::header remove X-Forwarded-For"
Apr 15 13:56:26 tmm tmm[1895]: 01220001:3: TCL error: strip_xforwardedfor  - Operation not supported (line 2)     invoked from within "HTTP::header remove X-Forwarded-For"
Apr 15 13:56:27 tmm tmm[1895]: 01220001:3: TCL error: strip_xforwardedfor  - Operation not supported (line 2)     invoked from within "HTTP::header remove X-Forwarded-For"

However, with the redirect rule moved to the bottom... all is well. No errors, no connection resets. This always worked in both OSX and Linux.

I also tried changing the xforwardedfor rules to be clientside only and received the same errors.

Thoughts?

4 Replies

  • Hi FishNix,

    Not sure why you need a WHILE loop for removing an x-FORWARDED-FOR header

    You should be able to do it in the following manner

    rule strip_xforwardedfor {
       when HTTP_REQUEST {
         if { [HTTP::header exists X-Forwarded-For] } {
           HTTP::header remove X-Forwarded-For
         }
      }
    }
    

    I hope this helps

    Bhattman

  • You're probably right, but I thought it was okay to have multiple XFF lines (as well as multiple comma separated hosts in the header).... not sure that would cause odd behavior?
  • 'HTTP::header remove' will remove all headers with the name, so you don't need the loop. The loop should only get executed once, but it's simpler code to not use it.

     

     

     

    http://devcentral.f5.com/wiki/default.aspx/iRules/http__header

     

     

    HTTP::header remove

     

     

    * Removes all headers names with the name .

     

     

     

    Aaron
  • Also, you can get the 'Operation not supported' from trying to insert (and possibly remove?) HTTP headers on the same request that you have or will redirect from an iRule. The simplest fix might be to combine all of the iRules into one and only do the header removal and insert if you're not going to redirect the request. Or you could configure a custom HTTP profile with the header to erase as X-Forwarded-For, the header to insert set as X-Forwarded-For: [IP::client_addr] and then remove both XFF iRules from the VIP. This should be more efficient and avoid the iRule error.

     

     

    Aaron