secubox-openwrt/DOCS-fr/MIGRATION-NETIFYD-TO-NDPID.md
CyberMind-FR ccfb58124c docs: Add trilingual documentation (French and Chinese translations)
Add complete French (fr) and Chinese (zh) translations for all documentation:

- Root files: README, CHANGELOG, SECURITY, BETA-RELEASE
- docs/: All 16 core documentation files
- DOCS/: All 19 deep-dive documents including embedded/ and archive/
- package/secubox/: All 123+ package READMEs
- Misc: secubox-tools/, scripts/, EXAMPLES/, config-backups/, streamlit-apps/

Total: 346 translation files created

Each file includes language switcher links for easy navigation between
English, French, and Chinese versions.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-20 10:00:18 +01:00

685 lines
20 KiB
Markdown

# Plan de Migration: Netifyd vers nDPId
> **Languages:** [English](../DOCS/MIGRATION-NETIFYD-TO-NDPID.md) | Francais | [中文](../DOCS-zh/MIGRATION-NETIFYD-TO-NDPID.md)
## Resume Executif
Ce document fournit un plan de migration complet pour remplacer **Netifyd v5.2.1** par **nDPId** dans le projet SecuBox OpenWrt tout en maintenant une compatibilite complete avec les consommateurs CrowdSec et Netdata existants.
**Constatation Cle**: Netifyd et nDPId sont tous deux construits sur **nDPI** (la bibliotheque DPI sous-jacente). Netifyd est essentiellement un wrapper riche en fonctionnalites autour de nDPI avec integration cloud, tandis que nDPId est un daemon minimaliste haute performance avec une architecture microservice.
---
## Analyse de l'Architecture Actuelle
### Apercu de l'Integration Netifyd
| Composant | Emplacement | Objectif |
|-----------|-------------|----------|
| Package de Base | `secubox-app-netifyd` | Moteur DPI Netifyd v5.2.1 |
| App LuCI | `luci-app-secubox-netifyd` | UI Web avec surveillance temps reel |
| Backend RPCD | `/usr/libexec/rpcd/luci.secubox-netifyd` | 15 methodes lecture + 9 ecriture RPC |
| Config UCI | `/etc/config/secubox-netifyd` | Bascules fonctionnelles, plugins, sinks |
| Fichier Etat | `/var/run/netifyd/status.json` | Statistiques resumees (PAS les flux) |
| Socket | `/var/run/netifyd/netifyd.sock` | Interface streaming JSON |
| Collecteur | `/usr/bin/netifyd-collector` | Stats periodiques vers `/tmp/netifyd-stats.json` |
### Consommateurs de Donnees Actuels
1. **CrowdSec**: AUCUNE integration directe n'existe. Fonctionne independamment.
2. **Netdata**: Tableau de bord separe. Lit les metriques systeme via `/proc`, pas les donnees DPI.
3. **Tableau de Bord LuCI**: Consommateur principal via backend RPCD.
### Formats de Sortie Netifyd
**Statistiques Resumees** (`/var/run/netifyd/status.json`):
```json
{
"flow_count": 150,
"flows_active": 42,
"devices": [...],
"stats": {
"br-lan": {
"ip_bytes": 1234567,
"wire_bytes": 1345678,
"tcp": 1200,
"udp": 300,
"icmp": 50
}
},
"dns_hint_cache": { "cache_size": 500 },
"uptime": 86400
}
```
**Donnees de Flux** (quand sink active, pas par defaut):
```json
{
"flow_id": "abc123",
"src_ip": "192.168.1.100",
"dst_ip": "8.8.8.8",
"src_port": 54321,
"dst_port": 443,
"protocol": "tcp",
"application": "google",
"category": "search_engine",
"bytes_rx": 1500,
"bytes_tx": 500,
"packets_rx": 10,
"packets_tx": 5
}
```
---
## Architecture nDPId
### Composants Principaux
| Composant | Objectif |
|-----------|----------|
| **nDPId** | Daemon de capture de trafic utilisant libpcap + libnDPI |
| **nDPIsrvd** | Broker qui distribue les evenements a plusieurs consommateurs |
| **libnDPI** | Bibliotheque DPI centrale (partagee avec Netifyd) |
### Systeme d'Evenements nDPId
**Format de Message**: `[longueur-5-chiffres][JSON]\n`
```
01223{"flow_event_id":7,"flow_event_name":"detection-update",...}\n
```
**Categories d'Evenements**:
| Categorie | Evenements | Description |
|-----------|------------|-------------|
| Erreur | 17 types | Echecs de traitement de paquets, problemes memoire |
| Daemon | 4 types | init, shutdown, reconnect, status |
| Paquet | 2 types | packet, packet-flow (encode base64) |
| Flux | 9 types | new, end, idle, update, detected, guessed, detection-update, not-detected, analyse |
### Exemple d'Evenement de Flux nDPId
```json
{
"flow_event_id": 5,
"flow_event_name": "detected",
"thread_id": 0,
"packet_id": 12345,
"source": "eth0",
"flow_id": 1001,
"flow_state": "finished",
"flow_src_packets_processed": 15,
"flow_dst_packets_processed": 20,
"flow_first_seen": 1704067200000,
"flow_src_last_pkt_time": 1704067260000,
"flow_dst_last_pkt_time": 1704067258000,
"flow_idle_time": 2000,
"flow_src_tot_l4_payload_len": 1500,
"flow_dst_tot_l4_payload_len": 2000,
"l3_proto": "ip4",
"src_ip": "192.168.1.100",
"dst_ip": "142.250.185.78",
"l4_proto": "tcp",
"src_port": 54321,
"dst_port": 443,
"ndpi": {
"proto": "TLS.Google",
"proto_id": 91,
"proto_by_ip": 0,
"encrypted": 1,
"breed": "Safe",
"category_id": 5,
"category": "Web"
}
}
```
---
## Strategie de Migration
### Phase 1: Developpement de la Couche de Compatibilite
Creer un daemon de traduction qui convertit les evenements nDPId au format compatible Netifyd.
**Nouveau Composant**: `secubox-ndpid-compat`
```
nDPId → nDPIsrvd → secubox-ndpid-compat → Consommateurs Existants
/var/run/netifyd/status.json (compatible)
/tmp/netifyd-stats.json (compatible)
Backend RPCD (inchange)
```
### Phase 2: Developpement des Packages
#### 2.1 Nouveau Package: `secubox-app-ndpid`
**Makefile**:
```makefile
PKG_NAME:=ndpid
PKG_VERSION:=1.7.0
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/utoni/nDPId.git
DEPENDS:=+libndpi +libpcap +libjson-c +libpthread
```
**Prerequis de Build**:
- libnDPI >=5.0.0
- libpcap
- libjson-c
- Systeme de build CMake
#### 2.2 Nouveau Package: `secubox-ndpid-compat`
Script de couche de traduction qui:
1. Se connecte au socket nDPIsrvd
2. Agregue les evenements de flux au format compatible Netifyd
3. Ecrit dans `/var/run/netifyd/status.json`
4. Fournit la meme interface RPCD
### Phase 3: Traduction du Format de Sortie
#### 3.1 Carte de Traduction du Fichier Etat
| Champ Netifyd | Source nDPId | Logique de Traduction |
|---------------|--------------|----------------------|
| `flow_count` | Compte des evenements de flux | Incrementer sur `new`, decrementer sur `end`/`idle` |
| `flows_active` | Suivi des flux actifs | Compter les flux sans evenements `end`/`idle` |
| `stats.{iface}.tcp` | `l4_proto == "tcp"` | Agreger par interface |
| `stats.{iface}.udp` | `l4_proto == "udp"` | Agreger par interface |
| `stats.{iface}.ip_bytes` | `flow_*_tot_l4_payload_len` | Somme par interface |
| `uptime` | Evenement daemon `status` | Mappage direct |
#### 3.2 Carte de Traduction des Donnees de Flux
| Champ Netifyd | Champ nDPId | Notes |
|---------------|-------------|-------|
| `src_ip` | `src_ip` | Direct |
| `dst_ip` | `dst_ip` | Direct |
| `src_port` | `src_port` | Direct |
| `dst_port` | `dst_port` | Direct |
| `protocol` | `l4_proto` | Minuscules |
| `application` | `ndpi.proto` | Parser depuis "TLS.Google" → "google" |
| `category` | `ndpi.category` | Direct |
| `bytes_rx` | `flow_dst_tot_l4_payload_len` | Note: inverse (dst=rx du point de vue du flux) |
| `bytes_tx` | `flow_src_tot_l4_payload_len` | Note: inverse |
#### 3.3 Normalisation des Noms d'Application
nDPId utilise un format comme `TLS.Google`, `QUIC.YouTube`. Normaliser en base minuscules:
```
TLS.Google → google
QUIC.YouTube → youtube
HTTP.Facebook → facebook
DNS → dns
```
### Phase 4: Compatibilite des Consommateurs
#### 4.1 Integration CrowdSec (NOUVEAU)
Puisqu'il n'y a pas d'integration CrowdSec existante, nous pouvons la concevoir correctement:
**Configuration d'Acquisition** (`/etc/crowdsec/acquis.d/ndpid.yaml`):
```yaml
source: file
filenames:
- /tmp/ndpid-flows.log
labels:
type: ndpid
---
source: journalctl
journalctl_filter:
- "_SYSTEMD_UNIT=ndpid.service"
labels:
type: syslog
```
**Parseur** (`/etc/crowdsec/parsers/s02-enrich/ndpid-flows.yaml`):
```yaml
name: secubox/ndpid-flows
description: "Parser les evenements de detection de flux nDPId"
filter: "evt.Parsed.program == 'ndpid'"
onsuccess: next_stage
statics:
- parsed: flow_application
expression: evt.Parsed.ndpi_proto
nodes:
- grok:
pattern: '%{IP:src_ip}:%{INT:src_port} -> %{IP:dst_ip}:%{INT:dst_port} %{WORD:proto} %{DATA:app}'
```
**Scenario** (`/etc/crowdsec/scenarios/ndpid-suspicious-app.yaml`):
```yaml
type: leaky
name: secubox/ndpid-suspicious-app
description: "Detecter l'utilisation d'applications suspectes"
filter: evt.Parsed.flow_application in ["bittorrent", "tor", "vpn_udp"]
groupby: evt.Parsed.src_ip
capacity: 5
leakspeed: 10m
blackhole: 1h
labels:
remediation: true
```
#### 4.2 Integration Netdata (NOUVEAU)
Creer un collecteur Netdata personnalise pour nDPId:
**Collecteur** (`/usr/lib/netdata/plugins.d/ndpid.chart.sh`):
```bash
#!/bin/bash
# Collecteur Netdata pour nDPId
NDPID_STATUS="/var/run/netifyd/status.json"
# Definitions des graphiques
cat << EOF
CHART ndpid.flows '' "Flux Reseau" "flux" ndpid ndpid.flows area
DIMENSION active '' absolute 1 1
DIMENSION total '' absolute 1 1
EOF
while true; do
if [ -f "$NDPID_STATUS" ]; then
active=$(jq -r '.flows_active // 0' "$NDPID_STATUS")
total=$(jq -r '.flow_count // 0' "$NDPID_STATUS")
echo "BEGIN ndpid.flows"
echo "SET active = $active"
echo "SET total = $total"
echo "END"
fi
sleep 1
done
```
### Phase 5: Migration du Systeme de Plugins
#### 5.1 Actions IPSet
Plugins Netifyd → processeur externe nDPId:
| Plugin Netifyd | Equivalent nDPId |
|----------------|------------------|
| `libnetify-plugin-ipset.so` | Script externe consommant les evenements de flux |
| `libnetify-plugin-nftables.so` | Actualiseur nftables externe |
**Script d'Action de Flux nDPId** (`/usr/bin/ndpid-flow-actions`):
```bash
#!/bin/bash
# Traiter les evenements nDPId et mettre a jour les ipsets
socat -u UNIX-RECV:/tmp/ndpid-actions.sock - | while read -r line; do
# Parser le prefixe de longueur 5 chiffres
json="${line:5}"
event=$(echo "$json" | jq -r '.flow_event_name')
app=$(echo "$json" | jq -r '.ndpi.proto' | tr '.' '\n' | tail -1 | tr '[:upper:]' '[:lower:]')
case "$event" in
detected)
case "$app" in
bittorrent)
src_ip=$(echo "$json" | jq -r '.src_ip')
ipset add secubox-bittorrent "$src_ip" timeout 900 2>/dev/null
;;
esac
;;
esac
done
```
---
## Phases d'Implementation
### Phase 1: Fondation (Semaine 1-2)
1. [ ] Creer le package `secubox-app-ndpid`
2. [ ] Build nDPId + nDPIsrvd pour OpenWrt
3. [ ] Tester la detection de flux de base
4. [ ] Creer le schema de configuration UCI
### Phase 2: Couche de Compatibilite (Semaine 3-4)
1. [ ] Developper le daemon de traduction `secubox-ndpid-compat`
2. [ ] Implementer la generation de status.json
3. [ ] Implementer l'agregation des evenements de flux
4. [ ] Tester avec le tableau de bord LuCI existant
### Phase 3: Mise a Jour du Backend RPCD (Semaine 5)
1. [ ] Mettre a jour les methodes RPCD pour utiliser les donnees nDPId
2. [ ] S'assurer que les 15 methodes de lecture fonctionnent
3. [ ] S'assurer que les 9 methodes d'ecriture fonctionnent
4. [ ] Tester la compatibilite de l'application LuCI
### Phase 4: Integration des Consommateurs (Semaine 6-7)
1. [ ] Creer le parseur/scenario CrowdSec
2. [ ] Creer le collecteur Netdata
3. [ ] Tester le flux de donnees de bout en bout
4. [ ] Documenter les nouvelles integrations
### Phase 5: Migration & Nettoyage (Semaine 8)
1. [ ] Creer un script de migration pour les utilisateurs existants
2. [ ] Mettre a jour la documentation
3. [ ] Supprimer le package Netifyd (optionnel, peut coexister)
4. [ ] Tests finaux et publication
---
## Structure des Fichiers Apres Migration
```
package/secubox/
├── secubox-app-ndpid/ # NOUVEAU: Package nDPId
│ ├── Makefile
│ ├── files/
│ │ ├── ndpid.config # Config UCI
│ │ ├── ndpid.init # Script init procd
│ │ └── ndpisrvd.init # init nDPIsrvd
│ └── patches/ # Patches OpenWrt si necessaire
├── secubox-ndpid-compat/ # NOUVEAU: Couche de compatibilite
│ ├── Makefile
│ └── files/
│ ├── ndpid-compat.lua # Daemon de traduction
│ ├── ndpid-flow-actions # Gestionnaire IPSet/nftables
│ └── ndpid-collector # Agregateur de stats
├── luci-app-secubox-netifyd/ # MODIFIE: Fonctionne avec les deux
│ └── root/usr/libexec/rpcd/
│ └── luci.secubox-netifyd # Mis a jour pour compat nDPId
└── secubox-app-netifyd/ # DEPRECIE: Garder en repli
```
---
## Mappage de Configuration
### Traduction Config UCI
**Netifyd** (`/etc/config/secubox-netifyd`):
```
config settings 'settings'
option enabled '1'
option socket_type 'unix'
config sink 'sink'
option enabled '1'
option type 'unix'
option unix_path '/tmp/netifyd-flows.json'
```
**nDPId** (`/etc/config/secubox-ndpid`):
```
config ndpid 'main'
option enabled '1'
option interfaces 'br-lan br-wan'
option collector_socket '/tmp/ndpid-collector.sock'
config ndpisrvd 'distributor'
option enabled '1'
option listen_socket '/tmp/ndpisrvd.sock'
option tcp_port '7000'
config compat 'compat'
option enabled '1'
option netifyd_status '/var/run/netifyd/status.json'
option netifyd_socket '/var/run/netifyd/netifyd.sock'
```
---
## Evaluation des Risques
| Risque | Impact | Attenuation |
|--------|--------|-------------|
| Differences de precision de detection | Moyen | Les deux utilisent libnDPI; resultats similaires attendus |
| Regression de performance | Faible | nDPId est plus leger; devrait ameliorer les performances |
| Compatibilite des plugins | Eleve | Doit reimplementer les actions de flux en externe |
| Casse des tableaux de bord existants | Eleve | La couche de compatibilite assure le meme format de sortie |
| Fonctionnalites Netifyd manquantes | Moyen | Documenter les ecarts de fonctionnalites; prioriser les critiques |
### Comparaison des Fonctionnalites
| Fonctionnalite | Netifyd | nDPId | Impact Migration |
|----------------|---------|-------|------------------|
| Detection de protocole | Oui | Oui | Aucun |
| Detection d'application | Oui | Oui | Aucun |
| Suivi de flux | Oui | Oui | Aucun |
| Sortie JSON | Oui | Oui | Traduction de format necessaire |
| Streaming socket | Oui | Oui | Format different |
| Integration cloud | Oui | Non | Fonctionnalite supprimee |
| Architecture plugin | Integree | Externe | Reimplementer |
| Empreinte memoire | ~50MB | ~15MB | Amelioration |
| Temps de demarrage | ~5s | ~1s | Amelioration |
---
## Plan de Tests
### Tests Unitaires
1. **Precision de Traduction**: Verifier que les evenements nDPId se mappent correctement au format Netifyd
2. **Agregation des Statistiques**: Verifier que les comptes de flux, octets, paquets correspondent
3. **Detection d'Application**: Comparer les resultats de detection entre les moteurs
### Tests d'Integration
1. **Tableau de Bord LuCI**: Toutes les vues s'affichent correctement
2. **Methodes RPCD**: Toutes les 24 methodes retournent les donnees attendues
3. **Actions IPSet**: La detection BitTorrent/streaming declenche les mises a jour ipset
4. **Parsing CrowdSec**: Les evenements de flux sont parses et les scenarios se declenchent
### Tests de Performance
1. **Debit**: Mesurer le max flux/seconde
2. **Memoire**: Comparer l'utilisation RAM sous charge
3. **CPU**: Comparer l'utilisation CPU pendant les pics de trafic
---
## Plan de Rollback
Si la migration echoue:
1. Arreter les services nDPId: `/etc/init.d/ndpid stop && /etc/init.d/ndpisrvd stop`
2. Demarrer Netifyd: `/etc/init.d/netifyd start`
3. La couche de compatibilite detecte automatiquement et bascule la source
4. Pas de perte de donnees; les deux peuvent coexister
---
## References
- [Depot GitHub nDPId](https://github.com/utoni/nDPId)
- [Bibliotheque nDPI](https://github.com/ntop/nDPI)
- [Documentation Netifyd](https://www.netify.ai/documentation/)
- [Acquisition CrowdSec](https://docs.crowdsec.net/docs/data_sources/intro)
- [Plugins Externes Netdata](https://learn.netdata.cloud/docs/agent/collectors/plugins.d)
---
## Annexe A: Reference du Schema d'Evenements nDPId
### Champs d'Evenement de Flux
```json
{
"flow_event_id": "entier (0-8)",
"flow_event_name": "chaine (new|end|idle|update|detected|guessed|detection-update|not-detected|analyse)",
"thread_id": "entier",
"packet_id": "entier",
"source": "chaine (nom d'interface)",
"flow_id": "entier",
"flow_state": "chaine (skipped|finished|info)",
"l3_proto": "chaine (ip4|ip6)",
"src_ip": "chaine",
"dst_ip": "chaine",
"l4_proto": "chaine (tcp|udp|icmp|...)",
"src_port": "entier",
"dst_port": "entier",
"flow_src_packets_processed": "entier",
"flow_dst_packets_processed": "entier",
"flow_first_seen": "entier (timestamp ms)",
"flow_src_tot_l4_payload_len": "entier (octets)",
"flow_dst_tot_l4_payload_len": "entier (octets)",
"ndpi": {
"proto": "chaine (ex: TLS.Google)",
"proto_id": "entier",
"encrypted": "entier (0|1)",
"breed": "chaine (Safe|Acceptable|Fun|Unsafe|...)",
"category_id": "entier",
"category": "chaine"
}
}
```
### Champs d'Evenement Etat Daemon
```json
{
"daemon_event_id": 3,
"daemon_event_name": "status",
"global_ts_usec": "entier",
"uptime": "entier (secondes)",
"packets": "entier",
"packet_bytes": "entier",
"flows_active": "entier",
"flows_idle": "entier",
"flows_detected": "entier",
"compressions": "entier",
"decompressions": "entier"
}
```
---
## Annexe B: Code Exemple de Couche de Compatibilite
```lua
#!/usr/bin/env lua
-- secubox-ndpid-compat: Traducteur de format nDPId vers Netifyd
local socket = require("socket")
local json = require("cjson")
local NDPISRVD_SOCK = "/tmp/ndpisrvd.sock"
local OUTPUT_STATUS = "/var/run/netifyd/status.json"
local UPDATE_INTERVAL = 1
-- Suivi d'etat
local state = {
flows = {},
flow_count = 0,
flows_active = 0,
stats = {},
devices = {},
uptime = 0,
start_time = os.time()
}
-- Traiter l'evenement nDPId entrant
local function process_event(raw)
-- Supprimer le prefixe de longueur 5 chiffres
local json_str = raw:sub(6)
local ok, event = pcall(json.decode, json_str)
if not ok then return end
local event_name = event.flow_event_name or event.daemon_event_name
if event_name == "new" then
state.flows[event.flow_id] = event
state.flow_count = state.flow_count + 1
state.flows_active = state.flows_active + 1
elseif event_name == "end" or event_name == "idle" then
state.flows[event.flow_id] = nil
state.flows_active = state.flows_active - 1
elseif event_name == "detected" then
if state.flows[event.flow_id] then
state.flows[event.flow_id].detected = event.ndpi
end
-- Mettre a jour les stats d'interface
local iface = event.source or "unknown"
if not state.stats[iface] then
state.stats[iface] = {ip_bytes=0, tcp=0, udp=0, icmp=0}
end
local proto = event.l4_proto or ""
if proto == "tcp" then state.stats[iface].tcp = state.stats[iface].tcp + 1 end
if proto == "udp" then state.stats[iface].udp = state.stats[iface].udp + 1 end
if proto == "icmp" then state.stats[iface].icmp = state.stats[iface].icmp + 1 end
local bytes = (event.flow_src_tot_l4_payload_len or 0) + (event.flow_dst_tot_l4_payload_len or 0)
state.stats[iface].ip_bytes = state.stats[iface].ip_bytes + bytes
elseif event_name == "status" then
state.uptime = event.uptime or (os.time() - state.start_time)
end
end
-- Generer status.json compatible Netifyd
local function generate_status()
return json.encode({
flow_count = state.flow_count,
flows_active = state.flows_active,
stats = state.stats,
devices = state.devices,
uptime = state.uptime,
dns_hint_cache = { cache_size = 0 }
})
end
-- Boucle principale
local function main()
-- Creer le repertoire de sortie
os.execute("mkdir -p /var/run/netifyd")
local sock = socket.unix()
local ok, err = sock:connect(NDPISRVD_SOCK)
if not ok then
print("Echec de connexion a nDPIsrvd: " .. (err or "inconnu"))
os.exit(1)
end
sock:settimeout(0.1)
local last_write = 0
while true do
local line, err = sock:receive("*l")
if line then
process_event(line)
end
-- Ecrire le fichier status periodiquement
local now = os.time()
if now - last_write >= UPDATE_INTERVAL then
local f = io.open(OUTPUT_STATUS, "w")
if f then
f:write(generate_status())
f:close()
end
last_write = now
end
end
end
main()
```
---
*Version du Document: 1.0*
*Cree: 2026-01-09*
*Auteur: Assistant Claude Code*