For more information regarding the security incident at F5, the actions we are taking to address it, and our ongoing efforts to protect our customers, click here.

Forum Discussion

tayyib_muzaina_'s avatar
tayyib_muzaina_
Icon for Nimbostratus rankNimbostratus
May 21, 2014

How do I create an irule that rewrites a request to be translated to an ipaddress and port

How do I create an irule that rewrites a rule request to an ipaddress and port or translated to http://192.168.192.35/elasticsearch/ == http://192.168.192.35:9200/

 

8 Replies

  • You should have a pool of servers listening on port 9200, and address and port translation are actually functions of LTM without an iRule. Otherwise, a non-standard port would show up in the incoming Host header, which is pretty straight forward to modify. I'm also adding the URI change code in the example below:

     

    when HTTP_REQUEST {
        if { not ( [HTTP::header Host] ends_with ":9200" ) } {
            HTTP::header replace Host "[HTTP::heeader Host]:9200"
        }
        if { [HTTP::uri] equals "/elasticsearch/" } {
            HTTP::uri "/"
        }
    }

    This will transparently replace the Host header and URI on incoming HTTP requests. Not sure if you meant to literally only change the URI and Host given a specific URI.

     

  • Hi kevin,

     

    Actually I meant it the other way around. I have a Vs of 192.156.202.22/elasticsearch on port 80 and would like the forwarding request be sent to the members as vs 192.156.202.22:9200. Because the members are expecting to see the call as it would be going to it directly i.e 192.168.18.111:9200

     

  • Understood, and as I mentioned before, address and/or port translation happen automatically via the virtual server configuration. It doesn't appear that you want to alter the destination address, so you'll probably want to disable address translation in the VIP, but since the VIP is listening on port 80 and the pool members are listening on port 9200, you'll want port translation enabled. The only other aspect of this, which I'm not too terribly clear on, is whether or not the server needs to see the port in the Host header. It's somewhat rare these days that this would be required, but otherwise:

    when HTTP_REQUEST {
        if { not ( [HTTP::header Host] ends_with ":9200" ) } {
            HTTP::header replace Host "[HTTP::header Host]:9200"
        }
    }
    

    This will change the incoming Host header from "192.156.202.22" to "192.156.202.22:9200".

  • The only other aspect of this, which I'm not too terribly clear on, is whether or not the server needs to see the port in the Host header.

     

    Yes this is the case.

     

    The direct connect to the server use the member address and the port in the reqest..

     

  • This is the request type.. You are leaveing of the /elasitcsearc prt from the request.. "This will change the incoming Host header from "192.156.202.22/elasticsearch" to "192.156.202.22:9200".

     

    You gave me this This will change the incoming Host header from "192.156.202.22" to "192.156.202.22:9200".

     

  • Should it look like this?

     

    when HTTP_REQUEST { if { not ( [HTTP::header Host] ends_with "/elasticsearch" ) } { HTTP::header replace Host "[HTTP::header Host]:9200" } }

     

  • An HTTP request (and response) has different parts. For example:

    GET /elasticsearch HTTP/1.1
    Host: 192.156.202.22
    User-Agent: Mozilla...
    Accept: */*
    

    In the above example HTTP request:

    1. "GET" is the HTTP method
    2. "/elasticsearch" is the HTTP URI
    3. "HTTP/1.1" is the HTTP version
    4. "Host: 192.156.202.22" (and everything below this) is an HTTP header

    The direct connect to the server use the member address and the port in the reqest

    When you use non-standard ports to access HTTP resources, a user agent will typically include this port number in the Host header. That does not necessarily, however, mean that the server needs or cares about this value in the Host header. While there are rare cases in which it's needed, it could very well be that the server ignores this value altogether.

    This is the request type.. You are leaveing of the /elasitcsearc prt from the request

    The "/elasticsearch" string is an HTTP URI value. It would NEVER be included in the HTTP Host header. So if you need an incoming request for "/" to be translated to "/elasticsearch", then:

    if { [HTTP::uri] equals "/" } {
        HTTP::uri "/elasticsearch"
    }   
    
  • I'd also add here that the Host header would only reflect the real server's IP if the VIP address is the same as the server's IP, in which case you'd probably have a wildcard 0.0.0.0 VIP with no translation. The user agent will use the host name or IP it uses to access the site as the Host header. So if the user accesses the VIP with "www.example.com", then the Host header would be "www.example.com". You can certainly change the Host header to reflect the IP of the server that the traffic is going to, but it may be worthwhile to examine if that's even required by the server.