Appearance
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)
| Function | Direction |
|---|---|
SSL_write, SSL_write_ex | Outbound: data before encryption |
SSL_read, SSL_read_ex | Inbound: data after decryption |
BIO_write, BIO_read | BIO layer (low-level crypto transport) |
GnuTLS (libgnutls.so)
| Function | Direction |
|---|---|
gnutls_record_send, gnutls_record_send2 | Outbound |
gnutls_record_recv | Inbound |
Go TLS (Go standard library crypto/tls)
| Function | Direction |
|---|---|
conn.Write | Outbound |
conn.Read | Inbound |
BoringSSL (libcrypto.so, Google's OpenSSL fork)
| Function | Direction |
|---|---|
SSL_write | Outbound |
SSL_read | Inbound |
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:
| Classification | Condition | Meaning |
|---|---|---|
Plaintext | H2C frames observed (cleartext HTTP/2) or raw TCP on a known protocol port | Connection is unencrypted; eBPF has full payload visibility |
OpenSslTls | SSL_write uprobe fired for this connection | TLS library is hooked; payload is capturable before encryption and after decryption |
OpaqueTls | TCP connection to a known TLS port (443, 8443, etc.) but no SSL_write fired | Connection is TLS but the library is not hooked; connection metadata visible, payload not |
Unknown | TCP connection with no data signal yet | Classification 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
| Field | Description |
|---|---|
http_method | HTTP method from the HEADERS frame (POST, GET, PUT, PATCH, DELETE) |
http_path | SBI resource path, for example /nudm-sdm/v1/{supi}/sm-data |
http_status | HTTP response status code from the response HEADERS frame |
http_authority | Target NF hostname or service address from the :authority header |
http_body | Full decrypted JSON body from the HTTP/2 DATA frame, up to 4096 bytes |
http_body_truncated | Set to true when the body exceeds the capture limit |
nf_role | Detected role of the NF process, for example AMF, UDM, AUSF |
capture_method | Identifies the interception point: SSL_write, SSL_read, or the equivalent GnuTLS or Go TLS symbol |
api_protocol | Set 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)
| Condition | Alert severity | Meaning |
|---|---|---|
SBI port classified as Plaintext | Critical | NF-to-NF SBI traffic is unencrypted; 3GPP TS 29.501 violation |
SBI port classified as OpaqueTls | High | TLS 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
| Control | What TLS data contributes |
|---|---|
3GPP_4_2_5B | SBI/NF API interface coverage; evidence from tls_inventory_report |
NIS2 Directive (Telecom)
| Control | What TLS data contributes |
|---|---|
NIS2_H | Cryptography 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:
| Field | Type | Meaning |
|---|---|---|
nf_role | String | NF role of the process (e.g., SMF, AMF, UPF) |
port | Integer | Port number of the TLS connection |
tls_posture | String | Classification: plaintext, openssl_tls, opaque_tls, or unknown |
interface_name | String | Interface label (e.g., SBI, N4, NGAP) |
coverage_gap | Boolean | true 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
OpaqueTlsregardless of TLS version. Thecoverage_gap: truefield 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 asOpaqueTlseven if the binary uses TLS. - Go TLS uprobe may fail with inlined binaries: Go's compiler can inline the
conn.Writeandconn.Readmethods used for uprobe attachment. When inlining occurs, the uprobe cannot attach and the coverage falls back toOpaqueTls. 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_reportreflects 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 asOpaqueTlsorPlaintextdo not producehttp_bodyevents. 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.
| Specification | Relevant requirement | How Telovix addresses it |
|---|---|---|
| FS.37 GTP-U Security | Deploy security capabilities on specific NF interfaces for inspection | The uprobe intercepts SBI traffic on the interface between NFs, producing structured telemetry and decoded payload content |
| FS.20 GTP Security | Peer validation and wrong-source-on-sensitive-interface detection | TLS downgrade detection on SBI ports fires a critical alert when a previously encrypted interface is observed without TLS |
| FS.31 Baseline Security Controls | Segmentation, access control, and security operations monitoring | Per-NF TLS posture inventory, coverage gap flagging, and SBI compliance checks contribute directly to the FS.31 operational monitoring baseline |