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

CK_Then_103583's avatar
CK_Then_103583
Icon for Nimbostratus rankNimbostratus
Jun 13, 2014

iRule for port translation of single public IP address to multiple real server IP

Hi,

 

Need help on iRule to port translate a single public address to multiple real server private IP.

 

Example. 1.1.1.1:15001 --> 192.168.1.1:80 (if the connection is HTTP) --> 192.168.1.1.443 (if the connection is HTTPS)

 

1.1.1.1:15002 --> 192.168.1.2:80 (if the connection is HTTP) --> 192.168.1.2.443 (if the connection is HTTPS)

 

1.1.1.1:15003 --> 192.168.1.3:80 (if the connection is HTTP) --> 192.168.1.3.443 (if the connection is HTTPS)

 

1.1.1.1:15004 --> 192.168.1.4:80 (if the connection is HTTP) --> 192.168.1.4.443 (if the connection is HTTPS)

 

and so on...

 

LTM version is 11.2.1.

 

Thanks.

 

6 Replies

  • You cannot have SSL listening on the same port as non SSL on the front end. If you do normal HTTP connections will fail.

     

    Detailed in a post by Kevin Stewart and I quote

     

    "it would be extremely difficult to do SSL and non-SSL with the same listening port. For example, let's say you want to do SSL to a VIP that is listening on port 8080 and has a client SSL profile. You also want to do non-SSL to the same IP address on the same 8080 port, but of course without a client SSL profile. You'd necessarily have to create a single VIP on port 8080, apply a client SSL profile, and use an iRule to disable that client SSL profile for non-SSL requests. Because of where SSL sits in the OSI layer, however, one of the only ways you'd have to determine the client's intentions (SSL or non-SSL) would be a layer BELOW SSL, as in at the IP layer. Prior to offloading the SSL, you don't know what the client's intentions are. Now, you could technically sniff the TCP payload at layer 4 and see if the client is sending SSL data, but then you're getting into some fairly complicated iRules."

     

  • Call me a liar.....

    when HTTP_REQUEST {  
       Check if the client used an SSL cipher  
      if {not ([catch {SSL::cipher version} result]) && $result ne "none"}{  
         Client did use a cipher  
        log local0. "\$result: $result. Allowing encrypted request."  
        if {[HTTP::path] eq "/"}{ 
          HTTP::redirect "https://[getfield [HTTP::host] : 1]/Login.jsp" 
        } 
      } else {  
         Client did not use a cipher  
        log local0. "\$result: $result. Redirecting unencrypted request."  
         HTTP::redirect "https://[getfield [HTTP::host] : 1]/Login.jsp" 
      }  
    }
    
    • Kevin_Davies_40's avatar
      Kevin_Davies_40
      Icon for Nacreous rankNacreous
      But does this work? As I understand it, if you have an SSL profile on the Virtual server it will try to negotiate SSL and this will cause a protocol error with the client browser.... there is something missing from this picture.
  • James_Deucker_2's avatar
    James_Deucker_2
    Historic F5 Account

    I wouldn't recommend doing this. However, maybe something like (completely untested):

    when CLIENT_ACCEPTED {
        TCP::collect 3
    }
    
    when CLIENT_DATA {
        if { [TCP::payload length] >= 3 } {
            switch [string range [TCP::payload] 0 2] {
                 list out the first 3 letters of the HTTP methods we want to see
                GET -
                POS -
                HEA -
                PUT -
                DEL -
                OPT {
                     looks like it'll be HTTP
                    pool http_pool
                }
                default {
                     doesn't look like HTTP
                    pool https_pool
                }
            }
        } else {
             we didn't get as many bytes as we wanted
            TCP::collect [expr {3 - [TCP::payload length]}]
        }
    }
    
  • Create server and client SSL profiles. Turn on the advanced option on the client SSL profile "Non-SSL Connections".

    when HTTP_REQUEST { 
    
       only need to set it on first http request
      if {[info exists connect_pool]} { return }
    
       are we using SSL?
      set connect_type "http"
      if {!([catch {SSL::cipher version} result]) && $result ne  "none" } { set connect_type "https" }
      if {[class match $connect_type:[TCP::local_port] equals myclass]} {
        set connect_pool [class match -value $connect_type:[TCP::local_port] equals myclass]
        log local0. "Pool selected for [IP::local_addr]:[TCP::local_port] was $connect_pool"
      } else {
        log local0. "Configuration not found for [IP::local_addr]:[TCP::local_port]. Connection rejected."
        reject
      }
      pool $connect_pool
      if {$connect_pool ends_with "80" } { SSL::disable }
    }
    

    Create the class myclass...

    Name           Value
    http:15001     pool_1.1_443
    https:15001    pool_1.1_80
    

    Then have the pools...

    pool_1.1_443 has member 192.168.1.1:443
    pool_1.1_80 has member 192.168.1.1:80
    

    Create virtual 1.1.1.1:* Attach SSL profiles and iRule

  • If any of the below posts have provided a solution to your issue, please indicate so by clicking the tick to the left of them. This gives feedback and recognition to the volunteers who responded to your issue