Shadow Fleet Tracker Light: Open Source Baltic Sea Vessel Monitoring
Overview
Shadow Fleet Tracker Light is an open-source Python application built by Former Lab that monitors over 1200 vessels identified in the Ukrainian GUR War&Sanctions catalogue as part of Russia’s shadow fleet, tankers and cargo ships used to evade sanctions, transport sanctioned oil, and operate covertly in European waters.
The tool connects to the AISStream WebSocket feed, filters positions against a local watchlist, and renders a self-updating map with cable proximity alerts, loitering detection, and Russia↔West transshipment pattern analysis. Everything runs locally. No cloud, no subscription beyond a free API key.
What Problem Does It Solve
The Russian shadow fleet is a growing maritime security concern in the Baltic Sea. These vessels frequently:
- Switch flags to obscure their identity
- Transmit AIS data intermittently or spoof positions
- Operate near undersea cables critical to European infrastructure
- Conduct ship-to-ship transfers to launder sanctioned cargo
Shadow Fleet Tracker Light makes this visible. It pulls live positions, cross-references them against a curated watchlist of 1200+ vessels, and surfaces the patterns, all from a single Python process running on a laptop.
Features
- Live AIS tracking — WebSocket consumer subscribes to a Baltic Sea bounding box (52.65–66°N, 9–30°E) and filters the stream against the watchlist
- 1200+ vessel watchlist — sourced from the Ukrainian GUR catalogue, including recently seized vessels like EAGLE S (Finland, Estlink-2 cable sabotage), EVENTIN (Germany, 100,000t Russian crude confiscated), and CAFFA (Sweden, stolen Ukrainian grain)
- Cable proximity alerts — flags vessels within 10 km of undersea cable segments defined in a KML file
- Loitering detection — identifies vessels stationary or moving below 0.5 kn for 20+ minutes in a fixed area
- Transshipment detection — infers port calls from position data and flags Russia↔West patterns within a 21-day window
- Interactive map — dark CartoDB basemap with cable routes, auto-refreshing every 3 minutes with live countdown
- Warm restart — pre-populates the map from the last 24 hours of position logs on startup, no blank-canvas wait
- FastAPI dashboard — vessel analysis, log inspection, CSV export, GPX track export, and interactive route replay
- Per-vessel pages — AIS blackouts, cable proximity percentage, flag change history, GPX export
- OpenSanctions integration (optional) — sanctions status in map popups
Quick Start
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 # free at aisstream.io
python shadow_tracker.py &
uvicorn webserver:app --host 0.0.0.0 --port 8000Open http://localhost:8000 - the live map is at /map.
Platform-specific start scripts are included: start.sh for Linux/macOS, start.bat and start.ps1 for Windows. All run a preflight check (check.py) that verifies Python version, dependencies, data files, API key, and network reachability before launching.
Architecture
The tracker runs a single async loop over the AISStream WebSocket. State is kept in-memory and flushed to SQLite on each render cycle. The map is written atomically via os.replace to avoid serving a partial file.
shadow_tracker.py WS consumer, map renderer, DB writes
loitering_module.py Loitering detection
transshipment_module.py Port call and transshipment analysis
webserver.py FastAPI dashboard
gur_scrape.py Builds IMO→GUR-ID mapping from catalogue
check.py Preflight checks
Vessels1.db Watchlist (1200+ vessels)
filtered_cables.kml Baltic undersea cable geometryThe webserver is stateless and reads directly from the SQLite files; no shared memory with the tracker process. Watchlist and GUR mapping reload from disk every 5 minutes, so vessels can be added while the tracker runs without a restart.
Notable Seized Vessels
The watchlist includes several vessels recently seized or intercepted by Baltic authorities:
| Vessel | IMO | Event |
|---|---|---|
| EAGLE S | 9329760 | Finland seized Dec 2024 — Estlink-2 cable sabotage, spy equipment found |
| EVENTIN | 9308065 | Germany seized Jan–Mar 2025 — drifted off Rügen, 100,000t Russian crude confiscated |
| KIWALA | 9332810 | Estonia detained Apr 2025 — flagless, EU/UK sanctioned |
| JAGUAR | 9293002 | Estonia intercepted May 2025 — Russia scrambled Su-35 to escort it |
| FITBURG | 9250397 | Finland seized 31 Dec 2025 — Helsinki-Tallinn cable sabotage |
| CAFFA | 9143611 | Sweden seized 6 Mar 2026 — stolen Ukrainian grain, false flag |
| SEA OWL I | 9321172 | Sweden seized 12 Mar 2026 — EU sanctioned, false Comoros flag |
Dashboard Routes
| Route | Description |
|---|---|
/map | Live map with vessel positions, cable routes, and alerts |
/analyze | Filterable vessel record table with CSV export |
/timeline | Activity overview — one card per vessel, sorted by last seen |
/vessel/<mmsi> | Per-vessel history, route replay, GPX export |
/loitering | Loitering events with near-cable flag |
/transshipment | Russia↔West port call patterns |
Why Open Source Matters Here
Maritime surveillance has traditionally been locked behind expensive commercial platforms. Shadow Fleet Tracker Light demonstrates that meaningful intelligence can be produced with open data (AISStream), public watchlists (GUR catalogue), and a few hundred lines of Python. Former Lab’s approach (sovereign computing on old hardware, no VC backing) makes this accessible to journalists, researchers, and anyone tracking hybrid threats in the Baltic.
Links
- GitHub: FormerLab/shadow-fleet-tracker-light
- Former Lab: formerlab.eu
- GUR War&Sanctions catalogue: war-sanctions.gur.gov.ua
- AISStream API: aisstream.io
License
MIT License.