Skip to content

Commit 7048451

Browse files
committed
Add kTLS tracker
1 parent 0549bb5 commit 7048451

File tree

16 files changed

+291
-6
lines changed

16 files changed

+291
-6
lines changed

bpf/flows.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,13 @@
4242

4343
/* Do flow filtering. Is optional. */
4444
#include "flows_filter.h"
45+
4546
/*
4647
* Defines an Network events monitoring tracker,
4748
* which runs inside flow_monitor. Is optional.
4849
*/
4950
#include "network_events_monitoring.h"
51+
5052
/*
5153
* Defines packets translation tracker
5254
*/
@@ -57,6 +59,11 @@
5759
*/
5860
#include "ipsec.h"
5961

62+
/*
63+
* Defines ktls tracker
64+
*/
65+
#include "ktls_tracker.h"
66+
6067
// return 0 on success, 1 if capacity reached
6168
static __always_inline int add_observed_intf(flow_metrics *value, pkt_info *pkt, u32 if_index,
6269
u8 direction) {

bpf/ktls_tracker.h

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/*
2+
kTLS tracker
3+
*/
4+
#include "utils.h"
5+
6+
#ifndef __KTLS_TRACKER_H__
7+
#define __KTLS_TRACKER_H__
8+
9+
#define MAX_SOCK_OPS_MAP_ENTRIES 65535
10+
struct sock_key {
11+
u8 remote_ip[IP_MAX_LEN];
12+
u8 local_ip[IP_MAX_LEN];
13+
u32 remote_port;
14+
u32 local_port;
15+
u32 family;
16+
};
17+
18+
struct {
19+
__uint(type, BPF_MAP_TYPE_SOCKHASH);
20+
__uint(max_entries, MAX_SOCK_OPS_MAP_ENTRIES);
21+
__type(key, struct sock_key);
22+
__type(value, u64);
23+
} sock_hash SEC(".maps");
24+
25+
static __always_inline void bpf_sock_ops_ip(struct bpf_sock_ops *skops) {
26+
int ret;
27+
28+
struct sock_key skk = {
29+
.local_port = skops->local_port,
30+
.remote_port = bpf_ntohl(skops->remote_port),
31+
.family = skops->family,
32+
};
33+
34+
switch (skops->family) {
35+
case AF_INET:
36+
__builtin_memcpy(skk.remote_ip, ip4in6, sizeof(ip4in6));
37+
__builtin_memcpy(skk.local_ip, ip4in6, sizeof(ip4in6));
38+
__builtin_memcpy(skk.remote_ip + sizeof(ip4in6), &skops->remote_ip4,
39+
sizeof(skops->remote_ip4));
40+
__builtin_memcpy(skk.local_ip + sizeof(ip4in6), &skops->local_ip4,
41+
sizeof(skops->local_ip4));
42+
break;
43+
case AF_INET6:
44+
return;
45+
}
46+
47+
ret = bpf_sock_hash_update(skops, &sock_hash, &skk, BPF_NOEXIST);
48+
if (ret) {
49+
bpf_printk("failed to update sock hash op: %d, port %d --> %d\n", skops->op, skk.local_port,
50+
skk.remote_port);
51+
return;
52+
}
53+
}
54+
55+
SEC("sockops")
56+
int bpf_sockops(struct bpf_sock_ops *skops) {
57+
u32 op = skops->op;
58+
59+
switch (op) {
60+
case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB:
61+
case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB:
62+
bpf_sock_ops_ip(skops);
63+
break;
64+
default:
65+
break;
66+
}
67+
68+
return 0;
69+
}
70+
71+
static __always_inline int find_update_flow(struct sk_msg_md *msg, int verdict) {
72+
int ret = 0;
73+
flow_id id;
74+
75+
__builtin_memset(&id, 0, sizeof(id));
76+
77+
id.src_port = msg->sk->src_port;
78+
id.dst_port = bpf_ntohs(msg->sk->dst_port);
79+
id.transport_protocol = msg->sk->protocol;
80+
__builtin_memcpy(id.src_ip, ip4in6, sizeof(ip4in6));
81+
__builtin_memcpy(id.dst_ip, ip4in6, sizeof(ip4in6));
82+
__builtin_memcpy(id.src_ip + sizeof(ip4in6), &msg->sk->src_ip4, sizeof(msg->sk->src_ip4));
83+
__builtin_memcpy(id.dst_ip + sizeof(ip4in6), &msg->sk->dst_ip4, sizeof(msg->sk->dst_ip4));
84+
85+
u64 current_ts = bpf_ktime_get_ns();
86+
additional_metrics *aggregate_flow =
87+
(additional_metrics *)bpf_map_lookup_elem(&additional_flow_metrics, &id);
88+
if (aggregate_flow != NULL) {
89+
aggregate_flow->end_mono_time_ts = current_ts;
90+
if (aggregate_flow->start_mono_time_ts == 0) {
91+
aggregate_flow->start_mono_time_ts = current_ts;
92+
}
93+
aggregate_flow->verdict = verdict;
94+
ret = bpf_map_update_elem(&additional_flow_metrics, &id, aggregate_flow, BPF_ANY);
95+
} else {
96+
additional_metrics new_flow = {
97+
.start_mono_time_ts = current_ts,
98+
.end_mono_time_ts = current_ts,
99+
.verdict = verdict,
100+
};
101+
ret = bpf_map_update_elem(&additional_flow_metrics, &id, &new_flow, BPF_ANY);
102+
}
103+
return ret;
104+
}
105+
106+
SEC("sk_msg")
107+
int bpf_ktls_redir(struct sk_msg_md *msg) {
108+
struct sock_key skk = {
109+
.local_port = bpf_ntohl(msg->remote_port),
110+
.remote_port = msg->local_port,
111+
.family = msg->family,
112+
};
113+
114+
switch (msg->family) {
115+
case AF_INET:
116+
__builtin_memcpy(skk.remote_ip, ip4in6, sizeof(ip4in6));
117+
__builtin_memcpy(skk.local_ip, ip4in6, sizeof(ip4in6));
118+
__builtin_memcpy(skk.remote_ip + sizeof(ip4in6), &msg->remote_ip4, sizeof(msg->remote_ip4));
119+
__builtin_memcpy(skk.local_ip + sizeof(ip4in6), &msg->local_ip4, sizeof(msg->local_ip4));
120+
break;
121+
case AF_INET6:
122+
return SK_PASS;
123+
}
124+
125+
int verdict = bpf_msg_redirect_hash(msg, &sock_hash, &skk, BPF_F_INGRESS);
126+
int ret = find_update_flow(msg, verdict);
127+
if (ret != 0 && trace_messages) {
128+
bpf_printk("error updating flow %d\n", ret);
129+
}
130+
131+
return SK_PASS;
132+
}
133+
134+
#endif // __KTLS_TRACKER_H__

bpf/types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ typedef struct additional_metrics_t {
132132
u8 latest_state;
133133
} pkt_drops;
134134
u64 flow_rtt;
135+
u8 verdict;
135136
u8 network_events[MAX_NETWORK_EVENTS][MAX_EVENT_MD];
136137
struct translated_flow_t {
137138
u8 saddr[IP_MAX_LEN];

pkg/agent/agent.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ func FlowsAgent(cfg *config.Agent) (*Flows, error) {
168168
EnableDNSTracker: cfg.EnableDNSTracking,
169169
DNSTrackerPort: cfg.DNSTrackingPort,
170170
EnableRTT: cfg.EnableRTT,
171+
EnableKTLS: cfg.EnableKTLSTracking,
171172
EnableNetworkEventsMonitoring: cfg.EnableNetworkEventsMonitoring,
172173
NetworkEventsMonitoringGroupID: cfg.NetworkEventsMonitoringGroupID,
173174
EnablePktTranslation: cfg.EnablePktTranslationTracking,

pkg/config/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,8 @@ type Agent struct {
215215
StaleEntriesEvictTimeout time.Duration `env:"STALE_ENTRIES_EVICT_TIMEOUT" envDefault:"5s"`
216216
// EnablePCA enables Packet Capture Agent (PCA). By default, PCA is off.
217217
EnablePCA bool `env:"ENABLE_PCA" envDefault:"false"`
218+
// EnableKTLSTracking enable tracking kernel encrypted packets
219+
EnableKTLSTracking bool `env:"ENABLE_KTLS_TRACKING" envDefault:"false"`
218220
// MetricsEnable enables http server to collect ebpf agent metrics, default is false.
219221
MetricsEnable bool `env:"METRICS_ENABLE" envDefault:"false"`
220222
// Metrics verbosity level. From more to less verbose: trace!, debug, info (default).

pkg/ebpf/bpf_arm64_bpfel.go

Lines changed: 20 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/ebpf/bpf_arm64_bpfel.o

9.81 KB
Binary file not shown.

pkg/ebpf/bpf_powerpc_bpfel.go

Lines changed: 20 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/ebpf/bpf_powerpc_bpfel.o

9.81 KB
Binary file not shown.

0 commit comments

Comments
 (0)