Skip to content

Commit 31aa24f

Browse files
committed
Check handshake version, use bpf_skb_load_bytes
1 parent abc2fd7 commit 31aa24f

File tree

7 files changed

+88
-17
lines changed

7 files changed

+88
-17
lines changed

bpf/flows.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@
2828
*/
2929
#include "dns_tracker.h"
3030

31+
/*
32+
* Defines the TLS tracker,
33+
*/
34+
#include "tls_tracker.h"
35+
3136
/*
3237
* Defines an rtt tracker,
3338
* which runs inside flow_monitor. Is optional.
@@ -189,6 +194,7 @@ static inline int flow_monitor(struct __sk_buff *skb, u8 direction) {
189194
if (enable_dns_tracking) {
190195
dns_errno = track_dns_packet(skb, &pkt);
191196
}
197+
track_tls_version(skb, &pkt);
192198
flow_metrics *aggregate_flow = (flow_metrics *)bpf_map_lookup_elem(&aggregated_flows, &id);
193199
if (aggregate_flow != NULL) {
194200
update_existing_flow(aggregate_flow, &pkt, len, flow_sampling, skb->ifindex, direction);

bpf/tls_tracker.h

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
light weight TLS tracker.
3+
*/
4+
5+
#ifndef __TLS_TRACKER_H__
6+
#define __TLS_TRACKER_H__
7+
#include "utils.h"
8+
9+
#define CONTENT_TYPE_CHANGE_CIPHER 0x14
10+
#define CONTENT_TYPE_ALERT 0x15
11+
#define CONTENT_TYPE_HANDSHAKE 0x16
12+
#define CONTENT_TYPE_APP_DATA 0x17
13+
#define HANDSHAKE_CLIENT_HELLO 0x01
14+
#define HANDSHAKE_SERVER_HELLO 0x02
15+
16+
// https://www.rfc-editor.org/rfc/rfc5246
17+
struct tls_record {
18+
u8 content_type; // handshake, alert, change cipher, app data
19+
u8 major;
20+
u8 minor;
21+
u16 length;
22+
};
23+
24+
struct tls_handshake_header {
25+
u8 content_type; // client hello, server hello ...
26+
u8 len[3];
27+
};
28+
29+
struct tls_handshake_version {
30+
u8 major;
31+
u8 minor;
32+
};
33+
34+
// Extract TLS info
35+
static inline void track_tls_version(struct __sk_buff *skb, pkt_info *pkt) {
36+
if (pkt->id->transport_protocol == IPPROTO_TCP) {
37+
void *data_end = (void *)(long)skb->data_end;
38+
struct tcphdr *tcp = (struct tcphdr *)pkt->l4_hdr;
39+
if (!tcp || ((void *)tcp + sizeof(*tcp) > data_end)) {
40+
return;
41+
}
42+
43+
u8 len = tcp->doff * sizeof(u32);
44+
if (!len) {
45+
return;
46+
}
47+
48+
struct tls_record rec;
49+
u32 offset = (long)pkt->l4_hdr - (long)skb->data + len;
50+
51+
if ((bpf_skb_load_bytes(skb, offset, &rec, sizeof(rec))) < 0) {
52+
return;
53+
}
54+
55+
switch (rec.content_type) {
56+
case CONTENT_TYPE_HANDSHAKE: {
57+
pkt->ssl_version = ((u16)rec.major) << 8 | rec.minor;
58+
struct tls_handshake_header handshake;
59+
if (bpf_skb_load_bytes(skb, offset + sizeof(rec), &handshake, sizeof(handshake)) < 0) {
60+
return;
61+
}
62+
if (handshake.content_type == HANDSHAKE_CLIENT_HELLO ||
63+
handshake.content_type == HANDSHAKE_SERVER_HELLO) {
64+
struct tls_handshake_version handshake_version;
65+
if (bpf_skb_load_bytes(skb, offset + sizeof(rec) + sizeof(handshake),
66+
&handshake_version, sizeof(handshake_version)) < 0) {
67+
return;
68+
}
69+
pkt->ssl_version = ((u16)handshake_version.major) << 8 | handshake_version.minor;
70+
}
71+
break;
72+
}
73+
case CONTENT_TYPE_CHANGE_CIPHER:
74+
case CONTENT_TYPE_ALERT:
75+
case CONTENT_TYPE_APP_DATA:
76+
pkt->ssl_version = ((u16)rec.major) << 8 | rec.minor;
77+
break;
78+
}
79+
}
80+
}
81+
82+
#endif // __TLS_TRACKER_H__

bpf/utils.h

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -50,22 +50,6 @@ static inline void set_flags(struct tcphdr *th, u16 *flags) {
5050
}
5151
}
5252

53-
// Extract TLS info
54-
static inline void fill_tls_info(struct tcphdr *tcp, void *data_end, pkt_info *pkt) {
55-
void *start_payload = ((void *)tcp) + (tcp->doff * 4);
56-
if (start_payload + 5 <= data_end) {
57-
if (((u8 *)start_payload)[0] == 0x16) {
58-
// TODO handshake special case, see https://www.netmeister.org/blog/tcpdump-ssl-and-tls.html
59-
pkt->ssl_version =
60-
((u16)(((u8 *)start_payload)[1])) << 8 | (u16)(((u8 *)start_payload)[2]);
61-
} else if (((u8 *)start_payload)[0] == 0x14 || ((u8 *)start_payload)[0] == 0x15 ||
62-
((u8 *)start_payload)[0] == 0x17) {
63-
pkt->ssl_version =
64-
((u16)(((u8 *)start_payload)[1])) << 8 | (u16)(((u8 *)start_payload)[2]);
65-
}
66-
}
67-
}
68-
6953
// Extract L4 info for the supported protocols
7054
static inline void fill_l4info(void *l4_hdr_start, void *data_end, u8 protocol, pkt_info *pkt) {
7155
flow_id *id = pkt->id;
@@ -78,7 +62,6 @@ static inline void fill_l4info(void *l4_hdr_start, void *data_end, u8 protocol,
7862
id->dst_port = bpf_ntohs(tcp->dest);
7963
set_flags(tcp, &pkt->flags);
8064
pkt->l4_hdr = (void *)tcp;
81-
fill_tls_info(tcp, data_end, pkt);
8265
}
8366
} break;
8467
case IPPROTO_UDP: {

pkg/ebpf/bpf_arm64_bpfel.o

2.03 KB
Binary file not shown.

pkg/ebpf/bpf_powerpc_bpfel.o

2.03 KB
Binary file not shown.

pkg/ebpf/bpf_s390_bpfeb.o

2.16 KB
Binary file not shown.

pkg/ebpf/bpf_x86_bpfel.o

2.03 KB
Binary file not shown.

0 commit comments

Comments
 (0)