用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/JohnNuwan/EVA_CORE --skill industrial-ebpf-diagnostics命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
基于 SOC 职业分类
正在显示 SKILL.md
| name | industrial-ebpf-diagnostics |
| description | Diagnostic réseau et filtrage de paquets OT via eBPF. |
| version | 1.0.0 |
| author | EVA |
| license | Privée EVA St-Étienne |
| metadata | {"EVA":{"maturity":"pilot","tags":["ebpf","kernel","networking","ot-security","modbus-tcp","bcc","python"],"related_skills":["low-level-assembly-optimization","industrial-ai-pipeline"]}} |
Vous êtes un ingénieur systèmes et réseaux Linux senior et un expert en cybersécurité industrielle (OT). Votre rôle est de concevoir, développer et déployer des programmes eBPF (Extended Berkeley Packet Filter) en C pour intercepter, analyser et filtrer à ultra-haute vitesse et au niveau du noyau Linux les flux de protocoles industriels (Modbus TCP, OPC UA, S7comm) afin de détecter les anomalies et les intrusions.
Les solutions de supervision réseau classiques (comme Wireshark ou tcpdump) nécessitent la copie de tous les paquets réseau du noyau Linux vers l'espace utilisateur (user space), ce qui engendre une surcharge CPU importante sur les PC industriels d'atelier (Edge).
eBPF permet d'exécuter du code sécurisé directement au sein du noyau Linux (au niveau du socket buffer ou de la couche XDP - eXpress Data Path). L'agent peut ainsi filtrer ou rejeter des requêtes industrielles malveillantes (ex: une commande d'écriture d'automate non autorisée) sans aucun surcoût de copie mémoire.
+------------------------------------+
| USER SPACE |
| Loader Python (BCC) |
+-----------------+------------------+
^
| Ring Buffer (Perf Event)
+-----------------------------------------------------+------------------+
| KERNEL SPACE |
| |
| [Paquet Modbus TCP] ──► [Interface Réseau] ──► [Hook XDP / tc] |
| | |
| ▼ |
| [Vérificateur eBPF] |
| | |
| ▼ |
| [Filtre eBPF (C)] ──► Map Array |
+------------------------------------------------------------------------+
Pour analyser la charge utile Modbus TCP au niveau du noyau, le filtre eBPF doit naviguer manuellement à travers les en-têtes réseau en appliquant des offsets précis :
Ce programme se charge de lire les paquets, de valider de manière sécurisée les accès mémoire (exigence stricte du vérificateur Linux), et d'isoler les commandes d'écriture industrielle.
#include <uapi/linux/ptrace.h>
#include <net/sock.h>
#include <bcc/proto.h>
#include <linux/ip.h>
#include <linux/tcp.h>
// Structure envoyée au user space lors d'une détection
struct modbus_alert_t {
u32 src_ip;
u32 dst_ip;
u16 src_port;
u8 function_code;
u8 unit_id;
};
// Map de type Ring Buffer pour transmettre les alertes
BPF_PERF_OUTPUT(modbus_alerts);
// Compteur global des écritures interceptées
BPF_ARRAY(write_counter, u64, 1);
int monitor_modbus(struct __sk_buff *skb) {
// 1. Accès sécurisé à l'en-tête IP
u32 ip_offset = ETH_HLEN;
// Charger le protocole IP (doit être TCP = 6)
u8 protocol = load_byte(skb, ip_offset + offsetof(struct iphdr, protocol));
if (protocol != IPPROTO_TCP) {
return 0;
}
// Déterminer la longueur de l'en-tête IP dynamiquement (IHL * 4)
u8 ihl = load_byte(skb, ip_offset + offsetof(struct iphdr, ihl)) & 0x0F;
u32 tcp_offset = ip_offset + (ihl * 4);
// 2. Accès à l'en-tête TCP
// Port de destination (Modbus = 502)
u16 dport = load_half(skb, tcp_offset + offsetof(struct tcphdr, dest));
if (dport != 502) {
return 0;
}
u8 data_offset = (load_byte(skb, tcp_offset + offsetof( tcphdr, doff)) & ) >> ;
u32 payload_offset = tcp_offset + (data_offset * );
u8 unit_id = load_byte(skb, payload_offset + );
u8 function_code = load_byte(skb, payload_offset + );
(function_code == || function_code == || function_code == || function_code == ) {
index = ;
u64 *value = write_counter.lookup(&index);
(value) {
__sync_fetch_and_add(value, );
}
{};
alert.src_ip = load_word(skb, ip_offset + offsetof( iphdr, saddr));
alert.dst_ip = load_word(skb, ip_offset + offsetof( iphdr, daddr));
alert.src_port = load_half(skb, tcp_offset + offsetof( tcphdr, source));
alert.function_code = function_code;
alert.unit_id = unit_id;
modbus_alerts.perf_submit(skb, &alert, (alert));
}
;
}
Ce chargeur compile le code eBPF, l'injecte dans le noyau, et résout les adresses réseaux IP et ports (conversion Network Byte Order).
from bcc import BPF
import socket
import struct
# Initialisation du compilateur BCC à la volée
b = BPF(src_file="modbus_filter.c")
# Attachement au raw socket sur l'interface de rebouclage ou Ethernet industrielle
fn = b.load_func("monitor_modbus", BPF.SOCKET_FILTER)
BPF.attach_raw_socket(fn, "eth0")
def network_to_ip(ip_network_order):
"""Convertit un entier 32-bit réseau en chaîne IP standard."""
return socket.inet_ntoa(struct.pack("<I", ip_network_order))
def handle_event(cpu, data, size):
"""Callback recevant les données binaires du noyau."""
# Décodage de la structure modbus_alert_t
# src_ip (u32), dst_ip (u32), src_port (u16), function_code (u8), unit_id (u8)
struct_format = "<IIHBB"
unpacked = struct.unpack(struct_format, data[:struct.calcsize(struct_format)])
src_ip = network_to_ip(unpacked[0])
dst_ip = network_to_ip(unpacked[1])
src_port = socket.ntohs(unpacked[2])
fun_code = unpacked[3]
unit_id = unpacked[4]
print(f"🚨 [CYBER OT] Tentative d'écriture détectée !")
print(f" IP Source : {src_ip}:{src_port} ──► IP Automate : {dst_ip}:502")
print(f" Modbus Unit ID : {unit_id} | Code Fonction : {fun_code}")
# Ouvrir la map d'événements et démarrer l'écoute cyclique
b["modbus_alerts"].open_perf_buffer(handle_event)
()
:
:
b.perf_buffer_poll()
KeyboardInterrupt:
stats = b[]
()
Pour un déploiement de type Cybersécurité, il est crucial de comprendre où attacher le code eBPF selon le besoin :
XDP_DROP pour rejeter instantanément un paquet d'écriture malveillant en moins d'une microseconde.float ou double). Tous les calculs sémantiques doivent être convertis en arithmétique entière ou délégués au user space.skb->data_end. Sur un Socket Filter, préférez toujours les helpers système du compilateur comme load_byte ou load_half qui gèrent ces vérifications de sécurité de manière native.eth0, enp0s3).root (privilèges d'exécution noyau).