Atathakr/maritime-osint

GitHub: Atathakr/maritime-osint

开源海事威胁情报平台,整合多源制裁筛查与 AIS 行为分析,专门用于识别规避制裁的影子船队。

Stars: 0 | Forks: 0

# 海事 OSINT — 制裁与影子船队情报 ![Python](https://img.shields.io/badge/python-3.11%2B-blue) ![Flask](https://img.shields.io/badge/flask-3.1-lightgrey) ![License: MIT](https://img.shields.io/badge/license-MIT-green) ![Status](https://img.shields.io/badge/status-active%20development-orange) ## 项目简介 影子船队 —— 那些故意隐瞒身份、所有权或行踪以逃避制裁的船只 —— 自 2022 年以来规模大幅增长。大多数开源工具要么只处理制裁筛查,要么只处理 AIS 跟踪,两者是割裂的。本平台将两者结合到一个面向分析师的界面中。 您加载一个船舶标识符(IMO 编号、MMSI 或名称),平台将返回: - 该船只是否出现在 OFAC SDN、OpenSanctions、EU、UN 或其他名单上 - 根据 13 个行为和结构指标得出的综合风险评分(0–100) - AIS 行为信号:黑暗期、船对船过驳、徘徊、速度异常 - 针对约 30 个受制裁或高风险码头停靠记录 - 船旗国风险等级和频繁换旗历史 - PSC 滞留记录(Paris MOU + Tokyo MOU) - 针对制裁数据库的所有权链筛查 这是一个研究和分类工具。它不能替代专业的合规分析。所有信号应由合格的分析师进行解读。 ## 功能特性 ### 制裁筛查 | 能力 | 详情 | |---|---| | OFAC SDN | 美国财政部特别指定国民名单中的船舶条目 | | OpenSanctions | 综合多司法管辖区名单:EU、UN SC、UK HMT、澳大利亚、加拿大、日本及其他 | | 统一规范注册表 | 使用 IMO > MMSI > 名称+船旗哈希优先级,对列表中的船只进行去重 | | 摄入后调和 | 两层合并:IMO 冲突扫描 + MMSI 到 IMO 升级 | | 搜索 | IMO 编号、MMSI 或带有匹配置信度标签的部分船名 | ### 实时 AIS 跟踪 | 能力 | 详情 | |---|---| | 实时数据流 | 连接到 aisstream.io 的 WebSocket(支持免费层级) | | 历史数据 | NOAA Marine Cadastre 月度 AIS CSV 摄入 | | 船舶名册 | 每个 MMSI 一行,包含最后已知位置 | | 航迹历史 | 每艘船 72 小时的航迹点轨迹(可配置至 168 小时) | | 实时地图 | Leaflet 1.9.4,综合风险着色,船舶航迹 | ### 行为分析 —— 影子船队框架 该平台实施了用于影子船队风险评估的 31 项指标框架的一个子集。指标分为六类。 | 状态 | 数量 | |---|---| | 完全实施并评分 | 13 | | 部分(已检测,未完全评分) | 1 | | 尚未实施 | 10 | | 开源数据无法实现 | 7 | **已实施的指标:** | 代码 | 名称 | 类别 | |---|---|---| | IND1 | AIS 黑暗期(应答器间隔 ≥ 2 小时) | AIS / 应答器 | | IND2 | 速度异常 / AIS 欺骗代理(SOG > 50 节) | AIS / 应答器 | | IND7 | 公海船对船过驳 | 移动 / 行为 | | IND8 | 9 个指定高风险区域的 STS 过驳 | 移动 / 行为 | | IND9 | 徘徊 / 异常的开放水域锚泊 | 移动 / 行为 | | IND10 | 异常速度剖面 | 移动 / 行为 | | IND15 | 频繁换旗(多次更改船旗) | 所有权 / 身份 | | IND16 | 船名差异(AIS 与规范名对比) | 所有权 / 身份 | | IND17 | 高风险 / 方便旗船旗国 | 所有权 / 身份 | | IND21 | 所有权链制裁匹配 | 所有权 / 身份 | | IND23 | 船龄(≥ 15 年为高风险) | 物理 / 运营 | | IND29 | 停靠受制裁 / 高风险港口 | 港口 / 地理 | | IND31 | PSC 滞留记录(Paris MOU / Tokyo MOU) | 港口 / 地理 | ### 风险评分 非受制裁船只获得 0 到 99 的综合评分。任何制裁名单上的船只总是获得 100 分。 ``` risk_score = min( min(dp_count × 10, 40) -- IND1 AIS dark periods + min(sts_count × 15, 45) -- IND7 STS transfers + min(sts_zone_count × 5, 10) -- IND8 STS in high-risk zones + flag_tier × 7 -- IND17 flag risk tier (max 21) + min(hop_count × 8, 16) -- IND15 flag hopping + min(spoof_count × 8, 24) -- IND10 speed anomalies + min(port_count × 20, 40) -- IND29 sanctioned port calls + min(loiter_count × 5, 15) -- IND9 loitering + max(0, min((age − 15) × 3, 15)) -- IND23 vessel age + min(owner_hits × 20, 40) -- IND21 ownership chain + min(psc_count × 10, 20), -- IND31 PSC detentions 99 -- hard ceiling for non-sanctioned ) ``` **船旗风险等级 (IND17):** | 等级 | 分数 | 示例 | |---|---|---| | 3 — 高风险 / 受制裁 | 21 分 | 伊朗、俄罗斯、朝鲜、叙利亚、喀麦隆、坦桑尼亚、科摩罗 | | 2 — 影子船队注册地 | 14 分 | 巴拿马、帕劳、多哥、加蓬、柬埔寨、塞拉利昂 | | 1 — 主流开放式注册地 | 7 分 | 马绍尔群岛、利比里亚、巴哈马、伯利兹 | | 0 — 标准 | 0 分 | 欧盟成员国、英国、美国、挪威、日本等 | ## 数据来源 | 来源 | 类型 | 许可 / 条款 | URL | |---|---|---|---| | OFAC SDN | 制裁名单 (XML) | 美国公共领域 | https://www.treasury.gov/ofac/downloads/sdn.xml | | OpenSanctions | 综合制裁 (JSON) | CC BY-SA 4.0 | https://opensanctions.org | | aisstream.io | 实时 AIS (WebSocket) | 提供免费层级 | https://aisstream.io | | NOAA Marine Cadastre | 历史 AIS (CSV) | 美国公共领域 | https://marinecadastre.gov | | Paris MOU | PSC 滞留 (CSV) | 公开 | https://www.parismou.org | | Tokyo MOU | PSC 滞留 (CSV) | 公开 | https://www.tokyo-mou.org | 所有数据源均为公开可用。无需商业订阅。 ## 快速开始(本地) **要求:** Python 3.11 或更高版本,Git ``` git clone https://github.com/Atathakr/maritime-osint.git cd maritime-osint python -m venv .venv # Linux / macOS source .venv/bin/activate # Windows .venv\Scripts\activate pip install -r requirements.txt cp .env.example .env # 编辑 .env — 本地开发所有字段可选 # 添加 AISSTREAM_API_KEY 以使用实时 AIS(在 aisstream.io 免费) python app.py ``` 打开 http://localhost:5000。 **初始数据加载(在浏览器中):** 1. 点击 **Fetch OFAC** —— 下载并解析 OFAC SDN XML(约 5–15 秒) 2. 点击 **Fetch OpenSanctions** —— 流式传输综合 JSON(约 30–90 秒) 3. 点击 **Reconcile** —— 合并重复的船舶记录 4. 可选:点击 **Start AIS** 以获取实时数据流(需要 API 密钥) 完成步骤 1–3 后,制裁筛查即可完全正常工作。AIS 行为分析在位置数据流动时激活。 ## 环境变量 | 变量 | 必需 | 描述 | |---|---|---| | `DATABASE_URL` | 否 | PostgreSQL 连接字符串。省略以使用 SQLite。 | | `APP_PASSWORD` | 否 | 仪表板登录页面的密码。留空以禁用身份验证。 | | `SECRET_KEY` | 否 | Flask 会话密钥。如果未设置,将在启动时自动生成。 | | `AISSTREAM_API_KEY` | 否 | aisstream.io 的 API 密钥。在 aisstream.io 免费注册。 | ## 部署(Railway) 1. Fork 本仓库。 2. 创建一个 Railway 项目并连接您的 fork。 3. 添加 **PostgreSQL 插件** —— Railway 会自动设置 `DATABASE_URL`。 4. 在 Railway 环境变量中设置 `APP_PASSWORD` 和 `AISSTREAM_API_KEY`。 5. 部署。`/health` 端点确认就绪状态。 `Procfile` 中 120 秒的 Gunicorn 超时是 OpenSanctions 流式摄入所必需的。 **自托管:** 任何运行 Python 和 Gunicorn 的平台均可。在生产环境中为 PostgreSQL 设置 `DATABASE_URL`,或留空以使用 SQLite。 ## 架构概览 ``` app.py Flask routes and auth middleware ├── ingest.py OFAC SDN + OpenSanctions + PSC CSV ingest ├── screening.py Unified vessel search and risk scoring engine ├── reconcile.py Two-tier canonical vessel deduplication ├── db.py Database abstraction layer (SQLite / PostgreSQL) ├── ais_listener.py aisstream.io WebSocket consumer (background thread) ├── dark_periods.py IND1 — AIS transponder gap detector ├── sts_detection.py IND7/8 — ship-to-ship proximity detector ├── loitering.py IND9 — open-water loitering detector ├── spoofing.py IND10 — speed anomaly detector ├── ports.py IND29 — sanctioned port call detector ├── noaa_ingest.py Historical AIS CSV ingest (NOAA Marine Cadastre) ├── normalize.py Flag normalisation, dataset labels, canonical IDs ├── risk_config.py Scoring weights, thresholds, flag tier registry ├── schemas.py Pydantic data models for all request/response types └── map_data.py Geospatial data preparation for Leaflet frontend ``` ## API 参考(部分端点) 如果设置了 `APP_PASSWORD`,则所有端点都需要身份验证。 | 方法 | 端点 | 描述 | |---|---|---| | POST | `/api/screen` | 按 IMO、MMSI 或名称筛查船只 | | GET | `/api/screen/` | 特定船只的完整风险概况 | | GET | `/api/sanctions` | 浏览带筛选功能的制裁条目 | | POST | `/api/ingest/ofac` | 触发 OFAC SDN 摄入 | | POST | `/api/ingest/opensanctions` | 触发 OpenSanctions 摄入 | | POST | `/api/ingest/psc/` | 摄入 PSC 滞留 CSV | | POST | `/api/reconcile` | 运行规范性去重 | | POST | `/api/ais/start` | 启动 AIS WebSocket 监听器 | | GET | `/api/ais/status` | AIS 监听器统计信息 | | GET | `/api/ais/vessels` | AIS 船舶名册 | | GET | `/api/ais/vessels//track` | 历史船舶航迹 | | POST | `/api/dark-periods/detect` | 运行黑暗期检测 | | POST | `/api/sts/detect` | 运行 STS 邻近检测 | | POST | `/api/ais/detect-loitering` | 运行徘徊检测 | | POST | `/api/ports/detect-calls` | 运行受制裁港口停靠检测 | | POST | `/api/ais/detect-anomalies` | 运行速度异常检测 | | GET | `/api/map/vessels` | 船舶位置 + 地图用的综合风险 | 完整的请求/响应模式在 `schemas.py` 中。 ## 限制 31 项影子船队指标中有七项需要商业数据: | 指标 | 为何不可行 | |---|---| | IND5 — 禁用 LRIT | 需要 LRIT 接收器网络订阅 | | IND13 — 航次与货物不符 | 需要货物舱单 / 提单 | | IND14 — VHF 通讯静默 | 需要海岸无线电监测 | | IND22 — 伪造文件 | 需要文件验证访问权限 | | IND24 — 物理改装 | 需要卫星图像 | | IND25 — 吃水异常 | AIS 吃水是自我报告的,不具强制性 | | IND28 — 货物不一致 | 需要海关 / 提单数据 | 速度异常检测器 (IND10) 是一个欺骗*代理* —— SOG > 50 节是一个保守的阈值。真正的 GNSS 欺骗检测需要与卫星接收器进行交叉参考。 AIS 覆盖盲区(非故意黑屏)存在于陆地接收器密度有限的地区。 ## 贡献 有关开发设置、代码风格以及如何向框架添加新指标,请参阅 [CONTRIBUTING.md](CONTRIBUTING.md)。 ## 安全 有关漏洞报告政策,请参阅 [SECURITY.md](SECURITY.md)。 ## 许可证 本项目根据 [MIT 许可证](LICENSE) 授权。 数据许可证单独适用: - OpenSanctions 数据:[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) - OFAC SDN 和 NOAA AIS 数据:美国政府公共领域
标签:AIS追踪, Flask, OFAC筛查, Python, 制裁合规, 地缘政治, 尽职调查, 影子舰队检测, 无后门, 测试用例, 海事分析, 自动识别系统, 船舶监控, 逆向工具, 金融犯罪