fix(ja4ebpf): split bpf2go generate into Ja4Tc + Ja4Ssl, fix RPM systemd-rpm-macros
- Use two separate //go:generate directives (Ja4Tc for tc_capture.c, Ja4Ssl
for uprobe_ssl.c) to avoid duplicate LICENSE symbol and multi-file clang issue
- Update loader.go to hold tcObjs/sslObjs separately with correct field names:
UprobeSslSetFd, UprobeSslReadEntry, UretprobeSslReadExit,
KprobeAccept4Entry, KretprobeAccept4Exit
- Add systemd-rpm-macros to all three RPM build stages (el8/el9/el10)
so that %{_unitdir} macro resolves correctly
- RPMs now build successfully for el8, el9, el10
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@ -16,12 +16,14 @@ import (
|
||||
"github.com/cilium/ebpf/rlimit"
|
||||
)
|
||||
|
||||
//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc clang -target amd64 -cflags "-O2 -g -Wall -Werror -D__TARGET_ARCH_x86" Ja4eBPF ../../bpf/tc_capture.c ../../bpf/uprobe_ssl.c -- -I../../bpf/headers
|
||||
//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc clang -target amd64 -cflags "-O2 -g -Wall -D__TARGET_ARCH_x86 -Wno-pass-failed" Ja4Tc ../../bpf/tc_capture.c -- -I../../bpf/headers
|
||||
//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc clang -target amd64 -cflags "-O2 -g -Wall -D__TARGET_ARCH_x86 -Wno-pass-failed" Ja4Ssl ../../bpf/uprobe_ssl.c -- -I../../bpf/headers
|
||||
|
||||
// Loader encapsule les objets eBPF compilés, les liens vers les hooks,
|
||||
// et les readers RingBuffer exposés au pipeline de traitement.
|
||||
type Loader struct {
|
||||
objs *Ja4eBPFObjects // généré par bpf2go
|
||||
tcObjs *Ja4TcObjects // généré par bpf2go (tc_capture.c)
|
||||
sslObjs *Ja4SslObjects // généré par bpf2go (uprobe_ssl.c)
|
||||
tcLink link.Link
|
||||
uprobeLinks []link.Link
|
||||
|
||||
@ -50,56 +52,68 @@ func New() (*Loader, error) {
|
||||
return nil, fmt.Errorf("suppression RLIMIT_MEMLOCK: %w", err)
|
||||
}
|
||||
|
||||
objs := &Ja4eBPFObjects{}
|
||||
// Charger le bytecode eBPF compilé (embarqué par bpf2go).
|
||||
// nil = cilium/ebpf résout le BTF kernel natif automatiquement.
|
||||
if err := LoadJa4eBPFObjects(objs, nil); err != nil {
|
||||
return nil, fmt.Errorf("chargement objets eBPF: %w", err)
|
||||
// Charger les objets TC (tc_capture.c)
|
||||
tcObjs := &Ja4TcObjects{}
|
||||
if err := LoadJa4TcObjects(tcObjs, nil); err != nil {
|
||||
return nil, fmt.Errorf("chargement objets TC eBPF: %w", err)
|
||||
}
|
||||
|
||||
// Charger les objets SSL/uprobe (uprobe_ssl.c)
|
||||
sslObjs := &Ja4SslObjects{}
|
||||
if err := LoadJa4SslObjects(sslObjs, nil); err != nil {
|
||||
tcObjs.Close()
|
||||
return nil, fmt.Errorf("chargement objets SSL eBPF: %w", err)
|
||||
}
|
||||
|
||||
// Initialiser les readers pour chaque ring buffer
|
||||
synReader, err := ringbuf.NewReader(objs.RbTcpSyn)
|
||||
synReader, err := ringbuf.NewReader(tcObjs.RbTcpSyn)
|
||||
if err != nil {
|
||||
objs.Close()
|
||||
sslObjs.Close()
|
||||
tcObjs.Close()
|
||||
return nil, fmt.Errorf("création reader rb_tcp_syn: %w", err)
|
||||
}
|
||||
|
||||
tlsReader, err := ringbuf.NewReader(objs.RbTlsHello)
|
||||
tlsReader, err := ringbuf.NewReader(tcObjs.RbTlsHello)
|
||||
if err != nil {
|
||||
synReader.Close()
|
||||
objs.Close()
|
||||
sslObjs.Close()
|
||||
tcObjs.Close()
|
||||
return nil, fmt.Errorf("création reader rb_tls_hello: %w", err)
|
||||
}
|
||||
|
||||
sslReader, err := ringbuf.NewReader(objs.RbSslData)
|
||||
httpPlainReader, err := ringbuf.NewReader(tcObjs.RbHttpPlain)
|
||||
if err != nil {
|
||||
tlsReader.Close()
|
||||
synReader.Close()
|
||||
objs.Close()
|
||||
return nil, fmt.Errorf("création reader rb_ssl_data: %w", err)
|
||||
}
|
||||
|
||||
acceptReader, err := ringbuf.NewReader(objs.RbAccept)
|
||||
if err != nil {
|
||||
sslReader.Close()
|
||||
tlsReader.Close()
|
||||
synReader.Close()
|
||||
objs.Close()
|
||||
return nil, fmt.Errorf("création reader rb_accept: %w", err)
|
||||
}
|
||||
|
||||
httpPlainReader, err := ringbuf.NewReader(objs.RbHttpPlain)
|
||||
if err != nil {
|
||||
acceptReader.Close()
|
||||
sslReader.Close()
|
||||
tlsReader.Close()
|
||||
synReader.Close()
|
||||
objs.Close()
|
||||
sslObjs.Close()
|
||||
tcObjs.Close()
|
||||
return nil, fmt.Errorf("création reader rb_http_plain: %w", err)
|
||||
}
|
||||
|
||||
sslReader, err := ringbuf.NewReader(sslObjs.RbSslData)
|
||||
if err != nil {
|
||||
httpPlainReader.Close()
|
||||
tlsReader.Close()
|
||||
synReader.Close()
|
||||
sslObjs.Close()
|
||||
tcObjs.Close()
|
||||
return nil, fmt.Errorf("création reader rb_ssl_data: %w", err)
|
||||
}
|
||||
|
||||
acceptReader, err := ringbuf.NewReader(sslObjs.RbAccept)
|
||||
if err != nil {
|
||||
sslReader.Close()
|
||||
httpPlainReader.Close()
|
||||
tlsReader.Close()
|
||||
synReader.Close()
|
||||
sslObjs.Close()
|
||||
tcObjs.Close()
|
||||
return nil, fmt.Errorf("création reader rb_accept: %w", err)
|
||||
}
|
||||
|
||||
return &Loader{
|
||||
objs: objs,
|
||||
tcObjs: tcObjs,
|
||||
sslObjs: sslObjs,
|
||||
SynReader: synReader,
|
||||
TLSReader: tlsReader,
|
||||
SSLReader: sslReader,
|
||||
@ -120,7 +134,7 @@ func (l *Loader) AttachTC(iface string) error {
|
||||
// Attacher le programme TC en ingress via TCX
|
||||
lnk, err := link.AttachTCX(link.TCXOptions{
|
||||
Interface: netIface.Index,
|
||||
Program: l.objs.CaptureTcIngress,
|
||||
Program: l.tcObjs.CaptureTcIngress,
|
||||
Attach: ebpf.AttachTCXIngress,
|
||||
})
|
||||
if err != nil {
|
||||
@ -146,21 +160,21 @@ func (l *Loader) AttachUprobes(sslLibPath string) error {
|
||||
}
|
||||
|
||||
// Uprobe sur SSL_set_fd (entry)
|
||||
setFdLink, err := ex.Uprobe("SSL_set_fd", l.objs.UprobeSSLSetFd, nil)
|
||||
setFdLink, err := ex.Uprobe("SSL_set_fd", l.sslObjs.UprobeSslSetFd, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("attachement uprobe SSL_set_fd: %w", err)
|
||||
}
|
||||
l.uprobeLinks = append(l.uprobeLinks, setFdLink)
|
||||
|
||||
// Uprobe sur SSL_read (entry)
|
||||
readEntryLink, err := ex.Uprobe("SSL_read", l.objs.UprobeSSLReadEntry, nil)
|
||||
readEntryLink, err := ex.Uprobe("SSL_read", l.sslObjs.UprobeSslReadEntry, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("attachement uprobe SSL_read (entry): %w", err)
|
||||
}
|
||||
l.uprobeLinks = append(l.uprobeLinks, readEntryLink)
|
||||
|
||||
// Uretprobe sur SSL_read (exit)
|
||||
readExitLink, err := ex.Uretprobe("SSL_read", l.objs.UretprobeSSLReadExit, nil)
|
||||
readExitLink, err := ex.Uretprobe("SSL_read", l.sslObjs.UretprobeSslReadExit, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("attachement uretprobe SSL_read (exit): %w", err)
|
||||
}
|
||||
@ -172,14 +186,14 @@ func (l *Loader) AttachUprobes(sslLibPath string) error {
|
||||
// AttachAcceptProbe attache les kprobes sur l'appel système accept4.
|
||||
func (l *Loader) AttachAcceptProbe() error {
|
||||
// Kprobe à l'entrée d'accept4
|
||||
kpEntry, err := link.Kprobe("accept4", l.objs.KprobeAccept4Entry, nil)
|
||||
kpEntry, err := link.Kprobe("accept4", l.sslObjs.KprobeAccept4Entry, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("attachement kprobe accept4 (entry): %w", err)
|
||||
}
|
||||
l.uprobeLinks = append(l.uprobeLinks, kpEntry)
|
||||
|
||||
// Kretprobe à la sortie d'accept4
|
||||
kpExit, err := link.Kretprobe("accept4", l.objs.KretprobeAccept4Exit, nil)
|
||||
kpExit, err := link.Kretprobe("accept4", l.sslObjs.KretprobeAccept4Exit, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("attachement kretprobe accept4 (exit): %w", err)
|
||||
}
|
||||
@ -220,8 +234,11 @@ func (l *Loader) Close() error {
|
||||
}
|
||||
|
||||
// Libérer les objets eBPF (maps, programmes)
|
||||
if l.objs != nil {
|
||||
l.objs.Close()
|
||||
if l.sslObjs != nil {
|
||||
l.sslObjs.Close()
|
||||
}
|
||||
if l.tcObjs != nil {
|
||||
l.tcObjs.Close()
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user