feat: multi-distro VM tests, ja4ebpf eBPF improvements, bot-detector scoring

ja4ebpf:
- Refactor BPF TC capture with improved SYN offset handling and TCP option parsing
- Enhance TLS uprobe SSL hooking for better key extraction
- Add ClickHouse writer improvements for HTTP log materialized views
- Update RPM spec for Rocky Linux 8/9/10, fix systemd service
- Simplify loader with cleaner bpf2go integration

bot-detector:
- Add H2 SETTINGS per-parameter comparison in browser_matcher
- Enhance browser signatures and scoring pipeline
- Improve preprocessing and cycle detection

infra:
- Multi-distro Vagrantfile (centos8, rocky9, rocky10) with per-distro provisioning
- New Makefile targets: vm-up-all, test-vm-matrix, test-vm-centos8/rocky10
- Add debug helpers and run-test-from-host.sh for host-driven VM testing
- Update run-tests-vm.sh for cross-distro compatibility
- Remove accidental binary blob (\004)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jacquin Antoine
2026-04-13 01:09:33 +02:00
parent d81463a589
commit d75825278e
32 changed files with 2148 additions and 890 deletions

View File

@ -4,6 +4,9 @@
* et corrige l'association socket ↔ SSL* via les tracepoints syscalls/accept4.
* Les tracepoints sont plus stables que les kprobes car ils ne dépendent pas
* du nom manglé __x64_sys_accept4 (variable selon la version du kernel).
*
* Utilise bpf_perf_event_output() (kernel 4.4+) pour compatibilité maximale.
* Les structs > 512o utilisent un PERCPU_ARRAY temporaire (__ssl_buf).
* ============================================================================ */
#include "vmlinux.h"
@ -105,7 +108,8 @@ int uprobe_ssl_read_entry(struct pt_regs *ctx)
/* ===========================================================================
* uretprobe_ssl_read_exit — Retour de SSL_read
*
* Lit le buffer déchiffré et l'émet dans rb_ssl_data.
* Lit le buffer déchiffré et l'émet via perf_event_output.
* Struct ssl_data_event = 4131 octets → PERCPU_ARRAY temporaire (__ssl_buf).
* ===========================================================================*/
SEC("uretprobe/SSL_read")
int uretprobe_ssl_read_exit(struct pt_regs *ctx)
@ -124,12 +128,21 @@ int uretprobe_ssl_read_exit(struct pt_regs *ctx)
return 0;
}
/* Allouer un slot dans le ring buffer */
struct ssl_data_event *evt = bpf_ringbuf_reserve(&rb_ssl_data, sizeof(*evt), 0);
/* Utiliser le buffer PERCPU (struct trop grande pour la stack) */
__u32 zero = 0;
struct ssl_data_event *evt = bpf_map_lookup_elem(&__ssl_buf, &zero);
if (!evt) {
bpf_map_delete_elem(&ssl_args_map, &pid_tgid);
return 0;
}
/* Initialiser les champs fixes (data sera écrasé par probe_read_user) */
evt->pid_tgid = 0;
evt->fd = 0;
evt->src_ip = 0;
evt->src_port = 0;
evt->data_len = 0;
evt->timestamp_ns = 0;
evt->direction = 0;
evt->pid_tgid = pid_tgid;
evt->direction = 0; /* lecture = client vers serveur */
@ -154,7 +167,8 @@ int uretprobe_ssl_read_exit(struct pt_regs *ctx)
evt->src_port = 0;
}
bpf_ringbuf_submit(evt, 0);
bpf_perf_event_output(ctx, &pb_ssl_data, BPF_F_CURRENT_CPU,
evt, sizeof(*evt));
bpf_map_delete_elem(&ssl_args_map, &pid_tgid);
return 0;
@ -181,7 +195,8 @@ int kprobe_accept4_entry(struct sys_enter_accept4_ctx *ctx)
* kretprobe_accept4_exit — Retour de accept4 via tracepoint syscalls
*
* Lit la sockaddr_in pour extraire src_ip:src_port du client,
* peuple accept_map et fd_conn_map, et émet dans rb_accept.
* peuple accept_map et fd_conn_map, et émet via perf_event_output.
* Struct accept_event = 26 octets → tient sur la stack (< 512o).
* ===========================================================================*/
SEC("tracepoint/syscalls/sys_exit_accept4")
int kretprobe_accept4_exit(struct sys_exit_accept4_ctx *ctx)
@ -238,21 +253,11 @@ int kretprobe_accept4_exit(struct sys_exit_accept4_ctx *ctx)
};
bpf_map_update_elem(&fd_conn_map, &fd, &conn_info, BPF_ANY);
/* Émettre dans rb_accept */
struct accept_event *out = bpf_ringbuf_reserve(&rb_accept, sizeof(*out), 0);
if (!out)
return 0;
out->pid_tgid = pid_tgid;
out->fd = fd;
out->src_ip = src_ip;
out->src_port = src_port;
out->timestamp_ns = aevt.timestamp_ns;
bpf_ringbuf_submit(out, 0);
/* Émettre via perf_event_output (struct 26o → sur la stack) */
bpf_perf_event_output(ctx, &pb_accept, BPF_F_CURRENT_CPU,
&aevt, sizeof(aevt));
return 0;
}
char LICENSE[] SEC("license") = "GPL";