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

paul_dcc's avatar
paul_dcc
Icon for Nimbostratus rankNimbostratus
Jul 07, 2014

Silent redirect to another server, with out changing the url

Hi All,

 

I have clients connecting to a server https://test.abc.com and I need to redirect them to https://xxx.com:8080/web/ but with out the original url (https://test.abc.com) changing. Is this possible with an Irule and if so what would it look like.

 

7 Replies

  • There are a few things required:

    1. You must terminate the client side SSL at the F5. If you do not, then you cannot see or manipulate the layer 7 HTTP data.

    2. You would use the HTP::uri command to silently change the URI in the ingress flow:

      when HTTP_REQUEST {
          HTTP::uri "/web/"
      }
      
    3. You may optionally need to change the HTTP host header:

      when HTTP_REQUEST {
          HTTP::header replace Host "xxx.com:8080"
          HTTP::uri "/web/"
      }
      
    4. You may also need to consider a) how the server responds to clients and b) if you'll need multiple URI patterns. If the server responds with document object references that point to the internal URL space, or you need to map more than one URI pattern, you'll need a mechanism to translate those for external consumption. That can be as simple as a STREAM profile iRule, or as complex as a ProxyPass iRule or 11.4+ rewrite profile.

  • i assume /web will always be added in uri (if not existing) when sending to pool member.

    e.g.

     config
    
    root@(ve11a)(cfg-sync In Sync)(Active)(/Common)(tmos) list ltm virtual bar
    ltm virtual bar {
        destination 172.28.24.10:443
        ip-protocol tcp
        mask 255.255.255.255
        pool foo
        profiles {
            http { }
            myclientssl {
                context clientside
            }
            serverssl {
                context serverside
            }
            tcp { }
        }
        rules {
            qux
        }
        source 0.0.0.0/0
        source-address-translation {
            type automap
        }
        vs-index 51
    }
    root@(ve11a)(cfg-sync In Sync)(Active)(/Common)(tmos) list ltm pool foo
    ltm pool foo {
        members {
            200.200.200.101:8080 {
                address 200.200.200.101
            }
        }
    }
    root@(ve11a)(cfg-sync In Sync)(Active)(/Common)(tmos) list ltm rule qux
    ltm rule qux {
        when HTTP_REQUEST {
      HTTP::header replace Host "xxx.com:8080"
      if { !([HTTP::path] starts_with "/web/") } {
        HTTP::uri "/web[HTTP::uri]"
      }
    }
    }
    
     trace
    
    [root@ve11a:Active:In Sync] config  ssldump -Aed -nni 0.0 -k /config/filestore/files_d/Common_d/certificate_key_d/\:Common\:test.key_50349_1 port 443 or port 8080
    New TCP connection 1: 172.28.24.1(48372) <-> 172.28.24.10(443)
    1 1  1404742921.7294 (0.0340)  C>S SSLv2 compatible client hello
    1 2  1404742921.7295 (0.0000)  S>CV3.1(81)  Handshake
    1 3  1404742921.7295 (0.0000)  S>CV3.1(1052)  Handshake
    1 4  1404742921.7295 (0.0000)  S>CV3.1(4)  Handshake
    1 5  1404742921.7356 (0.0061)  C>SV3.1(134)  Handshake
    1 6  1404742921.7356 (0.0000)  C>SV3.1(1)  ChangeCipherSpec
    1 7  1404742921.7356 (0.0000)  C>SV3.1(48)  Handshake
    1 8  1404742921.7374 (0.0017)  S>CV3.1(1)  ChangeCipherSpec
    1 9  1404742921.7374 (0.0000)  S>CV3.1(48)  Handshake
    1 10 1404742921.7385 (0.0010)  C>SV3.1(176)  application_data
        ---------------------------------------------------------------
        GET / 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: test.abc.com
    
        ---------------------------------------------------------------
    New TCP connection 2: 200.200.200.14(48457) <-> 200.200.200.101(8080)
    2 1  1404742921.7656 (0.0266)  C>SV3.3(141)  Handshake
    2 2  1404742923.9678 (2.2022)  S>CV3.1(81)  Handshake
    2 3  1404742923.9678 (0.0000)  S>CV3.1(1052)  Handshake
    2 4  1404742923.9678 (0.0000)  S>CV3.1(4)  Handshake
    2 5  1404742923.9695 (0.0017)  C>SV3.1(134)  Handshake
    2 6  1404742923.9695 (0.0000)  C>SV3.1(1)  ChangeCipherSpec
    2 7  1404742923.9696 (0.0000)  C>SV3.1(48)  Handshake
    2 8  1404742924.5055 (0.5359)  S>CV3.1(1)  ChangeCipherSpec
    2 9  1404742924.5055 (0.0000)  S>CV3.1(48)  Handshake
    2 10 1404742924.5061 (0.0005)  C>SV3.1(192)  application_data
        ---------------------------------------------------------------
        GET /web/ 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: xxx.com:8080
    
        ---------------------------------------------------------------
    
  • Hi Paul, Here is another example

     when HTTP_REQUEST {
       if { [HTTP::host] eq "test.abc.com" and [HTTP::uri] ends_with "/" } {
          HTTP::header replace Host "xxx.com:8080"
          HTTP::uri "/web/"
         }
     }
    

    I hope this helps

    -=Bhattman

  • Thanks Guys,

     

    Bhattman your Irule was nice and simple, but it does not display the web page correctly any ideas ?

     

    Many Thanks

     

    Paul

     

    • nitass's avatar
      nitass
      Icon for Employee rankEmployee
      i think you may have to try tcpdump/ssldump, http analyer tool (e.g. httpfox).
  • If I may add, this goes back to my original considerations. Simply changing the URI inbound may not be enough.

     

    • what if the server responds with internal links?

       

    • what if there's more to this URI mapping pattern (data after /web/ or other URI patterns)?

       

    As Nitass alludes, you need to take a closer look at the application with some tool, preferably a client side HTTP analysis tool like HTTPWatch, Fiddler, httpfox, etc. This will give you a better idea of what you're dealing with. If you only need to statically remap a handful of incoming/outgoing links, then a STREAM profile may suffice. If the mappings get complex, then you may need to turn to ProxyPass or an 11.4+ rewrite profile.

     

  • You might want to look at the ProxyPass iRule => https://devcentral.f5.com/wiki/iRules.proxypassv10.ashx