Skip to content

TLS Visibility and SBI Decryption

The telecom sensor instruments TLS libraries directly on each monitored node. It classifies every active NF connection as plaintext, uprobe-covered TLS, or opaque TLS, and for connections classified as uprobe-covered it also captures and decodes the full HTTP/2 SBI payload before encryption and after decryption at the library call level.

This gives operators real-time visibility into the content of encrypted 5G Core SBI traffic, including authentication vectors, subscriber identifiers, session parameters, and NF registration data, without requiring certificate access, private key material, or any change to the 5G Core configuration.

Requires: Telecom sensor flavor. TLS uprobe coverage and SBI decryption are automatically activated at sensor startup. No additional configuration is needed.


How TLS uprobe coverage works

At sensor startup, the sensor scans /proc for running binaries and inspects each binary for linked TLS libraries. When a supported library is found, the sensor generates a tracing policy YAML file for that library and writes it to compiled-policies/tls-uprobe-*.yaml. The policy is loaded automatically and instruments the library functions in the running process using uprobes (user-space probes).

This approach does not require configuration. It runs automatically for all processes on nodes where the telecom flavor is deployed.

Supported TLS libraries and hooked functions

OpenSSL (libssl.so)

FunctionDirection
SSL_write, SSL_write_exOutbound: data before encryption
SSL_read, SSL_read_exInbound: data after decryption
BIO_write, BIO_readBIO layer (low-level crypto transport)

GnuTLS (libgnutls.so)

FunctionDirection
gnutls_record_send, gnutls_record_send2Outbound
gnutls_record_recvInbound

Go TLS (Go standard library crypto/tls)

FunctionDirection
conn.WriteOutbound
conn.ReadInbound

BoringSSL (libcrypto.so, Google's OpenSSL fork)

FunctionDirection
SSL_writeOutbound
SSL_readInbound

If a binary does not link any of these libraries, no uprobe policy is generated for that process and the sensor falls back to network-layer coverage only.


Coverage classification

Every active connection on a monitored process is classified into one of four coverage states:

ClassificationConditionMeaning
PlaintextH2C frames observed (cleartext HTTP/2) or raw TCP on a known protocol portConnection is unencrypted; eBPF has full payload visibility
OpenSslTlsSSL_write uprobe fired for this connectionTLS library is hooked; payload is capturable before encryption and after decryption
OpaqueTlsTCP connection to a known TLS port (443, 8443, etc.) but no SSL_write firedConnection is TLS but the library is not hooked; connection metadata visible, payload not
UnknownTCP connection with no data signal yetClassification pending; typically resolves on the next heartbeat interval

The coverage classification is assigned per connection and reported in the tls_inventory_report heartbeat field alongside the NF role, port, interface name, and a coverage_gap boolean.

Example heartbeat record

json
{
  "tls_inventory_report": {
    "nf_tls_postures": [
      {
        "nf_role": "SMF",
        "port": 7777,
        "tls_posture": "openssl_tls",
        "interface_name": "SBI",
        "coverage_gap": false
      }
    ]
  }
}

SBI payload decryption

When an NF connection is classified as OpenSslTls, the sensor intercepts the plaintext SBI HTTP/2 frames at the point where the NF process passes the buffer to the TLS library. This interception point is after the application has assembled the HTTP/2 message and before encryption is applied on the write path, or after decryption and before the application processes the response on the read path.

The sensor parses the captured frames, extracts HTTP/2 HEADERS and DATA frames, and writes the decoded content to ClickHouse as structured runtime events. No private key is required and no man-in-the-middle position is needed. The interception is transparent to the NF.

What is captured

FieldDescription
http_methodHTTP method from the HEADERS frame (POST, GET, PUT, PATCH, DELETE)
http_pathSBI resource path, for example /nudm-sdm/v1/{supi}/sm-data
http_statusHTTP response status code from the response HEADERS frame
http_authorityTarget NF hostname or service address from the :authority header
http_bodyFull decrypted JSON body from the HTTP/2 DATA frame, up to 4096 bytes
http_body_truncatedSet to true when the body exceeds the capture limit
nf_roleDetected role of the NF process, for example AMF, UDM, AUSF
capture_methodIdentifies the interception point: SSL_write, SSL_read, or the equivalent GnuTLS or Go TLS symbol
api_protocolSet to 5g_sbi when the path matches a known 3GPP SBI service

Example captured event

The following is an example of a live AUSF authentication response captured from TLS 1.3 encrypted SBI traffic on a 5G Core node. The content was in transit encrypted on the wire and is reproduced here as the sensor delivers it to ClickHouse.

json
{
  "event_kind": "api_response",
  "nf_role": "AUSF",
  "capture_method": "SSL_read",
  "api_protocol": "5g_sbi",
  "http_status": "200",
  "http_body": "{\"authResult\":\"AUTHENTICATION_SUCCESS\",\"supi\":\"imsi-001010000000001\",\"kseaf\":\"7d452401cfd4a4d62eeaa0c54647046154f2e4e260414ecc3aa7257fcdbfe8a5\"}"
}

The supi field is the Subscription Permanent Identifier. The kseaf field is the session anchor key derived from the 5G-AKA authentication exchange. Both are transported in the SBI DATA frame and are visible in plaintext through the uprobe.

Body capture limit

The sensor captures up to 4096 bytes of DATA frame payload per HTTP/2 stream. This limit covers the full content of virtually all SBI exchanges in production deployments, including authentication vectors, subscription records, session management context, and NF registration payloads. Bulk operations that produce responses larger than 4096 bytes are truncated and the http_body_truncated field is set to true.

Container and Kubernetes support

On Kubernetes nodes, NF processes run inside containers that bring their own userspace libraries. The sensor resolves the correct library file within each container namespace at detection time and installs the uprobe on the container overlay inode. The interception is per-NF-process and works identically whether the NF runs as a host binary, a container, or a Kubernetes pod.

PCAP export

The Console provides a PCAP download per sensor in standard PCAPNG format. When SBI decryption is active, the downloaded capture includes the decrypted HTTP/2 frames alongside real SCTP and TCP signaling from the same node. Open the file in Wireshark and set port 7777 to decode as HTTP2 under Analyze then Decode As to browse the SBI content.


SBI compliance check

3GPP TS 29.501 requires mutual TLS (mTLS) for all SBI (Service-Based Interface) connections between 5G Core network functions. The sensor enforces this requirement at detection time.

SBI ports monitored: 7777 (Open5GS/Free5GC default) and 29500-29599 (3GPP standard range)

ConditionAlert severityMeaning
SBI port classified as PlaintextCriticalNF-to-NF SBI traffic is unencrypted; 3GPP TS 29.501 violation
SBI port classified as OpaqueTlsHighTLS is in use but library is not hooked; coverage gap on mTLS interface

These alerts feed directly into the telecom anomaly scoring system. A Plaintext SBI finding contributes a critical-weight factor to the node's telecom risk score.


Compliance control mapping

TLS posture data contributes evidence to two compliance frameworks:

3GPP TS 33.117

ControlWhat TLS data contributes
3GPP_4_2_5BSBI/NF API interface coverage; evidence from tls_inventory_report

NIS2 Directive (Telecom)

ControlWhat TLS data contributes
NIS2_HCryptography and SBI TLS monitoring; plaintext or opaque findings trigger evidence gaps

Heartbeat field reference

The tls_inventory field in the sensor heartbeat (also referenced as tls_inventory_report) contains the full TLS posture inventory for all monitored processes on that sensor.

Per-posture record fields:

FieldTypeMeaning
nf_roleStringNF role of the process (e.g., SMF, AMF, UPF)
portIntegerPort number of the TLS connection
tls_postureStringClassification: plaintext, openssl_tls, opaque_tls, or unknown
interface_nameStringInterface label (e.g., SBI, N4, NGAP)
coverage_gapBooleantrue when posture is opaque_tls on a compliance-relevant interface

AI assistant tool

Ask the AI assistant: "Show TLS inventory for AMF nodes."

The AI assistant get_tls_inventory tool queries the current TLS posture state for a sensor or across the fleet, surfacing which NF roles are serving SBI over plaintext or have opaque TLS coverage gaps before you enable enforcement.


TLS visibility and enforcement

TLS posture directly affects the quality of enforcement on telecom nodes. When a node has OpaqueTls coverage on a critical interface (SBI, N4, or a management interface), the sensor can still detect process behavior, privilege events, and file integrity anomalies. What it cannot do with opaque coverage is correlate payload-level protocol behavior with those events.

Before enabling enforcement mode on an AMF, SMF, or UPF node, confirm that the SBI interface shows openssl_tls or plaintext coverage. Enforcement on a node with opaque SBI coverage means the system is acting on behavioral signals without full protocol context.


Relationship to O-RAN WG11 controls

TLS posture findings on O-RAN management interfaces contribute evidence to:

  • ORAN_E2: E2 interface peer verification (TLS coverage on E2AP connections)
  • ORAN_O1: O1 management interface security (NETCONF over SSH on port 830 is tracked separately; TLS on O1 REST interfaces contributes here)
  • ORAN_XAPP: xApp API security (TLS coverage on E42 and xApp-to-RIC connections)

Operational guidance

StaticTLS libraries: Some vendor NF builds link TLS statically rather than as a shared library. When the library is statically compiled into the binary, the standard uprobe approach cannot hook it because there is no libssl.so or libgnutls.so file. These connections will be classified as OpaqueTls regardless of what TLS version they use. This is a known limitation of the uprobe approach and is reflected in the coverage_gap field.

Container environments: On Kubernetes nodes, the sensor instruments libraries inside container processes by resolving the TLS library path through each container namespace at NF detection time. This accounts for containers that carry their own userspace (for example, an NF pod using Ubuntu 24.04 with libssl at /usr/lib/aarch64-linux-gnu/libssl.so.3 rather than the host path). The sensor installs the uprobe on the correct container overlay inode automatically. If a container runs a stripped image without the shared library present, the connection is classified as OpaqueTls.

Go TLS: Go TLS (crypto/tls) is frequently used by open-source 5G implementations (Free5GC, for example). The sensor instruments Go TLS through the gotls_uprobes module using method-level uprobes on conn.Write and conn.Read. Go binary versions that use function inlining may prevent uprobe attachment; in those cases the classification falls back to OpaqueTls.

Resolving opaque TLS gaps on SBI: If SBI connections show OpaqueTls, verify that the NF binary links against OpenSSL, GnuTLS, Go TLS, or BoringSSL as a shared library. Switching from a statically linked to a shared library build resolves the gap. Contact the NF vendor if the build configuration is not user-controllable.


Limitations

  • Statically linked TLS libraries cannot be hooked: When a vendor NF links OpenSSL, GnuTLS, or BoringSSL statically into its binary, there is no shared library file for the uprobe to attach to. These connections are classified as OpaqueTls regardless of TLS version. The coverage_gap: true field indicates this condition. Contact the NF vendor to request a shared-library build.
  • Container images with stripped libraries produce OpaqueTls: On Kubernetes nodes, the sensor resolves TLS libraries through each container's namespace. A container that does not include the shared library files (libssl.so, libgnutls.so, etc.) in its image will be classified as OpaqueTls even if the binary uses TLS.
  • Go TLS uprobe may fail with inlined binaries: Go's compiler can inline the conn.Write and conn.Read methods used for uprobe attachment. When inlining occurs, the uprobe cannot attach and the coverage falls back to OpaqueTls. This affects some production builds of Go-based 5G implementations.
  • TLS classification only applies to processes monitored by the sensor: TLS traffic from processes that started before the sensor enrolled, or that run outside the sensor's process scope, is not classified. The tls_inventory_report reflects only currently monitored connections.
  • Payload decryption requires OpenSslTls coverage: SBI payload decryption is available only when the NF connection is classified as OpenSslTls. Connections classified as OpaqueTls or Plaintext do not produce http_body events. See the SBI payload decryption section above for the full list of supported TLS libraries.

GSMA alignment

The TLS visibility and SBI decryption capabilities map to the following GSMA Network Equipment Security Assurance Scheme specifications.

SpecificationRelevant requirementHow Telovix addresses it
FS.37 GTP-U SecurityDeploy security capabilities on specific NF interfaces for inspectionThe uprobe intercepts SBI traffic on the interface between NFs, producing structured telemetry and decoded payload content
FS.20 GTP SecurityPeer validation and wrong-source-on-sensitive-interface detectionTLS downgrade detection on SBI ports fires a critical alert when a previously encrypted interface is observed without TLS
FS.31 Baseline Security ControlsSegmentation, access control, and security operations monitoringPer-NF TLS posture inventory, coverage gap flagging, and SBI compliance checks contribute directly to the FS.31 operational monitoring baseline

Further reading

Released under the Telovix Commercial License.