Forum Discussion
PQC: a blindspot (logging) on BIG-IP - RFE
On BIG-IP it's currently not possible to log information such as proposed and negotiated Key Exchange Algorithm. No available iRule commands for that.
On the other hand, NGINX do offer the possible to log it ($ssl_curve/$ssl_curves variables).
I've got a RFE created for the following:
Provide new iRule commands in events CLIENTSSL_CLIENTHELLO and CLIENTSSL_HANDSHAKE that outputs the Key Exchange Algorithm:
- list of proposed (by the SSL client) Key Exchange Algorithms in CLIENTSSL_CLIENTHELLO
- negotiated Key Exchange Algorithms in CLIENTSSL_HANDSHAKE
=>
RFE ID2347153 β "iRule command equivalent to NGINX's $ssl_curve for logging the negotiated KEM/DH group"
Don't hesitate to open a support case to bind it to that RFE, the more we are the higher priority will be assigned to implement it (hopefully). π
Alexandre
4 Replies
you can try to log it using SSL::cipher object
- amolari
Cirrostratus
That won't work, as per the note from F5 support:
What IS Available via iRules on BIG-IP 17.5.1
1. Log negotiated cipher suite and TLS version (post-handshake) Per KB K86071030:
when CLIENTSSL_HANDSHAKE { log local0. "Client: [IP::client_addr] - TLS: [SSL::cipher version] - Cipher: [SSL::cipher name] - Bits: [SSL::cipher bits]" }
Limitation: [SSL::cipher name] returns the TLS 1.3 cipher suite (e.g., TLS_AES_128_GCM_SHA256), which does not include the key exchange group. In TLS 1.3, the cipher suite and key exchange group are decoupled by design.
2. Log client's offered cipher list (pre-handshake) Per KB K10452619:
when CLIENTSSL_CLIENTHELLO { log local0. "Client: [IP::client_addr] - OfferedCiphers: [SSL::cipher clientlist]" }
Limitation: [SSL::cipher clientlist] returns cipher suite hex codes from the ClientHello β it does not expose the supported_groups or key_share TLS extensions. The PQC group identifier (e.g., 0x11EC for X25519MLKEM768) is advertised in the key_share extension, which is not accessible via this command.
in my opinion, logging this tls details for live traffic continously is not sustainable and not useful:
because tls server, which in this case is f5 vserver, selects the highest priority cipher in the vserver's client side ssl profile that match clienthello's accepted cipher.
so admin basically defines the minimum cipher spec that can be used.so, if you only need this functionality in tests, you can use tcpdump which will show all details of tls session setup.
- Kevin_Stewart
Employee
Not discounting the actual need to support logging the negotiated key exchange algorithm, but in the short term please allow me to provide some options.
iRule solution that essentially "guesses" at the negotiation:
when CLIENTSSL_CLIENTHELLO { # Capture which PQC groups the client offered set ::pqc_offered "" if { [SSL::extensions exists -type 10] } { set sg [SSL::extensions -type 10] # X25519MLKEM768 = 0x11EC (4588) # SecP256r1MLKEM768 = 0x11EB (4587) # X25519Kyber768Draft = 0x6399 (25497) # X25519 = 0x001D (29) if { [string match *\x11\xEC* $sg] } { append ::pqc_offered "X25519MLKEM768 " } if { [string match *\x11\xEB* $sg] } { append ::pqc_offered "SecP256r1MLKEM768 " } if { [string match *\x63\x99* $sg] } { append ::pqc_offered "X25519Kyber768Draft " } if { [string match *\x00\x1D* $sg] } { append ::pqc_offered "X25519 " } if { [string match *\x00\x17* $sg] } { append ::pqc_offered "secp256r1 " } } } when CLIENTSSL_HANDSHAKE { # SSL::cipher name gives the bulk cipher suite (e.g. TLS_AES_256_GCM_SHA384) # SSL::cipher version confirms TLS 1.3 β required for ML-KEM set ver [SSL::cipher version] set ciph [SSL::cipher name] set ip [IP::client_addr] # If TLS 1.3 and client offered X25519MLKEM768, BIG-IP will have picked it # (assuming your cipher group lists it and no HelloRetryRequest occurred) if { $ver eq "TLSv1.3" && [string match *X25519MLKEM768* $::pqc_offered] } { log local0.info "LIKELY-MLKEM client=$ip cipher=$ciph version=$ver offered=$::pqc_offered" } else { log local0.info "NO-MLKEM client=$ip cipher=$ciph version=$ver offered=$::pqc_offered" } }Your LTM log output would look something like this:
LIKELY-MLKEM client=10.1.10.50 cipher=TLS13-AES128-GCM-SHA256 version=TLSv1.3 offered=X25519MLKEM768 X25519 secp256r1There's also a set of tmctl options you can use to view PQC stats:
## Client side tmctl -r -P -s common.cipher_uses.mlkem768,common.cipher_uses.mlkem1024,common.cipher_uses.x25519_mlkem768,common.cipher_uses.p256_mlkem768,common.cipher_uses.p384_mlkem1024,common.cipher_uses.kem_x25519_ml_kem768 profile_clientssl_stat Name Value --------------------------------------- ----- common.cipher_uses.mlkem768 6 common.cipher_uses.mlkem1024 0 common.cipher_uses.x25519_mlkem768 6 common.cipher_uses.p256_mlkem768 0 common.cipher_uses.p384_mlkem1024 0 common.cipher_uses.kem_x25519_ml_kem768 6## Server side tmctl -r -P -s common.cipher_uses.x25519_mlkem768,common.cipher_uses.mlkem768,common.cipher_uses.mlkem1024 profile_serverssl_stat Name Value ---------------------------------- ----- common.cipher_uses.x25519_mlkem768 6 common.cipher_uses.mlkem768 6 common.cipher_uses.mlkem1024 0## Total ML-KEM connections tmctl -q -c -s common.cipher_uses.mlkem768,common.cipher_uses.mlkem1024,common.cipher_uses.x25519_mlkem768,common.cipher_uses.p256_mlkem768,common.cipher_uses.p384_mlkem1024,common.cipher_uses.kem_x25519_ml_kem768 profile_clientssl_stat \ > | awk -F, '{for(i=1;i<=NF;i++)s+=$i} END{printf "TOTAL ML-KEM connections: %d\n", s}' TOTAL ML-KEM connections: 18## Total ML-KEM family count tmctl -q -c -s common.cipher_uses.mlkem768,common.cipher_uses.x25519_mlkem768,common.cipher_uses.p256_mlkem768,common.cipher_uses.kem_x25519_ml_kem768,common.cipher_uses.mlkem1024,common.cipher_uses.p384_mlkem1024 profile_clientssl_stat \ > | awk -F, '{k768+=$1+$2+$3+$4; k1024+=$5+$6} END{printf "ML-KEM768 family: %d\nML-KEM1024 family: %d\nTOTAL PQC: %d\n", k768, k1024, k768+k1024}' ML-KEM768 family: 18 ML-KEM1024 family: 0 TOTAL PQC: 18## Total ML-KEM + Kyber connections tmctl -q -c -s common.cipher_uses.mlkem768,common.cipher_uses.mlkem1024,common.cipher_uses.x25519_mlkem768,common.cipher_uses.p256_mlkem768,common.cipher_uses.p384_mlkem1024,common.cipher_uses.kem_x25519_ml_kem768,common.cipher_uses.kyber768,common.cipher_uses.x25519_kyber768,common.cipher_uses.kem_x25519_kyber768 profile_clientssl_stat \ > | awk -F, '{for(i=1;i<=NF;i++)s+=$i} END{printf "TOTAL PQC (ML-KEM + Kyber) connections: %d\n", s}' TOTAL PQC (ML-KEM + Kyber) connections: 18Thanks.
Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com