Skip to content

Commit

Permalink
feature(network): add network flow end base for events
Browse files Browse the repository at this point in the history
- add the base for keeping flow states (for future stats)
- flow states allow knowing end flows for tcp and udp
  • Loading branch information
rafaeldtinoco committed Dec 18, 2023
1 parent 34b6682 commit 7fa222f
Show file tree
Hide file tree
Showing 11 changed files with 674 additions and 328 deletions.
68 changes: 68 additions & 0 deletions docs/docs/events/builtin/network/net_flow_tcp_end.md
@@ -0,0 +1,68 @@

# NetFlowTCPEnd

## Intro

NetFlowTCPEnd - An event derived from base network raw event, designed to
monitor the termination of TCP flows. It leverages cgroup skb eBPF programs,
focusing specifically on the TCP protocol's termination phase, and is
instrumental in analyzing IP and TCP headers data to detect the end of TCP
connections.

## Description

`NetFlowTCPEnd` utilizes cgroup skb eBPF programs to intercept and analyze raw
network events at the kernel level, with a particular emphasis on the TCP
protocol's termination phase. It processes IP and TCP headers to pinpoint the
conclusion of TCP communication flows. The event identifies the termination of
TCP connections by analyzing the status of TCP flags, primarily focusing on the
FIN and RST flags.

By examining these flags, `NetFlowTCPEnd` provides valuable insights into the
end of TCP connections, a critical component for comprehensive network
monitoring and security analysis.

## Arguments

1. **connectionDirection** (`string`): Indicates whether the terminated connection was 'incoming' or 'outgoing'.
2. **srcIP** (`string`): The source IP address, extracted from the IP header, from the side terminating the connection.
3. **dstIP** (`string`): The destination IP address, obtained from the IP header, of the side receiving the termination.
4. **srcPort** (`uint16`): The source port number, derived from the TCP header.
5. **dstPort** (`uint16`): The destination port number, ascertained from the TCP header.
6. **srcDomains** (`[]string`): Associated domain names for the source IP, resolved using DNS cache.
7. **dstDomains** (`[]string`): Related domain names for the destination IP, determined through DNS cache.

## Origin

### Derived from cgroup skb eBPF Programs

#### Source

`NetFlowTCPEnd` originates from cgroup skb eBPF programs, enabling the tracing
of raw network packets at the kernel level. This advanced mechanism is adept at
dissecting TCP traffic, particularly focusing on the termination stage of TCP
connections.

#### Purpose

The primary aim of `NetFlowTCPEnd` is to provide detailed visibility into the
termination of TCP connections. By concentrating on FIN and RST flags within TCP
headers, it offers an effective and precise approach to identifying the
conclusion of TCP communication flows, crucial for network security and
performance monitoring.

## Example Use Case

Network administrators and security experts can use `NetFlowTCPEnd` to monitor
the termination of TCP connections. This capability is essential for detecting
unusual traffic patterns, potential security threats, or abrupt end of
communication, which are vital for ensuring network security and efficiency.

## Issues

While `NetFlowTCPEnd` is designed to minimize system overhead, its performance
may vary based on the volume of network traffic and the complexity of monitored
TCP flows. Efficient data management and analysis are key to leveraging the full
potential of this event without affecting system performance adversely.

> This document was automatically generated by OpenAI and reviewed by a Human.
1 change: 1 addition & 0 deletions mkdocs.yml
Expand Up @@ -69,6 +69,7 @@ nav:
- Network Events:
- Overview: docs/events/builtin/network/index.md
- net_flow_tcp_begin: docs/events/builtin/network/net_flow_tcp_begin.md
- net_flow_tcp_end: docs/events/builtin/network/net_flow_tcp_end.md
- net_packet_ipv4: docs/events/builtin/network/net_packet_ipv4.md
- net_packet_ipv6: docs/events/builtin/network/net_packet_ipv6.md
- net_packet_tcp: docs/events/builtin/network/net_packet_tcp.md
Expand Down
96 changes: 81 additions & 15 deletions pkg/ebpf/c/common/network.h
Expand Up @@ -18,6 +18,65 @@ typedef union iphdrs_t {
struct ipv6hdr ipv6hdr;
} iphdrs;

// network flow events

typedef struct netflow {
u32 host_pid;
u8 proto;
union {
__u8 u6_addr8[16];
__be16 u6_addr16[8];
__be32 u6_addr32[4];
} src, dst;
u16 srcport;
u16 dstport;
} __attribute__((__packed__)) netflow_t;

#define copy_netflow(flow) \
(netflow_t) { \
.host_pid = flow.host_pid, \
.proto = flow.proto, \
.src = flow.src, \
.dst = flow.dst, \
.srcport = flow.srcport, \
.dstport = flow.dstport, \
}

#define invert_netflow(flow) \
(netflow_t) { \
.host_pid = flow.host_pid, \
.proto = flow.proto, \
.src = flow.dst, \
.dst = flow.src, \
.srcport = flow.dstport, \
.dstport = flow.srcport, \
}

#define flow_unknown 0
#define flow_incoming 1
#define flow_outgoing 2

// TODO: per flow statistics can be added later
typedef struct netflowvalue {
u8 direction; // 0 = flow_unknown, 1 = flow_incoming, 2 = flow_outgoing
u64 last_update; // last time this flow was updated
// u64 bytes; // total bytes sent/received
// u64 packets; // total packets sent/received
// u64 events; // total events sent/received
// u64 last_bytes; // last bytes sent/received
// u64 last_packets; // last packets sent/received
// u64 last_events; // last events sent/received
} __attribute__((__packed__)) netflowvalue_t;

// netflowmap (keep track of network flows)

struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__uint(max_entries, 65535); // simultaneous network flows being tracked
__type(key, netflow_t); // the network flow ...
__type(value, netflowvalue_t); // ... linked to flow stats
} netflowmap SEC(".maps"); // relate sockets and tasks

// NOTE: proto header structs need full type in vmlinux.h (for correct skb copy)

typedef union protohdrs_t {
Expand Down Expand Up @@ -49,14 +108,13 @@ typedef enum net_packet {
// Layer 7
SUB_NET_PACKET_DNS = 1 << 6,
SUB_NET_PACKET_HTTP = 1 << 7,
// Flow Events
SUB_NET_PACKET_TCP_FLOW = 1 << 8,
} net_packet_t;

typedef struct net_event_contextmd {
u8 submit; // keeping this for a TODO (check should_submit_net_event)
u8 should_flow; // Cache result from should_submit_flow_event
u32 header_size;
u8 captured;
u8 captured; // packet has already been captured
netflow_t flow;
} __attribute__((__packed__)) net_event_contextmd_t;

typedef struct net_event_context {
Expand All @@ -76,8 +134,8 @@ typedef struct net_event_context {
typedef struct {
u64 ts;
u16 ip_csum;
struct in6_addr ip_saddr;
struct in6_addr ip_daddr;
struct in6_addr src;
struct in6_addr dst;
} indexer_t;

typedef struct {
Expand Down Expand Up @@ -155,15 +213,23 @@ struct {

// CONSTANTS

// network retval values
#define family_ipv4 (1 << 0)
#define family_ipv6 (1 << 1)
#define proto_http_req (1 << 2)
#define proto_http_resp (1 << 3)
#define packet_ingress (1 << 4)
#define packet_egress (1 << 5)
#define flow_tcp_begin (1 << 6) // syn+ack flag or first flow packet
#define flow_tcp_end (1 << 7) // fin flag or last flow packet
// Network return value (retval) codes

// Layer 3 Protocol (since no Layer 2 is available)
#define family_ipv4 (1 << 0)
#define family_ipv6 (1 << 1)
// HTTP Direction (request/response) Flag
#define proto_http_req (1 << 2)
#define proto_http_resp (1 << 3)
// Packet Direction (ingress/egress) Flag
#define packet_ingress (1 << 4)
#define packet_egress (1 << 5)
// Flows (begin/end) Flags per Protocol
#define flow_tcp_begin (1 << 6) // syn+ack flag or first flow packet
#define flow_tcp_end (1 << 7) // fin flag or last flow packet
#define flow_udp_begin (1 << 8) // first flow packet
#define flow_udp_end (1 << 9) // last flow packet
#define flow_src_initiator (1 << 10) // src is the flow initiator

// payload size: full packets, only headers
#define FULL 65536 // 1 << 16
Expand Down

0 comments on commit 7fa222f

Please sign in to comment.