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:
@ -28,6 +28,15 @@ test:
|
|||||||
## docker-build: Alias combiné generate + build
|
## docker-build: Alias combiné generate + build
|
||||||
docker-build: build
|
docker-build: build
|
||||||
|
|
||||||
|
## test-recvfrom-vm: Teste les alternatives recvfrom sur VM Rocky 9
|
||||||
|
test-recvfrom-vm:
|
||||||
|
@bash scripts/test-vm-recvfrom.sh rocky9
|
||||||
|
|
||||||
|
## test-recvfrom-docker: Teste les alternatives recvfrom dans Docker
|
||||||
|
test-recvfrom-docker:
|
||||||
|
@docker build -f Dockerfile.test-recvfrom -t ja4-recvfrom-test ../../
|
||||||
|
@docker run --rm --privileged ja4-recvfrom-test
|
||||||
|
|
||||||
## help: Affiche cette aide
|
## help: Affiche cette aide
|
||||||
help:
|
help:
|
||||||
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
|
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
|
||||||
|
|||||||
@ -257,6 +257,14 @@ struct {
|
|||||||
__type(value, struct ssl_conn_info);
|
__type(value, struct ssl_conn_info);
|
||||||
} fd_conn_map SEC(".maps");
|
} fd_conn_map SEC(".maps");
|
||||||
|
|
||||||
|
/* Hash map : PID nginx → flag pour filtrage recvfrom (tracepoints) */
|
||||||
|
struct {
|
||||||
|
__uint(type, BPF_MAP_TYPE_HASH);
|
||||||
|
__uint(max_entries, 16);
|
||||||
|
__type(key, __u32);
|
||||||
|
__type(value, __u8);
|
||||||
|
} nginx_pid_map SEC(".maps");
|
||||||
|
|
||||||
/* Hash map : pid_tgid → nginx_read_args (arguments read entry pour nginx) */
|
/* Hash map : pid_tgid → nginx_read_args (arguments read entry pour nginx) */
|
||||||
struct {
|
struct {
|
||||||
__uint(type, BPF_MAP_TYPE_HASH);
|
__uint(type, BPF_MAP_TYPE_HASH);
|
||||||
|
|||||||
@ -62,6 +62,13 @@ type Config struct {
|
|||||||
Level string `yaml:"level"` // niveau de log (debug, info, warn, error)
|
Level string `yaml:"level"` // niveau de log (debug, info, warn, error)
|
||||||
Format string `yaml:"format"` // format de log ("json" ou "text")
|
Format string `yaml:"format"` // format de log ("json" ou "text")
|
||||||
} `yaml:"log"`
|
} `yaml:"log"`
|
||||||
|
|
||||||
|
Uprobes struct {
|
||||||
|
Enabled bool `yaml:"enabled"` // activer l'attachement automatique des uprobes
|
||||||
|
NginxBinPath string `yaml:"nginx_bin_path"` // chemin vers le binaire nginx
|
||||||
|
MaxRetries int `yaml:"max_retries"` // nombre de tentatives d'attachement (défaut: 30)
|
||||||
|
RetryIntervalSec int `yaml:"retry_interval_sec"` // intervalle entre tentatives (défaut: 2)
|
||||||
|
} `yaml:"uprobes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// loadConfig charge la configuration depuis le fichier YAML spécifié,
|
// loadConfig charge la configuration depuis le fichier YAML spécifié,
|
||||||
@ -80,6 +87,10 @@ func loadConfig(path string) (*Config, error) {
|
|||||||
cfg.Correlation.SlowlorisMS = 10000
|
cfg.Correlation.SlowlorisMS = 10000
|
||||||
cfg.Log.Level = "info"
|
cfg.Log.Level = "info"
|
||||||
cfg.Log.Format = "json"
|
cfg.Log.Format = "json"
|
||||||
|
cfg.Uprobes.Enabled = false
|
||||||
|
cfg.Uprobes.NginxBinPath = "/usr/sbin/nginx"
|
||||||
|
cfg.Uprobes.MaxRetries = 30
|
||||||
|
cfg.Uprobes.RetryIntervalSec = 2
|
||||||
|
|
||||||
// Charger depuis le fichier YAML si spécifié
|
// Charger depuis le fichier YAML si spécifié
|
||||||
if path != "" {
|
if path != "" {
|
||||||
@ -123,6 +134,14 @@ func loadConfig(path string) (*Config, error) {
|
|||||||
if v := os.Getenv("JA4EBPF_IGNORE_SRC"); v != "" {
|
if v := os.Getenv("JA4EBPF_IGNORE_SRC"); v != "" {
|
||||||
cfg.IgnoreSrc = strings.Split(v, ",")
|
cfg.IgnoreSrc = strings.Split(v, ",")
|
||||||
}
|
}
|
||||||
|
// Uprobes configuration via environment variables
|
||||||
|
if v := os.Getenv("JA4EBPF_UPROBES_ENABLED"); v != "" {
|
||||||
|
cfg.Uprobes.Enabled = strings.EqualFold(v, "true") || v == "1" || v == "yes"
|
||||||
|
}
|
||||||
|
if v := os.Getenv("JA4EBPF_NGINX_BIN_PATH"); v != "" {
|
||||||
|
cfg.Uprobes.NginxBinPath = v
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return cfg, nil
|
return cfg, nil
|
||||||
}
|
}
|
||||||
@ -271,6 +290,12 @@ func main() {
|
|||||||
log.Printf("[ja4ebpf] avertissement tracepoint accept4: %v", err)
|
log.Printf("[ja4ebpf] avertissement tracepoint accept4: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- 4b. Attachement uprobes nginx (avec retry automatique) ---
|
||||||
|
if err := attachNginxUprobesWithRetry(ctx, ldr, cfg); err != nil {
|
||||||
|
log.Printf("[ja4ebpf] erreur attachement uprobes nginx: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// --- 5. Gestionnaire de sessions ---
|
// --- 5. Gestionnaire de sessions ---
|
||||||
sessionTimeout := time.Duration(cfg.Correlation.TimeoutMS) * time.Millisecond
|
sessionTimeout := time.Duration(cfg.Correlation.TimeoutMS) * time.Millisecond
|
||||||
mgr := correlation.NewManager(sessionTimeout)
|
mgr := correlation.NewManager(sessionTimeout)
|
||||||
@ -314,6 +339,8 @@ func main() {
|
|||||||
// --- 8. Compteurs d'événements consommés (mode debug) ---
|
// --- 8. Compteurs d'événements consommés (mode debug) ---
|
||||||
consumed := &eventCounters{}
|
consumed := &eventCounters{}
|
||||||
|
|
||||||
|
go consumeNginxHTTPEvents(ctx, ldr.NginxHTTPReader, mgr, &consumed.nginx)
|
||||||
|
|
||||||
// --- 9. Goroutines de consommation des ring buffers ---
|
// --- 9. Goroutines de consommation des ring buffers ---
|
||||||
go consumeSynEvents(ctx, ldr.SynReader, mgr, &consumed.syn)
|
go consumeSynEvents(ctx, ldr.SynReader, mgr, &consumed.syn)
|
||||||
go consumeTLSEvents(ctx, ldr.TLSReader, mgr, &consumed.tls)
|
go consumeTLSEvents(ctx, ldr.TLSReader, mgr, &consumed.tls)
|
||||||
@ -354,6 +381,7 @@ type eventCounters struct {
|
|||||||
ssl atomic.Uint64
|
ssl atomic.Uint64
|
||||||
accept atomic.Uint64
|
accept atomic.Uint64
|
||||||
httpPlain atomic.Uint64
|
httpPlain atomic.Uint64
|
||||||
|
nginx atomic.Uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
// debugStatsDumper affiche les compteurs BPF et les événements consommés toutes les 5 secondes.
|
// debugStatsDumper affiche les compteurs BPF et les événements consommés toutes les 5 secondes.
|
||||||
@ -1176,3 +1204,174 @@ func updateH2Settings(last *correlation.HTTPRequest, settings *parser.HTTP2Setti
|
|||||||
last.HTTP2Settings.PseudoHeaderOrder = settings.PseudoHeaderOrder
|
last.HTTP2Settings.PseudoHeaderOrder = settings.PseudoHeaderOrder
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// attachNginxUprobesWithRetry attache les uprobes nginx avec retry automatique.
|
||||||
|
// Retente jusqu'à maxRetries fois toutes les retryInterval secondes.
|
||||||
|
// Utile pour attendre que nginx démarre après ja4ebpf.
|
||||||
|
func attachNginxUprobesWithRetry(ctx context.Context, l *loader.Loader, cfg *Config) error {
|
||||||
|
if !cfg.Uprobes.Enabled {
|
||||||
|
log.Printf("[uprobes] nginx uprobes désactivés (uprobes.enabled=false)")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
binPath := cfg.Uprobes.NginxBinPath
|
||||||
|
maxRetries := cfg.Uprobes.MaxRetries
|
||||||
|
retryInterval := time.Duration(cfg.Uprobes.RetryIntervalSec) * time.Second
|
||||||
|
|
||||||
|
log.Printf("[uprobes] tentative d'attachement nginx uprobes (bin=%s, max_retries=%d, interval=%v)",
|
||||||
|
binPath, maxRetries, retryInterval)
|
||||||
|
|
||||||
|
for attempt := 1; attempt <= maxRetries; attempt++ {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return ctx.Err()
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vérifier que le binaire existe
|
||||||
|
if _, err := os.Stat(binPath); err != nil {
|
||||||
|
log.Printf("[uprobes] tentative %d/%d: binaire nginx non trouvé (%s), retry dans %v",
|
||||||
|
attempt, maxRetries, binPath, retryInterval)
|
||||||
|
time.Sleep(retryInterval)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tenter d'attacher les uprobes
|
||||||
|
err := l.AttachUprobesNginx(binPath)
|
||||||
|
if err == nil {
|
||||||
|
log.Printf("[uprobes] nginx uprobes attachés avec succès (tentative %d/%d)", attempt, maxRetries)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[uprobes] tentative %d/%d: échec attachement: %v, retry dans %v",
|
||||||
|
attempt, maxRetries, err, retryInterval)
|
||||||
|
|
||||||
|
// Dernière tentative : ne pas sleep
|
||||||
|
if attempt < maxRetries {
|
||||||
|
time.Sleep(retryInterval)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("attachement nginx uprobes échoué après %d tentatives", maxRetries)
|
||||||
|
}
|
||||||
|
|
||||||
|
// consumeNginxHTTPEvents lit et traite les événements HTTP depuis nginx via uprobes.
|
||||||
|
// Ces événements contiennent les requêtes HTTP complètes (méthode, URI, headers) capturées
|
||||||
|
// par nginx avant tout traitement, garantissant des headers complets.
|
||||||
|
func consumeNginxHTTPEvents(ctx context.Context, rd *perf.Reader, mgr *correlation.Manager, counter *atomic.Uint64) {
|
||||||
|
// Structure nginx_http_event BPF (version tracepoint recvfrom):
|
||||||
|
// Offset: 0:pid_tgid(8), 8:fd(4), 12:src_ip(4), 16:src_port(2), 18:timestamp_ns(8),
|
||||||
|
// 26:http_method[16], 42:uri[256], 298:query[128], 426:data[3640],
|
||||||
|
// 4066:method_len(4), 4070:uri_len(4), 4074:query_len(4), 4078:body_len(4), 4082:data_len(4)
|
||||||
|
// NOTE: Avec tracepoint recvfrom, http_method/uri/query sont vides, les données HTTP sont dans data[]
|
||||||
|
const minEventSize = 426
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
record, err := rd.Read()
|
||||||
|
if err != nil {
|
||||||
|
if err == os.ErrClosed {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
data := record.RawSample
|
||||||
|
if len(data) < 426 {
|
||||||
|
// Les événements doivent avoir au moins l'offset du champ data
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parser les metadata (structure tracepoint recvfrom)
|
||||||
|
pidTgid := binary.LittleEndian.Uint64(data[0:8])
|
||||||
|
fd := binary.LittleEndian.Uint32(data[8:12])
|
||||||
|
srcIPRaw := binary.LittleEndian.Uint32(data[12:16])
|
||||||
|
srcPort := binary.LittleEndian.Uint16(data[16:18])
|
||||||
|
dataLen := binary.LittleEndian.Uint32(data[4082:4086])
|
||||||
|
|
||||||
|
// Extraire les données HTTP brutes (offset 426)
|
||||||
|
rawHTTP := string(data[426 : 426+dataLen])
|
||||||
|
if len(rawHTTP) < 4 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parser la ligne de requête HTTP: "METHOD /path?query HTTP/1.1\r\n"
|
||||||
|
requestLineEnd := strings.Index(rawHTTP, "\r\n")
|
||||||
|
if requestLineEnd < 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
requestLine := rawHTTP[:requestLineEnd]
|
||||||
|
parts := strings.Fields(requestLine)
|
||||||
|
if len(parts) < 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
httpMethod := parts[0]
|
||||||
|
fullPath := parts[1]
|
||||||
|
|
||||||
|
// Séparer path et query string
|
||||||
|
queryStart := strings.Index(fullPath, "?")
|
||||||
|
var uri, query string
|
||||||
|
if queryStart >= 0 {
|
||||||
|
uri = fullPath[:queryStart]
|
||||||
|
query = fullPath[queryStart+1:]
|
||||||
|
} else {
|
||||||
|
uri = fullPath
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parser les headers HTTP
|
||||||
|
headersData := rawHTTP[requestLineEnd+2:]
|
||||||
|
var req correlation.HTTPRequest
|
||||||
|
req.Method = httpMethod
|
||||||
|
req.Path = uri
|
||||||
|
req.QueryString = query
|
||||||
|
req.Timestamp = time.Now()
|
||||||
|
req.HeaderKV = make(map[string]string)
|
||||||
|
|
||||||
|
lines := strings.Split(headersData, "\r\n")
|
||||||
|
for _, line := range lines {
|
||||||
|
if line == "" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
colon := strings.Index(line, ":")
|
||||||
|
if colon > 0 {
|
||||||
|
name := strings.TrimSpace(line[:colon])
|
||||||
|
value := ""
|
||||||
|
if colon+1 < len(line) {
|
||||||
|
value = strings.TrimSpace(line[colon+1:])
|
||||||
|
}
|
||||||
|
nameLower := strings.ToLower(name)
|
||||||
|
req.HeaderOrder = append(req.HeaderOrder, nameLower)
|
||||||
|
req.HeaderKV[nameLower] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
req.HeaderOrderSig = strings.Join(req.HeaderOrder, ";")
|
||||||
|
|
||||||
|
// Créer la clé de session
|
||||||
|
var key correlation.SessionKey
|
||||||
|
key.SrcIP[0] = byte(srcIPRaw >> 24)
|
||||||
|
key.SrcIP[1] = byte(srcIPRaw >> 16)
|
||||||
|
key.SrcIP[2] = byte(srcIPRaw >> 8)
|
||||||
|
key.SrcIP[3] = byte(srcIPRaw)
|
||||||
|
key.SrcPort = srcPort
|
||||||
|
|
||||||
|
// Filtrer les IPs sources ignorées
|
||||||
|
if isIgnoredIP(key.SrcIP) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mettre à jour la session
|
||||||
|
mgr.Update(key, func(s *correlation.SessionState) {
|
||||||
|
s.Requests = append(s.Requests, req)
|
||||||
|
})
|
||||||
|
|
||||||
|
counter.Add(1)
|
||||||
|
log.Printf("[nginx] HTTP: pid=%d fd=%d %s %s (headers=%d)",
|
||||||
|
pidTgid>>32, fd, httpMethod, uri, len(req.HeaderOrder))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -35,6 +35,29 @@ type Ja4SslHttpPlainEvent struct {
|
|||||||
TimestampNs uint64
|
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 {
|
type Ja4SslSslConnInfo struct {
|
||||||
Fd uint32
|
Fd uint32
|
||||||
SrcIp uint32
|
SrcIp uint32
|
||||||
@ -123,12 +146,15 @@ type Ja4SslProgramSpecs struct {
|
|||||||
// It can be passed ebpf.CollectionSpec.Assign.
|
// It can be passed ebpf.CollectionSpec.Assign.
|
||||||
type Ja4SslMapSpecs struct {
|
type Ja4SslMapSpecs struct {
|
||||||
HttpBuf *ebpf.MapSpec `ebpf:"__http_buf"`
|
HttpBuf *ebpf.MapSpec `ebpf:"__http_buf"`
|
||||||
|
NginxBuf *ebpf.MapSpec `ebpf:"__nginx_buf"`
|
||||||
SslBuf *ebpf.MapSpec `ebpf:"__ssl_buf"`
|
SslBuf *ebpf.MapSpec `ebpf:"__ssl_buf"`
|
||||||
TlsBuf *ebpf.MapSpec `ebpf:"__tls_buf"`
|
TlsBuf *ebpf.MapSpec `ebpf:"__tls_buf"`
|
||||||
AcceptArgsMap *ebpf.MapSpec `ebpf:"accept_args_map"`
|
AcceptArgsMap *ebpf.MapSpec `ebpf:"accept_args_map"`
|
||||||
AcceptMap *ebpf.MapSpec `ebpf:"accept_map"`
|
AcceptMap *ebpf.MapSpec `ebpf:"accept_map"`
|
||||||
FdConnMap *ebpf.MapSpec `ebpf:"fd_conn_map"`
|
FdConnMap *ebpf.MapSpec `ebpf:"fd_conn_map"`
|
||||||
|
NginxReadArgsMap *ebpf.MapSpec `ebpf:"nginx_read_args_map"`
|
||||||
PbAccept *ebpf.MapSpec `ebpf:"pb_accept"`
|
PbAccept *ebpf.MapSpec `ebpf:"pb_accept"`
|
||||||
|
PbGinxHttp *ebpf.MapSpec `ebpf:"pb_ginx_http"`
|
||||||
PbHttpPlain *ebpf.MapSpec `ebpf:"pb_http_plain"`
|
PbHttpPlain *ebpf.MapSpec `ebpf:"pb_http_plain"`
|
||||||
PbSslData *ebpf.MapSpec `ebpf:"pb_ssl_data"`
|
PbSslData *ebpf.MapSpec `ebpf:"pb_ssl_data"`
|
||||||
PbTcpSyn *ebpf.MapSpec `ebpf:"pb_tcp_syn"`
|
PbTcpSyn *ebpf.MapSpec `ebpf:"pb_tcp_syn"`
|
||||||
@ -157,12 +183,15 @@ func (o *Ja4SslObjects) Close() error {
|
|||||||
// It can be passed to LoadJa4SslObjects or ebpf.CollectionSpec.LoadAndAssign.
|
// It can be passed to LoadJa4SslObjects or ebpf.CollectionSpec.LoadAndAssign.
|
||||||
type Ja4SslMaps struct {
|
type Ja4SslMaps struct {
|
||||||
HttpBuf *ebpf.Map `ebpf:"__http_buf"`
|
HttpBuf *ebpf.Map `ebpf:"__http_buf"`
|
||||||
|
NginxBuf *ebpf.Map `ebpf:"__nginx_buf"`
|
||||||
SslBuf *ebpf.Map `ebpf:"__ssl_buf"`
|
SslBuf *ebpf.Map `ebpf:"__ssl_buf"`
|
||||||
TlsBuf *ebpf.Map `ebpf:"__tls_buf"`
|
TlsBuf *ebpf.Map `ebpf:"__tls_buf"`
|
||||||
AcceptArgsMap *ebpf.Map `ebpf:"accept_args_map"`
|
AcceptArgsMap *ebpf.Map `ebpf:"accept_args_map"`
|
||||||
AcceptMap *ebpf.Map `ebpf:"accept_map"`
|
AcceptMap *ebpf.Map `ebpf:"accept_map"`
|
||||||
FdConnMap *ebpf.Map `ebpf:"fd_conn_map"`
|
FdConnMap *ebpf.Map `ebpf:"fd_conn_map"`
|
||||||
|
NginxReadArgsMap *ebpf.Map `ebpf:"nginx_read_args_map"`
|
||||||
PbAccept *ebpf.Map `ebpf:"pb_accept"`
|
PbAccept *ebpf.Map `ebpf:"pb_accept"`
|
||||||
|
PbGinxHttp *ebpf.Map `ebpf:"pb_ginx_http"`
|
||||||
PbHttpPlain *ebpf.Map `ebpf:"pb_http_plain"`
|
PbHttpPlain *ebpf.Map `ebpf:"pb_http_plain"`
|
||||||
PbSslData *ebpf.Map `ebpf:"pb_ssl_data"`
|
PbSslData *ebpf.Map `ebpf:"pb_ssl_data"`
|
||||||
PbTcpSyn *ebpf.Map `ebpf:"pb_tcp_syn"`
|
PbTcpSyn *ebpf.Map `ebpf:"pb_tcp_syn"`
|
||||||
@ -174,12 +203,15 @@ type Ja4SslMaps struct {
|
|||||||
func (m *Ja4SslMaps) Close() error {
|
func (m *Ja4SslMaps) Close() error {
|
||||||
return _Ja4SslClose(
|
return _Ja4SslClose(
|
||||||
m.HttpBuf,
|
m.HttpBuf,
|
||||||
|
m.NginxBuf,
|
||||||
m.SslBuf,
|
m.SslBuf,
|
||||||
m.TlsBuf,
|
m.TlsBuf,
|
||||||
m.AcceptArgsMap,
|
m.AcceptArgsMap,
|
||||||
m.AcceptMap,
|
m.AcceptMap,
|
||||||
m.FdConnMap,
|
m.FdConnMap,
|
||||||
|
m.NginxReadArgsMap,
|
||||||
m.PbAccept,
|
m.PbAccept,
|
||||||
|
m.PbGinxHttp,
|
||||||
m.PbHttpPlain,
|
m.PbHttpPlain,
|
||||||
m.PbSslData,
|
m.PbSslData,
|
||||||
m.PbTcpSyn,
|
m.PbTcpSyn,
|
||||||
|
|||||||
@ -35,6 +35,29 @@ type Ja4TcHttpPlainEvent struct {
|
|||||||
TimestampNs uint64
|
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 {
|
type Ja4TcSslConnInfo struct {
|
||||||
Fd uint32
|
Fd uint32
|
||||||
SrcIp uint32
|
SrcIp uint32
|
||||||
@ -117,13 +140,16 @@ type Ja4TcProgramSpecs struct {
|
|||||||
// It can be passed ebpf.CollectionSpec.Assign.
|
// It can be passed ebpf.CollectionSpec.Assign.
|
||||||
type Ja4TcMapSpecs struct {
|
type Ja4TcMapSpecs struct {
|
||||||
HttpBuf *ebpf.MapSpec `ebpf:"__http_buf"`
|
HttpBuf *ebpf.MapSpec `ebpf:"__http_buf"`
|
||||||
|
NginxBuf *ebpf.MapSpec `ebpf:"__nginx_buf"`
|
||||||
SslBuf *ebpf.MapSpec `ebpf:"__ssl_buf"`
|
SslBuf *ebpf.MapSpec `ebpf:"__ssl_buf"`
|
||||||
TlsBuf *ebpf.MapSpec `ebpf:"__tls_buf"`
|
TlsBuf *ebpf.MapSpec `ebpf:"__tls_buf"`
|
||||||
AcceptMap *ebpf.MapSpec `ebpf:"accept_map"`
|
AcceptMap *ebpf.MapSpec `ebpf:"accept_map"`
|
||||||
AllowedPorts *ebpf.MapSpec `ebpf:"allowed_ports"`
|
AllowedPorts *ebpf.MapSpec `ebpf:"allowed_ports"`
|
||||||
FdConnMap *ebpf.MapSpec `ebpf:"fd_conn_map"`
|
FdConnMap *ebpf.MapSpec `ebpf:"fd_conn_map"`
|
||||||
IgnoredSrc *ebpf.MapSpec `ebpf:"ignored_src"`
|
IgnoredSrc *ebpf.MapSpec `ebpf:"ignored_src"`
|
||||||
|
NginxReadArgsMap *ebpf.MapSpec `ebpf:"nginx_read_args_map"`
|
||||||
PbAccept *ebpf.MapSpec `ebpf:"pb_accept"`
|
PbAccept *ebpf.MapSpec `ebpf:"pb_accept"`
|
||||||
|
PbGinxHttp *ebpf.MapSpec `ebpf:"pb_ginx_http"`
|
||||||
PbHttpPlain *ebpf.MapSpec `ebpf:"pb_http_plain"`
|
PbHttpPlain *ebpf.MapSpec `ebpf:"pb_http_plain"`
|
||||||
PbSslData *ebpf.MapSpec `ebpf:"pb_ssl_data"`
|
PbSslData *ebpf.MapSpec `ebpf:"pb_ssl_data"`
|
||||||
PbTcpSyn *ebpf.MapSpec `ebpf:"pb_tcp_syn"`
|
PbTcpSyn *ebpf.MapSpec `ebpf:"pb_tcp_syn"`
|
||||||
@ -153,13 +179,16 @@ func (o *Ja4TcObjects) Close() error {
|
|||||||
// It can be passed to LoadJa4TcObjects or ebpf.CollectionSpec.LoadAndAssign.
|
// It can be passed to LoadJa4TcObjects or ebpf.CollectionSpec.LoadAndAssign.
|
||||||
type Ja4TcMaps struct {
|
type Ja4TcMaps struct {
|
||||||
HttpBuf *ebpf.Map `ebpf:"__http_buf"`
|
HttpBuf *ebpf.Map `ebpf:"__http_buf"`
|
||||||
|
NginxBuf *ebpf.Map `ebpf:"__nginx_buf"`
|
||||||
SslBuf *ebpf.Map `ebpf:"__ssl_buf"`
|
SslBuf *ebpf.Map `ebpf:"__ssl_buf"`
|
||||||
TlsBuf *ebpf.Map `ebpf:"__tls_buf"`
|
TlsBuf *ebpf.Map `ebpf:"__tls_buf"`
|
||||||
AcceptMap *ebpf.Map `ebpf:"accept_map"`
|
AcceptMap *ebpf.Map `ebpf:"accept_map"`
|
||||||
AllowedPorts *ebpf.Map `ebpf:"allowed_ports"`
|
AllowedPorts *ebpf.Map `ebpf:"allowed_ports"`
|
||||||
FdConnMap *ebpf.Map `ebpf:"fd_conn_map"`
|
FdConnMap *ebpf.Map `ebpf:"fd_conn_map"`
|
||||||
IgnoredSrc *ebpf.Map `ebpf:"ignored_src"`
|
IgnoredSrc *ebpf.Map `ebpf:"ignored_src"`
|
||||||
|
NginxReadArgsMap *ebpf.Map `ebpf:"nginx_read_args_map"`
|
||||||
PbAccept *ebpf.Map `ebpf:"pb_accept"`
|
PbAccept *ebpf.Map `ebpf:"pb_accept"`
|
||||||
|
PbGinxHttp *ebpf.Map `ebpf:"pb_ginx_http"`
|
||||||
PbHttpPlain *ebpf.Map `ebpf:"pb_http_plain"`
|
PbHttpPlain *ebpf.Map `ebpf:"pb_http_plain"`
|
||||||
PbSslData *ebpf.Map `ebpf:"pb_ssl_data"`
|
PbSslData *ebpf.Map `ebpf:"pb_ssl_data"`
|
||||||
PbTcpSyn *ebpf.Map `ebpf:"pb_tcp_syn"`
|
PbTcpSyn *ebpf.Map `ebpf:"pb_tcp_syn"`
|
||||||
@ -172,13 +201,16 @@ type Ja4TcMaps struct {
|
|||||||
func (m *Ja4TcMaps) Close() error {
|
func (m *Ja4TcMaps) Close() error {
|
||||||
return _Ja4TcClose(
|
return _Ja4TcClose(
|
||||||
m.HttpBuf,
|
m.HttpBuf,
|
||||||
|
m.NginxBuf,
|
||||||
m.SslBuf,
|
m.SslBuf,
|
||||||
m.TlsBuf,
|
m.TlsBuf,
|
||||||
m.AcceptMap,
|
m.AcceptMap,
|
||||||
m.AllowedPorts,
|
m.AllowedPorts,
|
||||||
m.FdConnMap,
|
m.FdConnMap,
|
||||||
m.IgnoredSrc,
|
m.IgnoredSrc,
|
||||||
|
m.NginxReadArgsMap,
|
||||||
m.PbAccept,
|
m.PbAccept,
|
||||||
|
m.PbGinxHttp,
|
||||||
m.PbHttpPlain,
|
m.PbHttpPlain,
|
||||||
m.PbSslData,
|
m.PbSslData,
|
||||||
m.PbTcpSyn,
|
m.PbTcpSyn,
|
||||||
|
|||||||
Reference in New Issue
Block a user