6.5 KiB
ClamAV Configuration — Veza Backend API
Vue d'ensemble
Le backend Veza API intègre ClamAV pour scanner tous les fichiers uploadés avant toute persistance (base de données, système de fichiers, ou stockage S3). Cette fonctionnalité garantit qu'aucun malware ne peut être stocké sur le serveur.
MOD-P1-001: Le scan ClamAV est maintenant obligatoire et se fait AVANT toute persistance. Si ClamAV est indisponible, tous les uploads sont rejetés (fail-secure).
Variables d'environnement
Configuration ClamAV
# Activer/désactiver ClamAV (par défaut: true)
CLAMAV_ENABLED=true
# Adresse du daemon ClamAV (par défaut: localhost:3310)
# Format: host:port (ex: localhost:3310, 192.168.1.100:3310)
CLAMAV_ADDRESS=localhost:3310
Exemples de configuration
Développement local
CLAMAV_ENABLED=true
CLAMAV_ADDRESS=localhost:3310
Production avec ClamAV distant
CLAMAV_ENABLED=true
CLAMAV_ADDRESS=clamav.internal:3310
Désactiver ClamAV (non recommandé en production)
CLAMAV_ENABLED=false
Installation et démarrage de ClamAV
Linux (Ubuntu/Debian)
# Installer ClamAV
sudo apt-get update
sudo apt-get install clamav clamav-daemon
# Démarrer le daemon
sudo systemctl start clamav-daemon
sudo systemctl enable clamav-daemon
# Mettre à jour les signatures de virus
sudo freshclam
Docker
# Lancer ClamAV dans un conteneur Docker
docker run -d --name clamav \
-p 3310:3310 \
-v /var/lib/clamav:/var/lib/clamav \
clamav/clamav:latest
macOS (Homebrew)
# Installer ClamAV
brew install clamav
# Démarrer le daemon
brew services start clamav
Comportement fail-secure
Si ClamAV est activé mais indisponible
- ✅ Le serveur démarre (pas de blocage au démarrage)
- ❌ Tous les uploads sont rejetés avec HTTP 503 (Service Unavailable)
- 📝 Message d'erreur clair : "Virus scanning service is temporarily unavailable"
Si un virus est détecté
- ❌ L'upload est rejeté avec HTTP 422 (Unprocessable Entity)
- 📝 Message d'erreur : "File rejected: virus detected"
- 🔒 Le fichier n'est JAMAIS persistant (ni DB, ni FS, ni S3)
Si le scan échoue (timeout, erreur de connexion)
- ❌ L'upload est rejeté avec HTTP 503 (Service Unavailable)
- 📝 Message d'erreur : "Virus scan failed"
- 🔒 Fail-secure : en cas de doute, on rejette
Tests
Tests unitaires (sans ClamAV requis)
# Exécuter tous les tests unitaires
go test ./internal/services -run TestUploadValidator -v
# Tests spécifiques
go test ./internal/services -run TestUploadValidator_ClamAVDown_RejectsUploads -v
go test ./internal/services -run TestUploadValidator_ClamAVDisabled_AllowsUploads -v
Tests d'intégration (ClamAV requis)
Les tests d'intégration nécessitent ClamAV en cours d'exécution et utilisent un build tag.
# 1. Démarrer ClamAV (voir section Installation)
# 2. Exécuter les tests d'intégration avec le tag 'clamav'
go test -tags=clamav ./internal/services -run TestUploadValidator_ClamAV -v
# 3. Test spécifique avec fichier EICAR (test virus standard)
go test -tags=clamav ./internal/services -run TestUploadValidator_ClamAV_EICAR_Rejected -v
# 4. Test avec fichier propre
go test -tags=clamav ./internal/services -run TestUploadValidator_ClamAV_CleanFile_Accepted -v
Configuration pour les tests d'intégration
Par défaut, les tests utilisent localhost:3310. Pour utiliser une autre adresse :
export CLAMAV_ADDRESS=192.168.1.100:3310
go test -tags=clamav ./internal/services -run TestUploadValidator_ClamAV -v
Vérification que le scan se fait AVANT la persistance
Preuve dans le code
-
Handler (
internal/core/track/handler.go:117-160):- Le scan ClamAV est appelé AVANT
trackService.UploadTrack() - Si le scan échoue, la fonction retourne immédiatement (pas d'appel au service)
- Le scan ClamAV est appelé AVANT
-
Service (
internal/core/track/service.go:145-216):UploadTrack()sauvegarde le fichier (ligne 182) et crée l'enregistrement DB (ligne 213)- Ces opérations ne sont jamais appelées si le scan échoue dans le handler
-
Validateur (
internal/services/upload_validator.go:124-222):ValidateFile()fait le scan ClamAV avant de retournerresult.Valid = true- Si le scan détecte un virus,
result.Valid = falseet une erreur est retournée
Ordre d'exécution garanti
1. Handler reçoit le fichier uploadé
2. Handler appelle ValidateFile() avec context
3. ValidateFile() fait le scan ClamAV (timeout 30s)
4. Si scan OK → ValidateFile() retourne result.Valid = true
5. Si scan OK → Handler appelle trackService.UploadTrack()
6. UploadTrack() sauvegarde le fichier et crée l'enregistrement DB
Si le scan échoue à l'étape 3, les étapes 5-6 ne sont JAMAIS exécutées.
Timeouts et limites
- Timeout de scan : 30 secondes maximum
- Gestion du contexte : Utilise
context.WithTimeout()pour éviter les blocages - Logs structurés : Tous les scans sont loggés avec
zap.Logger
Codes HTTP retournés
| Situation | Code HTTP | Message |
|---|---|---|
| ClamAV indisponible (enabled mais down) | 503 | "Virus scanning service is temporarily unavailable" |
| Virus détecté | 422 | "File rejected: virus detected" |
| Erreur de scan (timeout, connexion) | 503 | "Virus scan failed" |
| Fichier propre | 201 | Upload réussi |
Dépannage
Le serveur démarre mais les uploads sont rejetés
Symptôme : HTTP 503 avec message "Virus scanning service is temporarily unavailable"
Causes possibles :
- ClamAV n'est pas démarré :
sudo systemctl status clamav-daemon - Mauvaise adresse : Vérifier
CLAMAV_ADDRESS - Firewall bloque le port 3310
Solution :
# Vérifier que ClamAV écoute
sudo netstat -tlnp | grep 3310
# Tester la connexion
telnet localhost 3310
# Redémarrer ClamAV
sudo systemctl restart clamav-daemon
Les tests d'intégration échouent
Symptôme : go test -tags=clamav échoue avec erreur de connexion
Solution :
- Vérifier que ClamAV est démarré
- Vérifier la variable
CLAMAV_ADDRESSsi ClamAV est sur une autre machine - Vérifier les logs :
sudo journalctl -u clamav-daemon -f