Skip to content

Commit

Permalink
Merge d9470dc into a8e151e
Browse files Browse the repository at this point in the history
  • Loading branch information
vklohiya committed May 7, 2024
2 parents a8e151e + d9470dc commit a7af551
Show file tree
Hide file tree
Showing 3 changed files with 250 additions and 218 deletions.
2 changes: 2 additions & 0 deletions docs/RELEASE-NOTES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ Added Functionality
* Multi Cluster
* CRD
* Support for Calico CNI with Static Routing Mode, See `Documentation <https://github.com/F5Networks/k8s-bigip-ctlr/blob/2.x-master/docs/config_examples/StaticRoute/README.md>`_

Bug Fixes
````````````
* `Issue 3371 https://github.com/F5Networks/k8s-bigip-ctlr/issues/3371`_: CIS added irules cannot have "event disable all"
* `Issue 3402 https://github.com/F5Networks/k8s-bigip-ctlr/issues/3402`_: TLS iRule fails after recent browser updates
* Fix for EDNS pool member empty issue.


Expand Down
219 changes: 117 additions & 102 deletions pkg/appmanager/routing.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,111 +267,127 @@ func (appMgr *Manager) sslPassthroughIRule() string {
# Bytes 1-2 are the TLS version.
# Bytes 3-4 are the TLS payload length.
# Bytes 5-$tls_payload_len are the TLS payload.
binary scan [TCP::payload] cSS tls_content_type tls_version tls_payload_len
if { ! [ expr { [info exists tls_content_type] && [string is integer -strict $tls_content_type] } ] } { reject ; event disable all; return; }
if { ! [ expr { [info exists tls_version] && [string is integer -strict $tls_version] } ] } { reject ; event disable all; return; }
switch -exact $tls_version {
"769" -
"770" -
"771" {
# Content type of 22 indicates the TLS payload contains a handshake.
if { $tls_content_type == 22 } {
# Byte 5 (the first byte of the handshake) indicates the handshake
# record type, and a value of 1 signifies that the handshake record is
# a ClientHello.
binary scan [TCP::payload] @5c tls_handshake_record_type
if { ! [ expr { [info exists tls_handshake_record_type] && [string is integer -strict $tls_handshake_record_type] } ] } { reject ; event disable all; return; }
if { $tls_handshake_record_type == 1 } {
# Bytes 6-8 are the handshake length (which we ignore).
# Bytes 9-10 are the TLS version (which we ignore).
# Bytes 11-42 are random data (which we ignore).
# Byte 43 is the session ID length. Following this are three
# variable-length fields which we shall skip over.
set record_offset 43
# Skip the session ID.
binary scan [TCP::payload] @${record_offset}c tls_session_id_len
if { ! [ expr { [info exists tls_session_id_len] && [string is integer -strict $tls_session_id_len] } ] } { reject ; event disable all; return; }
incr record_offset [expr {1 + $tls_session_id_len}]
# Skip the cipher_suites field.
binary scan [TCP::payload] @${record_offset}S tls_cipher_suites_len
if { ! [ expr { [info exists tls_cipher_suites_len] && [string is integer -strict $tls_cipher_suites_len] } ] } { reject ; event disable all; return; }
incr record_offset [expr {2 + $tls_cipher_suites_len}]
# Skip the compression_methods field.
binary scan [TCP::payload] @${record_offset}c tls_compression_methods_len
if { ! [ expr { [info exists tls_compression_methods_len] && [string is integer -strict $tls_compression_methods_len] } ] } { reject ; event disable all; return; }
incr record_offset [expr {1 + $tls_compression_methods_len}]
# Get the number of extensions, and store the extensions.
binary scan [TCP::payload] @${record_offset}S tls_extensions_len
if { ! [ expr { [info exists tls_extensions_len] && [string is integer -strict $tls_extensions_len] } ] } { reject ; event disable all; return; }
incr record_offset 2
binary scan [TCP::payload] @${record_offset}a* tls_extensions
if { ! [info exists tls_extensions] } { reject ; event disable all; return; }
for { set extension_start 0 }
{ $tls_extensions_len - $extension_start == abs($tls_extensions_len - $extension_start) }
{ incr extension_start 4 } {
# Bytes 0-1 of the extension are the extension type.
# Bytes 2-3 of the extension are the extension length.
binary scan $tls_extensions @${extension_start}SS extension_type extension_len
if { ! [ expr { [info exists extension_type] && [string is integer -strict $extension_type] } ] } { reject ; event disable all; return; }
if { ! [ expr { [info exists extension_len] && [string is integer -strict $extension_len] } ] } { reject ; event disable all; return; }
# Extension type 00 is the ServerName extension.
if { $extension_type == "00" } {
# Bytes 4-5 of the extension are the SNI length (we ignore this).
# Byte 6 of the extension is the SNI type.
set sni_type_offset [expr {$extension_start + 6}]
binary scan $tls_extensions @${sni_type_offset}S sni_type
if { ! [ expr { [info exists sni_type] && [string is integer -strict $sni_type] } ] } { reject ; event disable all; return; }
# Type 0 is host_name.
if { $sni_type == "0" } {
# Bytes 7-8 of the extension are the SNI data (host_name)
# length.
set sni_len_offset [expr {$extension_start + 7}]
binary scan $tls_extensions @${sni_len_offset}S sni_len
if { ! [ expr { [info exists sni_len] && [string is integer -strict $sni_len] } ] } { reject ; event disable all; return; }
# Bytes 9-$sni_len are the SNI data (host_name).
set sni_start [expr {$extension_start + 9}]
binary scan $tls_extensions @${sni_start}A${sni_len} tls_servername
set payload [TCP::payload]
set payloadlen [TCP::payload length]
if {![info exists payloadscan]} {
set payloadscan [binary scan $payload cSS tls_content_type tls_version tls_payload_len ]
}
if {($payloadscan == 3)} {
if {($tls_payload_len < 0 || $tls_payload_len > 16389)} {
log local0.warn "[IP::remote_addr] : parsed SSL/TLS record length ${tls_payload_len} outside of handled length (0..16389)"
reject
return
} elseif {($payloadlen < $tls_payload_len+5)} {
TCP::collect [expr {$tls_payload_len +5 - $payloadlen}]
return
}
if { ! [ expr { [info exists tls_content_type] && [string is integer -strict $tls_content_type] } ] } { reject ; event disable all; return; }
if { ! [ expr { [info exists tls_version] && [string is integer -strict $tls_version] } ] } { reject ; event disable all; return; }
switch -exact $tls_version {
"769" -
"770" -
"771" {
# Content type of 22 indicates the TLS payload contains a handshake.
if { $tls_content_type == 22 } {
# Byte 5 (the first byte of the handshake) indicates the handshake
# record type, and a value of 1 signifies that the handshake record is
# a ClientHello.
binary scan [TCP::payload] @5c tls_handshake_record_type
if { ! [ expr { [info exists tls_handshake_record_type] && [string is integer -strict $tls_handshake_record_type] } ] } { reject ; event disable all; return; }
if { $tls_handshake_record_type == 1 } {
# Bytes 6-8 are the handshake length (which we ignore).
# Bytes 9-10 are the TLS version (which we ignore).
# Bytes 11-42 are random data (which we ignore).
# Byte 43 is the session ID length. Following this are three
# variable-length fields which we shall skip over.
set record_offset 43
# Skip the session ID.
binary scan [TCP::payload] @${record_offset}c tls_session_id_len
if { ! [ expr { [info exists tls_session_id_len] && [string is integer -strict $tls_session_id_len] } ] } { reject ; event disable all; return; }
incr record_offset [expr {1 + $tls_session_id_len}]
# Skip the cipher_suites field.
binary scan [TCP::payload] @${record_offset}S tls_cipher_suites_len
if { ! [ expr { [info exists tls_cipher_suites_len] && [string is integer -strict $tls_cipher_suites_len] } ] } { reject ; event disable all; return; }
incr record_offset [expr {2 + $tls_cipher_suites_len}]
# Skip the compression_methods field.
binary scan [TCP::payload] @${record_offset}c tls_compression_methods_len
if { ! [ expr { [info exists tls_compression_methods_len] && [string is integer -strict $tls_compression_methods_len] } ] } { reject ; event disable all; return; }
incr record_offset [expr {1 + $tls_compression_methods_len}]
# Get the number of extensions, and store the extensions.
binary scan [TCP::payload] @${record_offset}S tls_extensions_len
if { ! [ expr { [info exists tls_extensions_len] && [string is integer -strict $tls_extensions_len] } ] } { reject ; event disable all; return; }
incr record_offset 2
binary scan [TCP::payload] @${record_offset}a* tls_extensions
if { ! [info exists tls_extensions] } { reject ; event disable all; return; }
for { set extension_start 0 }
{ $tls_extensions_len - $extension_start == abs($tls_extensions_len - $extension_start) }
{ incr extension_start 4 } {
# Bytes 0-1 of the extension are the extension type.
# Bytes 2-3 of the extension are the extension length.
binary scan $tls_extensions @${extension_start}SS extension_type extension_len
if { ! [ expr { [info exists extension_type] && [string is integer -strict $extension_type] } ] } { reject ; event disable all; return; }
if { ! [ expr { [info exists extension_len] && [string is integer -strict $extension_len] } ] } { reject ; event disable all; return; }
# Extension type 00 is the ServerName extension.
if { $extension_type == "00" } {
# Bytes 4-5 of the extension are the SNI length (we ignore this).
# Byte 6 of the extension is the SNI type.
set sni_type_offset [expr {$extension_start + 6}]
binary scan $tls_extensions @${sni_type_offset}S sni_type
if { ! [ expr { [info exists sni_type] && [string is integer -strict $sni_type] } ] } { reject ; event disable all; return; }
# Type 0 is host_name.
if { $sni_type == "0" } {
# Bytes 7-8 of the extension are the SNI data (host_name)
# length.
set sni_len_offset [expr {$extension_start + 7}]
binary scan $tls_extensions @${sni_len_offset}S sni_len
if { ! [ expr { [info exists sni_len] && [string is integer -strict $sni_len] } ] } { reject ; event disable all; return; }
# Bytes 9-$sni_len are the SNI data (host_name).
set sni_start [expr {$extension_start + 9}]
binary scan $tls_extensions @${sni_start}A${sni_len} tls_servername
}
}
incr extension_start $extension_len
}
incr extension_start $extension_len
}
if { [info exists tls_servername] } {
set passthru_class "/%[1]s/ssl_passthrough_servername_dg"
if { [class exists $passthru_class] } {
set servername_lower [string tolower $tls_servername]
SSL::disable serverside
set dflt_pool_passthrough ""
# Disable Serverside SSL for Passthrough Class
set dflt_pool_passthrough [class match -value $servername_lower equals $passthru_class]
if { not ($dflt_pool_passthrough equals "") } {
SSL::disable
HTTP::disable
}
set ab_class "/%[1]s/ab_deployment_dg"
if { not [class exists $ab_class] } {
if { $dflt_pool_passthrough == "" } then {
log local0.debug "Failed to find pool for $servername_lower"
} else {
pool $dflt_pool_passthrough
if { [info exists tls_servername] } {
set passthru_class "/%[1]s/ssl_passthrough_servername_dg"
if { [class exists $passthru_class] } {
set servername_lower [string tolower $tls_servername]
SSL::disable serverside
set dflt_pool_passthrough ""
# Disable Serverside SSL for Passthrough Class
set dflt_pool_passthrough [class match -value $servername_lower equals $passthru_class]
if { not ($dflt_pool_passthrough equals "") } {
SSL::disable
HTTP::disable
}
} else {
set selected_pool [call select_ab_pool $servername_lower $dflt_pool_passthrough]
if { $selected_pool == "" } then {
log local0.debug "Failed to find pool for $servername_lower"
set ab_class "/%[1]s/ab_deployment_dg"
if { not [class exists $ab_class] } {
if { $dflt_pool_passthrough == "" } then {
log local0.debug "Failed to find pool for $servername_lower"
} else {
pool $dflt_pool_passthrough
}
} else {
pool $selected_pool
set selected_pool [call select_ab_pool $servername_lower $dflt_pool_passthrough]
if { $selected_pool == "" } then {
log local0.debug "Failed to find pool for $servername_lower"
} else {
pool $selected_pool
}
}
}
}
Expand All @@ -380,7 +396,6 @@ func (appMgr *Manager) sslPassthroughIRule() string {
}
}
}
TCP::release
}
Expand Down
Loading

0 comments on commit a7af551

Please sign in to comment.