Forum Discussion

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

URL Rewrite - Closes TLS session

I need to rewrite the client request to a form that the server needs.

Example:

apps.svr1.oscplatform.site/rewrite/example-app-name/blah

to this:

example-app-name.apps.svr1.oscplatform.site/blah

I have a rule working using HTTP_REQUEST event.

PROBLEM:

The TLS session to the client is invalidated when I change the host. So every single call has to do TLS handshake again.

Is there a way to prevent host header change killing the TLS session?

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-app-name/blah
			
            # Result after rule:
            # example-app-name.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.
            # systemdates-mwa/blah becomes systemdates-mwa 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]
}