TLS Fingerprinting JA3 iRule Application: Rate limit and block malicious traffic based on TLS signature

In this article, we use the same techniques, as some previous authors, to enable a TLS Fingerprinting iRule and proc to rate limit and block TLS clients based on generated TLS signatures.

Related Resources

Sample Application: Protecting IMAPS/POP3S service

IMAPS/POP3S has been around for a long time and are also a target of brute force attacks. We will use the TLS Fingerprinting iRule and proc to generate a TLS signature and then rate limit a specific client or block a specific TLS signature .

Using the "Library Rule" from https://devcentral.f5.com/s/articles/TLS-Fingerprinting-to-profile-SSL-TLS-clients-without-decryption, we create the proc iRule, I will name it "fingerprintTLSproc". You can name it as you per your needs, just note that it is important to remember the name of the proc iRule as it will be referenced in next iRule - the rate limiting/block iRule. This will be listed as iRule#1. Note that this iRule does not need to be applied to a Virtual Server.

iRule#1 - fingerprintTLSproc

## Library-Rule


## JA3 TLS Fingerprint Procedure #################
##
## Author: Aaron Brailsford, 06/2020
## Based on the TLS Fingerprinting iRule by Kevin Stewart @ https://devcentral.f5.com/s/articles/tls-fingerprinting-a-method-for-identifying-a-tls-client-without-decrypting-24598
## Derived from Lee Brotherston's "tls-fingerprinting" project @ https://github.com/LeeBrotherston/tls-fingerprinting
## Purpose: to identify the user agent based on unique characteristics of the TLS ClientHello message
## Input:
##   Full TCP payload collected in CLIENT_DATA event of a TLS handshake ClientHello message
##   Record length (rlen)
##   TLS inner version (sslversion)
##############################################
proc fingerprintTLS { payload rlen sslversion } {


  ## The first 43 bytes of a ClientHello message are the record type, TLS versions, some length values and the
  ## handshake type. We should already know this stuff from the calling iRule. We're also going to be walking the
  ## packet, so the field_offset variable will be used to track where we are.
  set field_offset 43


  ## The first value in the payload after the offset is the session ID, which may be empty. Grab the session ID length
  ## value and move the field_offset variable that many bytes forward to skip it.
  binary scan ${payload} @${field_offset}c sessID_len
  set field_offset [expr {${field_offset} + 1 + ${sessID_len}}]


  ## The next value in the payload is the ciphersuite list length (how big the ciphersuite list is.
  binary scan ${payload} @${field_offset}S cipherList_len


  ## Now that we have the ciphersuite list length, let's offset the field_offset variable to skip over the length (2) bytes
  ## and go get the ciphersuite list.
  set field_offset [expr {${field_offset} + 2}]
  binary scan ${payload} @${field_offset}S[expr {${cipherList_len} / 2}] cipherlist_decimal


  ## Next is the compression method length and compression method. First move field_offset to skip past the ciphersuite
  ## list, then grab the compression method length. Then move field_offset past the length (2)
  ## Finally, move field_offset past the compression method bytes.
  set field_offset [expr {${field_offset} + ${cipherList_len}}]
  binary scan ${payload} @${field_offset}c compression_len
  set field_offset [expr {${field_offset} + 1}]
  set field_offset [expr {${field_offset} + ${compression_len}}]


  ## We should be in the extensions section now, so we're going to just run through the remaining data and
  ## pick out the extensions as we go. But first let's make sure there's more record data left, based on
  ## the current field_offset vs. rlen.
  if { [expr {${field_offset} < ${rlen}}] } {
    ## There's extension data, so let's go get it. Skip the first 2 bytes that are the extensions length
    set field_offset [expr {${field_offset} + 2}]


    ## Make a variable to store the extension types we find
    set extensions_list ""


    ## Pad rlen by 1 byte
    set rlen [expr {${rlen} + 1}]


    while { [expr {${field_offset} <= ${rlen}}] } {
      ## Grab the first 2 bytes to determine the extension type
      binary scan ${payload} @${field_offset}S ext
      set ext [expr {$ext & 0xFFFF}]


      ## Store the extension in the extensions_list variable
      lappend extensions_list ${ext}


      ## Increment field_offset past the 2 bytes of the extension type
      set field_offset [expr {${field_offset} + 2}]


      ## Grab the 2 bytes of extension lenth
      binary scan ${payload} @${field_offset}S ext_len


      ## Increment field_offset past the 2 bytes of the extension length
      set field_offset [expr {${field_offset} + 2}]


      ## Look for specific extension types in case these need to increment the field_offset (and because we need their values)
      switch $ext {
        "11" {
          ## ec_point_format - there's another 1 byte after length
          ## Grab the extension data
          binary scan ${payload} @[expr {${field_offset} + 1}]s ext_data
          set ec_point_format ${ext_data}
        }
        "10" {
          ## elliptic_curves - there's another 2 bytes after length
          ## Grab the extension data
          binary scan ${payload} @[expr {${field_offset} + 2}]S[expr {(${ext_len} - 2) / 2}] ext_data
          set elliptic_curves ${ext_data}
        }
        default {
          ## Grab the otherwise unknown extension data
          binary scan ${payload} @${field_offset}H[expr {${ext_len} * 2}] ext_data
        }
      }


      ## Increment the field_offset past the extension data length. Repeat this loop until we reach rlen (the end of the payload)
      set field_offset [expr {${field_offset} + ${ext_len}}]
    }
  }


  ## Now let's compile all of that data.
  ## The cipherlist values need masking with 0xFFFF to return the unsigned integers we need
  foreach cipher $cipherlist_decimal {
   lappend cipd [expr {$cipher & 0xFFFF}]
  }
  set cipd_str [join $cipd "-"]
  if { ( [info exists extensions_list] ) and ( ${extensions_list} ne "" ) } { set exte [join ${extensions_list} "-"] } else { set exte "" }
  if { ( [info exists elliptic_curves] ) and ( ${elliptic_curves} ne "" ) } { set ecur [join ${elliptic_curves} "-"] } else { set ecur "" }
  if { ( [info exists ec_point_format] ) and ( ${ec_point_format} ne "" ) } { set ecfp [join ${ec_point_format} "-"] } else { set ecfp "" }


  set ja3_str "${sslversion},${cipd_str},${exte},${ecur},${ecfp}"
  ## binary scan [md5 ${ja3_str}] H* ja3_digest


  ## Un-comment this line to display the fingerprint string in the LTM log for troubleshooting
  #log local0. "ja3 = ${ja3_str}"


  return ${ja3_str}
}

Here is the rate limiting / blocking iRule. This iRule will monitor TLS signatures and a corresponding IP address and if it exceeds the defined maximum rate of requests - the maxRate variable - the iRule will drop the traffic from the specific client IP and TLS signature. There is also a logic to check a known malicious TLS signature defined in a iRule Datagroup and if it matches, the iRule will drop the connection. I have named this iRule fingerprintTLSirule-ratelimit and listed as iRule#2. Note in this iRule, you will have to properly reference proc iRule for the detected signatures be checked -  see the section of this iRule commented  "## Call the fingerprintTLS proc".

Note the syntax in the reference line for calling the proc iRule is "call <iRule>:<proc>" . Note as well that this fingerprintTLSirule-ratelimit iRule need to be applied to a Virtual Server.

Note the "static::maxRate" variable as this controls the maxim number of requests before iRule rate limits a TLS signature hash and IP address combination. Adjust this value as per your needs.

iRule#2: fingerprintTLSirule-ratelimit                                               

when RULE_INIT {
  # Default rate to limit requests
  set static::maxRate 15
  # Default rate to
  set static::warnRate 12
  # During this many seconds
  set static::timeout 1
}
when CLIENT_ACCEPTED {
  ## Collect the TCP payload
  TCP::collect
}
when CLIENT_DATA {
  ## Get the TLS packet type and versions
  if { ! [info exists rlen] } {
    ## We actually only need the recort type (rtype), record length (rlen) handshake type (hs_type) and 'inner' SSL version (inner_sslver) here
    ## But it's easiest to parse them all out of the payload along with the bytes we don't need (outer_sslver & rilen)
    binary scan [TCP::payload] cSScH6S rtype outer_sslver rlen hs_type rilen inner_sslver


    if { ( ${rtype} == 22 ) and ( ${hs_type} == 1 ) } {
      ## This is a TLS ClientHello message (22 = TLS handshake, 1 = ClientHello)


      ## Call the fingerprintTLS proc
      set ja3_fingerprint [call fingerprintTLSproc::fingerprintTLS [TCP::payload] ${rlen} ${inner_sslver}]
      binary scan [md5 ${ja3_fingerprint}] H* ja3_digest


### Do Something here ###
      log local0. "[IP::client_addr]:[TCP::client_port] ja3 ${ja3_fingerprint}->${ja3_digest}"


#check if fingerprint matches a known malicious fingerprint, if yes, drop connection
if {[class match ${ja3_fingerprint} equals malicious_fingerprintdb]}{
set malicious_fingerprint [class match -value ${ja3_fingerprint} equals malicious_TLSfingerprintdb]
drop
log local0. "known malicious fingerprint matched $malicious_fingerprint - Action:DROP!"
} 


#use generated digest of the signature for rate limiting
set suspicious_fingerprint ${ja3_digest}
#rate limit fingerprint
# Increment and Get the current request count bucket
#set epoch [clock seconds]


#monitor an unrecognized fingerprint and rate limit it
set currentCount [table incr -mustexist "Count_[IP::client_addr]_${suspicious_fingerprint}"]
if { $currentCount eq "" } {
# Initialize a new request count bucket
table set "Count_[IP::client_addr]_${suspicious_fingerprint}" 1 indef $static::timeout
set currentCount 1
}


# Actually check fingerprint for being over limit
if { $currentCount >= $static::maxRate } {
log local0. "ERROR: fingerprint:[IP::client_addr]_${suspicious_fingerprint} exceeded ${static::maxRate} requests per second. Rejecting request. Current requests: ${currentCount}."
event disable all
drop
}
if { $currentCount > $static::warnRate } {
log local0. "WARNING: fingerprint:[IP::client_addr]_${suspicious_fingerprint} exceeded ${static::warnRate} requests per second. Will reject at ${static::maxRate}. Current requests: ${currentCount}."
}
log local0. "fingerprint:[IP::client_addr]_${suspicious_fingerprint}: currentCount: ${currentCount}"
### Do Something here ###


    }
  }


  # Collect the rest of the record if necessary
  if { [TCP::payload length] < $rlen } {
    TCP::collect $rlen
  }


  ## Release the paylaod
  TCP::release
}

Sample Test Output

A curl client simulates as an imaps (secure) client and successfully lists the folders for the sample user

[root@curlclient] config # curl -k --url = "imaps://172.16.0.30/" --user "lala:lala" -v
* Rebuilt URL to: =/
* Could not resolve host: =
* Closing connection 0
curl: (6) Could not resolve host: =
*   Trying 172.16.0.30...
* Connected to 172.16.0.30 (172.16.0.30) port 993 (#1)
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* Server certificate:
*        subject: C=US; ST=WA; L=Seattle; O=MyCompany; OU=IT; CN=localhost.localdomain; emailAddress=root@localhost.localdomain
*        start date: May 13 13:57:07 2020 GMT
*        expire date: May 11 13:57:07 2030 GMT
*        issuer: C=US; ST=WA; L=Seattle; O=MyCompany; OU=IT; CN=localhost.localdomain; emailAddress=root@localhost.localdomain
*        SSL certificate verify result: self signed certificate (18), continuing anyway.
< * OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE AUTH=PLAIN] Dovecot (Ubuntu) ready.
> B001 CAPABILITY
< * CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE AUTH=PLAIN
< B001 OK Pre-login capabilities listed, post-login capabilities have more.
> B002 AUTHENTICATE PLAIN bGFsYQBsYWxhAGxhbGE=
< * CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS BINARY MOVE
< B002 OK Logged in
> B003 LIST "" *
< * LIST (\HasNoChildren \Drafts) "." Drafts
* LIST (\HasNoChildren \Drafts) "." Drafts
< * LIST (\HasNoChildren \Sent) "." Sent
* LIST (\HasNoChildren \Sent) "." Sent
< * LIST (\HasNoChildren \Trash) "." Trash
* LIST (\HasNoChildren \Trash) "." Trash
< * LIST (\HasNoChildren) "." Templates
* LIST (\HasNoChildren) "." Templates
< * LIST (\HasNoChildren) "." INBOX
* LIST (\HasNoChildren) "." INBOX
< B003 OK List completed (0.001 + 0.000 secs).
* Connection #1 to host 172.16.0.30 left intact

The iRule fingerprintTLSirule-ratelimit will log the TLS signature generated when it called the fingerprintTLSproc::fingerprintTLS proc. The reference log can be seen in /var/log/ltm file of the BIG-IP as per configured in the iRule. The logs can be also be sent to a high speed logging server.

Jul 24 02:40:09 behavioral-dos-v15 info tmm1[11152]: Rule /Common/fingerprintTLSirule <CLIENT_DATA>: 172.16.7.31:59158 ja3 771,49200-49196-49192-49188-49172-49162-163-159-107-106-57-56-136-135-49202-49198-49194-49190-49167-49157-157-61-53-132-49199-49195-49191-49187-49171-49161-162-158-103-64-51-50-154-153-69-68-49201-49197-49193-49189-49166-49156-156-60-47-150-65-49170-49160-22-19-49165-49155-10-255,11-10-13-15-13172,25-24-22-23-20-21-18-19-15-16-17,256->19e387a2748bc0f70bc463d3af4cd04a

the TLS signature here is:

771,49200-49196-49192-49188-49172-49162-163-159-107-106-57-56-136-135-49202-49198-49194-49190-49167-49157-157-61-53-132-49199-49195-49191-49187-49171-49161-162-158-103-64-51-50-154-153-69-68-49201-49197-49193-49189-49166-49156-156-60-47-150-65-49170-49160-22-19-49165-49155-10-255,11-10-13-15-13172,25-24-22-23-20-21-18-19-15-16-17,256

This TLS signature can be defined in an iRule Datagroup and be matched as either a known good or bad TLS signature. As noted earlier, the iRule fingerprintTLSirule-ratelimit includes a logic block to drop known malicious TLS signature.

mutt is a mail client in linux and if it connects to the reference Virtual Server where the fingerprintTLSirule-ratelimit iRule is applied, this is the sample TLS signature in the generated log

Jul 24 02:37:35 behavioral-dos-v15 info tmm1[11152]: Rule /Common/fingerprintTLSirule <CLIENT_DATA>: 172.16.10.31:51844 ja3 771,4866-4867-4865-4868-49196-52393-49325-49162-49195-49324-49161-49200-52392-49172-49199-49171-157-49309-53-156-49308-47-159-52394-49311-57-158-49310-51,5-10-11-13-22-23-35-51-43-65281-0-45-28,23-24-25-29-30-256-257-258-259-260,0->f35ce21b44ac0b87d3266294bb1b0e20

mutt client's TLS signature is:

4866-4867-4865-4868-49196-52393-49325-49162-49195-49324-49161-49200-52392-49172-49199-49171-157-49309-53-156-49308-47-159-52394-49311-57-158-49310-51,5-10-11-13-22-23-35-51-43-65281-0-45-28,23-24-25-29-30-256-257-258-259-260

nmap has a NSE script that can brute force an imap service. This can be used ethically, however, it also possible to be used for malicious purpose. For testing purpose, I ran a nmap imap-brute NSE scan on a Virtual Server and as it is expected to send brute force traffic, there were multiple instances of the generated TLS signature.

Jul 24 02:49:04 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule <CLIENT_DATA>: 172.16.10.31:51974 ja3 771,4866-4867-4865-51-57-53-47-49196-49200-163-159-52393-52392-52394-49327-49325-49315-49311-49245-49249-49239-49235-49195-49199-162-158-49326-49324-49314-49310-49244-49248-49238-49234-49188-49192-107-106-49267-49271-196-195-49187-49191-103-64-49266-49270-190-189-49162-49172-56-136-135-49161-49171-50-154-153-69-68-157-49313-49309-49233-156-49312-49308-49232-61-192-60-186-132-150-65-255,11-10-35-22-23-13-43-45-51-21,29-23-30-25-24,256->912a836a48eb490e243eb28eef562687

nmap imap-brute generated TLS signature is:

 771,4866-4867-4865-51-57-53-47-49196-49200-163-159-52393-52392-52394-49327-49325-49315-49311-49245-49249-49239-49235-49195-49199-162-158-49326-49324-49314-49310-49244-49248-49238-49234-49188-49192-107-106-49267-49271-196-195-49187-49191-103-64-49266-49270-190-189-49162-49172-56-136-135-49161-49171-50-154-153-69-68-157-49313-49309-49233-156-49312-49308-49232-61-192-60-186-132-150-65-255,11-10-35-22-23-13-43-45-51-21,29-23-30-25-24,256

The occurrence of nmap imap-brute TLS signature was increasing as the nmap script brute forces the IMAP Virtual Server. Note in this output, the hash of the signature "912a836a48eb490e243eb28eef562687" was used as the search string,

[root@behavioral-dos-v15:Active:Standalone] config # grep 912a836a48eb490e243eb28eef562687 /var/log/ltm | wc -l
122

[root@behavioral-dos-v15:Active:Standalone] config # grep 912a836a48eb490e243eb28eef562687 /var/log/ltm | wc -l

262

[root@behavioral-dos-v15:Active:Standalone] config # grep 912a836a48eb490e243eb28eef562687 /var/log/ltm | wc -l

402

[root@behavioral-dos-v15:Active:Standalone] config # grep 912a836a48eb490e243eb28eef562687 /var/log/ltm | wc -l

522

As in this test nmap scan, if we want to block nmap from scanning the IMAP Virtual Server, we can define the detected TLS Signature to a iRule Datagroup and when its matched, the traffic will be dropped.

Here is the sample iRule Datagroup of type String. The TLS signature is added in the String part and the value is a name for the TLS signature

Here is a sample log when fingerprintTLSirule-ratelimit iRule drops the connection from the known malicious TLS signature

Jul 24 04:06:04 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: 172.16.10.31:57434 ja3 771,4866-4867-4865-51-57-53-47-49196-49200-163-159-52393-52392-52394-49327-49325-49315-49311-49245-49249-49239-49235-49195-49199-162-158-49326-49324-49314-49310-49244-49248-49238-49234-49188-49192-107-106-49267-49271-196-195-49187-49191-103-64-49266-49270-190-189-49162-49172-56-136-135-49161-49171-50-154-153-69-68-157-49313-49309-49233-156-49312-49308-49232-61-192-60-186-132-150-65-255,11-10-35-22-23-13-43-45-51-21,29-23-30-25-24,256->912a836a48eb490e243eb28eef562687

Jul 24 04:06:04 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: known malicious fingerprint matched nmapscanner - Action:DROP!

Jul 24 04:06:04 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687: currentCount: 1
Jul 24 04:06:04 behavioral-dos-v15 warning tmm[11152]: 01260009:4: 172.16.10.31:57434 -> 172.16.0.30:993: Connection error: hud_ssl_handler:1202: alert(40) invalid profile unknown on VIP /Common/dos-vs-v15

You may want to use this when you have determined a TLS signature to be malicious.

The fingerprintTLSirule-ratelimit iRule also have a rate limiting logic. TLS signatures hash can be generated and along with the client IP address, you can isolate and rate limit traffic should it exceeds the defined maximum rate of requests.

Here is the sample log where I ran the nmap script imap-brute, it was fingerprinted and applied rate limiting thru the iRule fingerprintTLSirule-ratelimit

[root@behavioral-dos-v15:Active:Standalone] config # grep -i Rejecting /var/log/ltm
Jul 24 03:16:43 behavioral-dos-v15 info tmm1[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 15.
Jul 24 03:16:43 behavioral-dos-v15 info tmm1[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 16.
Jul 24 03:16:43 behavioral-dos-v15 info tmm1[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 17.
Jul 24 03:16:43 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 18.
Jul 24 03:16:43 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 19.
Jul 24 03:16:43 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 20.
Jul 24 03:17:29 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 15.
Jul 24 03:17:51 behavioral-dos-v15 info tmm1[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 15.
Jul 24 03:19:20 behavioral-dos-v15 info tmm1[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 15.
Jul 24 03:19:20 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 16.
Jul 24 03:19:20 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 17.
Jul 24 03:19:20 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 18.
Jul 24 03:19:21 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 20.
Jul 24 03:19:32 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 15.
Jul 24 03:19:32 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 16.
Jul 24 03:19:32 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 17.
Jul 24 03:19:33 behavioral-dos-v15 info tmm1[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 18.
Jul 24 03:20:18 behavioral-dos-v15 info tmm1[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 15.
Jul 24 03:20:18 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 16.
[root@behavioral-dos-v15:Active:Standalone] config #

Considerations

iRule operation are CPU intensive, thus, expect an increase in CPU usage on the BIG-IP. The sample iRule here were tested in a controlled lab environment. Please test the iRules before applying to your production traffic. These iRules can be useful to quickly mitigate an attack or unexpected traffic and a trade off of additional CPU resource usage increase for the protected service availability and security.

The reference iRules also produces insight on the TLS signatures that accesses the TLS Virtual Server and may be useful to define a block or allow list thru a iRule Datagroup and optimize the access to the protected Virtual Server.

Published Aug 04, 2020
Version 1.0

1 Comment

  • Thanks for the nice article just for information why are two data groups "malicious_fingerprintdb" and "malicious_TLSfingerprintdb" ? I think that this could be an error and the data group should be just one.

     

    #check if fingerprint matches a known malicious fingerprint, if yes, drop connection

    if {[class match ${ja3_fingerprint} equals malicious_fingerprintdb]}{

    set malicious_fingerprint [class match -value ${ja3_fingerprint} equals malicious_TLSfingerprintdb]

    drop

    log local0. "known malicious fingerprint matched $malicious_fingerprint - Action:DROP!"

     

"}},"componentScriptGroups({\"componentId\":\"custom.widget.Beta_MetaNav\"})":{"__typename":"ComponentScriptGroups","scriptGroups":{"__typename":"ComponentScriptGroupsDefinition","afterInteractive":{"__typename":"PageScriptGroupDefinition","group":"AFTER_INTERACTIVE","scriptIds":[]},"lazyOnLoad":{"__typename":"PageScriptGroupDefinition","group":"LAZY_ON_LOAD","scriptIds":[]}},"componentScripts":[]},"component({\"componentId\":\"custom.widget.Beta_Footer\"})":{"__typename":"Component","render({\"context\":{\"component\":{\"entities\":[],\"props\":{}},\"page\":{\"entities\":[\"message:278609\"],\"name\":\"TkbMessagePage\",\"props\":{},\"url\":\"https://community.f5.com/kb/technicalarticles/tls-fingerprinting-ja3-irule-application-rate-limit-and-block-malicious-traffic-/278609\"}}})":{"__typename":"ComponentRenderResult","html":"
 
 
 
 
 

\"F5 ©2024 F5, Inc. All rights reserved.
Trademarks Policies Privacy California Privacy Do Not Sell My Personal Information
"}},"componentScriptGroups({\"componentId\":\"custom.widget.Beta_Footer\"})":{"__typename":"ComponentScriptGroups","scriptGroups":{"__typename":"ComponentScriptGroupsDefinition","afterInteractive":{"__typename":"PageScriptGroupDefinition","group":"AFTER_INTERACTIVE","scriptIds":[]},"lazyOnLoad":{"__typename":"PageScriptGroupDefinition","group":"LAZY_ON_LOAD","scriptIds":[]}},"componentScripts":[]},"component({\"componentId\":\"custom.widget.Tag_Manager_Helper\"})":{"__typename":"Component","render({\"context\":{\"component\":{\"entities\":[],\"props\":{}},\"page\":{\"entities\":[\"message:278609\"],\"name\":\"TkbMessagePage\",\"props\":{},\"url\":\"https://community.f5.com/kb/technicalarticles/tls-fingerprinting-ja3-irule-application-rate-limit-and-block-malicious-traffic-/278609\"}}})":{"__typename":"ComponentRenderResult","html":" "}},"componentScriptGroups({\"componentId\":\"custom.widget.Tag_Manager_Helper\"})":{"__typename":"ComponentScriptGroups","scriptGroups":{"__typename":"ComponentScriptGroupsDefinition","afterInteractive":{"__typename":"PageScriptGroupDefinition","group":"AFTER_INTERACTIVE","scriptIds":[]},"lazyOnLoad":{"__typename":"PageScriptGroupDefinition","group":"LAZY_ON_LOAD","scriptIds":[]}},"componentScripts":[]},"component({\"componentId\":\"custom.widget.Consent_Blackbar\"})":{"__typename":"Component","render({\"context\":{\"component\":{\"entities\":[],\"props\":{}},\"page\":{\"entities\":[\"message:278609\"],\"name\":\"TkbMessagePage\",\"props\":{},\"url\":\"https://community.f5.com/kb/technicalarticles/tls-fingerprinting-ja3-irule-application-rate-limit-and-block-malicious-traffic-/278609\"}}})":{"__typename":"ComponentRenderResult","html":"
"}},"componentScriptGroups({\"componentId\":\"custom.widget.Consent_Blackbar\"})":{"__typename":"ComponentScriptGroups","scriptGroups":{"__typename":"ComponentScriptGroupsDefinition","afterInteractive":{"__typename":"PageScriptGroupDefinition","group":"AFTER_INTERACTIVE","scriptIds":[]},"lazyOnLoad":{"__typename":"PageScriptGroupDefinition","group":"LAZY_ON_LOAD","scriptIds":[]}},"componentScripts":[]},"cachedText({\"lastModified\":\"1744046271000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/common/QueryHandler\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/common/QueryHandler-1744046271000"}],"cachedText({\"lastModified\":\"1744046271000\",\"locale\":\"en-US\",\"namespaces\":[\"components/community/NavbarDropdownToggle\"]})":[{"__ref":"CachedAsset:text:en_US-components/community/NavbarDropdownToggle-1744046271000"}],"cachedText({\"lastModified\":\"1744046271000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageSubject\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageSubject-1744046271000"}],"cachedText({\"lastModified\":\"1744046271000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageBody\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageBody-1744046271000"}],"cachedText({\"lastModified\":\"1744046271000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageCustomFields\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageCustomFields-1744046271000"}],"cachedText({\"lastModified\":\"1744046271000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageRevision\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageRevision-1744046271000"}],"cachedText({\"lastModified\":\"1744046271000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageReplyButton\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageReplyButton-1744046271000"}],"cachedText({\"lastModified\":\"1744046271000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageAuthorBio\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageAuthorBio-1744046271000"}],"cachedText({\"lastModified\":\"1744046271000\",\"locale\":\"en-US\",\"namespaces\":[\"components/guides/GuideBottomNavigation\"]})":[{"__ref":"CachedAsset:text:en_US-components/guides/GuideBottomNavigation-1744046271000"}],"cachedText({\"lastModified\":\"1744046271000\",\"locale\":\"en-US\",\"namespaces\":[\"components/tags/TagView/TagViewChip\"]})":[{"__ref":"CachedAsset:text:en_US-components/tags/TagView/TagViewChip-1744046271000"}],"cachedText({\"lastModified\":\"1744046271000\",\"locale\":\"en-US\",\"namespaces\":[\"components/users/UserLink\"]})":[{"__ref":"CachedAsset:text:en_US-components/users/UserLink-1744046271000"}],"cachedText({\"lastModified\":\"1744046271000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/users/UserRank\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/users/UserRank-1744046271000"}],"cachedText({\"lastModified\":\"1744046271000\",\"locale\":\"en-US\",\"namespaces\":[\"components/users/UserRegistrationDate\"]})":[{"__ref":"CachedAsset:text:en_US-components/users/UserRegistrationDate-1744046271000"}],"cachedText({\"lastModified\":\"1744046271000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageListMenu\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageListMenu-1744046271000"}],"cachedText({\"lastModified\":\"1744046271000\",\"locale\":\"en-US\",\"namespaces\":[\"components/messages/MessageTime\"]})":[{"__ref":"CachedAsset:text:en_US-components/messages/MessageTime-1744046271000"}],"cachedText({\"lastModified\":\"1744046271000\",\"locale\":\"en-US\",\"namespaces\":[\"components/customComponent/CustomComponent\"]})":[{"__ref":"CachedAsset:text:en_US-components/customComponent/CustomComponent-1744046271000"}],"message({\"id\":\"message:278610\"})":{"__ref":"TkbReplyMessage:message:278610"},"cachedText({\"lastModified\":\"1744046271000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/users/UserAvatar\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/users/UserAvatar-1744046271000"}],"cachedText({\"lastModified\":\"1744046271000\",\"locale\":\"en-US\",\"namespaces\":[\"shared/client/components/ranks/UserRankLabel\"]})":[{"__ref":"CachedAsset:text:en_US-shared/client/components/ranks/UserRankLabel-1744046271000"}]},"Theme:customTheme1":{"__typename":"Theme","id":"customTheme1"},"User:user:-1":{"__typename":"User","id":"user:-1","uid":-1,"login":"Former Member","email":"","avatar":null,"rank":null,"kudosWeight":1,"registrationData":{"__typename":"RegistrationData","status":"ANONYMOUS","registrationTime":null,"confirmEmailStatus":false,"registrationAccessLevel":"VIEW","ssoRegistrationFields":[]},"ssoId":null,"profileSettings":{"__typename":"ProfileSettings","dateDisplayStyle":{"__typename":"InheritableStringSettingWithPossibleValues","key":"layout.friendly_dates_enabled","value":"false","localValue":"true","possibleValues":["true","false"]},"dateDisplayFormat":{"__typename":"InheritableStringSetting","key":"layout.format_pattern_date","value":"dd-MMM-yyyy","localValue":"MM-dd-yyyy"},"language":{"__typename":"InheritableStringSettingWithPossibleValues","key":"profile.language","value":"en-US","localValue":null,"possibleValues":["en-US","es-ES"]},"repliesSortOrder":{"__typename":"InheritableStringSettingWithPossibleValues","key":"config.user_replies_sort_order","value":"DEFAULT","localValue":"DEFAULT","possibleValues":["DEFAULT","LIKES","PUBLISH_TIME","REVERSE_PUBLISH_TIME"]}},"deleted":false},"CachedAsset:pages-1745595724052":{"__typename":"CachedAsset","id":"pages-1745595724052","value":[{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"BlogViewAllPostsPage","type":"BLOG","urlPath":"/category/:categoryId/blog/:boardId/all-posts/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"CasePortalPage","type":"CASE_PORTAL","urlPath":"/caseportal","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"CreateGroupHubPage","type":"GROUP_HUB","urlPath":"/groups/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"CaseViewPage","type":"CASE_DETAILS","urlPath":"/case/:caseId/:caseNumber","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"InboxPage","type":"COMMUNITY","urlPath":"/inbox","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"HelpFAQPage","type":"COMMUNITY","urlPath":"/help","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"IdeaMessagePage","type":"IDEA_POST","urlPath":"/idea/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"IdeaViewAllIdeasPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId/all-ideas/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"LoginPage","type":"USER","urlPath":"/signin","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"BlogPostPage","type":"BLOG","urlPath":"/category/:categoryId/blogs/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1739501733000,"localOverride":null,"page":{"id":"Test","type":"CUSTOM","urlPath":"/custom-test-2","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"ThemeEditorPage","type":"COMMUNITY","urlPath":"/designer/themes","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"TkbViewAllArticlesPage","type":"TKB","urlPath":"/category/:categoryId/kb/:boardId/all-articles/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"OccasionEditPage","type":"EVENT","urlPath":"/event/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"OAuthAuthorizationAllowPage","type":"USER","urlPath":"/auth/authorize/allow","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"PageEditorPage","type":"COMMUNITY","urlPath":"/designer/pages","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"PostPage","type":"COMMUNITY","urlPath":"/category/:categoryId/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"ForumBoardPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"TkbBoardPage","type":"TKB","urlPath":"/category/:categoryId/kb/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"EventPostPage","type":"EVENT","urlPath":"/category/:categoryId/events/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"UserBadgesPage","type":"COMMUNITY","urlPath":"/users/:login/:userId/badges","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"GroupHubMembershipAction","type":"GROUP_HUB","urlPath":"/membership/join/:nodeId/:membershipType","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"MaintenancePage","type":"COMMUNITY","urlPath":"/maintenance","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"IdeaReplyPage","type":"IDEA_REPLY","urlPath":"/idea/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"UserSettingsPage","type":"USER","urlPath":"/mysettings/:userSettingsTab","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"GroupHubsPage","type":"GROUP_HUB","urlPath":"/groups","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"ForumPostPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"OccasionRsvpActionPage","type":"OCCASION","urlPath":"/event/:boardId/:messageSubject/:messageId/rsvp/:responseType","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"VerifyUserEmailPage","type":"USER","urlPath":"/verifyemail/:userId/:verifyEmailToken","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"AllOccasionsPage","type":"OCCASION","urlPath":"/category/:categoryId/events/:boardId/all-events/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"EventBoardPage","type":"EVENT","urlPath":"/category/:categoryId/events/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"TkbReplyPage","type":"TKB_REPLY","urlPath":"/kb/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"IdeaBoardPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"CommunityGuideLinesPage","type":"COMMUNITY","urlPath":"/communityguidelines","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"CaseCreatePage","type":"SALESFORCE_CASE_CREATION","urlPath":"/caseportal/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"TkbEditPage","type":"TKB","urlPath":"/kb/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"ForgotPasswordPage","type":"USER","urlPath":"/forgotpassword","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"IdeaEditPage","type":"IDEA","urlPath":"/idea/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"TagPage","type":"COMMUNITY","urlPath":"/tag/:tagName","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"BlogBoardPage","type":"BLOG","urlPath":"/category/:categoryId/blog/:boardId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"OccasionMessagePage","type":"OCCASION_TOPIC","urlPath":"/event/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"ManageContentPage","type":"COMMUNITY","urlPath":"/managecontent","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"ClosedMembershipNodeNonMembersPage","type":"GROUP_HUB","urlPath":"/closedgroup/:groupHubId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"CommunityPage","type":"COMMUNITY","urlPath":"/","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"ForumMessagePage","type":"FORUM_TOPIC","urlPath":"/discussions/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"IdeaPostPage","type":"IDEA","urlPath":"/category/:categoryId/ideas/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"BlogMessagePage","type":"BLOG_ARTICLE","urlPath":"/blog/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"RegistrationPage","type":"USER","urlPath":"/register","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"EditGroupHubPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"ForumEditPage","type":"FORUM","urlPath":"/discussions/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"ResetPasswordPage","type":"USER","urlPath":"/resetpassword/:userId/:resetPasswordToken","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"TkbMessagePage","type":"TKB_ARTICLE","urlPath":"/kb/:boardId/:messageSubject/:messageId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"BlogEditPage","type":"BLOG","urlPath":"/blog/:boardId/:messageSubject/:messageId/edit","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"ManageUsersPage","type":"USER","urlPath":"/users/manage/:tab?/:manageUsersTab?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"ForumReplyPage","type":"FORUM_REPLY","urlPath":"/discussions/:boardId/:messageSubject/:messageId/replies/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"PrivacyPolicyPage","type":"COMMUNITY","urlPath":"/privacypolicy","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"NotificationPage","type":"COMMUNITY","urlPath":"/notifications","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"UserPage","type":"USER","urlPath":"/users/:login/:userId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"HealthCheckPage","type":"COMMUNITY","urlPath":"/health","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"OccasionReplyPage","type":"OCCASION_REPLY","urlPath":"/event/:boardId/:messageSubject/:messageId/comments/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"ManageMembersPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/manage/:tab?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"SearchResultsPage","type":"COMMUNITY","urlPath":"/search","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"BlogReplyPage","type":"BLOG_REPLY","urlPath":"/blog/:boardId/:messageSubject/:messageId/replies/:replyId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"GroupHubPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"TermsOfServicePage","type":"COMMUNITY","urlPath":"/termsofservice","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"CategoryPage","type":"CATEGORY","urlPath":"/category/:categoryId","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"ForumViewAllTopicsPage","type":"FORUM","urlPath":"/category/:categoryId/discussions/:boardId/all-topics/(/:after|/:before)?","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"TkbPostPage","type":"TKB","urlPath":"/category/:categoryId/kbs/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"GroupHubPostPage","type":"GROUP_HUB","urlPath":"/group/:groupHubId/:boardId/create","__typename":"PageDescriptor"},"__typename":"PageResource"},{"lastUpdatedTime":1745595724052,"localOverride":null,"page":{"id":"HowDoI","type":"COMMUNITY","urlPath":"/c/how-do-i","__typename":"PageDescriptor"},"__typename":"PageResource"}],"localOverride":false},"CachedAsset:text:en_US-components/context/AppContext/AppContextProvider-0":{"__typename":"CachedAsset","id":"text:en_US-components/context/AppContext/AppContextProvider-0","value":{"noCommunity":"Cannot find community","noUser":"Cannot find current user","noNode":"Cannot find node with id {nodeId}","noMessage":"Cannot find message with id {messageId}","userBanned":"We're sorry, but you have been banned from using this site.","userBannedReason":"You have been banned for the following reason: {reason}"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Loading/LoadingDot-0":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Loading/LoadingDot-0","value":{"title":"Loading..."},"localOverride":false},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/cmstNDgtTlBVa2Rp\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/cmstNDgtTlBVa2Rp","height":0,"width":0,"mimeType":"image/svg+xml"},"Rank:rank:48":{"__typename":"Rank","id":"rank:48","position":4,"name":"SIRT","color":"C20025","icon":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/cmstNDgtTlBVa2Rp\"}"},"rankStyle":"OUTLINE"},"User:user:72057":{"__typename":"User","id":"user:72057","uid":72057,"login":"ArvinF","deleted":false,"avatar":{"__typename":"UserAvatar","url":"https://community.f5.com/t5/s/zihoc95639/images/dS03MjA1Ny1ndTdUdTE?image-coordinates=90%2C126%2C444%2C481"},"rank":{"__ref":"Rank:rank:48"},"email":"","messagesCount":48,"biography":null,"topicsCount":33,"kudosReceivedCount":106,"kudosGivenCount":37,"kudosWeight":1,"registrationData":{"__typename":"RegistrationData","status":null,"registrationTime":"2019-05-22T23:01:08.000-07:00","confirmEmailStatus":null},"followersCount":null,"solutionsCount":1},"Category:category:Articles":{"__typename":"Category","id":"category:Articles","entityType":"CATEGORY","displayId":"Articles","nodeType":"category","depth":1,"title":"Articles","shortTitle":"Articles","parent":{"__ref":"Category:category:top"},"categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:top":{"__typename":"Category","id":"category:top","entityType":"CATEGORY","displayId":"top","nodeType":"category","depth":0,"title":"Top","shortTitle":"Top"},"Tkb:board:TechnicalArticles":{"__typename":"Tkb","id":"board:TechnicalArticles","entityType":"TKB","displayId":"TechnicalArticles","nodeType":"board","depth":2,"conversationStyle":"TKB","repliesProperties":{"__typename":"RepliesProperties","sortOrder":"PUBLISH_TIME","repliesFormat":"threaded"},"tagProperties":{"__typename":"TagNodeProperties","tagsEnabled":{"__typename":"PolicyResult","failureReason":null}},"requireTags":true,"tagType":"FREEFORM_AND_PRESET","description":"F5 SMEs share good practice.","title":"Technical Articles","shortTitle":"Technical Articles","parent":{"__ref":"Category:category:Articles"},"ancestors":{"__typename":"CoreNodeConnection","edges":[{"__typename":"CoreNodeEdge","node":{"__ref":"Community:community:zihoc95639"}},{"__typename":"CoreNodeEdge","node":{"__ref":"Category:category:Articles"}}]},"userContext":{"__typename":"NodeUserContext","canAddAttachments":false,"canUpdateNode":false,"canPostMessages":false,"isSubscribed":false},"theme":{"__ref":"Theme:customTheme1"},"boardPolicies":{"__typename":"BoardPolicies","canViewSpamDashBoard":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.feature.moderation_spam.action.access_spam_quarantine.allowed.accessDenied","key":"error.lithium.policies.feature.moderation_spam.action.access_spam_quarantine.allowed.accessDenied","args":[]}},"canArchiveMessage":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.content_archivals.enable_content_archival_settings.accessDenied","key":"error.lithium.policies.content_archivals.enable_content_archival_settings.accessDenied","args":[]}},"canPublishArticleOnCreate":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.forums.policy_can_publish_on_create_workflow_action.accessDenied","key":"error.lithium.policies.forums.policy_can_publish_on_create_workflow_action.accessDenied","args":[]}},"canReadNode":{"__typename":"PolicyResult","failureReason":null}},"isManualSortOrderAvailable":false,"tkbPolicies":{"__typename":"TkbPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"eventPath":"category:Articles/community:zihoc95639board:TechnicalArticles/"},"TkbTopicMessage:message:278609":{"__typename":"TkbTopicMessage","uid":278609,"subject":"TLS Fingerprinting JA3 iRule Application: Rate limit and block malicious traffic based on TLS signature","id":"message:278609","revisionNum":1,"repliesCount":1,"author":{"__ref":"User:user:72057"},"depth":0,"hasGivenKudo":false,"helpful":null,"board":{"__ref":"Tkb:board:TechnicalArticles"},"conversation":{"__ref":"Conversation:conversation:278609"},"messagePolicies":{"__typename":"MessagePolicies","canPublishArticleOnEdit":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.forums.policy_can_publish_on_edit_workflow_action.accessDenied","key":"error.lithium.policies.forums.policy_can_publish_on_edit_workflow_action.accessDenied","args":[]}},"canModerateSpamMessage":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.feature.moderation_spam.action.moderate_entity.allowed.accessDenied","key":"error.lithium.policies.feature.moderation_spam.action.moderate_entity.allowed.accessDenied","args":[]}}},"contentWorkflow":{"__typename":"ContentWorkflow","state":"PUBLISH","scheduledPublishTime":null,"scheduledTimezone":null,"userContext":{"__typename":"MessageWorkflowContext","canSubmitForReview":null,"canEdit":false,"canRecall":null,"canSubmitForPublication":null,"canReturnToAuthor":null,"canPublish":null,"canReturnToReview":null,"canSchedule":false},"shortScheduledTimezone":null},"readOnly":false,"editFrozen":false,"moderationData":{"__ref":"ModerationData:moderation_data:278609"},"teaser":"","body":"

In this article, we use the same techniques, as some previous authors, to enable a TLS Fingerprinting iRule and proc to rate limit and block TLS clients based on generated TLS signatures.

\n\n

Related Resources

\n\n\n\n

Sample Application: Protecting IMAPS/POP3S service

\n\n

IMAPS/POP3S has been around for a long time and are also a target of brute force attacks. We will use the TLS Fingerprinting iRule and proc to generate a TLS signature and then rate limit a specific client or block a specific TLS signature .

\n\n

Using the \"Library Rule\" from https://devcentral.f5.com/s/articles/TLS-Fingerprinting-to-profile-SSL-TLS-clients-without-decryption, we create the proc iRule, I will name it \"fingerprintTLSproc\". You can name it as you per your needs, just note that it is important to remember the name of the proc iRule as it will be referenced in next iRule - the rate limiting/block iRule. This will be listed as iRule#1. Note that this iRule does not need to be applied to a Virtual Server.

\n\n

iRule#1 - fingerprintTLSproc

\n\n
\n## Library-Rule\n\n\n## JA3 TLS Fingerprint Procedure #################\n##\n## Author: Aaron Brailsford, 06/2020\n## Based on the TLS Fingerprinting iRule by Kevin Stewart @ https://devcentral.f5.com/s/articles/tls-fingerprinting-a-method-for-identifying-a-tls-client-without-decrypting-24598\n## Derived from Lee Brotherston's \"tls-fingerprinting\" project @ https://github.com/LeeBrotherston/tls-fingerprinting\n## Purpose: to identify the user agent based on unique characteristics of the TLS ClientHello message\n## Input:\n##   Full TCP payload collected in CLIENT_DATA event of a TLS handshake ClientHello message\n##   Record length (rlen)\n##   TLS inner version (sslversion)\n##############################################\nproc fingerprintTLS { payload rlen sslversion } {\n\n\n  ## The first 43 bytes of a ClientHello message are the record type, TLS versions, some length values and the\n  ## handshake type. We should already know this stuff from the calling iRule. We're also going to be walking the\n  ## packet, so the field_offset variable will be used to track where we are.\n  set field_offset 43\n\n\n  ## The first value in the payload after the offset is the session ID, which may be empty. Grab the session ID length\n  ## value and move the field_offset variable that many bytes forward to skip it.\n  binary scan ${payload} @${field_offset}c sessID_len\n  set field_offset [expr {${field_offset} + 1 + ${sessID_len}}]\n\n\n  ## The next value in the payload is the ciphersuite list length (how big the ciphersuite list is.\n  binary scan ${payload} @${field_offset}S cipherList_len\n\n\n  ## Now that we have the ciphersuite list length, let's offset the field_offset variable to skip over the length (2) bytes\n  ## and go get the ciphersuite list.\n  set field_offset [expr {${field_offset} + 2}]\n  binary scan ${payload} @${field_offset}S[expr {${cipherList_len} / 2}] cipherlist_decimal\n\n\n  ## Next is the compression method length and compression method. First move field_offset to skip past the ciphersuite\n  ## list, then grab the compression method length. Then move field_offset past the length (2)\n  ## Finally, move field_offset past the compression method bytes.\n  set field_offset [expr {${field_offset} + ${cipherList_len}}]\n  binary scan ${payload} @${field_offset}c compression_len\n  set field_offset [expr {${field_offset} + 1}]\n  set field_offset [expr {${field_offset} + ${compression_len}}]\n\n\n  ## We should be in the extensions section now, so we're going to just run through the remaining data and\n  ## pick out the extensions as we go. But first let's make sure there's more record data left, based on\n  ## the current field_offset vs. rlen.\n  if { [expr {${field_offset} < ${rlen}}] } {\n    ## There's extension data, so let's go get it. Skip the first 2 bytes that are the extensions length\n    set field_offset [expr {${field_offset} + 2}]\n\n\n    ## Make a variable to store the extension types we find\n    set extensions_list \"\"\n\n\n    ## Pad rlen by 1 byte\n    set rlen [expr {${rlen} + 1}]\n\n\n    while { [expr {${field_offset} <= ${rlen}}] } {\n      ## Grab the first 2 bytes to determine the extension type\n      binary scan ${payload} @${field_offset}S ext\n      set ext [expr {$ext & 0xFFFF}]\n\n\n      ## Store the extension in the extensions_list variable\n      lappend extensions_list ${ext}\n\n\n      ## Increment field_offset past the 2 bytes of the extension type\n      set field_offset [expr {${field_offset} + 2}]\n\n\n      ## Grab the 2 bytes of extension lenth\n      binary scan ${payload} @${field_offset}S ext_len\n\n\n      ## Increment field_offset past the 2 bytes of the extension length\n      set field_offset [expr {${field_offset} + 2}]\n\n\n      ## Look for specific extension types in case these need to increment the field_offset (and because we need their values)\n      switch $ext {\n        \"11\" {\n          ## ec_point_format - there's another 1 byte after length\n          ## Grab the extension data\n          binary scan ${payload} @[expr {${field_offset} + 1}]s ext_data\n          set ec_point_format ${ext_data}\n        }\n        \"10\" {\n          ## elliptic_curves - there's another 2 bytes after length\n          ## Grab the extension data\n          binary scan ${payload} @[expr {${field_offset} + 2}]S[expr {(${ext_len} - 2) / 2}] ext_data\n          set elliptic_curves ${ext_data}\n        }\n        default {\n          ## Grab the otherwise unknown extension data\n          binary scan ${payload} @${field_offset}H[expr {${ext_len} * 2}] ext_data\n        }\n      }\n\n\n      ## Increment the field_offset past the extension data length. Repeat this loop until we reach rlen (the end of the payload)\n      set field_offset [expr {${field_offset} + ${ext_len}}]\n    }\n  }\n\n\n  ## Now let's compile all of that data.\n  ## The cipherlist values need masking with 0xFFFF to return the unsigned integers we need\n  foreach cipher $cipherlist_decimal {\n   lappend cipd [expr {$cipher & 0xFFFF}]\n  }\n  set cipd_str [join $cipd \"-\"]\n  if { ( [info exists extensions_list] ) and ( ${extensions_list} ne \"\" ) } { set exte [join ${extensions_list} \"-\"] } else { set exte \"\" }\n  if { ( [info exists elliptic_curves] ) and ( ${elliptic_curves} ne \"\" ) } { set ecur [join ${elliptic_curves} \"-\"] } else { set ecur \"\" }\n  if { ( [info exists ec_point_format] ) and ( ${ec_point_format} ne \"\" ) } { set ecfp [join ${ec_point_format} \"-\"] } else { set ecfp \"\" }\n\n\n  set ja3_str \"${sslversion},${cipd_str},${exte},${ecur},${ecfp}\"\n  ## binary scan [md5 ${ja3_str}] H* ja3_digest\n\n\n  ## Un-comment this line to display the fingerprint string in the LTM log for troubleshooting\n  #log local0. \"ja3 = ${ja3_str}\"\n\n\n  return ${ja3_str}\n}\n
\n\n

Here is the rate limiting / blocking iRule. This iRule will monitor TLS signatures and a corresponding IP address and if it exceeds the defined maximum rate of requests - the maxRate variable - the iRule will drop the traffic from the specific client IP and TLS signature. There is also a logic to check a known malicious TLS signature defined in a iRule Datagroup and if it matches, the iRule will drop the connection. I have named this iRule fingerprintTLSirule-ratelimit and listed as iRule#2. Note in this iRule, you will have to properly reference proc iRule for the detected signatures be checked -  see the section of this iRule commented  \"## Call the fingerprintTLS proc\".

\n\n

Note the syntax in the reference line for calling the proc iRule is \"call <iRule>:<proc>\" . Note as well that this fingerprintTLSirule-ratelimit iRule need to be applied to a Virtual Server.

\n\n

Note the \"static::maxRate\" variable as this controls the maxim number of requests before iRule rate limits a TLS signature hash and IP address combination. Adjust this value as per your needs.

\n\n

iRule#2: fingerprintTLSirule-ratelimit                                               

\n\n
\nwhen RULE_INIT {\n  # Default rate to limit requests\n  set static::maxRate 15\n  # Default rate to\n  set static::warnRate 12\n  # During this many seconds\n  set static::timeout 1\n}\nwhen CLIENT_ACCEPTED {\n  ## Collect the TCP payload\n  TCP::collect\n}\nwhen CLIENT_DATA {\n  ## Get the TLS packet type and versions\n  if { ! [info exists rlen] } {\n    ## We actually only need the recort type (rtype), record length (rlen) handshake type (hs_type) and 'inner' SSL version (inner_sslver) here\n    ## But it's easiest to parse them all out of the payload along with the bytes we don't need (outer_sslver & rilen)\n    binary scan [TCP::payload] cSScH6S rtype outer_sslver rlen hs_type rilen inner_sslver\n\n\n    if { ( ${rtype} == 22 ) and ( ${hs_type} == 1 ) } {\n      ## This is a TLS ClientHello message (22 = TLS handshake, 1 = ClientHello)\n\n\n      ## Call the fingerprintTLS proc\n      set ja3_fingerprint [call fingerprintTLSproc::fingerprintTLS [TCP::payload] ${rlen} ${inner_sslver}]\n      binary scan [md5 ${ja3_fingerprint}] H* ja3_digest\n\n\n### Do Something here ###\n      log local0. \"[IP::client_addr]:[TCP::client_port] ja3 ${ja3_fingerprint}->${ja3_digest}\"\n\n\n#check if fingerprint matches a known malicious fingerprint, if yes, drop connection\nif {[class match ${ja3_fingerprint} equals malicious_fingerprintdb]}{\nset malicious_fingerprint [class match -value ${ja3_fingerprint} equals malicious_TLSfingerprintdb]\ndrop\nlog local0. \"known malicious fingerprint matched $malicious_fingerprint - Action:DROP!\"\n} \n\n\n#use generated digest of the signature for rate limiting\nset suspicious_fingerprint ${ja3_digest}\n#rate limit fingerprint\n# Increment and Get the current request count bucket\n#set epoch [clock seconds]\n\n\n#monitor an unrecognized fingerprint and rate limit it\nset currentCount [table incr -mustexist \"Count_[IP::client_addr]_${suspicious_fingerprint}\"]\nif { $currentCount eq \"\" } {\n# Initialize a new request count bucket\ntable set \"Count_[IP::client_addr]_${suspicious_fingerprint}\" 1 indef $static::timeout\nset currentCount 1\n}\n\n\n# Actually check fingerprint for being over limit\nif { $currentCount >= $static::maxRate } {\nlog local0. \"ERROR: fingerprint:[IP::client_addr]_${suspicious_fingerprint} exceeded ${static::maxRate} requests per second. Rejecting request. Current requests: ${currentCount}.\"\nevent disable all\ndrop\n}\nif { $currentCount > $static::warnRate } {\nlog local0. \"WARNING: fingerprint:[IP::client_addr]_${suspicious_fingerprint} exceeded ${static::warnRate} requests per second. Will reject at ${static::maxRate}. Current requests: ${currentCount}.\"\n}\nlog local0. \"fingerprint:[IP::client_addr]_${suspicious_fingerprint}: currentCount: ${currentCount}\"\n### Do Something here ###\n\n\n    }\n  }\n\n\n  # Collect the rest of the record if necessary\n  if { [TCP::payload length] < $rlen } {\n    TCP::collect $rlen\n  }\n\n\n  ## Release the paylaod\n  TCP::release\n}\n
\n\n

Sample Test Output

\n\n

A curl client simulates as an imaps (secure) client and successfully lists the folders for the sample user

\n\n
\n[root@curlclient] config # curl -k --url = \"imaps://172.16.0.30/\" --user \"lala:lala\" -v\n* Rebuilt URL to: =/\n* Could not resolve host: =\n* Closing connection 0\ncurl: (6) Could not resolve host: =\n*   Trying 172.16.0.30...\n* Connected to 172.16.0.30 (172.16.0.30) port 993 (#1)\n* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH\n* successfully set certificate verify locations:\n*   CAfile: /etc/pki/tls/certs/ca-bundle.crt\n  CApath: none\n* TLSv1.2 (OUT), TLS handshake, Client hello (1):\n* TLSv1.2 (IN), TLS handshake, Server hello (2):\n* TLSv1.2 (IN), TLS handshake, Certificate (11):\n* TLSv1.2 (IN), TLS handshake, Server key exchange (12):\n* TLSv1.2 (IN), TLS handshake, Server finished (14):\n* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):\n* TLSv1.2 (OUT), TLS change cipher, Client hello (1):\n* TLSv1.2 (OUT), TLS handshake, Finished (20):\n* TLSv1.2 (IN), TLS change cipher, Client hello (1):\n* TLSv1.2 (IN), TLS handshake, Finished (20):\n* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256\n* Server certificate:\n*        subject: C=US; ST=WA; L=Seattle; O=MyCompany; OU=IT; CN=localhost.localdomain; emailAddress=root@localhost.localdomain\n*        start date: May 13 13:57:07 2020 GMT\n*        expire date: May 11 13:57:07 2030 GMT\n*        issuer: C=US; ST=WA; L=Seattle; O=MyCompany; OU=IT; CN=localhost.localdomain; emailAddress=root@localhost.localdomain\n*        SSL certificate verify result: self signed certificate (18), continuing anyway.\n< * OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE AUTH=PLAIN] Dovecot (Ubuntu) ready.\n> B001 CAPABILITY\n< * CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE AUTH=PLAIN\n< B001 OK Pre-login capabilities listed, post-login capabilities have more.\n> B002 AUTHENTICATE PLAIN bGFsYQBsYWxhAGxhbGE=\n< * CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS BINARY MOVE\n< B002 OK Logged in\n> B003 LIST \"\" *\n< * LIST (\\HasNoChildren \\Drafts) \".\" Drafts\n* LIST (\\HasNoChildren \\Drafts) \".\" Drafts\n< * LIST (\\HasNoChildren \\Sent) \".\" Sent\n* LIST (\\HasNoChildren \\Sent) \".\" Sent\n< * LIST (\\HasNoChildren \\Trash) \".\" Trash\n* LIST (\\HasNoChildren \\Trash) \".\" Trash\n< * LIST (\\HasNoChildren) \".\" Templates\n* LIST (\\HasNoChildren) \".\" Templates\n< * LIST (\\HasNoChildren) \".\" INBOX\n* LIST (\\HasNoChildren) \".\" INBOX\n< B003 OK List completed (0.001 + 0.000 secs).\n* Connection #1 to host 172.16.0.30 left intact\n
\n\n

The iRule fingerprintTLSirule-ratelimit will log the TLS signature generated when it called the fingerprintTLSproc::fingerprintTLS proc. The reference log can be seen in /var/log/ltm file of the BIG-IP as per configured in the iRule. The logs can be also be sent to a high speed logging server.

\n\n
\nJul 24 02:40:09 behavioral-dos-v15 info tmm1[11152]: Rule /Common/fingerprintTLSirule <CLIENT_DATA>: 172.16.7.31:59158 ja3 771,49200-49196-49192-49188-49172-49162-163-159-107-106-57-56-136-135-49202-49198-49194-49190-49167-49157-157-61-53-132-49199-49195-49191-49187-49171-49161-162-158-103-64-51-50-154-153-69-68-49201-49197-49193-49189-49166-49156-156-60-47-150-65-49170-49160-22-19-49165-49155-10-255,11-10-13-15-13172,25-24-22-23-20-21-18-19-15-16-17,256->19e387a2748bc0f70bc463d3af4cd04a\n
\n\n

the TLS signature here is:

\n\n
\n771,49200-49196-49192-49188-49172-49162-163-159-107-106-57-56-136-135-49202-49198-49194-49190-49167-49157-157-61-53-132-49199-49195-49191-49187-49171-49161-162-158-103-64-51-50-154-153-69-68-49201-49197-49193-49189-49166-49156-156-60-47-150-65-49170-49160-22-19-49165-49155-10-255,11-10-13-15-13172,25-24-22-23-20-21-18-19-15-16-17,256\n
\n\n

This TLS signature can be defined in an iRule Datagroup and be matched as either a known good or bad TLS signature. As noted earlier, the iRule fingerprintTLSirule-ratelimit includes a logic block to drop known malicious TLS signature.

\n\n

mutt is a mail client in linux and if it connects to the reference Virtual Server where the fingerprintTLSirule-ratelimit iRule is applied, this is the sample TLS signature in the generated log

\n\n
\nJul 24 02:37:35 behavioral-dos-v15 info tmm1[11152]: Rule /Common/fingerprintTLSirule <CLIENT_DATA>: 172.16.10.31:51844 ja3 771,4866-4867-4865-4868-49196-52393-49325-49162-49195-49324-49161-49200-52392-49172-49199-49171-157-49309-53-156-49308-47-159-52394-49311-57-158-49310-51,5-10-11-13-22-23-35-51-43-65281-0-45-28,23-24-25-29-30-256-257-258-259-260,0->f35ce21b44ac0b87d3266294bb1b0e20\n
\n\n

mutt client's TLS signature is:

\n\n
\n4866-4867-4865-4868-49196-52393-49325-49162-49195-49324-49161-49200-52392-49172-49199-49171-157-49309-53-156-49308-47-159-52394-49311-57-158-49310-51,5-10-11-13-22-23-35-51-43-65281-0-45-28,23-24-25-29-30-256-257-258-259-260\n
\n\n

nmap has a NSE script that can brute force an imap service. This can be used ethically, however, it also possible to be used for malicious purpose. For testing purpose, I ran a nmap imap-brute NSE scan on a Virtual Server and as it is expected to send brute force traffic, there were multiple instances of the generated TLS signature.

\n\n
\nJul 24 02:49:04 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule <CLIENT_DATA>: 172.16.10.31:51974 ja3 771,4866-4867-4865-51-57-53-47-49196-49200-163-159-52393-52392-52394-49327-49325-49315-49311-49245-49249-49239-49235-49195-49199-162-158-49326-49324-49314-49310-49244-49248-49238-49234-49188-49192-107-106-49267-49271-196-195-49187-49191-103-64-49266-49270-190-189-49162-49172-56-136-135-49161-49171-50-154-153-69-68-157-49313-49309-49233-156-49312-49308-49232-61-192-60-186-132-150-65-255,11-10-35-22-23-13-43-45-51-21,29-23-30-25-24,256->912a836a48eb490e243eb28eef562687\n
\n\n

nmap imap-brute generated TLS signature is:

\n\n
\n 771,4866-4867-4865-51-57-53-47-49196-49200-163-159-52393-52392-52394-49327-49325-49315-49311-49245-49249-49239-49235-49195-49199-162-158-49326-49324-49314-49310-49244-49248-49238-49234-49188-49192-107-106-49267-49271-196-195-49187-49191-103-64-49266-49270-190-189-49162-49172-56-136-135-49161-49171-50-154-153-69-68-157-49313-49309-49233-156-49312-49308-49232-61-192-60-186-132-150-65-255,11-10-35-22-23-13-43-45-51-21,29-23-30-25-24,256\n
\n\n

The occurrence of nmap imap-brute TLS signature was increasing as the nmap script brute forces the IMAP Virtual Server. Note in this output, the hash of the signature \"912a836a48eb490e243eb28eef562687\" was used as the search string,

\n\n
\n[root@behavioral-dos-v15:Active:Standalone] config # grep 912a836a48eb490e243eb28eef562687 /var/log/ltm | wc -l\n122\n\n[root@behavioral-dos-v15:Active:Standalone] config # grep 912a836a48eb490e243eb28eef562687 /var/log/ltm | wc -l\n\n262\n\n[root@behavioral-dos-v15:Active:Standalone] config # grep 912a836a48eb490e243eb28eef562687 /var/log/ltm | wc -l\n\n402\n\n[root@behavioral-dos-v15:Active:Standalone] config # grep 912a836a48eb490e243eb28eef562687 /var/log/ltm | wc -l\n\n522\n
\n\n

As in this test nmap scan, if we want to block nmap from scanning the IMAP Virtual Server, we can define the detected TLS Signature to a iRule Datagroup and when its matched, the traffic will be dropped.

\n\n

Here is the sample iRule Datagroup of type String. The TLS signature is added in the String part and the value is a name for the TLS signature

\n\n

\n\n

Here is a sample log when fingerprintTLSirule-ratelimit iRule drops the connection from the known malicious TLS signature

\n\n
\nJul 24 04:06:04 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: 172.16.10.31:57434 ja3 771,4866-4867-4865-51-57-53-47-49196-49200-163-159-52393-52392-52394-49327-49325-49315-49311-49245-49249-49239-49235-49195-49199-162-158-49326-49324-49314-49310-49244-49248-49238-49234-49188-49192-107-106-49267-49271-196-195-49187-49191-103-64-49266-49270-190-189-49162-49172-56-136-135-49161-49171-50-154-153-69-68-157-49313-49309-49233-156-49312-49308-49232-61-192-60-186-132-150-65-255,11-10-35-22-23-13-43-45-51-21,29-23-30-25-24,256->912a836a48eb490e243eb28eef562687\n\nJul 24 04:06:04 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: known malicious fingerprint matched nmapscanner - Action:DROP!\n\nJul 24 04:06:04 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687: currentCount: 1\nJul 24 04:06:04 behavioral-dos-v15 warning tmm[11152]: 01260009:4: 172.16.10.31:57434 -> 172.16.0.30:993: Connection error: hud_ssl_handler:1202: alert(40) invalid profile unknown on VIP /Common/dos-vs-v15\n
\n\n

You may want to use this when you have determined a TLS signature to be malicious.

\n\n

The fingerprintTLSirule-ratelimit iRule also have a rate limiting logic. TLS signatures hash can be generated and along with the client IP address, you can isolate and rate limit traffic should it exceeds the defined maximum rate of requests.

\n\n

Here is the sample log where I ran the nmap script imap-brute, it was fingerprinted and applied rate limiting thru the iRule fingerprintTLSirule-ratelimit

\n\n
\n[root@behavioral-dos-v15:Active:Standalone] config # grep -i Rejecting /var/log/ltm\nJul 24 03:16:43 behavioral-dos-v15 info tmm1[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 15.\nJul 24 03:16:43 behavioral-dos-v15 info tmm1[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 16.\nJul 24 03:16:43 behavioral-dos-v15 info tmm1[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 17.\nJul 24 03:16:43 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 18.\nJul 24 03:16:43 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 19.\nJul 24 03:16:43 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 20.\nJul 24 03:17:29 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 15.\nJul 24 03:17:51 behavioral-dos-v15 info tmm1[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 15.\nJul 24 03:19:20 behavioral-dos-v15 info tmm1[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 15.\nJul 24 03:19:20 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 16.\nJul 24 03:19:20 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 17.\nJul 24 03:19:20 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 18.\nJul 24 03:19:21 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 20.\nJul 24 03:19:32 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 15.\nJul 24 03:19:32 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 16.\nJul 24 03:19:32 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 17.\nJul 24 03:19:33 behavioral-dos-v15 info tmm1[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 18.\nJul 24 03:20:18 behavioral-dos-v15 info tmm1[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 15.\nJul 24 03:20:18 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 16.\n[root@behavioral-dos-v15:Active:Standalone] config #\n\n
\n\n

Considerations

\n\n

iRule operation are CPU intensive, thus, expect an increase in CPU usage on the BIG-IP. The sample iRule here were tested in a controlled lab environment. Please test the iRules before applying to your production traffic. These iRules can be useful to quickly mitigate an attack or unexpected traffic and a trade off of additional CPU resource usage increase for the protected service availability and security.

\n\n

The reference iRules also produces insight on the TLS signatures that accesses the TLS Virtual Server and may be useful to define a block or allow list thru a iRule Datagroup and optimize the access to the protected Virtual Server.

","body@stringLength":"29960","rawBody":"

In this article, we use the same techniques, as some previous authors, to enable a TLS Fingerprinting iRule and proc to rate limit and block TLS clients based on generated TLS signatures.

\n\n

Related Resources

\n\n\n\n

Sample Application: Protecting IMAPS/POP3S service

\n\n

IMAPS/POP3S has been around for a long time and are also a target of brute force attacks. We will use the TLS Fingerprinting iRule and proc to generate a TLS signature and then rate limit a specific client or block a specific TLS signature .

\n\n

Using the \"Library Rule\" from https://devcentral.f5.com/s/articles/TLS-Fingerprinting-to-profile-SSL-TLS-clients-without-decryption, we create the proc iRule, I will name it \"fingerprintTLSproc\". You can name it as you per your needs, just note that it is important to remember the name of the proc iRule as it will be referenced in next iRule - the rate limiting/block iRule. This will be listed as iRule#1. Note that this iRule does not need to be applied to a Virtual Server.

\n\n

iRule#1 - fingerprintTLSproc

\n\n
\n## Library-Rule\n\n\n## JA3 TLS Fingerprint Procedure #################\n##\n## Author: Aaron Brailsford, 06/2020\n## Based on the TLS Fingerprinting iRule by Kevin Stewart @ https://devcentral.f5.com/s/articles/tls-fingerprinting-a-method-for-identifying-a-tls-client-without-decrypting-24598\n## Derived from Lee Brotherston's \"tls-fingerprinting\" project @ https://github.com/LeeBrotherston/tls-fingerprinting\n## Purpose: to identify the user agent based on unique characteristics of the TLS ClientHello message\n## Input:\n##   Full TCP payload collected in CLIENT_DATA event of a TLS handshake ClientHello message\n##   Record length (rlen)\n##   TLS inner version (sslversion)\n##############################################\nproc fingerprintTLS { payload rlen sslversion } {\n\n\n  ## The first 43 bytes of a ClientHello message are the record type, TLS versions, some length values and the\n  ## handshake type. We should already know this stuff from the calling iRule. We're also going to be walking the\n  ## packet, so the field_offset variable will be used to track where we are.\n  set field_offset 43\n\n\n  ## The first value in the payload after the offset is the session ID, which may be empty. Grab the session ID length\n  ## value and move the field_offset variable that many bytes forward to skip it.\n  binary scan ${payload} @${field_offset}c sessID_len\n  set field_offset [expr {${field_offset} + 1 + ${sessID_len}}]\n\n\n  ## The next value in the payload is the ciphersuite list length (how big the ciphersuite list is.\n  binary scan ${payload} @${field_offset}S cipherList_len\n\n\n  ## Now that we have the ciphersuite list length, let's offset the field_offset variable to skip over the length (2) bytes\n  ## and go get the ciphersuite list.\n  set field_offset [expr {${field_offset} + 2}]\n  binary scan ${payload} @${field_offset}S[expr {${cipherList_len} / 2}] cipherlist_decimal\n\n\n  ## Next is the compression method length and compression method. First move field_offset to skip past the ciphersuite\n  ## list, then grab the compression method length. Then move field_offset past the length (2)\n  ## Finally, move field_offset past the compression method bytes.\n  set field_offset [expr {${field_offset} + ${cipherList_len}}]\n  binary scan ${payload} @${field_offset}c compression_len\n  set field_offset [expr {${field_offset} + 1}]\n  set field_offset [expr {${field_offset} + ${compression_len}}]\n\n\n  ## We should be in the extensions section now, so we're going to just run through the remaining data and\n  ## pick out the extensions as we go. But first let's make sure there's more record data left, based on\n  ## the current field_offset vs. rlen.\n  if { [expr {${field_offset} < ${rlen}}] } {\n    ## There's extension data, so let's go get it. Skip the first 2 bytes that are the extensions length\n    set field_offset [expr {${field_offset} + 2}]\n\n\n    ## Make a variable to store the extension types we find\n    set extensions_list \"\"\n\n\n    ## Pad rlen by 1 byte\n    set rlen [expr {${rlen} + 1}]\n\n\n    while { [expr {${field_offset} <= ${rlen}}] } {\n      ## Grab the first 2 bytes to determine the extension type\n      binary scan ${payload} @${field_offset}S ext\n      set ext [expr {$ext & 0xFFFF}]\n\n\n      ## Store the extension in the extensions_list variable\n      lappend extensions_list ${ext}\n\n\n      ## Increment field_offset past the 2 bytes of the extension type\n      set field_offset [expr {${field_offset} + 2}]\n\n\n      ## Grab the 2 bytes of extension lenth\n      binary scan ${payload} @${field_offset}S ext_len\n\n\n      ## Increment field_offset past the 2 bytes of the extension length\n      set field_offset [expr {${field_offset} + 2}]\n\n\n      ## Look for specific extension types in case these need to increment the field_offset (and because we need their values)\n      switch $ext {\n        \"11\" {\n          ## ec_point_format - there's another 1 byte after length\n          ## Grab the extension data\n          binary scan ${payload} @[expr {${field_offset} + 1}]s ext_data\n          set ec_point_format ${ext_data}\n        }\n        \"10\" {\n          ## elliptic_curves - there's another 2 bytes after length\n          ## Grab the extension data\n          binary scan ${payload} @[expr {${field_offset} + 2}]S[expr {(${ext_len} - 2) / 2}] ext_data\n          set elliptic_curves ${ext_data}\n        }\n        default {\n          ## Grab the otherwise unknown extension data\n          binary scan ${payload} @${field_offset}H[expr {${ext_len} * 2}] ext_data\n        }\n      }\n\n\n      ## Increment the field_offset past the extension data length. Repeat this loop until we reach rlen (the end of the payload)\n      set field_offset [expr {${field_offset} + ${ext_len}}]\n    }\n  }\n\n\n  ## Now let's compile all of that data.\n  ## The cipherlist values need masking with 0xFFFF to return the unsigned integers we need\n  foreach cipher $cipherlist_decimal {\n   lappend cipd [expr {$cipher & 0xFFFF}]\n  }\n  set cipd_str [join $cipd \"-\"]\n  if { ( [info exists extensions_list] ) and ( ${extensions_list} ne \"\" ) } { set exte [join ${extensions_list} \"-\"] } else { set exte \"\" }\n  if { ( [info exists elliptic_curves] ) and ( ${elliptic_curves} ne \"\" ) } { set ecur [join ${elliptic_curves} \"-\"] } else { set ecur \"\" }\n  if { ( [info exists ec_point_format] ) and ( ${ec_point_format} ne \"\" ) } { set ecfp [join ${ec_point_format} \"-\"] } else { set ecfp \"\" }\n\n\n  set ja3_str \"${sslversion},${cipd_str},${exte},${ecur},${ecfp}\"\n  ## binary scan [md5 ${ja3_str}] H* ja3_digest\n\n\n  ## Un-comment this line to display the fingerprint string in the LTM log for troubleshooting\n  #log local0. \"ja3 = ${ja3_str}\"\n\n\n  return ${ja3_str}\n}\n
\n\n

Here is the rate limiting / blocking iRule. This iRule will monitor TLS signatures and a corresponding IP address and if it exceeds the defined maximum rate of requests - the maxRate variable - the iRule will drop the traffic from the specific client IP and TLS signature. There is also a logic to check a known malicious TLS signature defined in a iRule Datagroup and if it matches, the iRule will drop the connection. I have named this iRule fingerprintTLSirule-ratelimit and listed as iRule#2. Note in this iRule, you will have to properly reference proc iRule for the detected signatures be checked -  see the section of this iRule commented  \"## Call the fingerprintTLS proc\".

\n\n

Note the syntax in the reference line for calling the proc iRule is \"call <iRule>:<proc>\" . Note as well that this fingerprintTLSirule-ratelimit iRule need to be applied to a Virtual Server.

\n\n

Note the \"static::maxRate\" variable as this controls the maxim number of requests before iRule rate limits a TLS signature hash and IP address combination. Adjust this value as per your needs.

\n\n

iRule#2: fingerprintTLSirule-ratelimit                                               

\n\n
\nwhen RULE_INIT {\n  # Default rate to limit requests\n  set static::maxRate 15\n  # Default rate to\n  set static::warnRate 12\n  # During this many seconds\n  set static::timeout 1\n}\nwhen CLIENT_ACCEPTED {\n  ## Collect the TCP payload\n  TCP::collect\n}\nwhen CLIENT_DATA {\n  ## Get the TLS packet type and versions\n  if { ! [info exists rlen] } {\n    ## We actually only need the recort type (rtype), record length (rlen) handshake type (hs_type) and 'inner' SSL version (inner_sslver) here\n    ## But it's easiest to parse them all out of the payload along with the bytes we don't need (outer_sslver & rilen)\n    binary scan [TCP::payload] cSScH6S rtype outer_sslver rlen hs_type rilen inner_sslver\n\n\n    if { ( ${rtype} == 22 ) and ( ${hs_type} == 1 ) } {\n      ## This is a TLS ClientHello message (22 = TLS handshake, 1 = ClientHello)\n\n\n      ## Call the fingerprintTLS proc\n      set ja3_fingerprint [call fingerprintTLSproc::fingerprintTLS [TCP::payload] ${rlen} ${inner_sslver}]\n      binary scan [md5 ${ja3_fingerprint}] H* ja3_digest\n\n\n### Do Something here ###\n      log local0. \"[IP::client_addr]:[TCP::client_port] ja3 ${ja3_fingerprint}->${ja3_digest}\"\n\n\n#check if fingerprint matches a known malicious fingerprint, if yes, drop connection\nif {[class match ${ja3_fingerprint} equals malicious_fingerprintdb]}{\nset malicious_fingerprint [class match -value ${ja3_fingerprint} equals malicious_TLSfingerprintdb]\ndrop\nlog local0. \"known malicious fingerprint matched $malicious_fingerprint - Action:DROP!\"\n} \n\n\n#use generated digest of the signature for rate limiting\nset suspicious_fingerprint ${ja3_digest}\n#rate limit fingerprint\n# Increment and Get the current request count bucket\n#set epoch [clock seconds]\n\n\n#monitor an unrecognized fingerprint and rate limit it\nset currentCount [table incr -mustexist \"Count_[IP::client_addr]_${suspicious_fingerprint}\"]\nif { $currentCount eq \"\" } {\n# Initialize a new request count bucket\ntable set \"Count_[IP::client_addr]_${suspicious_fingerprint}\" 1 indef $static::timeout\nset currentCount 1\n}\n\n\n# Actually check fingerprint for being over limit\nif { $currentCount >= $static::maxRate } {\nlog local0. \"ERROR: fingerprint:[IP::client_addr]_${suspicious_fingerprint} exceeded ${static::maxRate} requests per second. Rejecting request. Current requests: ${currentCount}.\"\nevent disable all\ndrop\n}\nif { $currentCount > $static::warnRate } {\nlog local0. \"WARNING: fingerprint:[IP::client_addr]_${suspicious_fingerprint} exceeded ${static::warnRate} requests per second. Will reject at ${static::maxRate}. Current requests: ${currentCount}.\"\n}\nlog local0. \"fingerprint:[IP::client_addr]_${suspicious_fingerprint}: currentCount: ${currentCount}\"\n### Do Something here ###\n\n\n    }\n  }\n\n\n  # Collect the rest of the record if necessary\n  if { [TCP::payload length] < $rlen } {\n    TCP::collect $rlen\n  }\n\n\n  ## Release the paylaod\n  TCP::release\n}\n
\n\n

Sample Test Output

\n\n

A curl client simulates as an imaps (secure) client and successfully lists the folders for the sample user

\n\n
\n[root@curlclient] config # curl -k --url = \"imaps://172.16.0.30/\" --user \"lala:lala\" -v\n* Rebuilt URL to: =/\n* Could not resolve host: =\n* Closing connection 0\ncurl: (6) Could not resolve host: =\n*   Trying 172.16.0.30...\n* Connected to 172.16.0.30 (172.16.0.30) port 993 (#1)\n* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH\n* successfully set certificate verify locations:\n*   CAfile: /etc/pki/tls/certs/ca-bundle.crt\n  CApath: none\n* TLSv1.2 (OUT), TLS handshake, Client hello (1):\n* TLSv1.2 (IN), TLS handshake, Server hello (2):\n* TLSv1.2 (IN), TLS handshake, Certificate (11):\n* TLSv1.2 (IN), TLS handshake, Server key exchange (12):\n* TLSv1.2 (IN), TLS handshake, Server finished (14):\n* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):\n* TLSv1.2 (OUT), TLS change cipher, Client hello (1):\n* TLSv1.2 (OUT), TLS handshake, Finished (20):\n* TLSv1.2 (IN), TLS change cipher, Client hello (1):\n* TLSv1.2 (IN), TLS handshake, Finished (20):\n* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256\n* Server certificate:\n*        subject: C=US; ST=WA; L=Seattle; O=MyCompany; OU=IT; CN=localhost.localdomain; emailAddress=root@localhost.localdomain\n*        start date: May 13 13:57:07 2020 GMT\n*        expire date: May 11 13:57:07 2030 GMT\n*        issuer: C=US; ST=WA; L=Seattle; O=MyCompany; OU=IT; CN=localhost.localdomain; emailAddress=root@localhost.localdomain\n*        SSL certificate verify result: self signed certificate (18), continuing anyway.\n< * OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE AUTH=PLAIN] Dovecot (Ubuntu) ready.\n> B001 CAPABILITY\n< * CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE AUTH=PLAIN\n< B001 OK Pre-login capabilities listed, post-login capabilities have more.\n> B002 AUTHENTICATE PLAIN bGFsYQBsYWxhAGxhbGE=\n< * CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS BINARY MOVE\n< B002 OK Logged in\n> B003 LIST \"\" *\n< * LIST (\\HasNoChildren \\Drafts) \".\" Drafts\n* LIST (\\HasNoChildren \\Drafts) \".\" Drafts\n< * LIST (\\HasNoChildren \\Sent) \".\" Sent\n* LIST (\\HasNoChildren \\Sent) \".\" Sent\n< * LIST (\\HasNoChildren \\Trash) \".\" Trash\n* LIST (\\HasNoChildren \\Trash) \".\" Trash\n< * LIST (\\HasNoChildren) \".\" Templates\n* LIST (\\HasNoChildren) \".\" Templates\n< * LIST (\\HasNoChildren) \".\" INBOX\n* LIST (\\HasNoChildren) \".\" INBOX\n< B003 OK List completed (0.001 + 0.000 secs).\n* Connection #1 to host 172.16.0.30 left intact\n
\n\n

The iRule fingerprintTLSirule-ratelimit will log the TLS signature generated when it called the fingerprintTLSproc::fingerprintTLS proc. The reference log can be seen in /var/log/ltm file of the BIG-IP as per configured in the iRule. The logs can be also be sent to a high speed logging server.

\n\n
\nJul 24 02:40:09 behavioral-dos-v15 info tmm1[11152]: Rule /Common/fingerprintTLSirule <CLIENT_DATA>: 172.16.7.31:59158 ja3 771,49200-49196-49192-49188-49172-49162-163-159-107-106-57-56-136-135-49202-49198-49194-49190-49167-49157-157-61-53-132-49199-49195-49191-49187-49171-49161-162-158-103-64-51-50-154-153-69-68-49201-49197-49193-49189-49166-49156-156-60-47-150-65-49170-49160-22-19-49165-49155-10-255,11-10-13-15-13172,25-24-22-23-20-21-18-19-15-16-17,256->19e387a2748bc0f70bc463d3af4cd04a\n
\n\n

the TLS signature here is:

\n\n
\n771,49200-49196-49192-49188-49172-49162-163-159-107-106-57-56-136-135-49202-49198-49194-49190-49167-49157-157-61-53-132-49199-49195-49191-49187-49171-49161-162-158-103-64-51-50-154-153-69-68-49201-49197-49193-49189-49166-49156-156-60-47-150-65-49170-49160-22-19-49165-49155-10-255,11-10-13-15-13172,25-24-22-23-20-21-18-19-15-16-17,256\n
\n\n

This TLS signature can be defined in an iRule Datagroup and be matched as either a known good or bad TLS signature. As noted earlier, the iRule fingerprintTLSirule-ratelimit includes a logic block to drop known malicious TLS signature.

\n\n

mutt is a mail client in linux and if it connects to the reference Virtual Server where the fingerprintTLSirule-ratelimit iRule is applied, this is the sample TLS signature in the generated log

\n\n
\nJul 24 02:37:35 behavioral-dos-v15 info tmm1[11152]: Rule /Common/fingerprintTLSirule <CLIENT_DATA>: 172.16.10.31:51844 ja3 771,4866-4867-4865-4868-49196-52393-49325-49162-49195-49324-49161-49200-52392-49172-49199-49171-157-49309-53-156-49308-47-159-52394-49311-57-158-49310-51,5-10-11-13-22-23-35-51-43-65281-0-45-28,23-24-25-29-30-256-257-258-259-260,0->f35ce21b44ac0b87d3266294bb1b0e20\n
\n\n

mutt client's TLS signature is:

\n\n
\n4866-4867-4865-4868-49196-52393-49325-49162-49195-49324-49161-49200-52392-49172-49199-49171-157-49309-53-156-49308-47-159-52394-49311-57-158-49310-51,5-10-11-13-22-23-35-51-43-65281-0-45-28,23-24-25-29-30-256-257-258-259-260\n
\n\n

nmap has a NSE script that can brute force an imap service. This can be used ethically, however, it also possible to be used for malicious purpose. For testing purpose, I ran a nmap imap-brute NSE scan on a Virtual Server and as it is expected to send brute force traffic, there were multiple instances of the generated TLS signature.

\n\n
\nJul 24 02:49:04 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule <CLIENT_DATA>: 172.16.10.31:51974 ja3 771,4866-4867-4865-51-57-53-47-49196-49200-163-159-52393-52392-52394-49327-49325-49315-49311-49245-49249-49239-49235-49195-49199-162-158-49326-49324-49314-49310-49244-49248-49238-49234-49188-49192-107-106-49267-49271-196-195-49187-49191-103-64-49266-49270-190-189-49162-49172-56-136-135-49161-49171-50-154-153-69-68-157-49313-49309-49233-156-49312-49308-49232-61-192-60-186-132-150-65-255,11-10-35-22-23-13-43-45-51-21,29-23-30-25-24,256->912a836a48eb490e243eb28eef562687\n
\n\n

nmap imap-brute generated TLS signature is:

\n\n
\n 771,4866-4867-4865-51-57-53-47-49196-49200-163-159-52393-52392-52394-49327-49325-49315-49311-49245-49249-49239-49235-49195-49199-162-158-49326-49324-49314-49310-49244-49248-49238-49234-49188-49192-107-106-49267-49271-196-195-49187-49191-103-64-49266-49270-190-189-49162-49172-56-136-135-49161-49171-50-154-153-69-68-157-49313-49309-49233-156-49312-49308-49232-61-192-60-186-132-150-65-255,11-10-35-22-23-13-43-45-51-21,29-23-30-25-24,256\n
\n\n

The occurrence of nmap imap-brute TLS signature was increasing as the nmap script brute forces the IMAP Virtual Server. Note in this output, the hash of the signature \"912a836a48eb490e243eb28eef562687\" was used as the search string,

\n\n
\n[root@behavioral-dos-v15:Active:Standalone] config # grep 912a836a48eb490e243eb28eef562687 /var/log/ltm | wc -l\n122\n\n[root@behavioral-dos-v15:Active:Standalone] config # grep 912a836a48eb490e243eb28eef562687 /var/log/ltm | wc -l\n\n262\n\n[root@behavioral-dos-v15:Active:Standalone] config # grep 912a836a48eb490e243eb28eef562687 /var/log/ltm | wc -l\n\n402\n\n[root@behavioral-dos-v15:Active:Standalone] config # grep 912a836a48eb490e243eb28eef562687 /var/log/ltm | wc -l\n\n522\n
\n\n

As in this test nmap scan, if we want to block nmap from scanning the IMAP Virtual Server, we can define the detected TLS Signature to a iRule Datagroup and when its matched, the traffic will be dropped.

\n\n

Here is the sample iRule Datagroup of type String. The TLS signature is added in the String part and the value is a name for the TLS signature

\n\n

\n\n

Here is a sample log when fingerprintTLSirule-ratelimit iRule drops the connection from the known malicious TLS signature

\n\n
\nJul 24 04:06:04 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: 172.16.10.31:57434 ja3 771,4866-4867-4865-51-57-53-47-49196-49200-163-159-52393-52392-52394-49327-49325-49315-49311-49245-49249-49239-49235-49195-49199-162-158-49326-49324-49314-49310-49244-49248-49238-49234-49188-49192-107-106-49267-49271-196-195-49187-49191-103-64-49266-49270-190-189-49162-49172-56-136-135-49161-49171-50-154-153-69-68-157-49313-49309-49233-156-49312-49308-49232-61-192-60-186-132-150-65-255,11-10-35-22-23-13-43-45-51-21,29-23-30-25-24,256->912a836a48eb490e243eb28eef562687\n\nJul 24 04:06:04 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: known malicious fingerprint matched nmapscanner - Action:DROP!\n\nJul 24 04:06:04 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687: currentCount: 1\nJul 24 04:06:04 behavioral-dos-v15 warning tmm[11152]: 01260009:4: 172.16.10.31:57434 -> 172.16.0.30:993: Connection error: hud_ssl_handler:1202: alert(40) invalid profile unknown on VIP /Common/dos-vs-v15\n
\n\n

You may want to use this when you have determined a TLS signature to be malicious.

\n\n

The fingerprintTLSirule-ratelimit iRule also have a rate limiting logic. TLS signatures hash can be generated and along with the client IP address, you can isolate and rate limit traffic should it exceeds the defined maximum rate of requests.

\n\n

Here is the sample log where I ran the nmap script imap-brute, it was fingerprinted and applied rate limiting thru the iRule fingerprintTLSirule-ratelimit

\n\n
\n[root@behavioral-dos-v15:Active:Standalone] config # grep -i Rejecting /var/log/ltm\nJul 24 03:16:43 behavioral-dos-v15 info tmm1[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 15.\nJul 24 03:16:43 behavioral-dos-v15 info tmm1[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 16.\nJul 24 03:16:43 behavioral-dos-v15 info tmm1[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 17.\nJul 24 03:16:43 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 18.\nJul 24 03:16:43 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 19.\nJul 24 03:16:43 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 20.\nJul 24 03:17:29 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 15.\nJul 24 03:17:51 behavioral-dos-v15 info tmm1[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 15.\nJul 24 03:19:20 behavioral-dos-v15 info tmm1[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 15.\nJul 24 03:19:20 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 16.\nJul 24 03:19:20 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 17.\nJul 24 03:19:20 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 18.\nJul 24 03:19:21 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 20.\nJul 24 03:19:32 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 15.\nJul 24 03:19:32 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 16.\nJul 24 03:19:32 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 17.\nJul 24 03:19:33 behavioral-dos-v15 info tmm1[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 18.\nJul 24 03:20:18 behavioral-dos-v15 info tmm1[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 15.\nJul 24 03:20:18 behavioral-dos-v15 info tmm[11152]: Rule /Common/fingerprintTLSirule-ratelimit <CLIENT_DATA>: ERROR: fingerprint:172.16.10.31_912a836a48eb490e243eb28eef562687 exceeded 15 requests per second. Rejecting request. Current requests: 16.\n[root@behavioral-dos-v15:Active:Standalone] config #\n\n
\n\n

Considerations

\n\n

iRule operation are CPU intensive, thus, expect an increase in CPU usage on the BIG-IP. The sample iRule here were tested in a controlled lab environment. Please test the iRules before applying to your production traffic. These iRules can be useful to quickly mitigate an attack or unexpected traffic and a trade off of additional CPU resource usage increase for the protected service availability and security.

\n\n

The reference iRules also produces insight on the TLS signatures that accesses the TLS Virtual Server and may be useful to define a block or allow list thru a iRule Datagroup and optimize the access to the protected Virtual Server.

","kudosSumWeight":1,"postTime":"2020-08-04T09:12:19.000-07:00","images":{"__typename":"AssociatedImageConnection","edges":[{"__typename":"AssociatedImageEdge","cursor":"MjUuM3wyLjF8b3wyNXxfTlZffDE","node":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yNzg2MDktMTI1NjNpMDVFQTA3NzBBRDUxQzVCNQ?revision=1\"}"}}],"totalCount":1,"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"attachments":{"__typename":"AttachmentConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[]},"tags":{"__typename":"TagConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[{"__typename":"TagEdge","cursor":"MjUuM3wyLjF8b3wxMHxfTlZffDE","node":{"__typename":"Tag","id":"tag:application delivery","text":"application delivery","time":"2021-06-30T01:48:44.000-07:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuM3wyLjF8b3wxMHxfTlZffDI","node":{"__typename":"Tag","id":"tag:f5 sirt","text":"f5 sirt","time":"2022-11-30T10:40:39.228-08:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuM3wyLjF8b3wxMHxfTlZffDM","node":{"__typename":"Tag","id":"tag:fingerprinting","text":"fingerprinting","time":"2022-01-24T02:33:33.958-08:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuM3wyLjF8b3wxMHxfTlZffDQ","node":{"__typename":"Tag","id":"tag:iRules","text":"iRules","time":"2022-01-24T02:29:45.106-08:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuM3wyLjF8b3wxMHxfTlZffDU","node":{"__typename":"Tag","id":"tag:JA3","text":"JA3","time":"2022-01-24T02:33:33.911-08:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuM3wyLjF8b3wxMHxfTlZffDY","node":{"__typename":"Tag","id":"tag:security","text":"security","time":"2009-07-03T08:19:36.000-07:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}},{"__typename":"TagEdge","cursor":"MjUuM3wyLjF8b3wxMHxfTlZffDc","node":{"__typename":"Tag","id":"tag:tls","text":"tls","time":"2022-01-24T02:29:53.590-08:00","lastActivityTime":null,"messagesCount":null,"followersCount":null}}]},"timeToRead":16,"rawTeaser":"","introduction":"","currentRevision":{"__ref":"Revision:revision:278609_1"},"latestVersion":{"__typename":"FriendlyVersion","major":"1","minor":"0"},"metrics":{"__typename":"MessageMetrics","views":3121},"visibilityScope":"PUBLIC","canonicalUrl":null,"seoTitle":null,"seoDescription":null,"placeholder":false,"originalMessageForPlaceholder":null,"contributors":{"__typename":"UserConnection","edges":[]},"nonCoAuthorContributors":{"__typename":"UserConnection","edges":[]},"coAuthors":{"__typename":"UserConnection","edges":[{"__typename":"UserEdge","node":{"__ref":"User:user:72057"}}]},"tkbMessagePolicies":{"__typename":"TkbMessagePolicies","canDoAuthoringActionsOnTkb":{"__typename":"PolicyResult","failureReason":{"__typename":"FailureReason","message":"error.lithium.policies.tkb.policy_can_do_authoring_action.accessDenied","key":"error.lithium.policies.tkb.policy_can_do_authoring_action.accessDenied","args":[]}}},"archivalData":null,"replies":{"__typename":"MessageConnection","edges":[{"__typename":"MessageEdge","cursor":"MjUuM3wyLjF8aXwxMHwzOToxfGludCwyNzg2MTAsMjc4NjEw","node":{"__ref":"TkbReplyMessage:message:278610"}}],"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}},"customFields":[],"revisions({\"constraints\":{\"isPublished\":{\"eq\":true}},\"first\":1})":{"__typename":"RevisionConnection","totalCount":1}},"Conversation:conversation:278609":{"__typename":"Conversation","id":"conversation:278609","solved":false,"topic":{"__ref":"TkbTopicMessage:message:278609"},"lastPostingActivityTime":"2021-06-22T04:57:33.000-07:00","lastPostTime":"2021-06-22T04:57:33.000-07:00","unreadReplyCount":1,"isSubscribed":false},"ModerationData:moderation_data:278609":{"__typename":"ModerationData","id":"moderation_data:278609","status":"APPROVED","rejectReason":null,"isReportedAbuse":false,"rejectUser":null,"rejectTime":null,"rejectActorType":null},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/bS0yNzg2MDktMTI1NjNpMDVFQTA3NzBBRDUxQzVCNQ?revision=1\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/bS0yNzg2MDktMTI1NjNpMDVFQTA3NzBBRDUxQzVCNQ?revision=1","title":"0151T000002dsGUQAY.PNG","associationType":"BODY","width":846,"height":576,"altText":null},"Revision:revision:278609_1":{"__typename":"Revision","id":"revision:278609_1","lastEditTime":"2020-08-04T09:12:19.000-07:00"},"CachedAsset:theme:customTheme1-1745595709159":{"__typename":"CachedAsset","id":"theme:customTheme1-1745595709159","value":{"id":"customTheme1","animation":{"fast":"150ms","normal":"250ms","slow":"500ms","slowest":"750ms","function":"cubic-bezier(0.07, 0.91, 0.51, 1)","__typename":"AnimationThemeSettings"},"avatar":{"borderRadius":"50%","collections":["custom"],"__typename":"AvatarThemeSettings"},"basics":{"browserIcon":{"imageAssetName":"JimmyPackets-512-1702592938213.png","imageLastModified":"1702592945815","__typename":"ThemeAsset"},"customerLogo":{"imageAssetName":"f5_logo_fix-1704824537976.svg","imageLastModified":"1704824540697","__typename":"ThemeAsset"},"maximumWidthOfPageContent":"1600px","oneColumnNarrowWidth":"800px","gridGutterWidthMd":"30px","gridGutterWidthXs":"10px","pageWidthStyle":"WIDTH_OF_PAGE_CONTENT","__typename":"BasicsThemeSettings"},"buttons":{"borderRadiusSm":"5px","borderRadius":"5px","borderRadiusLg":"5px","paddingY":"5px","paddingYLg":"7px","paddingYHero":"var(--lia-bs-btn-padding-y-lg)","paddingX":"12px","paddingXLg":"14px","paddingXHero":"42px","fontStyle":"NORMAL","fontWeight":"400","textTransform":"NONE","disabledOpacity":0.5,"primaryTextColor":"var(--lia-bs-white)","primaryTextHoverColor":"var(--lia-bs-white)","primaryTextActiveColor":"var(--lia-bs-white)","primaryBgColor":"var(--lia-bs-primary)","primaryBgHoverColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) * 0.85))","primaryBgActiveColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) * 0.7))","primaryBorder":"1px solid transparent","primaryBorderHover":"1px solid transparent","primaryBorderActive":"1px solid transparent","primaryBorderFocus":"1px solid var(--lia-bs-white)","primaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","secondaryTextColor":"var(--lia-bs-gray-900)","secondaryTextHoverColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.95))","secondaryTextActiveColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.9))","secondaryBgColor":"var(--lia-bs-gray-400)","secondaryBgHoverColor":"hsl(var(--lia-bs-gray-400-h), var(--lia-bs-gray-400-s), calc(var(--lia-bs-gray-400-l) * 0.96))","secondaryBgActiveColor":"hsl(var(--lia-bs-gray-400-h), var(--lia-bs-gray-400-s), calc(var(--lia-bs-gray-400-l) * 0.92))","secondaryBorder":"1px solid transparent","secondaryBorderHover":"1px solid transparent","secondaryBorderActive":"1px solid transparent","secondaryBorderFocus":"1px solid transparent","secondaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","tertiaryTextColor":"var(--lia-bs-gray-900)","tertiaryTextHoverColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.95))","tertiaryTextActiveColor":"hsl(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), calc(var(--lia-bs-gray-900-l) * 0.9))","tertiaryBgColor":"transparent","tertiaryBgHoverColor":"transparent","tertiaryBgActiveColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.04)","tertiaryBorder":"1px solid transparent","tertiaryBorderHover":"1px solid hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","tertiaryBorderActive":"1px solid transparent","tertiaryBorderFocus":"1px solid transparent","tertiaryBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","destructiveTextColor":"var(--lia-bs-danger)","destructiveTextHoverColor":"hsl(var(--lia-bs-danger-h), var(--lia-bs-danger-s), calc(var(--lia-bs-danger-l) * 0.95))","destructiveTextActiveColor":"hsl(var(--lia-bs-danger-h), var(--lia-bs-danger-s), calc(var(--lia-bs-danger-l) * 0.9))","destructiveBgColor":"var(--lia-bs-gray-300)","destructiveBgHoverColor":"hsl(var(--lia-bs-gray-300-h), var(--lia-bs-gray-300-s), calc(var(--lia-bs-gray-300-l) * 0.96))","destructiveBgActiveColor":"hsl(var(--lia-bs-gray-300-h), var(--lia-bs-gray-300-s), calc(var(--lia-bs-gray-300-l) * 0.92))","destructiveBorder":"1px solid transparent","destructiveBorderHover":"1px solid transparent","destructiveBorderActive":"1px solid transparent","destructiveBorderFocus":"1px solid transparent","destructiveBoxShadowFocus":"0 0 0 1px var(--lia-bs-primary), 0 0 0 4px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","__typename":"ButtonsThemeSettings"},"border":{"color":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","mainContent":"NONE","sideContent":"NONE","radiusSm":"3px","radius":"5px","radiusLg":"9px","radius50":"100vw","__typename":"BorderThemeSettings"},"boxShadow":{"xs":"0 0 0 1px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.08), 0 3px 0 -1px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.08)","sm":"0 2px 4px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.06)","md":"0 5px 15px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.15)","lg":"0 10px 30px hsla(var(--lia-bs-gray-900-h), var(--lia-bs-gray-900-s), var(--lia-bs-gray-900-l), 0.15)","__typename":"BoxShadowThemeSettings"},"cards":{"bgColor":"var(--lia-panel-bg-color)","borderRadius":"var(--lia-panel-border-radius)","boxShadow":"var(--lia-box-shadow-xs)","__typename":"CardsThemeSettings"},"chip":{"maxWidth":"300px","height":"30px","__typename":"ChipThemeSettings"},"coreTypes":{"defaultMessageLinkColor":"var(--lia-bs-primary)","defaultMessageLinkDecoration":"none","defaultMessageLinkFontStyle":"NORMAL","defaultMessageLinkFontWeight":"400","defaultMessageFontStyle":"NORMAL","defaultMessageFontWeight":"400","defaultMessageFontFamily":"var(--lia-bs-font-family-base)","forumColor":"#0C5C8D","forumFontFamily":"var(--lia-bs-font-family-base)","forumFontWeight":"var(--lia-default-message-font-weight)","forumLineHeight":"var(--lia-bs-line-height-base)","forumFontStyle":"var(--lia-default-message-font-style)","forumMessageLinkColor":"var(--lia-default-message-link-color)","forumMessageLinkDecoration":"var(--lia-default-message-link-decoration)","forumMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","forumMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","forumSolvedColor":"#62C026","blogColor":"#730015","blogFontFamily":"var(--lia-bs-font-family-base)","blogFontWeight":"var(--lia-default-message-font-weight)","blogLineHeight":"1.75","blogFontStyle":"var(--lia-default-message-font-style)","blogMessageLinkColor":"var(--lia-default-message-link-color)","blogMessageLinkDecoration":"var(--lia-default-message-link-decoration)","blogMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","blogMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","tkbColor":"#C20025","tkbFontFamily":"var(--lia-bs-font-family-base)","tkbFontWeight":"var(--lia-default-message-font-weight)","tkbLineHeight":"1.75","tkbFontStyle":"var(--lia-default-message-font-style)","tkbMessageLinkColor":"var(--lia-default-message-link-color)","tkbMessageLinkDecoration":"var(--lia-default-message-link-decoration)","tkbMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","tkbMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","qandaColor":"#4099E2","qandaFontFamily":"var(--lia-bs-font-family-base)","qandaFontWeight":"var(--lia-default-message-font-weight)","qandaLineHeight":"var(--lia-bs-line-height-base)","qandaFontStyle":"var(--lia-default-message-link-font-style)","qandaMessageLinkColor":"var(--lia-default-message-link-color)","qandaMessageLinkDecoration":"var(--lia-default-message-link-decoration)","qandaMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","qandaMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","qandaSolvedColor":"#3FA023","ideaColor":"#F3704B","ideaFontFamily":"var(--lia-bs-font-family-base)","ideaFontWeight":"var(--lia-default-message-font-weight)","ideaLineHeight":"var(--lia-bs-line-height-base)","ideaFontStyle":"var(--lia-default-message-font-style)","ideaMessageLinkColor":"var(--lia-default-message-link-color)","ideaMessageLinkDecoration":"var(--lia-default-message-link-decoration)","ideaMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","ideaMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","contestColor":"#FCC845","contestFontFamily":"var(--lia-bs-font-family-base)","contestFontWeight":"var(--lia-default-message-font-weight)","contestLineHeight":"var(--lia-bs-line-height-base)","contestFontStyle":"var(--lia-default-message-link-font-style)","contestMessageLinkColor":"var(--lia-default-message-link-color)","contestMessageLinkDecoration":"var(--lia-default-message-link-decoration)","contestMessageLinkFontStyle":"ITALIC","contestMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","occasionColor":"#EE4B5B","occasionFontFamily":"var(--lia-bs-font-family-base)","occasionFontWeight":"var(--lia-default-message-font-weight)","occasionLineHeight":"var(--lia-bs-line-height-base)","occasionFontStyle":"var(--lia-default-message-font-style)","occasionMessageLinkColor":"var(--lia-default-message-link-color)","occasionMessageLinkDecoration":"var(--lia-default-message-link-decoration)","occasionMessageLinkFontStyle":"var(--lia-default-message-link-font-style)","occasionMessageLinkFontWeight":"var(--lia-default-message-link-font-weight)","grouphubColor":"#491B62","categoryColor":"#949494","communityColor":"#FFFFFF","productColor":"#949494","__typename":"CoreTypesThemeSettings"},"colors":{"black":"#000000","white":"#FFFFFF","gray100":"#F7F7F7","gray200":"#F7F7F7","gray300":"#E8E8E8","gray400":"#D9D9D9","gray500":"#CCCCCC","gray600":"#949494","gray700":"#707070","gray800":"#545454","gray900":"#333333","dark":"#545454","light":"#F7F7F7","primary":"#0C5C8D","secondary":"#333333","bodyText":"#222222","bodyBg":"#F5F5F5","info":"#1D9CD3","success":"#62C026","warning":"#FFD651","danger":"#C20025","alertSystem":"#FF6600","textMuted":"#707070","highlight":"#FFFCAD","outline":"var(--lia-bs-primary)","custom":["#C20025","#081B85","#009639","#B3C6D7","#7CC0EB","#F29A36"],"__typename":"ColorsThemeSettings"},"divider":{"size":"3px","marginLeft":"4px","marginRight":"4px","borderRadius":"50%","bgColor":"var(--lia-bs-gray-600)","bgColorActive":"var(--lia-bs-gray-600)","__typename":"DividerThemeSettings"},"dropdown":{"fontSize":"var(--lia-bs-font-size-sm)","borderColor":"var(--lia-bs-border-color)","borderRadius":"var(--lia-bs-border-radius-sm)","dividerBg":"var(--lia-bs-gray-300)","itemPaddingY":"5px","itemPaddingX":"20px","headerColor":"var(--lia-bs-gray-700)","__typename":"DropdownThemeSettings"},"email":{"link":{"color":"#0069D4","hoverColor":"#0061c2","decoration":"none","hoverDecoration":"underline","__typename":"EmailLinkSettings"},"border":{"color":"#e4e4e4","__typename":"EmailBorderSettings"},"buttons":{"borderRadiusLg":"5px","paddingXLg":"16px","paddingYLg":"7px","fontWeight":"700","primaryTextColor":"#ffffff","primaryTextHoverColor":"#ffffff","primaryBgColor":"#0069D4","primaryBgHoverColor":"#005cb8","primaryBorder":"1px solid transparent","primaryBorderHover":"1px solid transparent","__typename":"EmailButtonsSettings"},"panel":{"borderRadius":"5px","borderColor":"#e4e4e4","__typename":"EmailPanelSettings"},"__typename":"EmailThemeSettings"},"emoji":{"skinToneDefault":"#ffcd43","skinToneLight":"#fae3c5","skinToneMediumLight":"#e2cfa5","skinToneMedium":"#daa478","skinToneMediumDark":"#a78058","skinToneDark":"#5e4d43","__typename":"EmojiThemeSettings"},"heading":{"color":"var(--lia-bs-body-color)","fontFamily":"Inter","fontStyle":"NORMAL","fontWeight":"600","h1FontSize":"30px","h2FontSize":"25px","h3FontSize":"20px","h4FontSize":"18px","h5FontSize":"16px","h6FontSize":"16px","lineHeight":"1.2","subHeaderFontSize":"11px","subHeaderFontWeight":"500","h1LetterSpacing":"normal","h2LetterSpacing":"normal","h3LetterSpacing":"normal","h4LetterSpacing":"normal","h5LetterSpacing":"normal","h6LetterSpacing":"normal","subHeaderLetterSpacing":"2px","h1FontWeight":"var(--lia-bs-headings-font-weight)","h2FontWeight":"var(--lia-bs-headings-font-weight)","h3FontWeight":"var(--lia-bs-headings-font-weight)","h4FontWeight":"var(--lia-bs-headings-font-weight)","h5FontWeight":"var(--lia-bs-headings-font-weight)","h6FontWeight":"var(--lia-bs-headings-font-weight)","__typename":"HeadingThemeSettings"},"icons":{"size10":"10px","size12":"12px","size14":"14px","size16":"16px","size20":"20px","size24":"24px","size30":"30px","size40":"40px","size50":"50px","size60":"60px","size80":"80px","size120":"120px","size160":"160px","__typename":"IconsThemeSettings"},"imagePreview":{"bgColor":"var(--lia-bs-gray-900)","titleColor":"var(--lia-bs-white)","controlColor":"var(--lia-bs-white)","controlBgColor":"var(--lia-bs-gray-800)","__typename":"ImagePreviewThemeSettings"},"input":{"borderColor":"var(--lia-bs-gray-600)","disabledColor":"var(--lia-bs-gray-600)","focusBorderColor":"var(--lia-bs-primary)","labelMarginBottom":"10px","btnFontSize":"var(--lia-bs-font-size-sm)","focusBoxShadow":"0 0 0 3px hsla(var(--lia-bs-primary-h), var(--lia-bs-primary-s), var(--lia-bs-primary-l), 0.2)","checkLabelMarginBottom":"2px","checkboxBorderRadius":"3px","borderRadiusSm":"var(--lia-bs-border-radius-sm)","borderRadius":"var(--lia-bs-border-radius)","borderRadiusLg":"var(--lia-bs-border-radius-lg)","formTextMarginTop":"4px","textAreaBorderRadius":"var(--lia-bs-border-radius)","activeFillColor":"var(--lia-bs-primary)","__typename":"InputThemeSettings"},"loading":{"dotDarkColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.2)","dotLightColor":"hsla(var(--lia-bs-white-h), var(--lia-bs-white-s), var(--lia-bs-white-l), 0.5)","barDarkColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.06)","barLightColor":"hsla(var(--lia-bs-white-h), var(--lia-bs-white-s), var(--lia-bs-white-l), 0.4)","__typename":"LoadingThemeSettings"},"link":{"color":"var(--lia-bs-primary)","hoverColor":"hsl(var(--lia-bs-primary-h), var(--lia-bs-primary-s), calc(var(--lia-bs-primary-l) - 10%))","decoration":"none","hoverDecoration":"underline","__typename":"LinkThemeSettings"},"listGroup":{"itemPaddingY":"15px","itemPaddingX":"15px","borderColor":"var(--lia-bs-gray-300)","__typename":"ListGroupThemeSettings"},"modal":{"contentTextColor":"var(--lia-bs-body-color)","contentBg":"var(--lia-bs-white)","backgroundBg":"var(--lia-bs-black)","smSize":"440px","mdSize":"760px","lgSize":"1080px","backdropOpacity":0.3,"contentBoxShadowXs":"var(--lia-bs-box-shadow-sm)","contentBoxShadow":"var(--lia-bs-box-shadow)","headerFontWeight":"700","__typename":"ModalThemeSettings"},"navbar":{"position":"FIXED","background":{"attachment":null,"clip":null,"color":"var(--lia-bs-white)","imageAssetName":null,"imageLastModified":"0","origin":null,"position":"CENTER_CENTER","repeat":"NO_REPEAT","size":"COVER","__typename":"BackgroundProps"},"backgroundOpacity":0.8,"paddingTop":"15px","paddingBottom":"15px","borderBottom":"1px solid var(--lia-bs-border-color)","boxShadow":"var(--lia-bs-box-shadow-sm)","brandMarginRight":"30px","brandMarginRightSm":"10px","brandLogoHeight":"30px","linkGap":"10px","linkJustifyContent":"flex-start","linkPaddingY":"5px","linkPaddingX":"10px","linkDropdownPaddingY":"9px","linkDropdownPaddingX":"var(--lia-nav-link-px)","linkColor":"var(--lia-bs-body-color)","linkHoverColor":"var(--lia-bs-primary)","linkFontSize":"var(--lia-bs-font-size-sm)","linkFontStyle":"NORMAL","linkFontWeight":"400","linkTextTransform":"NONE","linkLetterSpacing":"normal","linkBorderRadius":"var(--lia-bs-border-radius-sm)","linkBgColor":"transparent","linkBgHoverColor":"transparent","linkBorder":"none","linkBorderHover":"none","linkBoxShadow":"none","linkBoxShadowHover":"none","linkTextBorderBottom":"none","linkTextBorderBottomHover":"none","dropdownPaddingTop":"10px","dropdownPaddingBottom":"15px","dropdownPaddingX":"10px","dropdownMenuOffset":"2px","dropdownDividerMarginTop":"10px","dropdownDividerMarginBottom":"10px","dropdownBorderColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","controllerBgHoverColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.1)","controllerIconColor":"var(--lia-bs-body-color)","controllerIconHoverColor":"var(--lia-bs-body-color)","controllerTextColor":"var(--lia-nav-controller-icon-color)","controllerTextHoverColor":"var(--lia-nav-controller-icon-hover-color)","controllerHighlightColor":"hsla(30, 100%, 50%)","controllerHighlightTextColor":"var(--lia-yiq-light)","controllerBorderRadius":"var(--lia-border-radius-50)","hamburgerColor":"var(--lia-nav-controller-icon-color)","hamburgerHoverColor":"var(--lia-nav-controller-icon-color)","hamburgerBgColor":"transparent","hamburgerBgHoverColor":"transparent","hamburgerBorder":"none","hamburgerBorderHover":"none","collapseMenuMarginLeft":"20px","collapseMenuDividerBg":"var(--lia-nav-link-color)","collapseMenuDividerOpacity":0.16,"__typename":"NavbarThemeSettings"},"pager":{"textColor":"var(--lia-bs-link-color)","textFontWeight":"var(--lia-font-weight-md)","textFontSize":"var(--lia-bs-font-size-sm)","__typename":"PagerThemeSettings"},"panel":{"bgColor":"var(--lia-bs-white)","borderRadius":"var(--lia-bs-border-radius)","borderColor":"var(--lia-bs-border-color)","boxShadow":"none","__typename":"PanelThemeSettings"},"popover":{"arrowHeight":"8px","arrowWidth":"16px","maxWidth":"300px","minWidth":"100px","headerBg":"var(--lia-bs-white)","borderColor":"var(--lia-bs-border-color)","borderRadius":"var(--lia-bs-border-radius)","boxShadow":"0 0.5rem 1rem hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.15)","__typename":"PopoverThemeSettings"},"prism":{"color":"#000000","bgColor":"#f5f2f0","fontFamily":"var(--font-family-monospace)","fontSize":"var(--lia-bs-font-size-base)","fontWeightBold":"var(--lia-bs-font-weight-bold)","fontStyleItalic":"italic","tabSize":2,"highlightColor":"#b3d4fc","commentColor":"#62707e","punctuationColor":"#6f6f6f","namespaceOpacity":"0.7","propColor":"#990055","selectorColor":"#517a00","operatorColor":"#906736","operatorBgColor":"hsla(0, 0%, 100%, 0.5)","keywordColor":"#0076a9","functionColor":"#d3284b","variableColor":"#c14700","__typename":"PrismThemeSettings"},"rte":{"bgColor":"var(--lia-bs-white)","borderRadius":"var(--lia-panel-border-radius)","boxShadow":" var(--lia-panel-box-shadow)","customColor1":"#bfedd2","customColor2":"#fbeeb8","customColor3":"#f8cac6","customColor4":"#eccafa","customColor5":"#c2e0f4","customColor6":"#2dc26b","customColor7":"#f1c40f","customColor8":"#e03e2d","customColor9":"#b96ad9","customColor10":"#3598db","customColor11":"#169179","customColor12":"#e67e23","customColor13":"#ba372a","customColor14":"#843fa1","customColor15":"#236fa1","customColor16":"#ecf0f1","customColor17":"#ced4d9","customColor18":"#95a5a6","customColor19":"#7e8c8d","customColor20":"#34495e","customColor21":"#000000","customColor22":"#ffffff","defaultMessageHeaderMarginTop":"14px","defaultMessageHeaderMarginBottom":"10px","defaultMessageItemMarginTop":"0","defaultMessageItemMarginBottom":"10px","diffAddedColor":"hsla(170, 53%, 51%, 0.4)","diffChangedColor":"hsla(43, 97%, 63%, 0.4)","diffNoneColor":"hsla(0, 0%, 80%, 0.4)","diffRemovedColor":"hsla(9, 74%, 47%, 0.4)","specialMessageHeaderMarginTop":"14px","specialMessageHeaderMarginBottom":"10px","specialMessageItemMarginTop":"0","specialMessageItemMarginBottom":"10px","__typename":"RteThemeSettings"},"tags":{"bgColor":"var(--lia-bs-gray-200)","bgHoverColor":"var(--lia-bs-gray-400)","borderRadius":"var(--lia-bs-border-radius-sm)","color":"var(--lia-bs-body-color)","hoverColor":"var(--lia-bs-body-color)","fontWeight":"var(--lia-font-weight-md)","fontSize":"var(--lia-font-size-xxs)","textTransform":"UPPERCASE","letterSpacing":"0.5px","__typename":"TagsThemeSettings"},"toasts":{"borderRadius":"var(--lia-bs-border-radius)","paddingX":"12px","__typename":"ToastsThemeSettings"},"typography":{"fontFamilyBase":"Atkinson Hyperlegible","fontStyleBase":"NORMAL","fontWeightBase":"400","fontWeightLight":"300","fontWeightNormal":"400","fontWeightMd":"500","fontWeightBold":"700","letterSpacingSm":"normal","letterSpacingXs":"normal","lineHeightBase":"1.3","fontSizeBase":"15px","fontSizeXxs":"11px","fontSizeXs":"12px","fontSizeSm":"13px","fontSizeLg":"20px","fontSizeXl":"24px","smallFontSize":"14px","customFonts":[],"__typename":"TypographyThemeSettings"},"unstyledListItem":{"marginBottomSm":"5px","marginBottomMd":"10px","marginBottomLg":"15px","marginBottomXl":"20px","marginBottomXxl":"25px","__typename":"UnstyledListItemThemeSettings"},"yiq":{"light":"#ffffff","dark":"#000000","__typename":"YiqThemeSettings"},"colorLightness":{"primaryDark":0.36,"primaryLight":0.74,"primaryLighter":0.89,"primaryLightest":0.95,"infoDark":0.39,"infoLight":0.72,"infoLighter":0.85,"infoLightest":0.93,"successDark":0.24,"successLight":0.62,"successLighter":0.8,"successLightest":0.91,"warningDark":0.39,"warningLight":0.68,"warningLighter":0.84,"warningLightest":0.93,"dangerDark":0.41,"dangerLight":0.72,"dangerLighter":0.89,"dangerLightest":0.95,"__typename":"ColorLightnessThemeSettings"},"localOverride":false,"__typename":"Theme"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/common/Loading/LoadingDot-1744046271000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/Loading/LoadingDot-1744046271000","value":{"title":"Loading..."},"localOverride":false},"CachedAsset:quilt:f5.prod:pages/kbs/TkbMessagePage:board:TechnicalArticles-1745595707587":{"__typename":"CachedAsset","id":"quilt:f5.prod:pages/kbs/TkbMessagePage:board:TechnicalArticles-1745595707587","value":{"id":"TkbMessagePage","container":{"id":"Common","headerProps":{"backgroundImageProps":null,"backgroundColor":null,"addComponents":null,"removeComponents":["community.widget.bannerWidget"],"componentOrder":null,"__typename":"QuiltContainerSectionProps"},"headerComponentProps":{"community.widget.breadcrumbWidget":{"disableLastCrumbForDesktop":false}},"footerProps":null,"footerComponentProps":null,"items":[{"id":"message-list","layout":"MAIN_SIDE","bgColor":"transparent","showTitle":true,"showDescription":true,"textPosition":"CENTER","textColor":"var(--lia-bs-body-color)","sectionEditLevel":null,"bgImage":null,"disableSpacing":null,"edgeToEdgeDisplay":null,"fullHeight":null,"showBorder":null,"__typename":"MainSideQuiltSection","columnMap":{"main":[{"id":"tkbs.widget.tkbArticleWidget","className":"lia-tkb-container","props":{"contributorListType":"panel","showHelpfulness":false,"showTimestamp":true,"showGuideNavigationSection":true,"showVersion":true,"lazyLoad":false,"editLevel":"CONFIGURE"},"__typename":"QuiltComponent"}],"side":[{"id":"featuredWidgets.widget.featuredContentWidget","className":null,"props":{"instanceId":"featuredWidgets.widget.featuredContentWidget-1702666556326","layoutProps":{"layout":"card","layoutOptions":{"useRepliesCount":false,"useAuthorRank":false,"useTimeToRead":true,"useKudosCount":false,"useViewCount":true,"usePreviewMedia":true,"useBody":false,"useCenteredCardContent":false,"useTags":true,"useTimestamp":false,"useBoardLink":true,"useAuthorLink":false,"useSolvedBadge":true}},"titleSrOnly":false,"showPager":true,"pageSize":3,"lazyLoad":true},"__typename":"QuiltComponent"},{"id":"messages.widget.relatedContentWidget","className":null,"props":{"hideIfEmpty":true,"enablePagination":true,"useTitle":true,"listVariant":{"type":"listGroup"},"pageSize":3,"style":"list","pagerVariant":{"type":"loadMore"},"viewVariant":{"type":"inline","props":{"useRepliesCount":true,"useMedia":true,"useAuthorRank":false,"useNode":true,"useTimeToRead":true,"useSpoilerFreeBody":true,"useKudosCount":true,"useNodeLink":true,"useViewCount":true,"usePreviewMedia":false,"useBody":false,"timeStampType":"postTime","useTags":true,"clampSubjectLines":2,"useBoardIcon":false,"useMessageTimeLink":true,"clampBodyLines":3,"useTextBody":true,"useSolvedBadge":true,"useAvatar":true,"useAuthorLogin":true,"useUnreadCount":true}},"lazyLoad":true,"panelType":"divider"},"__typename":"QuiltComponent"}],"__typename":"MainSideSectionColumns"}}],"__typename":"QuiltContainer"},"__typename":"Quilt","localOverride":false},"localOverride":false},"CachedAsset:text:en_US-components/common/EmailVerification-1744046271000":{"__typename":"CachedAsset","id":"text:en_US-components/common/EmailVerification-1744046271000","value":{"email.verification.title":"Email Verification Required","email.verification.message.update.email":"To participate in the community, you must first verify your email address. The verification email was sent to {email}. To change your email, visit My Settings.","email.verification.message.resend.email":"To participate in the community, you must first verify your email address. The verification email was sent to {email}. Resend email."},"localOverride":false},"CachedAsset:text:en_US-pages/kbs/TkbMessagePage-1744046271000":{"__typename":"CachedAsset","id":"text:en_US-pages/kbs/TkbMessagePage-1744046271000","value":{"title":"{contextMessageSubject} | {communityTitle}","errorMissing":"This article cannot be found","name":"TKB Message Page","section.message-list.title":"","archivedMessageTitle":"This Content Has Been Archived","section.erPqcf.title":"","section.erPqcf.description":"","section.message-list.description":""},"localOverride":false},"CachedAsset:quiltWrapper:f5.prod:Common:1745595707342":{"__typename":"CachedAsset","id":"quiltWrapper:f5.prod:Common:1745595707342","value":{"id":"Common","header":{"backgroundImageProps":{"assetName":"header.jpg","backgroundSize":"COVER","backgroundRepeat":"NO_REPEAT","backgroundPosition":"LEFT_CENTER","lastModified":"1702932449000","__typename":"BackgroundImageProps"},"backgroundColor":"transparent","items":[{"id":"custom.widget.GainsightShared","props":{"widgetVisibility":"signedInOnly","useTitle":true,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"},{"id":"custom.widget.Beta_MetaNav","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"},{"id":"community.widget.navbarWidget","props":{"showUserName":false,"showRegisterLink":true,"style":{"boxShadow":"var(--lia-bs-box-shadow-sm)","linkFontWeight":"700","controllerHighlightColor":"hsla(30, 100%, 50%)","dropdownDividerMarginBottom":"10px","hamburgerBorderHover":"none","linkFontSize":"15px","linkBoxShadowHover":"none","backgroundOpacity":0.4,"controllerBorderRadius":"var(--lia-border-radius-50)","hamburgerBgColor":"transparent","linkTextBorderBottom":"none","hamburgerColor":"var(--lia-nav-controller-icon-color)","brandLogoHeight":"48px","linkLetterSpacing":"normal","linkBgHoverColor":"transparent","collapseMenuDividerOpacity":0.16,"paddingBottom":"10px","dropdownPaddingBottom":"15px","dropdownMenuOffset":"2px","hamburgerBgHoverColor":"transparent","borderBottom":"0","hamburgerBorder":"none","dropdownPaddingX":"10px","brandMarginRightSm":"10px","linkBoxShadow":"none","linkJustifyContent":"center","linkColor":"var(--lia-bs-primary)","collapseMenuDividerBg":"var(--lia-nav-link-color)","dropdownPaddingTop":"10px","controllerHighlightTextColor":"var(--lia-yiq-dark)","background":{"imageAssetName":"","color":"var(--lia-bs-white)","size":"COVER","repeat":"NO_REPEAT","position":"CENTER_CENTER","imageLastModified":""},"linkBorderRadius":"var(--lia-bs-border-radius-sm)","linkHoverColor":"var(--lia-bs-primary)","position":"FIXED","linkBorder":"none","linkTextBorderBottomHover":"2px solid #0C5C8D","brandMarginRight":"30px","hamburgerHoverColor":"var(--lia-nav-controller-icon-color)","linkBorderHover":"none","collapseMenuMarginLeft":"20px","linkFontStyle":"NORMAL","linkPaddingX":"10px","paddingTop":"10px","linkPaddingY":"5px","linkTextTransform":"NONE","dropdownBorderColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.08)","controllerBgHoverColor":"hsla(var(--lia-bs-black-h), var(--lia-bs-black-s), var(--lia-bs-black-l), 0.1)","linkDropdownPaddingX":"var(--lia-nav-link-px)","linkBgColor":"transparent","linkDropdownPaddingY":"9px","controllerIconColor":"#0C5C8D","dropdownDividerMarginTop":"10px","linkGap":"10px","controllerIconHoverColor":"#0C5C8D"},"links":{"sideLinks":[],"mainLinks":[{"children":[{"linkType":"INTERNAL","id":"migrated-link-1","params":{"boardId":"TechnicalForum","categoryId":"Forums"},"routeName":"ForumBoardPage"},{"linkType":"INTERNAL","id":"migrated-link-2","params":{"boardId":"WaterCooler","categoryId":"Forums"},"routeName":"ForumBoardPage"}],"linkType":"INTERNAL","id":"migrated-link-0","params":{"categoryId":"Forums"},"routeName":"CategoryPage"},{"children":[{"linkType":"INTERNAL","id":"migrated-link-4","params":{"boardId":"codeshare","categoryId":"CrowdSRC"},"routeName":"TkbBoardPage"},{"linkType":"INTERNAL","id":"migrated-link-5","params":{"boardId":"communityarticles","categoryId":"CrowdSRC"},"routeName":"TkbBoardPage"}],"linkType":"INTERNAL","id":"migrated-link-3","params":{"categoryId":"CrowdSRC"},"routeName":"CategoryPage"},{"children":[{"linkType":"INTERNAL","id":"migrated-link-7","params":{"boardId":"TechnicalArticles","categoryId":"Articles"},"routeName":"TkbBoardPage"},{"linkType":"INTERNAL","id":"article-series","params":{"boardId":"article-series","categoryId":"Articles"},"routeName":"TkbBoardPage"},{"linkType":"INTERNAL","id":"security-insights","params":{"boardId":"security-insights","categoryId":"Articles"},"routeName":"TkbBoardPage"},{"linkType":"INTERNAL","id":"migrated-link-8","params":{"boardId":"DevCentralNews","categoryId":"Articles"},"routeName":"TkbBoardPage"}],"linkType":"INTERNAL","id":"migrated-link-6","params":{"categoryId":"Articles"},"routeName":"CategoryPage"},{"children":[{"linkType":"INTERNAL","id":"migrated-link-10","params":{"categoryId":"CommunityGroups"},"routeName":"CategoryPage"},{"linkType":"INTERNAL","id":"migrated-link-11","params":{"categoryId":"F5-Groups"},"routeName":"CategoryPage"}],"linkType":"INTERNAL","id":"migrated-link-9","params":{"categoryId":"GroupsCategory"},"routeName":"CategoryPage"},{"children":[],"linkType":"INTERNAL","id":"migrated-link-12","params":{"boardId":"Events","categoryId":"top"},"routeName":"EventBoardPage"},{"children":[],"linkType":"INTERNAL","id":"migrated-link-13","params":{"boardId":"Suggestions","categoryId":"top"},"routeName":"IdeaBoardPage"},{"children":[],"linkType":"EXTERNAL","id":"Common-external-link","url":"https://community.f5.com/c/how-do-i","target":"SELF"}]},"className":"QuiltComponent_lia-component-edit-mode__lQ9Z6","showSearchIcon":false},"__typename":"QuiltComponent"},{"id":"community.widget.bannerWidget","props":{"backgroundColor":"transparent","visualEffects":{"showBottomBorder":false},"backgroundImageProps":{"backgroundSize":"COVER","backgroundPosition":"CENTER_CENTER","backgroundRepeat":"NO_REPEAT"},"fontColor":"#222222"},"__typename":"QuiltComponent"},{"id":"community.widget.breadcrumbWidget","props":{"backgroundColor":"var(--lia-bs-primary)","linkHighlightColor":"#FFFFFF","visualEffects":{"showBottomBorder":false},"backgroundOpacity":60,"linkTextColor":"#FFFFFF"},"__typename":"QuiltComponent"}],"__typename":"QuiltWrapperSection"},"footer":{"backgroundImageProps":{"assetName":null,"backgroundSize":"COVER","backgroundRepeat":"NO_REPEAT","backgroundPosition":"CENTER_CENTER","lastModified":null,"__typename":"BackgroundImageProps"},"backgroundColor":"var(--lia-bs-body-color)","items":[{"id":"custom.widget.Beta_Footer","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"},{"id":"custom.widget.Tag_Manager_Helper","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"},{"id":"custom.widget.Consent_Blackbar","props":{"widgetVisibility":"signedInOrAnonymous","useTitle":true,"useBackground":false,"title":"","lazyLoad":false},"__typename":"QuiltComponent"}],"__typename":"QuiltWrapperSection"},"__typename":"QuiltWrapper","localOverride":false},"localOverride":false},"CachedAsset:text:en_US-components/common/ActionFeedback-1744046271000":{"__typename":"CachedAsset","id":"text:en_US-components/common/ActionFeedback-1744046271000","value":{"joinedGroupHub.title":"Welcome","joinedGroupHub.message":"You are now a member of this group and are subscribed to updates.","groupHubInviteNotFound.title":"Invitation Not Found","groupHubInviteNotFound.message":"Sorry, we could not find your invitation to the group. The owner may have canceled the invite.","groupHubNotFound.title":"Group Not Found","groupHubNotFound.message":"The grouphub you tried to join does not exist. It may have been deleted.","existingGroupHubMember.title":"Already Joined","existingGroupHubMember.message":"You are already a member of this group.","accountLocked.title":"Account Locked","accountLocked.message":"Your account has been locked due to multiple failed attempts. Try again in {lockoutTime} minutes.","editedGroupHub.title":"Changes Saved","editedGroupHub.message":"Your group has been updated.","leftGroupHub.title":"Goodbye","leftGroupHub.message":"You are no longer a member of this group and will not receive future updates.","deletedGroupHub.title":"Deleted","deletedGroupHub.message":"The group has been deleted.","groupHubCreated.title":"Group Created","groupHubCreated.message":"{groupHubName} is ready to use","accountClosed.title":"Account Closed","accountClosed.message":"The account has been closed and you will now be redirected to the homepage","resetTokenExpired.title":"Reset Password Link has Expired","resetTokenExpired.message":"Try resetting your password again","invalidUrl.title":"Invalid URL","invalidUrl.message":"The URL you're using is not recognized. Verify your URL and try again.","accountClosedForUser.title":"Account Closed","accountClosedForUser.message":"{userName}'s account is closed","inviteTokenInvalid.title":"Invitation Invalid","inviteTokenInvalid.message":"Your invitation to the community has been canceled or expired.","inviteTokenError.title":"Invitation Verification Failed","inviteTokenError.message":"The url you are utilizing is not recognized. Verify your URL and try again","pageNotFound.title":"Access Denied","pageNotFound.message":"You do not have access to this area of the community or it doesn't exist","eventAttending.title":"Responded as Attending","eventAttending.message":"You'll be notified when there's new activity and reminded as the event approaches","eventInterested.title":"Responded as Interested","eventInterested.message":"You'll be notified when there's new activity and reminded as the event approaches","eventNotFound.title":"Event Not Found","eventNotFound.message":"The event you tried to respond to does not exist.","redirectToRelatedPage.title":"Showing Related Content","redirectToRelatedPageForBaseUsers.title":"Showing Related Content","redirectToRelatedPageForBaseUsers.message":"The content you are trying to access is archived","redirectToRelatedPage.message":"The content you are trying to access is archived","relatedUrl.archivalLink.flyoutMessage":"The content you are trying to access is archived View Archived Content"},"localOverride":false},"CachedAsset:component:custom.widget.GainsightShared-en-us-1745595741765":{"__typename":"CachedAsset","id":"component:custom.widget.GainsightShared-en-us-1745595741765","value":{"component":{"id":"custom.widget.GainsightShared","template":{"id":"GainsightShared","markupLanguage":"HTML","style":null,"texts":{},"defaults":{"config":{"applicablePages":[],"description":"Shared functions for Gainsight integration","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.GainsightShared","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"TEXTHTML","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"Shared functions for Gainsight integration","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":null,"form":null},"localOverride":false},"CachedAsset:component:custom.widget.Beta_MetaNav-en-us-1745595741765":{"__typename":"CachedAsset","id":"component:custom.widget.Beta_MetaNav-en-us-1745595741765","value":{"component":{"id":"custom.widget.Beta_MetaNav","template":{"id":"Beta_MetaNav","markupLanguage":"HANDLEBARS","style":null,"texts":{},"defaults":{"config":{"applicablePages":[],"description":"MetaNav menu at the top of every page.","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.Beta_MetaNav","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"MetaNav menu at the top of every page.","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":null,"form":null},"localOverride":false},"CachedAsset:component:custom.widget.Beta_Footer-en-us-1745595741765":{"__typename":"CachedAsset","id":"component:custom.widget.Beta_Footer-en-us-1745595741765","value":{"component":{"id":"custom.widget.Beta_Footer","template":{"id":"Beta_Footer","markupLanguage":"HANDLEBARS","style":null,"texts":{},"defaults":{"config":{"applicablePages":[],"description":"DevCentral´s custom footer.","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.Beta_Footer","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"DevCentral´s custom footer.","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":null,"form":null},"localOverride":false},"CachedAsset:component:custom.widget.Tag_Manager_Helper-en-us-1745595741765":{"__typename":"CachedAsset","id":"component:custom.widget.Tag_Manager_Helper-en-us-1745595741765","value":{"component":{"id":"custom.widget.Tag_Manager_Helper","template":{"id":"Tag_Manager_Helper","markupLanguage":"HANDLEBARS","style":null,"texts":{},"defaults":{"config":{"applicablePages":[],"description":"Helper widget to inject Tag Manager scripts into head element","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.Tag_Manager_Helper","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"CUSTOM","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"Helper widget to inject Tag Manager scripts into head element","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":null,"form":null},"localOverride":false},"CachedAsset:component:custom.widget.Consent_Blackbar-en-us-1745595741765":{"__typename":"CachedAsset","id":"component:custom.widget.Consent_Blackbar-en-us-1745595741765","value":{"component":{"id":"custom.widget.Consent_Blackbar","template":{"id":"Consent_Blackbar","markupLanguage":"HTML","style":null,"texts":{},"defaults":{"config":{"applicablePages":[],"description":"","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"components":[{"id":"custom.widget.Consent_Blackbar","form":null,"config":null,"props":[],"__typename":"Component"}],"grouping":"TEXTHTML","__typename":"ComponentTemplate"},"properties":{"config":{"applicablePages":[],"description":"","fetchedContent":null,"__typename":"ComponentConfiguration"},"props":[],"__typename":"ComponentProperties"},"form":null,"__typename":"Component","localOverride":false},"globalCss":null,"form":null},"localOverride":false},"CachedAsset:text:en_US-components/community/Breadcrumb-1744046271000":{"__typename":"CachedAsset","id":"text:en_US-components/community/Breadcrumb-1744046271000","value":{"navLabel":"Breadcrumbs","dropdown":"Additional parent page navigation"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageBanner-1744046271000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageBanner-1744046271000","value":{"messageMarkedAsSpam":"This post has been marked as spam","messageMarkedAsSpam@board:TKB":"This article has been marked as spam","messageMarkedAsSpam@board:BLOG":"This post has been marked as spam","messageMarkedAsSpam@board:FORUM":"This discussion has been marked as spam","messageMarkedAsSpam@board:OCCASION":"This event has been marked as spam","messageMarkedAsSpam@board:IDEA":"This idea has been marked as spam","manageSpam":"Manage Spam","messageMarkedAsAbuse":"This post has been marked as abuse","messageMarkedAsAbuse@board:TKB":"This article has been marked as abuse","messageMarkedAsAbuse@board:BLOG":"This post has been marked as abuse","messageMarkedAsAbuse@board:FORUM":"This discussion has been marked as abuse","messageMarkedAsAbuse@board:OCCASION":"This event has been marked as abuse","messageMarkedAsAbuse@board:IDEA":"This idea has been marked as abuse","preModCommentAuthorText":"This comment will be published as soon as it is approved","preModCommentModeratorText":"This comment is awaiting moderation","messageMarkedAsOther":"This post has been rejected due to other reasons","messageMarkedAsOther@board:TKB":"This article has been rejected due to other reasons","messageMarkedAsOther@board:BLOG":"This post has been rejected due to other reasons","messageMarkedAsOther@board:FORUM":"This discussion has been rejected due to other reasons","messageMarkedAsOther@board:OCCASION":"This event has been rejected due to other reasons","messageMarkedAsOther@board:IDEA":"This idea has been rejected due to other reasons","messageArchived":"This post was archived on {date}","relatedUrl":"View Related Content","relatedContentText":"Showing related content","archivedContentLink":"View Archived Content"},"localOverride":false},"CachedAsset:text:en_US-components/tkbs/TkbArticleWidget-1744046271000":{"__typename":"CachedAsset","id":"text:en_US-components/tkbs/TkbArticleWidget-1744046271000","value":{},"localOverride":false},"Category:category:Forums":{"__typename":"Category","id":"category:Forums","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Forum:board:TechnicalForum":{"__typename":"Forum","id":"board:TechnicalForum","forumPolicies":{"__typename":"ForumPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Forum:board:WaterCooler":{"__typename":"Forum","id":"board:WaterCooler","forumPolicies":{"__typename":"ForumPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Tkb:board:DevCentralNews":{"__typename":"Tkb","id":"board:DevCentralNews","tkbPolicies":{"__typename":"TkbPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:GroupsCategory":{"__typename":"Category","id":"category:GroupsCategory","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:F5-Groups":{"__typename":"Category","id":"category:F5-Groups","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:CommunityGroups":{"__typename":"Category","id":"category:CommunityGroups","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Occasion:board:Events":{"__typename":"Occasion","id":"board:Events","boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"occasionPolicies":{"__typename":"OccasionPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Idea:board:Suggestions":{"__typename":"Idea","id":"board:Suggestions","boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"ideaPolicies":{"__typename":"IdeaPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Category:category:CrowdSRC":{"__typename":"Category","id":"category:CrowdSRC","categoryPolicies":{"__typename":"CategoryPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Tkb:board:codeshare":{"__typename":"Tkb","id":"board:codeshare","tkbPolicies":{"__typename":"TkbPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Tkb:board:communityarticles":{"__typename":"Tkb","id":"board:communityarticles","tkbPolicies":{"__typename":"TkbPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Tkb:board:security-insights":{"__typename":"Tkb","id":"board:security-insights","tkbPolicies":{"__typename":"TkbPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"Tkb:board:article-series":{"__typename":"Tkb","id":"board:article-series","tkbPolicies":{"__typename":"TkbPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}},"boardPolicies":{"__typename":"BoardPolicies","canReadNode":{"__typename":"PolicyResult","failureReason":null}}},"QueryVariables:TopicReplyList:message:278609:1":{"__typename":"QueryVariables","id":"TopicReplyList:message:278609:1","value":{"id":"message:278609","first":10,"sorts":{"postTime":{"direction":"ASC"}},"repliesFirst":3,"repliesFirstDepthThree":1,"repliesSorts":{"postTime":{"direction":"ASC"}},"useAvatar":true,"useAuthorLogin":true,"useAuthorRank":true,"useBody":true,"useKudosCount":true,"useTimeToRead":false,"useMedia":false,"useReadOnlyIcon":false,"useRepliesCount":true,"useSearchSnippet":false,"useAcceptedSolutionButton":false,"useSolvedBadge":false,"useAttachments":false,"attachmentsFirst":5,"useTags":true,"useNodeAncestors":false,"useUserHoverCard":false,"useNodeHoverCard":false,"useModerationStatus":true,"usePreviewSubjectModal":false,"useMessageStatus":true}},"ROOT_MUTATION":{"__typename":"Mutation"},"CachedAsset:text:en_US-components/community/Navbar-1744046271000":{"__typename":"CachedAsset","id":"text:en_US-components/community/Navbar-1744046271000","value":{"community":"Community Home","inbox":"Inbox","manageContent":"Manage Content","tos":"Terms of Service","forgotPassword":"Forgot Password","themeEditor":"Theme Editor","edit":"Edit Navigation Bar","skipContent":"Skip to content","migrated-link-9":"Groups","migrated-link-7":"Technical Articles","migrated-link-8":"DevCentral News","migrated-link-1":"Technical Forum","migrated-link-10":"Community Groups","migrated-link-2":"Water Cooler","migrated-link-11":"F5 Groups","Common-external-link":"How Do I...?","migrated-link-0":"Forums","article-series":"Article Series","migrated-link-5":"Community Articles","migrated-link-6":"Articles","security-insights":"Security Insights","migrated-link-3":"CrowdSRC","migrated-link-4":"CodeShare","migrated-link-12":"Events","migrated-link-13":"Suggestions"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarHamburgerDropdown-1744046271000":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarHamburgerDropdown-1744046271000","value":{"hamburgerLabel":"Side Menu"},"localOverride":false},"CachedAsset:text:en_US-components/community/BrandLogo-1744046271000":{"__typename":"CachedAsset","id":"text:en_US-components/community/BrandLogo-1744046271000","value":{"logoAlt":"Khoros","themeLogoAlt":"Brand Logo"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarTextLinks-1744046271000":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarTextLinks-1744046271000","value":{"more":"More"},"localOverride":false},"CachedAsset:text:en_US-components/authentication/AuthenticationLink-1744046271000":{"__typename":"CachedAsset","id":"text:en_US-components/authentication/AuthenticationLink-1744046271000","value":{"title.login":"Sign In","title.registration":"Register","title.forgotPassword":"Forgot Password","title.multiAuthLogin":"Sign In"},"localOverride":false},"CachedAsset:text:en_US-components/nodes/NodeLink-1744046271000":{"__typename":"CachedAsset","id":"text:en_US-components/nodes/NodeLink-1744046271000","value":{"place":"Place {name}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageView/MessageViewStandard-1744046271000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageView/MessageViewStandard-1744046271000","value":{"anonymous":"Anonymous","author":"{messageAuthorLogin}","authorBy":"{messageAuthorLogin}","board":"{messageBoardTitle}","replyToUser":" to {parentAuthor}","showMoreReplies":"Show More","replyText":"Reply","repliesText":"Replies","markedAsSolved":"Marked as Solution","movedMessagePlaceholder.BLOG":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholder.TKB":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholder.FORUM":"{count, plural, =0 {This reply has been} other {These replies have been} }","movedMessagePlaceholder.IDEA":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholder.OCCASION":"{count, plural, =0 {This comment has been} other {These comments have been} }","movedMessagePlaceholderUrlText":"moved.","messageStatus":"Status: ","statusChanged":"Status changed: {previousStatus} to {currentStatus}","statusAdded":"Status added: {status}","statusRemoved":"Status removed: {status}","labelExpand":"expand replies","labelCollapse":"collapse replies","unhelpfulReason.reason1":"Content is outdated","unhelpfulReason.reason2":"Article is missing information","unhelpfulReason.reason3":"Content is for a different Product","unhelpfulReason.reason4":"Doesn't match what I was searching for"},"localOverride":false},"CachedAsset:text:en_US-components/messages/ThreadedReplyList-1744046271000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/ThreadedReplyList-1744046271000","value":{"title":"{count, plural, one{# Reply} other{# Replies}}","title@board:BLOG":"{count, plural, one{# Comment} other{# Comments}}","title@board:TKB":"{count, plural, one{# Comment} other{# Comments}}","title@board:IDEA":"{count, plural, one{# Comment} other{# Comments}}","title@board:OCCASION":"{count, plural, one{# Comment} other{# Comments}}","noRepliesTitle":"No Replies","noRepliesTitle@board:BLOG":"No Comments","noRepliesTitle@board:TKB":"No Comments","noRepliesTitle@board:IDEA":"No Comments","noRepliesTitle@board:OCCASION":"No Comments","noRepliesDescription":"Be the first to reply","noRepliesDescription@board:BLOG":"Be the first to comment","noRepliesDescription@board:TKB":"Be the first to comment","noRepliesDescription@board:IDEA":"Be the first to comment","noRepliesDescription@board:OCCASION":"Be the first to comment","messageReadOnlyAlert:BLOG":"Comments have been turned off for this post","messageReadOnlyAlert:TKB":"Comments have been turned off for this article","messageReadOnlyAlert:IDEA":"Comments have been turned off for this idea","messageReadOnlyAlert:FORUM":"Replies have been turned off for this discussion","messageReadOnlyAlert:OCCASION":"Comments have been turned off for this event"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageReplyCallToAction-1744046271000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageReplyCallToAction-1744046271000","value":{"leaveReply":"Leave a reply...","leaveReply@board:BLOG@message:root":"Leave a comment...","leaveReply@board:TKB@message:root":"Leave a comment...","leaveReply@board:IDEA@message:root":"Leave a comment...","leaveReply@board:OCCASION@message:root":"Leave a comment...","repliesTurnedOff.FORUM":"Replies are turned off for this topic","repliesTurnedOff.BLOG":"Comments are turned off for this topic","repliesTurnedOff.TKB":"Comments are turned off for this topic","repliesTurnedOff.IDEA":"Comments are turned off for this topic","repliesTurnedOff.OCCASION":"Comments are turned off for this topic","infoText":"Stop poking me!"},"localOverride":false},"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/cmstMjktRWl0NU5q\"}":{"__typename":"AssociatedImage","url":"https://community.f5.com/t5/s/zihoc95639/images/cmstMjktRWl0NU5q","height":24,"width":21,"mimeType":"image/png"},"Rank:rank:29":{"__typename":"Rank","id":"rank:29","position":6,"name":"MVP","color":"7CC0EB","icon":{"__ref":"AssociatedImage:{\"url\":\"https://community.f5.com/t5/s/zihoc95639/images/cmstMjktRWl0NU5q\"}"},"rankStyle":"FILLED"},"User:user:305752":{"__typename":"User","id":"user:305752","uid":305752,"login":"Nikoolayy1","biography":null,"registrationData":{"__typename":"RegistrationData","status":null,"registrationTime":"2019-10-15T01:14:48.000-07:00"},"deleted":false,"email":"","avatar":{"__typename":"UserAvatar","url":"https://community.f5.com/t5/s/zihoc95639/images/dS0zMDU3NTItd2tMWnln?image-coordinates=3%2C3%2C176%2C176"},"rank":{"__ref":"Rank:rank:29"},"entityType":"USER","eventPath":"community:zihoc95639/user:305752"},"ModerationData:moderation_data:278610":{"__typename":"ModerationData","id":"moderation_data:278610","status":"APPROVED","rejectReason":null,"isReportedAbuse":false,"rejectUser":null,"rejectTime":null,"rejectActorType":null},"TkbReplyMessage:message:278610":{"__typename":"TkbReplyMessage","author":{"__ref":"User:user:305752"},"id":"message:278610","revisionNum":1,"uid":278610,"depth":1,"hasGivenKudo":false,"subscribed":false,"board":{"__ref":"Tkb:board:TechnicalArticles"},"parent":{"__ref":"TkbTopicMessage:message:278609"},"conversation":{"__ref":"Conversation:conversation:278609"},"subject":"Re: TLS Fingerprinting JA3 iRule Application: Rate limit and block malicious traffic based on TLS signature","moderationData":{"__ref":"ModerationData:moderation_data:278610"},"body":"

Thanks for the nice article just for information why are two data groups \"malicious_fingerprintdb\" and \"malicious_TLSfingerprintdb\" ? I think that this could be an error and the data group should be just one.

 

#check if fingerprint matches a known malicious fingerprint, if yes, drop connection

if {[class match ${ja3_fingerprint} equals malicious_fingerprintdb]}{

set malicious_fingerprint [class match -value ${ja3_fingerprint} equals malicious_TLSfingerprintdb]

drop

log local0. \"known malicious fingerprint matched $malicious_fingerprint - Action:DROP!\"

 

","body@stripHtml({\"removeProcessingText\":false,\"removeSpoilerMarkup\":false,\"removeTocMarkup\":false,\"truncateLength\":200})@stringLength":"203","kudosSumWeight":0,"repliesCount":0,"postTime":"2021-06-22T04:57:33.000-07:00","lastPublishTime":"2021-06-22T04:57:33.000-07:00","metrics":{"__typename":"MessageMetrics","views":2419},"visibilityScope":"PUBLIC","placeholder":false,"originalMessageForPlaceholder":null,"entityType":"TKB_REPLY","eventPath":"category:Articles/community:zihoc95639board:TechnicalArticles/message:278609/message:278610","replies":{"__typename":"MessageConnection","pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null},"edges":[]},"customFields":[],"attachments":{"__typename":"AttachmentConnection","edges":[],"pageInfo":{"__typename":"PageInfo","hasNextPage":false,"endCursor":null,"hasPreviousPage":false,"startCursor":null}}},"CachedAsset:text:en_US-shared/client/components/common/QueryHandler-1744046271000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/common/QueryHandler-1744046271000","value":{"title":"Query Handler"},"localOverride":false},"CachedAsset:text:en_US-components/community/NavbarDropdownToggle-1744046271000":{"__typename":"CachedAsset","id":"text:en_US-components/community/NavbarDropdownToggle-1744046271000","value":{"ariaLabelClosed":"Press the down arrow to open the menu"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageSubject-1744046271000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageSubject-1744046271000","value":{"noSubject":"(no subject)"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageBody-1744046271000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageBody-1744046271000","value":{"showMessageBody":"Show More","mentionsErrorTitle":"{mentionsType, select, board {Board} user {User} message {Message} other {}} No Longer Available","mentionsErrorMessage":"The {mentionsType} you are trying to view has been removed from the community.","videoProcessing":"Video is being processed. Please try again in a few minutes.","bannerTitle":"Video provider requires cookies to play the video. Accept to continue or {url} it directly on the provider's site.","buttonTitle":"Accept","urlText":"watch"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageCustomFields-1744046271000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageCustomFields-1744046271000","value":{"CustomField.default.label":"Value of {name}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageRevision-1744046271000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageRevision-1744046271000","value":{"lastUpdatedDatePublished":"{publishCount, plural, one{Published} other{Updated}} {date}","lastUpdatedDateDraft":"Created {date}","version":"Version {major}.{minor}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageReplyButton-1744046271000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageReplyButton-1744046271000","value":{"repliesCount":"{count}","title":"Reply","title@board:BLOG@message:root":"Comment","title@board:TKB@message:root":"Comment","title@board:IDEA@message:root":"Comment","title@board:OCCASION@message:root":"Comment"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageAuthorBio-1744046271000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageAuthorBio-1744046271000","value":{"sendMessage":"Send Message","actionMessage":"Follow this blog board to get notified when there's new activity","coAuthor":"CO-PUBLISHER","contributor":"CONTRIBUTOR","userProfile":"View Profile","iconlink":"Go to {name} {type}"},"localOverride":false},"CachedAsset:text:en_US-components/guides/GuideBottomNavigation-1744046271000":{"__typename":"CachedAsset","id":"text:en_US-components/guides/GuideBottomNavigation-1744046271000","value":{"nav.label":"Previous/Next Page","nav.previous":"Previous","nav.next":"Next"},"localOverride":false},"CachedAsset:text:en_US-components/tags/TagView/TagViewChip-1744046271000":{"__typename":"CachedAsset","id":"text:en_US-components/tags/TagView/TagViewChip-1744046271000","value":{"tagLabelName":"Tag name {tagName}"},"localOverride":false},"CachedAsset:text:en_US-components/users/UserLink-1744046271000":{"__typename":"CachedAsset","id":"text:en_US-components/users/UserLink-1744046271000","value":{"authorName":"View Profile: {author}","anonymous":"Anonymous"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/users/UserRank-1744046271000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/users/UserRank-1744046271000","value":{"rankName":"{rankName}","userRank":"Author rank {rankName}"},"localOverride":false},"CachedAsset:text:en_US-components/users/UserRegistrationDate-1744046271000":{"__typename":"CachedAsset","id":"text:en_US-components/users/UserRegistrationDate-1744046271000","value":{"noPrefix":"{date}","withPrefix":"Joined {date}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageListMenu-1744046271000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageListMenu-1744046271000","value":{"postTimeAsc":"Oldest","postTimeDesc":"Newest","kudosSumWeightAsc":"Least Liked","kudosSumWeightDesc":"Most Liked","sortTitle":"Sort By","sortedBy.item":" { itemName, select, postTimeAsc {Oldest} postTimeDesc {Newest} kudosSumWeightAsc {Least Liked} kudosSumWeightDesc {Most Liked} other {}}"},"localOverride":false},"CachedAsset:text:en_US-components/messages/MessageTime-1744046271000":{"__typename":"CachedAsset","id":"text:en_US-components/messages/MessageTime-1744046271000","value":{"postTime":"Published: {time}","lastPublishTime":"Last Update: {time}","conversation.lastPostingActivityTime":"Last posting activity time: {time}","conversation.lastPostTime":"Last post time: {time}","moderationData.rejectTime":"Rejected time: {time}"},"localOverride":false},"CachedAsset:text:en_US-components/customComponent/CustomComponent-1744046271000":{"__typename":"CachedAsset","id":"text:en_US-components/customComponent/CustomComponent-1744046271000","value":{"errorMessage":"Error rendering component id: {customComponentId}","bannerTitle":"Video provider requires cookies to play the video. Accept to continue or {url} it directly on the provider's site.","buttonTitle":"Accept","urlText":"watch"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/users/UserAvatar-1744046271000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/users/UserAvatar-1744046271000","value":{"altText":"{login}'s avatar","altTextGeneric":"User's avatar"},"localOverride":false},"CachedAsset:text:en_US-shared/client/components/ranks/UserRankLabel-1744046271000":{"__typename":"CachedAsset","id":"text:en_US-shared/client/components/ranks/UserRankLabel-1744046271000","value":{"altTitle":"Icon for {rankName} rank"},"localOverride":false}}}},"page":"/kbs/TkbMessagePage/TkbMessagePage","query":{"boardId":"technicalarticles","messageSubject":"tls-fingerprinting-ja3-irule-application-rate-limit-and-block-malicious-traffic-","messageId":"278609"},"buildId":"ISAhs0UxT148eG089lpQq","runtimeConfig":{"buildInformationVisible":false,"logLevelApp":"info","logLevelMetrics":"info","openTelemetryClientEnabled":false,"openTelemetryConfigName":"f5","openTelemetryServiceVersion":"25.3.0","openTelemetryUniverse":"prod","openTelemetryCollector":"http://localhost:4318","openTelemetryRouteChangeAllowedTime":"5000","apolloDevToolsEnabled":false,"inboxMuteWipFeatureEnabled":false},"isFallback":false,"isExperimentalCompile":false,"dynamicIds":["./components/customComponent/CustomComponent/CustomComponent.tsx","./components/community/Navbar/NavbarWidget.tsx","./components/community/Breadcrumb/BreadcrumbWidget.tsx","./components/tkbs/TkbArticleWidget/TkbArticleWidget.tsx","./components/messages/MessageView/MessageViewStandard/MessageViewStandard.tsx","./components/messages/ThreadedReplyList/ThreadedReplyList.tsx","./components/customComponent/CustomComponentContent/TemplateContent.tsx","../shared/client/components/common/List/UnwrappedList/UnwrappedList.tsx","./components/tags/TagView/TagView.tsx","./components/tags/TagView/TagViewChip/TagViewChip.tsx","../shared/client/components/common/List/UnstyledList/UnstyledList.tsx","./components/messages/MessageView/MessageView.tsx","./components/customComponent/CustomComponentContent/HtmlContent.tsx","./components/customComponent/CustomComponentContent/CustomComponentScripts.tsx"],"appGip":true,"scriptLoader":[]}