CodeShare
Have some code. Share some code.
cancel
Showing results for 
Search instead for 
Did you mean: 
Kai_Wilke
MVP
MVP

Problem this snippet solves:

Hi Folks,

the iRule below can be used to inject a TLS SNI extension to the server side based on e.g. HOST-Header values. The iRule is usefull if your pool servers depending on valid SNI records and you don't want to configure dedicated Server SSL Profiles for each single web application.

Cheers, Kai

How to use this snippet:

  1. Attach the iRule to the Virtual Server where you need to insert a TLS SNI expension
  2. Tweak the
    $sni_value
    variable within the
    HTTP_REQUEST
    to meet your requirements or move it to a different event as needed.
  3. Make sure you've cleared the "Server Name" option in your Server_SSL_Profile.

Code :

when HTTP_REQUEST {
#Set the SNI value (e.g. HTTP::host)
set sni_value [getfield [HTTP::host] ":" 1]
}
when SERVERSSL_CLIENTHELLO_SEND {

# 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]

}

Tested this on version:

12.0
Comments
Stanislas_Piro2
Cumulonimbus
Cumulonimbus

Hi Kai,

Nice irule... I used this irule for APM portal access resource by replacing the

HTTP_REQUEST
event by
ACCESS_ACL_ALLOWED
.

and it worked.

Kai_Wilke
MVP
MVP

Hi Stanislas,

 

I've slightly optimized the iRule. Make sure to update your toolbox... 😉

 

Cheers, Kai

 

Stanislas_Piro2
Cumulonimbus
Cumulonimbus

4 lines for such need.... with encoding explanations!

 

Awesome!

 

Kai_Wilke
MVP
MVP

And its now ~4-times faster than before 🙂

 

Cheers, Kai

 

Impressive, five stars! 🙂

 

Stanislas_Piro2
Cumulonimbus
Cumulonimbus

Hi Kai,

 

with this optimized code, do you still use the "Client side to server side SNI relay iRule" or do you always use this one?

 

JoeTheFifth
Altostratus
Altostratus

I was redirected from this thread (https://devcentral.f5.com/questions/help-with-sni-not-being-passed-to-pool-serverscomment50962) to this one by Stanislas. I was struggling with two certs/two profiles with SNI support. couldn't make it work. I just tested this irule and it works fine. I wanted to use the default config instead of an irule as I already have a complex irule/apm setup but this solves my issue for the moment. I had a question in mind about how to make it work with two certs but I answered my question with a quick test. I created a client profile (no sni setting defined) and added the two certs ( with only one key otherwise you get the error 'Client SSL profile cannot contain more than one set of same certificate/key type'). I created a server profile (no sni no cert just inherited from th default ssl server). Pluged the iRule to the VS and voilà ! :-) Cheers ! But I'd like to know if configuring multiple profiles with sni entries (and a default sni profile) on a single VS work !

 

Stanislas_Piro2
Cumulonimbus
Cumulonimbus

you can configure on the virtual server multiple clientssl profile (to manage client servername certificate selection) and with only one serverssl profile with this irule.

 

Angorya
Nimbostratus
Nimbostratus

I still can't make it work. For some reason I don't know, the F5 is still sending its own hostname in the Client Hello.

 

Stanislas_Piro2
Cumulonimbus
Cumulonimbus

@angorya f5 can't know its own host name in irule. I guess you mean the host name of the virtual server!

 

If you use APM With rewrite mode, read my first comment!

 

This might be a bit out of context, but you can actually extract the hostname of the F5 from an iRule:

 

https://clouddocs.f5.com/api/irules/tcl_platform.html

 

Check out:

 

tcl_platform(machine)

 

/Patrik

 

Angorya
Nimbostratus
Nimbostratus

Stanislas, you're correct, I expressed myself incorrectly. It's sending the VS hostname.

 

I'm using APM with rewrite mode, so I followed your suggestion when I read this thread (I did test Kai's iRule too). I had the iRule log what it does, so I can see that the hostname that it's going to inject is the correct one, but in the packet capture I still see the VS hostname.

 

Edit: Just in case, this is in 13.0.0.

 

Dane_19050
Nimbostratus
Nimbostratus

@angorya, I am seeing the same behavior you are. I have a portal access profile setup to route traffic to an internal app. I used the rule above and the tcpdumps still show the original server name instead of the injected server name.

 

Kai_Wilke
MVP
MVP

Patrik mentioned:

tcl_platform(machine)

Hi Patrik, instead of using the slightly bugged tcl_platform(machine) global variable, you may try the build-in TCL command

[info hostname]
to easily access the HOST-Name of your F5.

Cheers, Kai

alex_talmage_28
Nimbostratus
Nimbostratus

I am struggling the same as Angorya and Dane to get this working with Portal-Access. Replaced HTTP_Request with ACCESS_ACL_ALLOWED and its still sending the original SNI

 

Angorya
Nimbostratus
Nimbostratus

F5 has it as a Known Issue for 13.0:

 

653495-1 : Incorrect SNI hostname attached to serverside connections

 

Component: Local Traffic Manager

 

Symptoms: SNI hostname submitted to a virtual server on the client side is sent to server side, even if there is a different hostname specified in the server SSL profile.

 

Conditions: -- Client side ClientHello contains SNI.

 

Impact: SNI is sent from client to server without stripping or rewriting the SNI.

 

Workaround: None.

 

It seems we have to wait for them to patch it...

 

Kai_Wilke
MVP
MVP

Hi Angorya,

 

Workaround: None.

 

Seems to be an dead end then, since you can not remove an existing SNI extension from the Handshake for now (see my prequisites Step 3.).

 

The last chance I see for you is by utilizing a VIP-targeting-VIP setup, so that you can still use SNI to flip SSL Profiles for the client side connection (aka. external VS) while making sure to not forward a SNI value to APM (aka. internal VS). At least this approach will allow you to mitigate the listed condition "Client side ClientHello contains SNI." and would then allow you to insert a SNI value of your choice on the connection between the internal VS and backend servers.

 

Cheers, Kai

 

Enrique_Estudil
Nimbostratus
Nimbostratus

Great iRule! Tested on 11.5.4 and works!

 

Christoph_Lange
Altostratus
Altostratus

I have two virtual servers with multiple server ssl profiles applied. One is working, the second only work with one domain. Replacing the multiple server ssl profiles with this irule solved the problem. Thanks!

 

Kai_Wilke
MVP
MVP

You're both very welcome!

 

Cheers, Kai

 

youssef_100679
Nimbostratus
Nimbostratus

Good JOB!!!

 

kgaigl
Cirrostratus
Cirrostratus

Hello Kai,

 

could you please explain, how to tweak the sni_value? I'm to stupid to get this...

 

we've 2 servernames behind a Portal-Access (different from the FQDN of Client-Side), now only the one works, I insert the servername in the sni-field of the SSL-Profile.

 

But what would there be the $sni_value ? At the moment I don't get it.

 

thanks

 

Karl

 

Stanislas_Piro2
Cumulonimbus
Cumulonimbus

Hello kgaigl,

 

look at the first comment above...

 

Kai_Wilke
MVP
MVP

Hi kgaigl,

the iRule uses the

HTTP_REQUEST
event to extract the HOST-header value of the client requested ressource. This value is then used as Server_SSL SNI-Value.

If the client requests https://www.domain.com/ the Server_SSL SNI-Value will become If the client requests https://ww2.domain.com/ the Server_SSL SNI-Value will become ww2.domain.com

Note: You may use whatever logic during the

HTTP_REQUEST
event you like to decide which SNI-Value should be used to negotiate the Server Side SSL connection.

Important: To make this iRule work you have to make sure that you dont specify a SNI-Value in your Server_SSL_Profile. This will allow the iRule to simply inject the SNI-Value without clearing existing values (aka. clearing existing values is not supported). If you set the "Server Name" option in your Server_SSL_Profile, the SSL negotiation will most likely fail...

Cheers, Kai

kgaigl
Cirrostratus
Cirrostratus

Hi Stanislas,

 

that did it, thanks a lot.

 

Hi Kai, thanks too for explaining and for the Rule

 

Karl

 

dragonflymr
Cirrostratus
Cirrostratus

Hi Kay,

Actually Server Name can be enabled, it just has to be empty. Wonder why not use something like that in SERVERSSL_CLIENTHELLO_SEND:

clientside {
   set sni_value [getfield [HTTP::host] ":" 1]
   log local0. "SNI should be: \"$sni_value\""
}

I know that TCL error ("{badEventContext {command is not valid in current event context (SERVER_CONNECTED)} is generated when saving iRule but according to support as long as you are actually processing HTTP at clientside this will work without issue - and indeed it works for me.

Any comments why not to use?

Piotr

Leonardo_Souza
Cirrocumulus
Cirrocumulus

This is now part of an askf5 solution:

https://support.f5.com/csp/article/K41600007

kernelpanic1
Nimbostratus
Nimbostratus

Has this been fixed in v14?

 

Leonardo_Souza
Cirrocumulus
Cirrocumulus
dragonflymr
Cirrostratus
Cirrostratus

  and we know that it's more advanced now because of CLI only parameter for virtual 🙂

Version history
Last update:
‎05-Jun-2023 22:48
Updated by: