235 lines
6.5 KiB
Markdown
235 lines
6.5 KiB
Markdown
# 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
|
|
|
|
```bash
|
|
# 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
|
|
```bash
|
|
CLAMAV_ENABLED=true
|
|
CLAMAV_ADDRESS=localhost:3310
|
|
```
|
|
|
|
#### Production avec ClamAV distant
|
|
```bash
|
|
CLAMAV_ENABLED=true
|
|
CLAMAV_ADDRESS=clamav.internal:3310
|
|
```
|
|
|
|
#### Désactiver ClamAV (non recommandé en production)
|
|
```bash
|
|
CLAMAV_ENABLED=false
|
|
```
|
|
|
|
---
|
|
|
|
## Installation et démarrage de ClamAV
|
|
|
|
### Linux (Ubuntu/Debian)
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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)
|
|
|
|
```bash
|
|
# 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)
|
|
|
|
```bash
|
|
# 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.
|
|
|
|
```bash
|
|
# 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 :
|
|
|
|
```bash
|
|
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
|
|
|
|
1. **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)
|
|
|
|
2. **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
|
|
|
|
3. **Validateur** (`internal/services/upload_validator.go:124-222`):
|
|
- `ValidateFile()` fait le scan ClamAV **avant** de retourner `result.Valid = true`
|
|
- Si le scan détecte un virus, `result.Valid = false` et 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** :
|
|
1. ClamAV n'est pas démarré : `sudo systemctl status clamav-daemon`
|
|
2. Mauvaise adresse : Vérifier `CLAMAV_ADDRESS`
|
|
3. Firewall bloque le port 3310
|
|
|
|
**Solution** :
|
|
```bash
|
|
# 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** :
|
|
1. Vérifier que ClamAV est démarré
|
|
2. Vérifier la variable `CLAMAV_ADDRESS` si ClamAV est sur une autre machine
|
|
3. Vérifier les logs : `sudo journalctl -u clamav-daemon -f`
|
|
|
|
---
|
|
|
|
## Références
|
|
|
|
- [ClamAV Documentation](https://docs.clamav.net/)
|
|
- [go-clamd Library](https://github.com/dutchcoders/go-clamd)
|
|
- [EICAR Test File](https://en.wikipedia.org/wiki/EICAR_test_file)
|