Files
formation-manager-itinova/server/fail2banAlertService.ts

178 lines
6.4 KiB
TypeScript

import { countRecentBans } from './fail2banDb';
import { sendEmail } from './_core/emailSender';
import { ENV } from './_core/env';
// Seuil de déclenchement de l'alerte (nombre d'IPs bannies par heure)
const ALERT_THRESHOLD = 10;
// Intervalle de vérification (en millisecondes) - toutes les 15 minutes
const CHECK_INTERVAL = 15 * 60 * 1000;
// Dernière alerte envoyée (timestamp)
let lastAlertTime = 0;
// Délai minimum entre deux alertes (1 heure)
const MIN_ALERT_INTERVAL = 60 * 60 * 1000;
/**
* Vérifie s'il y a une attaque massive et envoie une alerte email si nécessaire
*/
async function checkAndSendAlert() {
try {
const recentBans = await countRecentBans(1); // Dernière heure
console.log(`[Fail2Ban Alert] ${recentBans} bannissements dans la dernière heure`);
// Vérifier si le seuil est atteint
if (recentBans >= ALERT_THRESHOLD) {
const now = Date.now();
// Vérifier si on n'a pas déjà envoyé une alerte récemment
if (now - lastAlertTime >= MIN_ALERT_INTERVAL) {
console.log(`[Fail2Ban Alert] Seuil atteint (${recentBans} >= ${ALERT_THRESHOLD}), envoi de l'alerte...`);
await sendAlertEmail(recentBans);
lastAlertTime = now;
console.log('[Fail2Ban Alert] Alerte envoyée avec succès');
} else {
console.log('[Fail2Ban Alert] Alerte déjà envoyée récemment, pas de nouvel envoi');
}
}
} catch (error) {
console.error('[Fail2Ban Alert] Erreur lors de la vérification:', error);
}
}
/**
* Envoie un email d'alerte pour une attaque massive
*/
async function sendAlertEmail(banCount: number) {
const ownerEmail = ENV.ownerName; // Utiliser l'email du propriétaire
if (!ownerEmail || !ownerEmail.includes('@')) {
console.error('[Fail2Ban Alert] Email du propriétaire non configuré');
return;
}
const subject = `🚨 Alerte Sécurité: Attaque SSH massive détectée`;
const htmlContent = `
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
.container { max-width: 600px; margin: 0 auto; padding: 20px; }
.header { background-color: #dc2626; color: white; padding: 20px; border-radius: 8px 8px 0 0; }
.content { background-color: #f9fafb; padding: 30px; border-radius: 0 0 8px 8px; }
.alert-box { background-color: #fee2e2; border-left: 4px solid #dc2626; padding: 15px; margin: 20px 0; }
.stats { background-color: white; padding: 15px; border-radius: 8px; margin: 20px 0; }
.stat-item { display: flex; justify-content: space-between; padding: 10px 0; border-bottom: 1px solid #e5e7eb; }
.stat-value { font-weight: bold; color: #dc2626; }
.footer { text-align: center; color: #6b7280; font-size: 12px; margin-top: 20px; }
.button { display: inline-block; background-color: #2563eb; color: white; padding: 12px 24px; text-decoration: none; border-radius: 6px; margin-top: 20px; }
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1 style="margin: 0;">🚨 Alerte Sécurité SSH</h1>
<p style="margin: 5px 0 0 0;">Attaque massive détectée sur votre serveur</p>
</div>
<div class="content">
<div class="alert-box">
<strong>⚠️ Attention !</strong><br>
Une activité suspecte importante a été détectée sur votre serveur SSH.
</div>
<div class="stats">
<h3 style="margin-top: 0;">Statistiques de l'attaque</h3>
<div class="stat-item">
<span>IPs bannies (dernière heure)</span>
<span class="stat-value">${banCount}</span>
</div>
<div class="stat-item">
<span>Seuil d'alerte</span>
<span class="stat-value">${ALERT_THRESHOLD}</span>
</div>
<div class="stat-item">
<span>Date de détection</span>
<span class="stat-value">${new Date().toLocaleString('fr-FR')}</span>
</div>
</div>
<h3>Actions recommandées</h3>
<ul>
<li>Vérifiez le tableau de bord Fail2Ban pour plus de détails</li>
<li>Examinez les logs SSH pour identifier les patterns d'attaque</li>
<li>Envisagez de renforcer temporairement les règles Fail2Ban</li>
<li>Vérifiez que vos mots de passe sont robustes</li>
</ul>
<p style="text-align: center;">
<a href="https://votre-domaine.com/admin/fail2ban" class="button">
Voir le tableau de bord Fail2Ban
</a>
</p>
<p style="color: #6b7280; font-size: 14px; margin-top: 30px;">
<strong>Note:</strong> Cette alerte est automatiquement déclenchée lorsque plus de ${ALERT_THRESHOLD} IPs sont bannies en moins d'une heure.
Fail2Ban continue de protéger votre serveur en bannissant automatiquement les adresses IP suspectes.
</p>
</div>
<div class="footer">
<p>Cet email a été envoyé automatiquement par le système de monitoring Fail2Ban</p>
<p>Gestion des Formations Manager Itinova</p>
</div>
</div>
</body>
</html>
`;
const textContent = `
🚨 ALERTE SÉCURITÉ SSH
Une attaque massive a été détectée sur votre serveur.
STATISTIQUES:
- IPs bannies (dernière heure): ${banCount}
- Seuil d'alerte: ${ALERT_THRESHOLD}
- Date de détection: ${new Date().toLocaleString('fr-FR')}
ACTIONS RECOMMANDÉES:
1. Vérifiez le tableau de bord Fail2Ban
2. Examinez les logs SSH
3. Renforcez les règles Fail2Ban si nécessaire
4. Vérifiez la robustesse de vos mots de passe
Fail2Ban continue de protéger votre serveur automatiquement.
---
Gestion des Formations Manager Itinova
`;
await sendEmail({
to: ownerEmail,
subject,
html: htmlContent,
text: textContent,
});
}
/**
* Initialise le système d'alertes Fail2Ban
*/
export function initFail2BanAlertSystem() {
console.log('[Fail2Ban Alert] Initialisation du système d\'alertes');
console.log(`[Fail2Ban Alert] Seuil: ${ALERT_THRESHOLD} IPs/heure, Vérification toutes les ${CHECK_INTERVAL / 60000} minutes`);
// Première vérification immédiate
checkAndSendAlert();
// Vérifications périodiques
setInterval(checkAndSendAlert, CHECK_INTERVAL);
console.log('[Fail2Ban Alert] Système d\'alertes initialisé');
}