- Rename apache_pid_map to apache_http_pid_map - Rename apache_read_args_map to apache_http_recv_args_map - Update all references in C code and Go loader - Attempt both tracepoints and kretprobe for Apache HTTP capture Test results: - Rocky 9 (kernel 5.14): nginx HTTP capture works perfectly - Rocky 10 (kernel 6.12): Apache HTTP capture not working (headers=0) - CentOS 8 (kernel 4.18): Apache HTTP capture not working The issue appears to be that Apache event MPM may not use recvfrom() in the same way as nginx, or uses a different code path. Further investigation needed for Apache HTTP capture. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
84 lines
2.6 KiB
C
84 lines
2.6 KiB
C
/* uprobe_apache.c — Kretprobe pour capturer le trafic HTTP depuis Apache httpd
|
|
*
|
|
* Cette version utilise kretprobe sur __x64_sys_recvfrom (identique à nginx)
|
|
* pour capturer les appels système recvfrom() du serveur Apache httpd.
|
|
*
|
|
* ============================================================================
|
|
*/
|
|
|
|
#include "vmlinux.h"
|
|
#include <bpf/bpf_helpers.h>
|
|
#include <bpf/bpf_tracing.h>
|
|
#include "bpf_types.h"
|
|
|
|
/* Taille maximale d'une capture recvfrom() */
|
|
#define MAX_RECV_SIZE 4096
|
|
|
|
/* ============================================================================
|
|
* kretprobe_sys_exit_recvfrom — Sortie du syscall recvfrom
|
|
*
|
|
* Capture les données reçues et les envoie vers pb_apache_http.
|
|
* Utilise kretprobe pour contourner les limitations de tracepoint exit.
|
|
* ============================================================================
|
|
*/
|
|
SEC("kretprobe/__x64_sys_recvfrom")
|
|
int kretprobe_sys_exit_recvfrom(struct pt_regs *ctx)
|
|
{
|
|
__u64 pid_tgid = bpf_get_current_pid_tgid();
|
|
__u32 pid = pid_tgid >> 32;
|
|
|
|
/* Vérifier si ce PID est dans la map apache_http_pid_map */
|
|
__u32 pid_key = pid;
|
|
__u8 *enabled = bpf_map_lookup_elem(&apache_http_pid_map, &pid_key);
|
|
if (!enabled || *enabled == 0) {
|
|
return 0; /* Pas un PID Apache, ignore */
|
|
}
|
|
|
|
/* Obtenir la valeur de retour (nombre d'octets reçus) */
|
|
long retval = PT_REGS_RC(ctx);
|
|
if (retval < 0 || retval > MAX_RECV_SIZE) {
|
|
/* Erreur ou trop de données */
|
|
return 0;
|
|
}
|
|
|
|
/* Préparer l'événement Apache HTTP */
|
|
struct apache_http_event *e = bpf_map_lookup_elem(&__apache_buf, &pid_tgid);
|
|
if (!e) {
|
|
return 0;
|
|
}
|
|
|
|
/* Initialiser l'événement */
|
|
e->pid_tgid = pid_tgid;
|
|
e->fd = 0;
|
|
e->src_ip = 0;
|
|
e->src_port = 0;
|
|
e->timestamp_ns = bpf_ktime_get_ns();
|
|
e->method_len = 0;
|
|
e->uri_len = 0;
|
|
e->query_len = 0;
|
|
e->body_len = 0;
|
|
e->data_len = 0;
|
|
|
|
/* Copier les données depuis le buffer utilisateur (2ème argument: RSI) */
|
|
__u64 buf_ptr = PT_REGS_PARM2(ctx);
|
|
|
|
/* Limiter la copie à retval octets */
|
|
__u64 copy_size = retval;
|
|
if (copy_size > sizeof(e->data)) {
|
|
copy_size = sizeof(e->data);
|
|
}
|
|
|
|
if (copy_size > 0) {
|
|
__u64 bytes_read = bpf_probe_read_user_str(e->data, copy_size, (void *)buf_ptr);
|
|
if (bytes_read > 0) {
|
|
e->data_len = bytes_read;
|
|
/* Envoyer vers l'espace utilisateur via perf buffer */
|
|
bpf_perf_event_output(ctx, &pb_apache_http, BPF_F_CURRENT_CPU, e, sizeof(*e));
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
char LICENSE[] SEC("license") = "GPL";
|