Forum Discussion

Danny_Arroyo's avatar
Sep 03, 2013

How do I change an incoming uri to a different string before the VIP sends it to the Pool?

I expect the users to enter the following uri: http://server.domain.com/webapplication?frc=AO

 

I want the irule to convert the uri to the following: http://server.domain.com/flexiblewebapplication/index.jsp?frc=A0

 

Needless to say, I cant get this to work. I've looked all over google (F5 Devcentral) and found that what I'm doing should work, but it doesn't. This is my irule:

 

when HTTP_REQUEST { log local0. "Request Before if statement: [HTTP::uri]" if { ([HTTP::host] == "server.domain.com") and ([HTTP::uri] == "webapplication?frc=AO") } { log local0. "We are inside the if statement" HTTP::uri "/flexiblewebapplication/index.jsp?frc=A0" log local0. "Inside if statement: [HTTP::uri]" } }

 

PS..I added the log statements so I could try to see what is actually happening. For some reason, the irule never changes the "[HPPT::uri]" to what I listed above. The uri stays as it was originally entered by the user and of course the web site fails to load with the error "Internet Explorer cannot display the webpage".

 

any assistance is appreciated.

 

11 Replies

  • A URI always begins with a forward slash: / - this is missing from your second if statement 'test' condition.

     

  • OK. Possibly, you are using AO (letter o) in your if test, A0 (zero) with your HTTP::uri command. I assume this isn't intentional.

     

  • Depending on BIG-IP version (don't recall when it changed) the HTTP::uri command will always return what's in the request buffer, even if you've changed it inline. So what you're seeing in the last log statement is to be expected. Other than that, here's a slight modification to your iRule:

    when HTTP_REQUEST { 
        log local0. "Request Before if statement: [HTTP::uri]" 
        if { ( [string tolower [HTTP::host]] equals "server.domain.com" ) and ( [string tolower [HTTP::uri]] starts_with "/webapplication?frc=AO" ) } { 
            log local0. "We are inside the if statement" 
            HTTP::uri "/flexiblewebapplication/index.jsp?frc=A0" 
        } 
    }
    

    If that still fails, then what happens if you navigate to "/flexiblewebapplication/index.jsp?frc=A0" directly?

  • How are you accessing the VIP? The VIP is listening on port 80. Are you appending the port to your request (http://VIP:8006)? Do you have port or address translation disabled in the VIP config?

     

  • Just out of curiosity, can you:

     

    1. Verify that the request is actually making it to the pool member on port 8006 and that the server is responding? TCPDUMP on the internal interface. Do you have SNAT applied to the VIP, or does the pool member default route back through the BIG-IP?

       

    2. Verify that your iRule criteria matches and that you see the "We are inside the if statement" log statement?

       

    3. Verify that your application doesn't require the port (:8006) in the Host header?

       

  • Colin_Walker_12's avatar
    Colin_Walker_12
    Historic F5 Account

    Could you please clarify what results you're actually getting here? Are you getting a properly returned web page? (200 response) An error of some sort in the browser? A timeout? etc. It's unclear to me what behavior you're actually seeing as a response from the server.

     

    If you're re-writing the URI at the LTM, you will likely need to re-write the response from the server as well, or the client will be getting responses for pages it didn't request which can be...confusing.

     

    I'm interested in hearing the answers to Kevin's questions above, too. Hopefully we can get a clear picture of what's going on here and give you a hand.

     

    Colin
    • Danny_Arroyo's avatar
      Danny_Arroyo
      Icon for Cirrus rankCirrus
      I get the message "This webpage is not available" from chrome I get the message "Internet Explorer cannot display the webpage" from IE I get the message "The connection was reset - The connection to the server was reset while the page was loading" from Mozilla It takes about 10-30 seconds for these messages to come up. It appears that something is trying to happen, but then I get the errors listed above. If when you say "If you're re-writing the URI at the LTM..." . I think the answer is yes because, I expect the users to enter the following uri: http://server.domain.com/webapplication?frc=AO. And I want the irule to convert the uri to the following: http://server.domain.com/flexiblewebapplication/index.jsp?frc=A0. I answered Kevin's questions in my last comment. And I found from the application specialist that port 8006 is required in the URL. However doesn't the Pool handle this?
  • Easiest to answer inline:

    1. I have SNAT applied to the VIP, however I don't understand what you mean when you say "or does the pool member default route back through the BIG-IP?". If you could explain the difference that would be great. Also is the TCPDUMP done on the RedHat box or the F5? I've never done that.

    A SNAT changes the client's source address to something that is owned by the BIG-IP (a self-IP address when using Automap, for example). This forces the client to route back through the BIG-IP for responses. You don't technically need a SNAT though if you can guarantee that the server will route back through the BIG-IP. This is usually accomplished with a default gateway setting on the server - which would affect all source addresses NOT emanating from the same subnet. The only real downside of SNAT is that you lose the client's true source in the TCP header. If that's not a concern, then SNAT makes life a lot easier. As for TCPDUMP, you can run it anywhere there's visibility. So assuming you have TWO interfaces (external and internal), the following would allow you to see the incoming and outgoing traffic for a given VIP or server:

    tcpdump -lnni external host [VIP IP] [and other filters]
    tcpdump -lnni internal host [server IP] [and other filters]
    

    where "external" and "internal" are the actual names of the VLANs that you created. The MAN page for TCPDUMP (man tcpdump from the BIG-IP command line) has all of the syntax you'll need to tweak the filters so that you're looking at only the traffic that is specific to this VIP/server. What you're looking for is a) the client communicating with the VIP, and b) the BIG-IP (SNAT address) communicating with the server. You also want to look for the server to respond to the BIG-IP's request. You can also use the -Xs0 switch on TCPDUMP to see the actual HTTP payload passing back and forth. Very useful.

    1. I never see the statement "We are inside the if statement" in the log. I see "Request before if statement" and then 4 seconds later I see "Request before if statement". Nothing further is shown that seems to apply to the irule. Before I changed the irule to what you suggested, I did see "We are inside the if statement', but it was also stuck in a loop that ran 12 times before it gave up. I think applying your irule helped with the loop but the irule logic is still not giving the expected result.

    Interesting. That leads me to believe that the condition isn't matching:

    if { ( [string tolower [HTTP::host]] equals "server.domain.com" ) and ( [string tolower [HTTP::uri]] starts_with "/webapplication?frc=AO" ) }
    

    So either the host isn't "server.domain.com" or the URI doesn't start with "/webapplication?frc=AO". Change the first log statement to read like this:

    log local0. "Request Before if statement: [HTTP::host][HTTP::uri]"
    

    What do you get?

    1. I've asked the application administrator if port :8006 is required in the Host header. I'm awaiting his reply.

    I'm beginning to believe that 2 above is the problem - the request isn't matching the condition, but good to know what the app admin says in any case.

  • A few things:

     

    1. HTTP::uri changes the request URI value as it passes through the proxy. There's no client side interaction so the browser doesn't see this.

       

    2. Changing the URI does not actually change the value in the HTTP::uri buffer, so (and this actually depends on BIG-IP version) you won't see the modified URI in HTTP::uri. In other words what you're seeing is to be expected.

       

    3. Since the traffic isn't encrypted it doesn't matter where you run the tcpdump. I typically run it from the BIG-IP though because I know the traffic is at least coming from there. So from the BIG-IP management shell (console or SSH), run the following:

       

      tcpdump -lnni [internal VLAN name] -Xs0 host [redhat server IP]

       

    If you're getting any traffic at all between the BIG-IP and server, you'll also see what the HTTP looks like - including the URI value.

     

  • just an example when you run tcpdump (i.e. ssldump is used to decode http traffic, so you can see http header).

     configuration
    
    root@(ve11a)(cfg-sync Changes Pending)(Active)(/Common)(tmos) list ltm virtual bar
    ltm virtual bar {
        destination 172.28.20.111:80
        ip-protocol tcp
        mask 255.255.255.255
        pool foo
        profiles {
            http { }
            tcp { }
        }
        rules {
            myrule
        }
        source 0.0.0.0/0
        source-address-translation {
            type automap
        }
        vs-index 2
    }
    root@(ve11a)(cfg-sync Changes Pending)(Active)(/Common)(tmos) list ltm pool foo
    ltm pool foo {
        members {
            200.200.200.101:80 {
                address 200.200.200.101
            }
        }
    }
    root@(ve11a)(cfg-sync Changes Pending)(Active)(/Common)(tmos) list ltm rule myrule
    ltm rule myrule {
        when HTTP_REQUEST {
      if { [HTTP::host] equals "server.domain.com" and [HTTP::uri] starts_with "/webapplication?frc=AO" } {
        HTTP::uri "/flexiblewebapplication/index.jsp?frc=A0"
      }
    }
    }
    
     packet trace
    
    [root@ve11a:Active:Changes Pending] config  ssldump -Aed -nni 0.0 port 80
    New TCP connection 1: 172.28.19.251(55281) <-> 172.28.20.111(80)
    1378564869.6187 (0.0019)  C>S
    ---------------------------------------------------------------
    GET /webapplication?frc=AO HTTP/1.1
    User-Agent: curl/7.15.5 (i686-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
    Accept: */*
    Host: server.domain.com
    
    ---------------------------------------------------------------
    
    New TCP connection 2: 200.200.200.14(55281) <-> 200.200.200.101(80)
    1378564869.6250 (0.0032)  C>S
    ---------------------------------------------------------------
    GET /flexiblewebapplication/index.jsp?frc=A0 HTTP/1.1
    User-Agent: curl/7.15.5 (i686-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
    Accept: */*
    Host: server.domain.com
    
    ---------------------------------------------------------------
    
  • Thank for all your help guys. A Support guy from F5 finally called me back today. He was able to resolve the problem. He said what you guys said, that the iRule looked right (I had changed the VIP to port 80 sometime ago while troubleshooting and never changed it back so he changed that as well). However he determined that the web page was not returning anything but a blank page which was causing the irule to "not work". He felt the problem was something with the websites's content. He re-wrote the irule as follows:

     

    when HTTP_REQUEST { if {[HTTP::uri] equals "/webapplication?frc=AO"" } { HTTP::redirect https://[getfield [HTTP::host] ":" 1]/flexiblewebapplication/index.jsp?frc=A0 } }

     

    Thanks again!!