feat(ebpf): add nginx HTTP capture infrastructure via kretprobe recvfrom

Add supporting infrastructure for nginx HTTP capture using kretprobe
on __x64_sys_recvfrom to replace the blocked tracepoint sys_exit_recvfrom.

Changes:
- bpf/bpf_types.h: Add nginx_pid_map for filtering recvfrom by PID
- cmd/ja4ebpf/main.go: Add Uprobes configuration section
- Makefile: Add test targets for recvfrom validation
- internal/loader: Generate nginx HTTP event structures

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jacquin Antoine
2026-04-20 13:30:41 +02:00
parent bb2160efbc
commit 382683710a
5 changed files with 336 additions and 56 deletions

View File

@ -35,6 +35,29 @@ type Ja4SslHttpPlainEvent struct {
TimestampNs uint64
}
type Ja4SslNginxHttpEvent struct {
PidTgid uint64
Fd uint32
SrcIp uint32
SrcPort uint16
TimestampNs uint64
HttpMethod [16]uint8
Uri [256]uint8
Query [128]uint8
Data [3640]uint8
MethodLen uint32
UriLen uint32
QueryLen uint32
BodyLen uint32
DataLen uint32
}
type Ja4SslNginxReadArgs struct {
Fd int32
BufPtr uint64
Count uint64
}
type Ja4SslSslConnInfo struct {
Fd uint32
SrcIp uint32
@ -122,19 +145,22 @@ type Ja4SslProgramSpecs struct {
//
// It can be passed ebpf.CollectionSpec.Assign.
type Ja4SslMapSpecs struct {
HttpBuf *ebpf.MapSpec `ebpf:"__http_buf"`
SslBuf *ebpf.MapSpec `ebpf:"__ssl_buf"`
TlsBuf *ebpf.MapSpec `ebpf:"__tls_buf"`
AcceptArgsMap *ebpf.MapSpec `ebpf:"accept_args_map"`
AcceptMap *ebpf.MapSpec `ebpf:"accept_map"`
FdConnMap *ebpf.MapSpec `ebpf:"fd_conn_map"`
PbAccept *ebpf.MapSpec `ebpf:"pb_accept"`
PbHttpPlain *ebpf.MapSpec `ebpf:"pb_http_plain"`
PbSslData *ebpf.MapSpec `ebpf:"pb_ssl_data"`
PbTcpSyn *ebpf.MapSpec `ebpf:"pb_tcp_syn"`
PbTlsHello *ebpf.MapSpec `ebpf:"pb_tls_hello"`
SslArgsMap *ebpf.MapSpec `ebpf:"ssl_args_map"`
SslConnMap *ebpf.MapSpec `ebpf:"ssl_conn_map"`
HttpBuf *ebpf.MapSpec `ebpf:"__http_buf"`
NginxBuf *ebpf.MapSpec `ebpf:"__nginx_buf"`
SslBuf *ebpf.MapSpec `ebpf:"__ssl_buf"`
TlsBuf *ebpf.MapSpec `ebpf:"__tls_buf"`
AcceptArgsMap *ebpf.MapSpec `ebpf:"accept_args_map"`
AcceptMap *ebpf.MapSpec `ebpf:"accept_map"`
FdConnMap *ebpf.MapSpec `ebpf:"fd_conn_map"`
NginxReadArgsMap *ebpf.MapSpec `ebpf:"nginx_read_args_map"`
PbAccept *ebpf.MapSpec `ebpf:"pb_accept"`
PbGinxHttp *ebpf.MapSpec `ebpf:"pb_ginx_http"`
PbHttpPlain *ebpf.MapSpec `ebpf:"pb_http_plain"`
PbSslData *ebpf.MapSpec `ebpf:"pb_ssl_data"`
PbTcpSyn *ebpf.MapSpec `ebpf:"pb_tcp_syn"`
PbTlsHello *ebpf.MapSpec `ebpf:"pb_tls_hello"`
SslArgsMap *ebpf.MapSpec `ebpf:"ssl_args_map"`
SslConnMap *ebpf.MapSpec `ebpf:"ssl_conn_map"`
}
// Ja4SslObjects contains all objects after they have been loaded into the kernel.
@ -156,30 +182,36 @@ func (o *Ja4SslObjects) Close() error {
//
// It can be passed to LoadJa4SslObjects or ebpf.CollectionSpec.LoadAndAssign.
type Ja4SslMaps struct {
HttpBuf *ebpf.Map `ebpf:"__http_buf"`
SslBuf *ebpf.Map `ebpf:"__ssl_buf"`
TlsBuf *ebpf.Map `ebpf:"__tls_buf"`
AcceptArgsMap *ebpf.Map `ebpf:"accept_args_map"`
AcceptMap *ebpf.Map `ebpf:"accept_map"`
FdConnMap *ebpf.Map `ebpf:"fd_conn_map"`
PbAccept *ebpf.Map `ebpf:"pb_accept"`
PbHttpPlain *ebpf.Map `ebpf:"pb_http_plain"`
PbSslData *ebpf.Map `ebpf:"pb_ssl_data"`
PbTcpSyn *ebpf.Map `ebpf:"pb_tcp_syn"`
PbTlsHello *ebpf.Map `ebpf:"pb_tls_hello"`
SslArgsMap *ebpf.Map `ebpf:"ssl_args_map"`
SslConnMap *ebpf.Map `ebpf:"ssl_conn_map"`
HttpBuf *ebpf.Map `ebpf:"__http_buf"`
NginxBuf *ebpf.Map `ebpf:"__nginx_buf"`
SslBuf *ebpf.Map `ebpf:"__ssl_buf"`
TlsBuf *ebpf.Map `ebpf:"__tls_buf"`
AcceptArgsMap *ebpf.Map `ebpf:"accept_args_map"`
AcceptMap *ebpf.Map `ebpf:"accept_map"`
FdConnMap *ebpf.Map `ebpf:"fd_conn_map"`
NginxReadArgsMap *ebpf.Map `ebpf:"nginx_read_args_map"`
PbAccept *ebpf.Map `ebpf:"pb_accept"`
PbGinxHttp *ebpf.Map `ebpf:"pb_ginx_http"`
PbHttpPlain *ebpf.Map `ebpf:"pb_http_plain"`
PbSslData *ebpf.Map `ebpf:"pb_ssl_data"`
PbTcpSyn *ebpf.Map `ebpf:"pb_tcp_syn"`
PbTlsHello *ebpf.Map `ebpf:"pb_tls_hello"`
SslArgsMap *ebpf.Map `ebpf:"ssl_args_map"`
SslConnMap *ebpf.Map `ebpf:"ssl_conn_map"`
}
func (m *Ja4SslMaps) Close() error {
return _Ja4SslClose(
m.HttpBuf,
m.NginxBuf,
m.SslBuf,
m.TlsBuf,
m.AcceptArgsMap,
m.AcceptMap,
m.FdConnMap,
m.NginxReadArgsMap,
m.PbAccept,
m.PbGinxHttp,
m.PbHttpPlain,
m.PbSslData,
m.PbTcpSyn,

View File

@ -35,6 +35,29 @@ type Ja4TcHttpPlainEvent struct {
TimestampNs uint64
}
type Ja4TcNginxHttpEvent struct {
PidTgid uint64
Fd uint32
SrcIp uint32
SrcPort uint16
TimestampNs uint64
HttpMethod [16]uint8
Uri [256]uint8
Query [128]uint8
Data [3640]uint8
MethodLen uint32
UriLen uint32
QueryLen uint32
BodyLen uint32
DataLen uint32
}
type Ja4TcNginxReadArgs struct {
Fd int32
BufPtr uint64
Count uint64
}
type Ja4TcSslConnInfo struct {
Fd uint32
SrcIp uint32
@ -116,21 +139,24 @@ type Ja4TcProgramSpecs struct {
//
// It can be passed ebpf.CollectionSpec.Assign.
type Ja4TcMapSpecs struct {
HttpBuf *ebpf.MapSpec `ebpf:"__http_buf"`
SslBuf *ebpf.MapSpec `ebpf:"__ssl_buf"`
TlsBuf *ebpf.MapSpec `ebpf:"__tls_buf"`
AcceptMap *ebpf.MapSpec `ebpf:"accept_map"`
AllowedPorts *ebpf.MapSpec `ebpf:"allowed_ports"`
FdConnMap *ebpf.MapSpec `ebpf:"fd_conn_map"`
IgnoredSrc *ebpf.MapSpec `ebpf:"ignored_src"`
PbAccept *ebpf.MapSpec `ebpf:"pb_accept"`
PbHttpPlain *ebpf.MapSpec `ebpf:"pb_http_plain"`
PbSslData *ebpf.MapSpec `ebpf:"pb_ssl_data"`
PbTcpSyn *ebpf.MapSpec `ebpf:"pb_tcp_syn"`
PbTlsHello *ebpf.MapSpec `ebpf:"pb_tls_hello"`
SslArgsMap *ebpf.MapSpec `ebpf:"ssl_args_map"`
SslConnMap *ebpf.MapSpec `ebpf:"ssl_conn_map"`
TcStats *ebpf.MapSpec `ebpf:"tc_stats"`
HttpBuf *ebpf.MapSpec `ebpf:"__http_buf"`
NginxBuf *ebpf.MapSpec `ebpf:"__nginx_buf"`
SslBuf *ebpf.MapSpec `ebpf:"__ssl_buf"`
TlsBuf *ebpf.MapSpec `ebpf:"__tls_buf"`
AcceptMap *ebpf.MapSpec `ebpf:"accept_map"`
AllowedPorts *ebpf.MapSpec `ebpf:"allowed_ports"`
FdConnMap *ebpf.MapSpec `ebpf:"fd_conn_map"`
IgnoredSrc *ebpf.MapSpec `ebpf:"ignored_src"`
NginxReadArgsMap *ebpf.MapSpec `ebpf:"nginx_read_args_map"`
PbAccept *ebpf.MapSpec `ebpf:"pb_accept"`
PbGinxHttp *ebpf.MapSpec `ebpf:"pb_ginx_http"`
PbHttpPlain *ebpf.MapSpec `ebpf:"pb_http_plain"`
PbSslData *ebpf.MapSpec `ebpf:"pb_ssl_data"`
PbTcpSyn *ebpf.MapSpec `ebpf:"pb_tcp_syn"`
PbTlsHello *ebpf.MapSpec `ebpf:"pb_tls_hello"`
SslArgsMap *ebpf.MapSpec `ebpf:"ssl_args_map"`
SslConnMap *ebpf.MapSpec `ebpf:"ssl_conn_map"`
TcStats *ebpf.MapSpec `ebpf:"tc_stats"`
}
// Ja4TcObjects contains all objects after they have been loaded into the kernel.
@ -152,33 +178,39 @@ func (o *Ja4TcObjects) Close() error {
//
// It can be passed to LoadJa4TcObjects or ebpf.CollectionSpec.LoadAndAssign.
type Ja4TcMaps struct {
HttpBuf *ebpf.Map `ebpf:"__http_buf"`
SslBuf *ebpf.Map `ebpf:"__ssl_buf"`
TlsBuf *ebpf.Map `ebpf:"__tls_buf"`
AcceptMap *ebpf.Map `ebpf:"accept_map"`
AllowedPorts *ebpf.Map `ebpf:"allowed_ports"`
FdConnMap *ebpf.Map `ebpf:"fd_conn_map"`
IgnoredSrc *ebpf.Map `ebpf:"ignored_src"`
PbAccept *ebpf.Map `ebpf:"pb_accept"`
PbHttpPlain *ebpf.Map `ebpf:"pb_http_plain"`
PbSslData *ebpf.Map `ebpf:"pb_ssl_data"`
PbTcpSyn *ebpf.Map `ebpf:"pb_tcp_syn"`
PbTlsHello *ebpf.Map `ebpf:"pb_tls_hello"`
SslArgsMap *ebpf.Map `ebpf:"ssl_args_map"`
SslConnMap *ebpf.Map `ebpf:"ssl_conn_map"`
TcStats *ebpf.Map `ebpf:"tc_stats"`
HttpBuf *ebpf.Map `ebpf:"__http_buf"`
NginxBuf *ebpf.Map `ebpf:"__nginx_buf"`
SslBuf *ebpf.Map `ebpf:"__ssl_buf"`
TlsBuf *ebpf.Map `ebpf:"__tls_buf"`
AcceptMap *ebpf.Map `ebpf:"accept_map"`
AllowedPorts *ebpf.Map `ebpf:"allowed_ports"`
FdConnMap *ebpf.Map `ebpf:"fd_conn_map"`
IgnoredSrc *ebpf.Map `ebpf:"ignored_src"`
NginxReadArgsMap *ebpf.Map `ebpf:"nginx_read_args_map"`
PbAccept *ebpf.Map `ebpf:"pb_accept"`
PbGinxHttp *ebpf.Map `ebpf:"pb_ginx_http"`
PbHttpPlain *ebpf.Map `ebpf:"pb_http_plain"`
PbSslData *ebpf.Map `ebpf:"pb_ssl_data"`
PbTcpSyn *ebpf.Map `ebpf:"pb_tcp_syn"`
PbTlsHello *ebpf.Map `ebpf:"pb_tls_hello"`
SslArgsMap *ebpf.Map `ebpf:"ssl_args_map"`
SslConnMap *ebpf.Map `ebpf:"ssl_conn_map"`
TcStats *ebpf.Map `ebpf:"tc_stats"`
}
func (m *Ja4TcMaps) Close() error {
return _Ja4TcClose(
m.HttpBuf,
m.NginxBuf,
m.SslBuf,
m.TlsBuf,
m.AcceptMap,
m.AllowedPorts,
m.FdConnMap,
m.IgnoredSrc,
m.NginxReadArgsMap,
m.PbAccept,
m.PbGinxHttp,
m.PbHttpPlain,
m.PbSslData,
m.PbTcpSyn,