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

JohnInJaxBK's avatar
JohnInJaxBK
Icon for Nimbostratus rankNimbostratus
Jun 08, 2021

SSL Bridging with URL Rewrite

I need to terminate SSL, rewrite the URL and URI, then send to the new destination server with SSL.

I have this working, but the SSL session resumption is failing so I have to re-handshake for every call. For a 20 millisecond server call, 80 milliseconds of handshaking is a non-starter.

What am I doing wrong?

when HTTP_REQUEST {
    #log local0. "host: [HTTP::host], uri: [HTTP::uri]"


    switch -glob [string tolower [HTTP::host]] {
        "apps.svr1.oscplatform.site" -
        "apps.svr2.oscplatform.site" -
        "apps.svr3.oscplatform.site" {
            # Example rewrite URL:
            # apps.svr1.oscplatform.site/rerwite/example-service/blah
			
            # Result after rule:
            # example-service.apps.svr1.oscplatform.site/blah


            # Removed the /rewrite/
            set svc_uri [substr [HTTP::uri] 9]
            #log local0. "svc_uri: $svc_uri"


            # Splits the remaining URI into service name and original URI.
            # 'example-service/blah' becomes 'example-service' and '/blah'
            set part_count [scan $svc_uri {%[^?/#]%s} svc uri]


            # If there was no original URI update it to blank.
            if { $part_count == 1 } {
                set uri ""
            }
            #log local0. "host: $svc.[HTTP::host] uri: '$uri'"


            # Set the new host value.
            HTTP::host "$svc.[HTTP::host]"


            # Update URI to the correct value.
            HTTP::uri  "$uri"
        }
    }


    # Set the value used in the SNI extension record.
    # This is used in the SSL handshake to the destination server.
    # This is how we implement SSL Bridging with a possible URL rewrite in the middle.
    set sni_value [HTTP::host]
}


when SERVERSSL_CLIENTHELLO_SEND {
    #log local0. "sni_value: $sni_value"


    # SNI extension record as defined in RFC 3546/3.1
    #
    # - TLS Extension Type       =  int16( 0 = SNI ) 
    # - TLS Extension Length     =  int16( $sni_length + 5 byte )
    # - SNI Record Length        =  int16( $sni_length + 3 byte)
    # - SNI Record Type          =   int8( 0 = HOST )
    # - SNI Record Value Length  =  int16( $sni_length )
    # - SNI Record Value         =    str( $sni_value )
    #
    # Calculate the length of the SNI value, Compute the SNI Record / TLS extension fields and add the result to the SERVERSSL_CLIENTHELLO 
    SSL::extensions insert [binary format SSScSa* 0 [expr { [set sni_length [string length $sni_value]] + 5 }] [expr { $sni_length + 3 }] 0 $sni_length $sni_value]
}

2 Replies

  • Your irule may require a

    SSL::renegotiate

    when SERVERSSL_HANDSHAKE {
       SSL::renegotiate enable
    }

    Rather than changing the SNI header like that, you could create multiple server-ssl profiles and set the appropriate SNI name in each profile.

    In the irule you can select the correct server-ssl profile with the SSL::profile command.

    You may still require the SSL::renegotiate if SSL negotiation has already occurred

  • Simon is right you can review devcentral for such issues as many people before, so I will advice for first to for older questions before writting a post.

     

     

     

    https://devcentral.f5.com/s/feed/0D51T000082mMgRSAU