Forum Discussion
Walker_111918
Nimbostratus
Apr 24, 2012Change SSL::profile depending on user-agent
Is it possible to change the SSL::profile depending on user-agent? I tried something like this:
fingerprint_sha hase 3 states:
0: not set
1: sha1
2: sha256
set fingerprint_sha 0
}
when HTTP_REQUEST {
if { $fingerprint_sha == 0 } {
if {[HTTP::header User-Agent] contains "Paul"} {
log local0.info "Paul"
set fingerprint_sha 1
} else {
log local0.info "nicht Paul"
set fingerprint_sha 2
SSL::profile profile2
}
}
}
The problem is that I couldn't user SSL::Profile in HTTP_REQUEST event. Does anyone have any ideas on it?
5 Replies
- hoolio
Cirrostratus
Hi Walker,
What's your goal for this? If you provide more detail we can try to suggest an alternative.
It's too late to change the client SSL profile for the current SSL session in HTTP_REQUEST as the session has already been established.
Aaron - Walker_111918
Nimbostratus
Our problem is, that we would like to use ssl-certificates with sha256. Windows XP with service pack 2 have an error so they could'nt finish the ssl-handshake with a sha256-certificate. My idea was that i try to start with a certifikate with sha1. If i know that the user doesn't use Windows XP with service pack 2 i would like to change the certificate to the sha256. - Joel_Moses
Nimbostratus
Here's an idea.
Windows XP doesn't present the SSL SNI field when setting up an SSL/TLS session. It's not a totally precise way to identify Windows XP (it will also get other browsers that don't send an SNI field), but it would let you switch the profile after the initial client SSL request -- which is absolutely possible. I wrote an iRule that switches pools and SSL profiles based on the SNI hostname:
https://devcentral.f5.com/wiki/iRules.TLS-ServerNameIndication.ashx
A modification to this rule could replace the default sha256-cert containing profile with the sha1 profile for browsers that don't seem to present SNI. That would include all XP users but present the "more secure" default cert for Vista/Win7. I'll see if I can find some time to try this. - Joel_Moses
Nimbostratus
I've not been able to fully verify syntax (let me know), but I think this might work for your purposes:when RULE_INIT { set static::alternate_profile_for_non_sni "clientssl_mysite_xp" } when CLIENT_ACCEPTED { if { [PROFILE::exists clientssl] } { set detect_non_sni 1 SSL::disable TCP::collect } else { log local0. "This iRule is applied to a VS that has no clientssl profile." set detect_non_sni 0 } } when CLIENT_DATA { if { ($detect_non_sni) } { binary scan [TCP::payload] cSS tls_xacttype tls_version tls_recordlen switch "$tls_version" { "769" - "770" - "771" { if { ($tls_xacttype == 22) } { binary scan [TCP::payload] @5c tls_action if { not (($tls_action == 1) && ([TCP::payload length] > $tls_recordlen)) } { set detect_non_sni 0 } } } default { set detect_non_sni 0 } } if { ($detect_non_sni) } { set record_offset 43 binary scan [TCP::payload] @${record_offset}c tls_sessidlen set record_offset [expr {$record_offset + 1 + $tls_sessidlen}] binary scan [TCP::payload] @${record_offset}S tls_ciphlen set record_offset [expr {$record_offset + 2 + $tls_ciphlen}] binary scan [TCP::payload] @${record_offset}c tls_complen set record_offset [expr {$record_offset + 1 + $tls_complen}] if { ([TCP::payload length] >= $record_offset) } { binary scan [TCP::payload] @${record_offset}S tls_extenlen set record_offset [expr {$record_offset + 2}] binary scan [TCP::payload] @${record_offset}a* tls_extensions for { set x 0 } { $x < $tls_extenlen } { incr x 4 } { set start [expr {$x}] binary scan $tls_extensions @${start}SS etype elen if { ($etype == "00") } { set grabstart [expr {$start + 9}] set grabend [expr {$elen - 5}] binary scan $tls_extensions @${grabstart}A${grabend} tls_servername set start [expr {$start + $elen}] } else { set start [expr {$start + $elen}] } set x $start } if { ([info exists tls_servername] ) } { SSL::enable } else { set ssl_profile_enable "SSL::profile $ssl_profile" catch { eval $ssl_profile_enable } SSL::enable } } else { SSL::enable } set detect_non_sni 0 TCP::release } else { set detect_non_sni 0 SSL::enable TCP::release } } }
This is modified from the SNI switching iRule and looks big and ugly, but it's really quite simple. If it does not find an SNI field in the client's first handshake, it switches the SSL profile to the alternate one named in RULE_INIT. Otherwise, it passes the connection through using whatever was previously set (so your SHA256 cert should be on the default clientssl profile). - Walker_111918
Nimbostratus
Thank you very much. I think we give it a try next week.
Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects
