Guide gratuit SSem SecuMon
À partir d’un seul serveur personnel · à jour en octobre 2026
BientôtLa distribution des fichiers d’installation est en préparation.
Ce guide présente dès maintenant les prérequis, les étapes d’installation et ce qu’il faut savoir pour l’exploitation. L’adresse de téléchargement sera indiquée ici dès l’ouverture de la distribution.
1. Prérequis
| Élément | Exigence |
|---|---|
| Serveurs à protéger | Linux (systemd) + fail2ban · nftables · sqlite3. amd64 ou arm64. Testé sur Ubuntu 22.04 · CentOS 8. |
| Serveur de console | Un seul. JDK 21 · Tomcat 11 · PostgreSQL 17. Le plus simple est de passer par Docker. |
| Réseau | Les serveurs doivent pouvoir joindre l’adresse de la console en HTTPS. Aucun port entrant n’est nécessaire sur les serveurs. Il est recommandé de placer la console derrière un VPN ou sur un réseau interne. |
| Horloge | Synchronisez par NTP l’horloge de tous les serveurs et de la console. Si l’horodatage d’une signature s’écarte de plus de 60 secondes, la requête est rejetée. |
| Certificat | Un certificat HTTPS pour la console (par ex. Let's Encrypt). Le cookie de connexion n’étant envoyé qu’en HTTPS, il est impossible de se connecter en HTTP non chiffré. |
Installez d’abord les paquets sur chaque serveur à protéger.
# Debian · Ubuntu apt-get update && apt-get install -y fail2ban nftables sqlite3 # RHEL · Rocky · CentOS dnf install -y epel-release && dnf install -y fail2ban nftables sqlite systemctl enable --now fail2ban
2. Activer le bannissement exponentiel de fail2ban
Configurez fail2ban pour qu’une IP soit bloquée d’autant plus longtemps qu’elle revient. SecuMon s’appuie sur ces multiplicateurs pour calculer « le niveau actuel » et « la durée du prochain blocage ».
# /etc/fail2ban/jail.local [DEFAULT] bantime = 1h findtime = 10m maxretry = 5 bantime.increment = true bantime.multipliers = 1 2 4 8 16 32 64 168 bantime.maxtime = 168h ignoreip = 127.0.0.1/8 ::1 <plage de votre VPN> # /etc/fail2ban/fail2ban.local — conserver l'historique des récidives 60 jours (avec 1 jour par défaut, une IP repart de zéro dès le lendemain) [DEFINITION] dbpurgeage = 60d
Avec cette configuration, les durées de bannissement sont les suivantes. fail2ban ajoutant un peu de temps aléatoire, les valeurs réelles varient légèrement.
| Bannissements cumulés | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 ou plus |
|---|---|---|---|---|---|---|---|---|
| Durée du bannissement | 1 h | 2 h | 4 h | 8 h | 16 h | 32 h | 64 h | 7 jours |
Ajoutez impérativement vos propres voies d’accès (plage VPN, etc.) à ignoreip. Vous éviterez ainsi d’être banni de votre propre serveur pour quelques erreurs de mot de passe.
3. Installer la console
3-1. Fichiers secrets
Les valeurs secrètes ne sont écrites ni dans le code ni dans des variables d’environnement : elles sont rangées sous forme de fichiers dans un seul dossier. Le conteneur de la console monte ce dossier en lecture seule sur /App/secrets.
mkdir -p /srv/secumon/secrets/tls && chmod 700 /srv/secumon cd /srv/secumon/secrets openssl rand -hex 24 > db_password openssl rand -base64 18 > admin_password # Mot de passe de première connexion (compte admin) openssl genpkey -algorithm ed25519 -out console_ed25519.key openssl pkey -in console_ed25519.key -pubout -out console_ed25519.key.pub # Fichiers en 644 pour que le compte du conteneur puisse les lire — la protection repose sur le dossier parent en 700 chmod 644 db_password admin_password console_ed25519.key console_ed25519.key.pub
| Fichier | Usage | S’il manque |
|---|---|---|
db_password | Connexion à la base de données | La console ne démarre pas |
admin_password | Mot de passe du premier compte administrateur admin | Le compte n’est pas créé : impossible de se connecter |
console_ed25519.key · .pub | Signature des commandes | Consultation seule, aucune exécution possible |
abuseipdb.key | Clé d’API AbuseIPDB (facultatif) | Signalement · consultation de réputation indisponibles |
telegram.env | Notifications Telegram (facultatif) | Aucune notification n’est envoyée |
tls/cert.pem · chain.pem · privkey.pem | Certificat HTTPS de la console | Pas d’accès en HTTPS |
Le seul fichier console_ed25519.key suffit à signer des commandes valides pour tous vos serveurs. Ne le placez ni dans un dépôt ni sur un lecteur partagé : conservez-le à part.
3-2. Base de données
Le port de la base n’est pas exposé à l’extérieur. La console s’y connecte par le nom du conteneur, au sein du même réseau Docker.
docker network create secumon-net docker run -d --name secumon-db --network secumon-net --restart unless-stopped \ -e POSTGRES_DB=secumon -e POSTGRES_USER=secumon \ -e POSTGRES_PASSWORD_FILE=/run/secrets/db_password \ -v /srv/secumon/secrets/db_password:/run/secrets/db_password:ro \ -v secumon_pgdata:/var/lib/postgresql/data \ postgres:17
Les tables et les données initiales sont créées par la console elle-même à son premier démarrage. Inutile de charger le schéma séparément avec psql.
3-3. Configuration de la console
La console est une application web qui tourne sur Tomcat 11. Sa procédure de lancement sera publiée avec le paquet de distribution ; voici d’abord les variables d’environnement à définir.
| Variable d’environnement | Valeur par défaut | Signification |
|---|---|---|
F2B_DB_URL | jdbc:postgresql://…:5432/secumon | Adresse de la base. Indiquez-la par le nom du conteneur. |
F2B_CANONICAL_HOST | À définir obligatoirement | Le domaine de votre console. Les accès en HTTP non chiffré ou par une autre adresse sont redirigés vers cette adresse en HTTPS. |
F2B_PROTECTED_CIDRS | À définir obligatoirement | Plages à ne jamais bloquer — votre VPN · réseau interne · IP publiques des serveurs. Les réseaux privés et la boucle locale sont toujours protégés, quelle que soit cette valeur. |
F2B_BLOCK_TTL_DAYS | 30 | Durée par défaut d’un blocage de plage (jours). 0 = permanent. |
F2B_AUTO_BLOCK_ENABLED | true | Active ou désactive le blocage automatique des IP récidivistes. |
F2B_AUTO_BLOCK_THRESHOLD | 3 | Nombre de bannissements à partir duquel le blocage automatique s’applique. |
F2B_AUTO_BLOCK_TTL_DAYS | 30 | Durée du blocage automatique (jours). |
F2B_FEED_REFRESH_HOURS | 24 | Intervalle de re-téléchargement des listes de blocage publiques et des listes de pays (heures). |
F2B_BAN_MULTIPLIERS | 1 2 4 8 16 32 64 168 | Doit correspondre exactement aux multiplicateurs de la configuration des jails. |
F2B_ABUSE_DAILY_LIMIT | 1000 | Quota quotidien d’utilisation d’AbuseIPDB. |
Après le démarrage, vérifiez l’état. Si "db":"ok" s’affiche, tout est en ordre.
curl -s https://<adresse de la console>/api/health
4. Enregistrer un serveur — agent
- Connectez-vous à la console en tant que
admin, saisissez le nom du serveur dans l’onglet Cibles, puis cliquez sur Enregistrer + émettre un jeton. - L’ID de la cible et un jeton à usage unique s’affichent. Le jeton n’est visible qu’à ce moment-là et expire au bout de 15 minutes.
- Sur le serveur à protéger, exécutez le script d’installation en root.
# Sur le serveur à protéger (root) tar xzf agent-amd64.tgz && cd agent ./install-agent.sh --console https://<adresse de la console> \ --target-id <ID de la cible> --token <jeton à usage unique> journalctl -u secumon-agent -f # OK si une ligne comme ci-dessous apparaît sous 30 s
Si tout va bien, une ligne comme celle-ci s’affiche secumon-agent: 2026/10/06 16:40:12 전송 완료 — jail 2개, 밴 5건
Le script d’installation ne fait rien d’autre que ce qui suit. Il n’ouvre aucun port du pare-feu.
- Il crée un compte dédié, sans connexion possible :
f2bagent— l’agent ne tourne pas en root. - Il n’autorise via sudo qu’un seul wrapper à privilèges root :
/usr/local/sbin/f2b-agent-exec. - Il génère la clé de signature de l’agent sur le serveur lui-même. La clé privée ne transite jamais par le réseau.
- Après l’enregistrement auprès de la console, il fait tourner l’agent en permanence via le service
secumon-agent.
N’utilisez pas, dans l’adresse de la console, de nom d’hôte contenant un tiret bas (_). Tomcat 11 le rejette comme non conforme. Vérifiez d’abord que le serveur parvient à résoudre le domaine de la console avec getent hosts <domaine de la console>.
Si l’enregistrement a réussi mais qu’une étape suivante a échoué, corrigez la cause puis relancez exactement la même commande. Un agent déjà enregistré ne réutilise pas le jeton.
Pour retirer un serveur, utilisez Désactiver dans la console (les requêtes de cet agent sont aussitôt refusées), puis exécutez systemctl disable --now secumon-agent sur le serveur.
5. Lire l’interface
- Tableau de bord — bannissements en cours · bannissements cumulés · IP récidivistes · évolution de tous les serveurs. Si la « dernière réception » d’une carte serveur dépasse nettement 30 secondes, vérifiez l’agent de ce serveur.
- IP bannies — les IP bloquées en ce moment, avec leur niveau de récidive · temps restant · pays. Le pays est déterminé grâce à la table de correspondance intégrée à la console.
- Détail de l’IP — les serveurs où cette IP est bannie, son historique de bannissements, la durée prévue du prochain bannissement, sa réputation AbuseIPDB.
Les « bannissements en cours » sont lus dans la liste de ce que fail2ban bloque réellement à l’instant, et le « nombre de récidives » dans l’historique des bannissements de fail2ban, séparément. Ainsi, un bannissement déjà levé n’apparaît jamais à tort comme en cours.
6. Bannir · débannir · bloquer une plage
- Bannir · débannir est possible à partir du rôle opérateur. On peut bannir n’importe quelle IP ; si aucune jail n’est choisie, c’est
sshdqui s’applique. - Le blocage de plage est réservé aux administrateurs. Il ne s’exécute qu’après ressaisie de la plage, et toute plage plus large que /16 en IPv4 · /48 en IPv6 est refusée. Par défaut, le blocage se lève de lui-même au bout de 30 jours.
- Vous pouvez viser plusieurs plages × plusieurs serveurs en une seule fois. Aucune commande n’est émise tant que toutes n’ont pas passé les contrôles — un blocage appliqué à moitié est la situation la plus dangereuse.
- Une commande n’est exécutée que si l’agent du serveur la récupère dans les 60 secondes. Le résultat (terminé · échoué · expiré) se consulte dans l’historique des commandes de l’onglet Exécution.
En cas de blocage par erreur, levez-le dans la console via Exécution → Débloquer. Si l’urgence est telle que vous ne pouvez même plus accéder à la console, supprimez-le directement sur le serveur.
# Une seule plage nft delete element inet f2b_console blocklist4 '{ 203.0.113.0/24 }' # Tous les blocages ajoutés par SecuMon (les règles fail2ban, dans une autre table, restent intactes) nft delete table inet f2b_console
7. Bloquer automatiquement
Blocage automatique des IP récidivistes
Toutes les 5 minutes, les IP bannies au moins 3 fois au total sont sélectionnées et bloquées 30 jours sur tous les serveurs. C’est la seule fonction qui modifie le pare-feu sans validation humaine ; elle est donc encadrée par plusieurs garde-fous.
- Seules des IP individuelles (
/32·/128) sont bloquées, jamais des plages. - Les plages protégées sont ignorées. 20 blocages au maximum sont émis à la fois.
- Une même IP n’est jamais escaladée deux fois, et tout est consigné dans le journal d’audit et notifié sur Telegram.
Pour désactiver la fonction, définissez F2B_AUTO_BLOCK_ENABLED=false pour la console puis redémarrez-la. Pour une IP bloquée à tort, levez d’abord le blocage via Débloquer, puis supprimez son enregistrement d’escalade afin qu’elle puisse être réévaluée plus tard.
docker exec secumon-db psql -U secumon -d secumon -c "DELETE FROM auto_block WHERE ip = '<IP>'"
Listes de blocage publiques
Activez-les dans l’onglet Flux de blocage. Au départ, les deux sont désactivées.
- Spamhaus DROP — plages détournées ou utilisées exclusivement à des fins criminelles. Aucun trafic légitime ne peut en provenir : le risque de faux positif est quasi nul.
- FireHOL level1 — adresses inutilisées et plages malveillantes avérées. Elle contient aussi des réseaux privés : la console écarte donc les entrées qui chevauchent les plages protégées avant l’envoi.
Les listes sont re-téléchargées une fois par jour ; si leur contenu n’a pas changé, rien n’est renvoyé aux serveurs. Les plages retirées d’une liste sont débloquées automatiquement à la mise à jour suivante.
8. Blocage par pays — avant d’activer
Les services qui doivent rester joignables du monde entier ne peuvent pas être bloqués par pays.
- Serveur DNS faisant autorité — votre domaine ne se résout que si les résolveurs du monde entier peuvent l’atteindre. SecuMon autorise toujours le port 53.
- Réception de courrier (25) · VPN — les bloquer coupe le courrier, et vous ne pouvez plus accéder à votre propre serveur depuis l’étranger. N’activez pas le blocage par pays sur ce type de serveur.
- Robots des moteurs de recherche — bloquer un grand pays bloque aussi les robots d’indexation, et votre site peut disparaître des résultats de recherche.
Dans l’onglet Blocage par pays, le nombre de plages d’un pays s’affiche dès que vous le sélectionnez. À l’application, la liste est téléchargée sur-le-champ et déployée sur tous les serveurs en moins de 30 secondes ; à la désactivation, la liste de ce pays est supprimée. Un grand pays peut compter des dizaines de milliers de plages.
Même pour un pays d’où viennent beaucoup d’attaques, il s’agit souvent en réalité de quelques plages ou de serveurs loués. Bloquez-les, et les attaques repartent depuis des serveurs d’un autre pays. Considérez le blocage par pays comme un complément à utiliser avec les listes de blocage publiques et le blocage automatique des récidivistes.
SecuMon autorise, tout en tête des règles du pare-feu, les réponses aux connexions déjà établies. Sans cette règle, même les réponses aux connexions que votre serveur ouvre vers les services de ce pays (miroirs de paquets · API de notification · émission de certificats) seraient bloquées.
9. AbuseIPDB · Telegram
AbuseIPDB
Placez abuseipdb.key dans le dossier des secrets pour activer la fonction. La clé reste sur le serveur de la console et n’est jamais transmise, ni à l’interface, ni à la base, ni aux serveurs.
- Seules les IP actuellement bannies ou bannies au cours des 30 derniers jours peuvent être signalées — impossible de signaler une IP arbitraire.
- Une même IP n’est pas signalée deux fois en 15 minutes. La console décompte elle-même le quota quotidien.
- La catégorie dépend du nom de la jail — ssh → 18 · 22, web (apache · nginx) → 18 · 21, courrier → 18 · 11, autres → 18.
Telegram
# /srv/secumon/secrets/telegram.env
TELEGRAM_TOKEN=<jeton du bot>
TELEGRAM_CHAT_ID=<ID du chat>
Les blocages automatiques de récidivistes et les changements des listes publiques sont notifiés, la liste complète étant jointe en fichier. Rien n’est envoyé si rien n’a changé — recevoir chaque jour « aucun changement » finit par faire manquer les alertes vraiment importantes.
10. Comptes · authentification à deux facteurs
| Rôle | Autorisations |
|---|---|
VIEWER lecture seule | Consultation : tableau de bord · IP bannies · détail de l’IP · historique des commandes |
OPERATOR opérateur | + bannir · débannir · signalement AbuseIPDB et consultation de réputation |
ADMIN administrateur | + blocage de plage · enregistrement de serveurs · flux de blocage · blocage par pays · utilisateurs · journal d’audit |
- Pour la première connexion, utilisez
adminet le mot de passe du fichieradmin_password. Une fois connecté, changez le mot de passe dans Mon compte. - Dans Mon compte → Authentification à deux facteurs, scannez le QR code avec une application d’authentification ou saisissez le code à la main. Un même code ne peut pas servir deux fois.
- Après 5 erreurs de mot de passe, le compte est verrouillé 15 minutes, et une même IP ne peut faire que 10 tentatives par minute. Au bout de 30 minutes d’inactivité, vous êtes déconnecté.
Si vous avez perdu votre application d’authentification, impossible de lever la double authentification depuis l’interface. Une personne ayant accès au serveur de la console doit la désactiver directement dans la base.
docker exec secumon-db psql -U secumon -d secumon -c \ "UPDATE app_user SET totp_enabled=false, totp_secret=NULL, totp_last_counter=0 WHERE username='admin';"
11. Sauvegarde · gestion des clés
# Base de données — les mots de passe y sont hachés, et les jetons d'enregistrement n'y figurent que sous forme de hachage docker exec secumon-db pg_dump -U secumon secumon | gzip > secumon-$(date +%F).sql.gz # Dossier des secrets — ce sont eux, les vrais secrets. À conserver ailleurs que la sauvegarde de la base tar czf secumon-secrets-$(date +%F).tgz -C /srv/secumon secrets
- Si vous changez la clé de signature de la console, tous les agents refuseront les commandes. Dans ce cas, réenregistrez chaque serveur dans cet ordre : désactivation → réémission d’un jeton → suppression de
/etc/secumon/agent.json·agent_ed25519.keysur le serveur → réinstallation. - À vérifier régulièrement : chaque jour, l’état des serveurs et les commandes échouées ; chaque semaine, les refus consignés dans le journal d’audit et les comptes sans authentification à deux facteurs.
12. Dépannage
Les messages de l’agent et de la console sont affichés en coréen. Recherchez dans le journal le texte exact affiché en police de code dans le tableau ci-dessous.
| Symptôme | Cause | Que faire |
|---|---|---|
Journal de l’agent 등록되지 않았거나 비활성 상태인 타겟 | Serveur désactivé dans la console | Obtenir un nouveau jeton et réenregistrer |
Journal de l’agent 요청 시각 편차가 허용치를 넘습니다 | L’horloge du serveur dérive de plus de 60 secondes | Synchroniser l’horloge par NTP |
Journal de l’agent 이미 사용된 nonce | La même requête a été reçue une seconde fois | C’est une défense normale. Si cela persiste, soupçonner une retransmission en double sur le réseau |
Résultat de commande 거부: 만료된 명령 | L’agent ne l’a pas récupérée dans les 60 secondes | Vérifier l’état de secumon-agent sur le serveur, puis relancer |
Résultat de commande 거부: 서명이 유효하지 않음 | Clé de signature de la console changée sans réenregistrement | Réenregistrer en suivant l’ordre du chapitre 11 |
| La dernière réception de la carte serveur est figée · le journal s’interrompt | L’agent s’est figé | systemctl restart secumon-agent |
| Blocage par pays activé, mais rien n’est appliqué sur le serveur | Cette ligne manque dans le journal de l’agent : 국가 차단 적용 | Vérifier que l’agent est à jour et consulter les erreurs dans son journal |
| Déconnexions à répétition | Accès par une adresse non HTTPS | Se connecter via l’adresse HTTPS de la console |
Pour toute autre question, écrivez-nous à halo@levelupsoft.com.
fail2ban · nftables · AbuseIPDB · Spamhaus · FireHOL · Telegram · Let's Encrypt sont la propriété de leurs détenteurs respectifs ; SSem SecuMon n’est ni affilié à ceux-ci ni approuvé par eux.