Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Capture tls version from openssl libs #2123

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/pxl_scripts/px/http_data/data.pxl
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ def http_data(start_time: str, source_filter: str, destination_filter: str, num_
# Add context.
df.node = df.ctx['node']
df.pid = px.upid_to_pid(df.upid)
df.ssl_version = df.ctx['ssl_version']

ssl_version_map = {
0: "SSLv1.0",
1: "SSLv1.1",
2: "SSLv1.2",
3: "SSLv1.3"
}
df.ssl_version_str = px.select(df.ssl_version in ssl_version_map, ssl_version_map[df.ssl_version], "Unknown")
df = add_source_dest_columns(df)
df = add_source_dest_links(df, start_time)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

// LINT_C_FILE: Do not remove this line. It ensures cpplint treats this as a C file.

#include "../bcc_bpf_intf/socket_trace.h"
#include "src/stirling/source_connectors/socket_tracer/bcc_bpf/macros.h"
#include "src/stirling/source_connectors/socket_tracer/bcc_bpf/node_openssl_trace.c"
#include "src/stirling/source_connectors/socket_tracer/bcc_bpf_intf/symaddrs.h"
Expand Down Expand Up @@ -170,10 +171,15 @@ int probe_entry_SSL_write(struct pt_regs* ctx) {
return 0;
}

int32_t tls_version = 0;
bpf_probe_read_user(&tls_version, sizeof(tls_version), ssl);

struct data_args_t write_args = {};
write_args.source_fn = kSSLWrite;
write_args.fd = fd;
write_args.buf = buf;
write_args.ssl_version = tls_version;

active_ssl_write_args_map.update(&id, &write_args);

// Mark connection as SSL right away, so encrypted traffic does not get traced.
Expand Down Expand Up @@ -209,11 +215,14 @@ int probe_entry_SSL_read(struct pt_regs* ctx) {
if (fd == kInvalidFD) {
return 0;
}
int32_t tls_version = 0;
bpf_probe_read_user(&tls_version, sizeof(tls_version), ssl);

struct data_args_t read_args = {};
read_args.source_fn = kSSLRead;
read_args.fd = fd;
read_args.buf = buf;
read_args.ssl_version = tls_version;
active_ssl_read_args_map.update(&id, &read_args);

// Mark connection as SSL right away, so encrypted traffic does not get traced.
Expand Down Expand Up @@ -250,6 +259,10 @@ static int probe_entry_SSL_write_syscall_fd_access_agnostic(struct pt_regs* ctx,
struct data_args_t write_args = {};
write_args.source_fn = kSSLWrite;
write_args.buf = buf;
int32_t tls_version = 0;
bpf_probe_read_user(&tls_version, sizeof(tls_version), ssl);
write_args.ssl_version = tls_version;

if (is_ex_call) {
size_t* ssl_ex_len = (size_t*)PT_REGS_PARM4(ctx);
write_args.ssl_ex_len = ssl_ex_len;
Expand Down Expand Up @@ -317,6 +330,9 @@ static int probe_entry_SSL_read_syscall_fd_access_agnostic(struct pt_regs* ctx,
struct data_args_t read_args = {};
read_args.source_fn = kSSLRead;
read_args.buf = buf;
int32_t tls_version = 0;
bpf_probe_read_user(&tls_version, sizeof(tls_version), ssl);
read_args.ssl_version = tls_version; // Store the extracted TLS version
if (is_ex_call) {
size_t* ssl_ex_len = (size_t*)PT_REGS_PARM4(ctx);
read_args.ssl_ex_len = ssl_ex_len;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@

#define socklen_t size_t

#include "../bcc_bpf_intf/socket_trace.h"

#include "src/stirling/bpf_tools/bcc_bpf/task_struct_utils.h"
#include "src/stirling/bpf_tools/bcc_bpf/utils.h"
#include "src/stirling/source_connectors/socket_tracer/bcc_bpf/protocol_inference.h"
Expand Down Expand Up @@ -213,6 +215,7 @@ static __inline struct socket_data_event_t* fill_socket_data_event(
event->attr.timestamp_ns = bpf_ktime_get_ns();
event->attr.source_fn = src_fn;
event->attr.ssl = conn_info->ssl;
event->attr.ssl_version = conn_info->ssl_version;
event->attr.ssl_source = conn_info->ssl_source;
event->attr.direction = direction;
event->attr.conn_id = conn_info->conn_id;
Expand Down Expand Up @@ -822,6 +825,10 @@ static __inline void process_data(const bool vecs, struct pt_regs* ctx, uint64_t
return;
}

if (ssl) {
conn_info->ssl_version = args->ssl_version;
}

if (!should_trace_conn(conn_info)) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,12 @@ enum ssl_source_t {
kLibNettyTcnativeSource,
kStaticallyLinkedSource,
};

// Indicates the TLS version under trace if TLS is in use.
enum ssl_version_t {
kSSLvNone = 0,
kSSLv1_0,
kSSLv1_1,
kSSLv1_2,
kSSLv1_3,
};
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ static const std::map<int64_t, std::string_view> kTrafficProtocolDecoder =
static const std::map<int64_t, std::string_view> kEndpointRoleDecoder =
px::EnumDefToMap<endpoint_role_t>();

static const std::map<int64_t, std::string_view> kSSLVersionDecoder =
px::EnumDefToMap<ssl_version_t>();

inline std::string ToString(const conn_id_t& conn_id) {
return absl::Substitute("[upid=$0:$1 fd=$2 gen=$3]", conn_id.upid.pid,
conn_id.upid.start_time_ticks, conn_id.fd, conn_id.tsid);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ struct conn_info_t {
// Whether the connection uses SSL.
bool ssl;

// TLS version if connection uses SSL
int32_t ssl_version;

enum ssl_source_t ssl_source;

// The number of bytes written/read on this connection.
Expand Down Expand Up @@ -188,6 +191,9 @@ struct socket_data_event_t {
// Whether the traffic was collected from an encrypted channel.
bool ssl;

// TLS version of the connection
int32_t ssl_version;

enum ssl_source_t ssl_source;

// Represents the syscall or function that produces this event.
Expand Down Expand Up @@ -294,6 +300,8 @@ struct data_args_t {

// For SSL_write_ex and SSL_read_ex
size_t* ssl_ex_len;

int32_t ssl_version;
};

struct close_args_t {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,15 @@ constexpr DataElement kTraceRole = {
&kEndpointRoleDecoder,
};

constexpr DataElement kSSLVersion = {
"ssl_version",
"The SSL version if connection is tls",
types::DataType::INT64,
types::SemanticType::ST_NONE,
types::PatternType::GENERAL_ENUM,
&kSSLVersionDecoder,
};

constexpr DataElement kLatencyNS = {
"latency",
"Request-response latency.",
Expand Down
26 changes: 25 additions & 1 deletion src/stirling/source_connectors/socket_tracer/conn_tracker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ void ConnTracker::AddDataEvent(std::unique_ptr<SocketDataEvent> event) {
SetRole(event->attr.role, "inferred from data_event");
SetProtocol(event->attr.protocol, "inferred from data_event");
SetSSL(event->attr.ssl, event->attr.ssl_source, "inferred from data_event");

SetSSLVersion(event->attr.ssl, event->attr.ssl_version, "infered from data event");
CheckTracker();
UpdateTimestamps(event->attr.timestamp_ns);
UpdateDataStats(*event);
Expand Down Expand Up @@ -565,6 +565,30 @@ bool ConnTracker::SetSSL(bool ssl, ssl_source_t ssl_source, std::string_view rea
return true;
}

bool ConnTracker::SetSSLVersion(bool ssl, int32_t ssl_version, std::string_view reason) {
if (ssl) {
switch (ssl_version) {
case 0x301:
ssl_version_ = kSSLv1_0;
break;
case 0x302:
ssl_version_ = kSSLv1_1;
break;
case 0x303:
ssl_version_ = kSSLv1_2;
break;
case 0x304:
ssl_version_ = kSSLv1_3;
break;
default:
ssl_version_ = kSSLvNone;
}
return true;
}

CONN_TRACE(1) << absl::Substitute("SSL version was updated : $0, reason=[$1]", ssl_version, reason);
return true;
}
void ConnTracker::UpdateTimestamps(uint64_t bpf_timestamp) {
last_bpf_timestamp_ns_ = std::max(last_bpf_timestamp_ns_, bpf_timestamp);

Expand Down
5 changes: 5 additions & 0 deletions src/stirling/source_connectors/socket_tracer/conn_tracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ class ConnTracker : NotCopyMoveable {
traffic_protocol_t protocol() const { return protocol_; }
endpoint_role_t role() const { return role_; }
bool ssl() const { return ssl_; }
ssl_version_t ssl_version() const { return ssl_version_; }
ConnStatsTracker& conn_stats() { return conn_stats_; }

/**
Expand Down Expand Up @@ -591,6 +592,9 @@ class ConnTracker : NotCopyMoveable {
// Returns false if the protocol change is disallowed.
bool SetSSL(bool ssl, ssl_source_t ssl_source, std::string_view reason);

// returns true if version was assigned
bool SetSSLVersion(bool ssl, int32_t ssl_version, std::string_view reason);

// Returns true if the state was changed.
bool SetRole(endpoint_role_t role, std::string_view reason);

Expand Down Expand Up @@ -706,6 +710,7 @@ class ConnTracker : NotCopyMoveable {
endpoint_role_t role_ = kRoleUnknown;
bool ssl_ = false;
ssl_source_t ssl_source_ = kSSLNone;
ssl_version_t ssl_version_ = kSSLvNone;
SocketOpen open_info_;
SocketClose close_info_;
ConnStatsTracker conn_stats_;
Expand Down
2 changes: 2 additions & 0 deletions src/stirling/source_connectors/socket_tracer/http_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ constexpr DataElement kHTTPElements[] = {
canonical_data_elements::kLocalAddr,
canonical_data_elements::kLocalPort,
canonical_data_elements::kTraceRole,
canonical_data_elements::kSSLVersion,
canonical_data_elements::kEncrypted,
{"major_version", "HTTP major version, can be 1 or 2",
types::DataType::INT64,
Expand Down Expand Up @@ -133,6 +134,7 @@ constexpr int kHTTPRespMessageIdx = kHTTPTable.ColIndex("resp_message");
constexpr int kHTTPRespBodyIdx = kHTTPTable.ColIndex("resp_body");
constexpr int kHTTPRespBodySizeIdx = kHTTPTable.ColIndex("resp_body_size");
constexpr int kHTTPLatencyIdx = kHTTPTable.ColIndex("latency");
constexpr int kHTTPSSLVersion = kHTTPTable.ColIndex("ssl_version");

} // namespace stirling
} // namespace px
Original file line number Diff line number Diff line change
Expand Up @@ -1306,6 +1306,7 @@ void SocketTraceConnector::AppendMessage(ConnectorContext* ctx, const ConnTracke
r.Append<r.ColIndex("local_port")>(conn_tracker.local_endpoint().port());
r.Append<r.ColIndex("trace_role")>(conn_tracker.role());
r.Append<r.ColIndex("encrypted")>(conn_tracker.ssl());
r.Append<r.ColIndex("ssl_version")>(conn_tracker.ssl_version());
r.Append<r.ColIndex("major_version")>(1);
r.Append<r.ColIndex("minor_version")>(resp_message.minor_version);
r.Append<r.ColIndex("content_type")>(static_cast<uint64_t>(content_type));
Expand Down