
Outil open source de suivi de la flotte fantôme de la mer Baltique. 1200+ navires, AIS en direct, alertes de proximité de câbles. Pas de cloud, pas d'abonnement, fonctionne localement
Surveillance de la flotte fantôme en mer Baltique via les données AIS en direct. Surveille plus de 1200 navires du catalogue GUR War&Sanctions ukrainien par rapport au flux WebSocket AISStream, affiche les positions sur une carte auto-mise à jour, signale la proximité des câbles sous-marins et détecte les schémas de transbordement Russie↔Occident.
Gratuit, open source, fonctionne localement. Pas de cloud, pas d'abonnement au-delà d'une clé API AISStream gratuite.
Fait partie de la chaîne d'outils souverains du Former Lab.
Shadow Fleet Tracker Light est construit et maintenu par l'équipe de Former Lab — informatique souveraine, construisant des outils open source et respectueux de la vie privée sur du vieux matériel, sans financement VC.
Si cet outil vous est utile, envisagez de nous soutenir sur Patreon. Un niveau gratuit est disponible, avec un essai de 7 jours sur les niveaux payants. Soutenez toujours l'Ukraine !
git clone https://github.com/FormerLab/shadow-fleet-tracker-light.git
cd shadow-fleet-tracker-light
pip install -r requirements.txt
export AISSTREAM_API_KEY=your_key_here # gratuit sur aisstream.io
python shadow_tracker.py &
uvicorn webserver:app --host 0.0.0.0 --port 8000
Ouvrez http://localhost:8000 — la carte est à /map.
Utilisateurs Windows : voir la section Configuration pour la syntaxe des variables d'environnement dans PowerShell/cmd.
Les utilisateurs Linux / macOS peuvent utiliser start.sh. Les utilisateurs Windows peuvent utiliser start.bat ou start.ps1 — les deux ouvrent le tracker et le tableau de bord dans des fenêtres séparées et lancent le navigateur automatiquement.
Vessels1.db)filtered_cables.kml)Fond de carte CartoDB sombre avec les itinéraires de câbles superposés en vert. Les marqueurs de navires se mettent à jour toutes les 3 minutes avec un compte à rebours en direct jusqu'à la prochaine actualisation — la page se recharge automatiquement. Les popups montrent MMSI, IMO, pavillon, vitesse, cap, destination et des liens profonds vers MarineTraffic, VesselFinder et War&Sanctions. Le statut des sanctions OpenSanctions est affiché si une clé API est configurée.
Les noms de navires connus de Vessels1.db sont affichés immédiatement à leur première apparition sans attendre un message statique AIS.
Au démarrage, la carte est préremplie avec les dernières 24 heures du journal de position. Les navires non encore vus dans la session en cours sont affichés avec des marqueurs gris et une étiquette "vu pour la dernière fois il y a Xh" — ils passent à la couleur en direct à mesure que de nouveaux pings arrivent.
shadow_tracker.py Processus principal — consommateur WS, rendu de carte, écritures DB
loitering_module.py Détection de flânerie et annotation de carte
transshipment_module.py Détection d'escales portuaires et signalement de transbordement Russie↔Occident
webserver.py Tableau de bord FastAPI
gur_scrape.py Récupérateur unique — construit le mapping IMO→GUR-ID + catalogue complet des navires
check.py Vérifications préalables — version Python, dépendances, clé API, réseau
start.sh Lanceur pour Linux / macOS
start.bat Lanceur pour Windows (Invité de commandes)
start.ps1 Lanceur pour Windows (PowerShell)
requirements.txt Dépendances
Vessels1.db Liste de surveillance — plus de 1200 navires (MMSI + IMO + nom si connu)
vessel_data_log.db Journal de position — exécution, ajout seulement
vessel_static.db Cache des données statiques AIS (nom, destination, historique des pavillons)
transshipment.db Journal des escales portuaires et événements de transbordement
loitering_events.db Événements de flânerie
filtered_cables.kml Géométrie des câbles sous-marins de la mer Baltique
cables.kml Jeu de données complet des câbles (source pré-filtrage)
gur_mapping.json Mapping IMO→GUR-ID (produit par gur_scrape.py, optionnel)
gur_vessels_full.json Catalogue GUR complet — GUR-ID→{imo, mmsi, name, flag} (produit par gur_scrape.py)
Vessels1.db est la liste canonique des navires suivis. Plus de 1200 entrées provenant du catalogue GUR War&Sanctions ukrainien, couvrant les pétroliers et cargos identifiés comme faisant partie de la flotte fantôme russe ou impliqués dans des activités hybrides en Baltique.
La liste comprend des navires récemment saisis ou interceptés par les autorités baltes :
| Navire | IMO | Événement |
|---|---|---|
| EAGLE S | 9329760 | Finlande a saisi déc. 2024 — sabotage du câble Estlink-2, équipement d'espionnage trouvé |
| EVENTIN | 9308065 | Allemagne a saisi janv.–mars 2025 — dérive près de Rügen, 100 000 t de pétrole brut russe confisquées |
| KIWALA | 9332810 | Estonie a détenu avr. 2025 — sans pavillon, sanctionné UE/RU |
| JAGUAR | 9293002 | Estonie a intercepté mai 2025 — la Russie a envoyé un Su-35 pour l'escorter |
| KIRA K | 9346720 | Équipage Wagner/GRU confirmé à bord déc. 2025 |
| QENDIL | 9310525 | Équipage Wagner/GRU sept. 2025 — frappe de drone ukrainien déc. 2025 |
| FITBURG | 9250397 | Finlande a saisi le 31 déc. 2025 — sabotage du câble Helsinki-Tallinn |
| CAFFA | 9143611 | Suède a saisi le 6 mars 2026 — céréales ukrainiennes volées, faux pavillon |
| SEA OWL I | 9321172 | Suède a saisi le 12 mars 2026 — sanctionné UE, faux pavillon des Comores |
Les MMSI sont corrigés par rapport aux données AIS actuelles — les navires de la flotte fantôme changent fréquemment de pavillon. Le fichier update_vessels_2026_03.sql documente tous les changements avec leurs sources.
La liste de surveillance est intentionnellement ouverte. Ajoutez des navires directement dans Vessels1.db pendant que le tracker fonctionne — ils seront pris en compte dans les 5 minutes sans redémarrage.
Linux / macOS :
sqlite3 Vessels1.db "INSERT OR IGNORE INTO vessels (mmsi, imo, name) VALUES ('123456789', '9999999', 'VESSEL NAME');"
Windows (pas besoin d'interface CLI sqlite3) :
import sqlite3
conn = sqlite3.connect("Vessels1.db")
conn.execute("INSERT OR IGNORE INTO vessels (mmsi, imo, name) VALUES ('123456789', '9999999', 'VESSEL NAME')")
conn.commit()
conn.close()