fix(ja4ebpf): Rocky Linux RPM builder, remove correlated field, fix thesis
- Dockerfile.package: migre go-builder de golang:bookworm (Debian) vers
rockylinux:9, installe Go depuis le tarball officiel, remplace apt par
dnf (clang llvm libbpf-devel bpftool)
- Suppression du champ 'correlated' de l'agent ja4ebpf : avec eBPF/XDP,
la corrélation L3/L4↔L7 est toujours implicite par présence des champs.
Supprimé de : session.go, manager.go, main.go (x5), clickhouse.go
- Thèse (6 corrections listées + cohérence correlated) :
1. §3.5 + §3.9.1 : SSL_read retourne des octets bruts sans respecter les
frontières H2 → buffer circulaire de réassemblage en Go userspace
2. §3.1 : supprimé libpcap + CAP_NET_RAW, remplacé par définition uprobe
3. §4 + §7 : compte exact 96 features en 8 familles (Famille 1–8),
supprimé taxonomie F1–F11 obsolète, tous les totaux mis à jour
4. §2.4 + §8 : remplacé 7 fausses URLs arXiv par [Référence à vérifier]
5. §4 Famille 2 : ja4_drift_ratio → renvoi à Famille 8 (définition complète)
6. §6.4 : ajouté limite 'Overhead de l'uprobe SSL_read'
+ §3.6 : supprimé correlated=0/1 du texte architectural
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@ -23,13 +23,19 @@ ARG BUILD_VERSION=dev
|
||||
ARG GO_VERSION=1.24
|
||||
|
||||
# ── Stage 1 : compilation Go ──────────────────────────────────────────────
|
||||
FROM golang:${GO_VERSION}-bookworm AS go-builder
|
||||
FROM rockylinux:9 AS go-builder
|
||||
|
||||
ARG BUILD_VERSION
|
||||
ARG GO_VERSION
|
||||
clang llvm libbpf-devel bpftool \
|
||||
curl tar gzip && \
|
||||
dnf clean all
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
clang llvm libbpf-dev && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
RUN curl -fsSL https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz \
|
||||
| tar -C /usr/local -xz
|
||||
|
||||
ENV PATH="/usr/local/go/bin:${PATH}" \
|
||||
GOPATH=/go
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
|
||||
@ -283,9 +283,9 @@ func consumeSynEvents(ctx context.Context, rd *ringbuf.Reader, mgr *correlation.
|
||||
TCPOptionsRaw: tcpOpts,
|
||||
SYNTimestamp: time.Now(),
|
||||
}
|
||||
// Si TLS est déjà présent (arrivé avant SYN), marquer la session corrélée.
|
||||
// Si TLS est déjà présent (arrivé avant SYN), les deux couches sont disponibles.
|
||||
if s.TLS != nil {
|
||||
s.Correlated = true
|
||||
_ = s.TLS // corrélation implicite par présence des deux champs
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -363,7 +363,7 @@ func consumeTLSEvents(ctx context.Context, rd *ringbuf.Reader, mgr *correlation.
|
||||
}
|
||||
// Corréler si L3/L4 est déjà présent
|
||||
if s.L3L4 != nil {
|
||||
s.Correlated = true
|
||||
_ = s.L3L4 // corrélation implicite par présence des deux champs
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -471,9 +471,7 @@ func consumeSSLEvents(ctx context.Context, rd *ringbuf.Reader, mgr *correlation.
|
||||
if len(s.Requests) == 0 {
|
||||
s.Requests = append(s.Requests, req)
|
||||
}
|
||||
if s.TLS != nil {
|
||||
s.Correlated = true
|
||||
}
|
||||
_ = s.TLS // corrélation implicite
|
||||
})
|
||||
continue
|
||||
}
|
||||
@ -493,9 +491,7 @@ func consumeSSLEvents(ctx context.Context, rd *ringbuf.Reader, mgr *correlation.
|
||||
HeaderOrder: req.Headers,
|
||||
HeaderOrderSig: req.HeaderSig,
|
||||
})
|
||||
if s.TLS != nil {
|
||||
s.Correlated = true
|
||||
}
|
||||
_ = s.TLS // corrélation implicite
|
||||
})
|
||||
continue
|
||||
}
|
||||
@ -635,9 +631,7 @@ func consumeHTTPPlainEvents(ctx context.Context, rd *ringbuf.Reader, mgr *correl
|
||||
HeaderOrderSig: req.HeaderSig,
|
||||
})
|
||||
// Corréler si L3/L4 est déjà présent (TCP SYN capturé)
|
||||
if s.L3L4 != nil {
|
||||
s.Correlated = true
|
||||
}
|
||||
_ = s.L3L4 // corrélation implicite
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -76,7 +76,6 @@ func (m *Manager) GetOrCreate(key SessionKey) *SessionState {
|
||||
Key: key,
|
||||
FirstSeen: now,
|
||||
LastActivity: now,
|
||||
Correlated: false,
|
||||
MaxKeepAlives: 1,
|
||||
}
|
||||
sh.sessions[key] = s
|
||||
@ -128,12 +127,6 @@ func (m *Manager) gcRound(slowlorisThreshold time.Duration) {
|
||||
slowloris := s.IsSlowloris(slowlorisThreshold)
|
||||
|
||||
if expired || slowloris {
|
||||
// Marquer les sessions Slowloris comme non corrélées
|
||||
if slowloris && !expired {
|
||||
s.mu.Lock()
|
||||
s.Correlated = false
|
||||
s.mu.Unlock()
|
||||
}
|
||||
toDelete = append(toDelete, key)
|
||||
// Envoyer sans bloquer (drop si le canal est plein)
|
||||
select {
|
||||
|
||||
@ -75,7 +75,6 @@ type SessionState struct {
|
||||
|
||||
FirstSeen time.Time // horodatage de création de la session
|
||||
LastActivity time.Time // horodatage de la dernière activité
|
||||
Correlated bool // true si L3/L4 et L7 sont corrélés
|
||||
|
||||
mu sync.Mutex // protection des modifications concurrentes
|
||||
}
|
||||
|
||||
@ -32,7 +32,6 @@ type sessionRecord struct {
|
||||
SrcPort int `json:"src_port"`
|
||||
DstIP string `json:"dst_ip"`
|
||||
DstPort int `json:"dst_port"`
|
||||
Correlated int `json:"correlated"`
|
||||
|
||||
// Métadonnées IP (noms attendus par le MV)
|
||||
IPMetaDF *bool `json:"ip_meta_df,omitempty"`
|
||||
@ -182,18 +181,12 @@ func sessionToRecord(s *correlation.SessionState) sessionRecord {
|
||||
srcIP := fmt.Sprintf("%d.%d.%d.%d",
|
||||
s.Key.SrcIP[0], s.Key.SrcIP[1], s.Key.SrcIP[2], s.Key.SrcIP[3])
|
||||
|
||||
correlated := 0
|
||||
if s.Correlated {
|
||||
correlated = 1
|
||||
}
|
||||
|
||||
rec := sessionRecord{
|
||||
Time: s.FirstSeen,
|
||||
SrcIP: srcIP,
|
||||
SrcPort: int(s.Key.SrcPort),
|
||||
DstIP: "0.0.0.0", // destination non capturée par les sondes eBPF actuelles
|
||||
DstPort: 0,
|
||||
Correlated: correlated,
|
||||
KeepAlives: len(s.Requests),
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user