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émentExigence
Serveurs à protégerLinux (systemd) + fail2ban · nftables · sqlite3. amd64 ou arm64. Testé sur Ubuntu 22.04 · CentOS 8.
Serveur de consoleUn seul. JDK 21 · Tomcat 11 · PostgreSQL 17. Le plus simple est de passer par Docker.
RéseauLes 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.
HorlogeSynchronisez 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.
CertificatUn 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és12345678 ou plus
Durée du bannissement1 h2 h4 h8 h16 h32 h64 h7 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
FichierUsageS’il manque
db_passwordConnexion à la base de donnéesLa console ne démarre pas
admin_passwordMot de passe du premier compte administrateur adminLe compte n’est pas créé : impossible de se connecter
console_ed25519.key · .pubSignature des commandesConsultation seule, aucune exécution possible
abuseipdb.keyClé d’API AbuseIPDB (facultatif)Signalement · consultation de réputation indisponibles
telegram.envNotifications Telegram (facultatif)Aucune notification n’est envoyée
tls/cert.pem · chain.pem · privkey.pemCertificat HTTPS de la consolePas 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’environnementValeur par défautSignification
F2B_DB_URLjdbc:postgresql://…:5432/secumonAdresse de la base. Indiquez-la par le nom du conteneur.
F2B_CANONICAL_HOSTÀ définir obligatoirementLe 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 obligatoirementPlages à 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_DAYS30Durée par défaut d’un blocage de plage (jours). 0 = permanent.
F2B_AUTO_BLOCK_ENABLEDtrueActive ou désactive le blocage automatique des IP récidivistes.
F2B_AUTO_BLOCK_THRESHOLD3Nombre de bannissements à partir duquel le blocage automatique s’applique.
F2B_AUTO_BLOCK_TTL_DAYS30Durée du blocage automatique (jours).
F2B_FEED_REFRESH_HOURS24Intervalle de re-téléchargement des listes de blocage publiques et des listes de pays (heures).
F2B_BAN_MULTIPLIERS1 2 4 8 16 32 64 168Doit correspondre exactement aux multiplicateurs de la configuration des jails.
F2B_ABUSE_DAILY_LIMIT1000Quota 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

  1. Connectez-vous à la console en tant que admin, saisissez le nom du serveur dans l’onglet Cibles, puis cliquez sur Enregistrer + émettre un jeton.
  2. 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.
  3. 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 sshd qui 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ôleAutorisations
VIEWER lecture seuleConsultation : 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 admin et le mot de passe du fichier admin_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.key sur 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ômeCauseQue faire
Journal de l’agent 등록되지 않았거나 비활성 상태인 타겟Serveur désactivé dans la consoleObtenir un nouveau jeton et réenregistrer
Journal de l’agent 요청 시각 편차가 허용치를 넘습니다L’horloge du serveur dérive de plus de 60 secondesSynchroniser l’horloge par NTP
Journal de l’agent 이미 사용된 nonceLa même requête a été reçue une seconde foisC’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 secondesVé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éenregistrementRéenregistrer en suivant l’ordre du chapitre 11
La dernière réception de la carte serveur est figée · le journal s’interromptL’agent s’est figésystemctl restart secumon-agent
Blocage par pays activé, mais rien n’est appliqué sur le serveurCette 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étitionAccès par une adresse non HTTPSSe connecter via l’adresse HTTPS de la console

Pour toute autre question, écrivez-nous à halo@levelupsoft.com.