简介
什么是 Flowsint ?
Flowsint 是一个开源的 OSINT(开源情报)图形化调查平台,专为道德调查、透明度和验证而设计。它允许用户通过可视化图形界面探索实体之间的关系,并使用自动化 enrichers 进行数据丰富化。
主要特点
- 图形化探索:通过可视化图形界面探索实体之间的关系
- 自动化 Enrichers:内置多种自动化数据丰富化工具
- 本地存储:所有数据存储在本地,保护隐私
- 无默认账号:不预设任何账号,需要自行注册
- 多数据源支持:支持连接
PostgreSQL、Redis、Neo4j 等数据库
- 开源免费:基于
Apache 2.0 协议开源,可免费使用和修改
应用场景
- 网络安全分析:网络安全分析师可以使用
Flowsint 进行情报调查和关联分析
- 事件调查:调查人员可以使用图形化方式梳理事件脉络
- 开源情报收集:
OSINT 研究人员可以自动化收集和整理公开情报
- 关系分析:可视化了解决策实体之间的复杂关系

Flowsint 是一个专注于伦理调查的开源 OSINT 工具,适合网络安全分析师和调查人员使用。
安装
在群晖上以 Docker 方式安装。
官方在 ghcr.io 上有预编译的镜像,flowsint-app

和 flowsint-api 的 latest 对应的均为 1.2.7 版

但是如果你按照官方提供的 docker-compose.yml 部署,大概率不会成功,会卡在注册用户时遇到 405 错误
虽然我们设置了 VITE_API_URL,但前端运行时并没有把 API 地址指向后端,而是仍然在同源地请求前端服务本身。原因可能是前端镜像里代码在构建时没读到该变量,或者代码里写死了相对路径
所以老苏在官方基础上增加了 nginx 容器来处理地址转发,现在设不设置 VITE_API_URL 应该已经无所谓了
准备文件
该项目包含多个服务,需要准备以下文件:
docker-compose.yml - Docker 容器编排文件
env.txt - 环境变量配置
nginx.conf - Nginx 反向代理配置
目录结构
在群晖上新建文件夹 flowsint,并在其中创建必要的子目录:
1 2
| mkdir -p /volume1/docker/flowsint/{data,import,logs,plugins,pgdata}
|
| 文件夹 |
路径 |
说明 |
data |
/volume1/docker/flowsint/data |
Neo4j 数据目录 |
import |
/volume1/docker/flowsint/import |
Neo4j 导入目录 |
logs |
/volume1/docker/flowsint/logs |
Neo4j 日志目录 |
plugins |
/volume1/docker/flowsint/plugins |
Neo4j 插件目录 |
pgdata |
/volume1/docker/flowsint/pgdata |
PostgreSQL 数据目录 |
docker-compose 安装
将以下三个文件放入 /volume1/docker/flowsint 目录:
env.txt
env.txt 存放所有敏感配置和运行时参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| NODE_ENV=production AUTH_SECRET=n8sZgJ6DmhxCYFvXnFwnm22v44iqspQg
POSTGRES_USER=flowsint POSTGRES_PASSWORD=flowsint POSTGRES_DB=flowsint
MASTER_VAULT_KEY_V1=base64:qnHTmwYb+uoygIw9MsRMY22vS5YPchY+QOi/E79GAvM=
NEO4J_URI_BOLT=bolt://neo4j:7687 NEO4J_USERNAME=neo4j NEO4J_PASSWORD=password
VITE_API_URL=http://127.0.0.1:5001 REDIS_URL=redis://redis:6379/0
|
nginx.conf
nginx.conf 是 Nginx 反向代理配置,用于将外部请求路由到内部服务,同时设置了 WebSocket 支持和最大上传文件大小(50MB)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| server { listen 80; server_name _;
client_max_body_size 50m;
location /api/ { proxy_pass http://api:5001; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; }
location / { proxy_pass http://app:8080; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } }
|
docker-compose.yml
定义了 7 个容器服务,比官方增加了 1 反向代理容器 nginx
| 服务 |
镜像 |
用途 |
postgres |
postgres:15-alpine |
关系型数据库,存储业务数据 |
redis |
redis:7-alpine |
缓存 + Celery 消息队列 |
neo4j |
neo4j:5 |
图数据库,存储实体关系图 |
api |
ghcr.io/reconurge/flowsint-api |
Flask 后端 API |
celery |
同 api |
异步任务处理器 |
app |
ghcr.io/reconurge/flowsint-app |
Vue.js 前端 |
nginx |
nginx:alpine |
反向代理 + 负载均衡 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
| services: postgres: image: postgres:15-alpine container_name: flowsint-postgres-prod restart: always environment: POSTGRES_USER: ${POSTGRES_USER:-flowsint} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-flowsint} POSTGRES_DB: ${POSTGRES_DB:-flowsint} volumes: - ./pgdata:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-flowsint}"] interval: 10s timeout: 5s retries: 5
redis: image: redis:7-alpine container_name: flowsint-redis-prod restart: always healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5
neo4j: image: neo4j:5 container_name: flowsint-neo4j-prod restart: always ports: - "7474:7474" - "7687:7687" environment: - NEO4J_AUTH=${NEO4J_USERNAME}/${NEO4J_PASSWORD} - NEO4J_PLUGINS=["apoc"] - NEO4J_apoc_export_file_enabled=true - NEO4J_apoc_import_file_enabled=true - NEO4J_apoc_import_file_use__neo4j__config=true volumes: - ./data:/data - ./logs:/logs - ./import:/var/lib/neo4j/import - ./plugins:/plugins healthcheck: test: cypher-shell -u ${NEO4J_USERNAME} -p ${NEO4J_PASSWORD} "RETURN 1" interval: 5s timeout: 5s retries: 10
api: image: ghcr.io/reconurge/flowsint-api:latest container_name: flowsint-api-prod restart: always volumes: - /var/run/docker.sock:/var/run/docker.sock:ro environment: - DATABASE_URL=postgresql://${POSTGRES_USER:-flowsint}:${POSTGRES_PASSWORD:-flowsint}@postgres:5432/${POSTGRES_DB:-flowsint} - NEO4J_URI_BOLT=${NEO4J_URI_BOLT} - NEO4J_USERNAME=${NEO4J_USERNAME} - NEO4J_PASSWORD=${NEO4J_PASSWORD} - AUTH_SECRET=${AUTH_SECRET} - MASTER_VAULT_KEY_V1=${MASTER_VAULT_KEY_V1} - REDIS_URL=${REDIS_URL} depends_on: postgres: condition: service_healthy redis: condition: service_healthy neo4j: condition: service_healthy healthcheck: test: ["CMD-SHELL", "curl -f http://localhost:5001/health || exit 1"] interval: 10s timeout: 5s retries: 5
celery: image: ghcr.io/reconurge/flowsint-api:latest container_name: flowsint-celery-prod restart: always command: [ "celery", "-A", "flowsint_core.core.celery", "worker", "--loglevel=info", "--pool=threads", "--concurrency=10", ] volumes: - /var/run/docker.sock:/var/run/docker.sock:ro environment: - DATABASE_URL=postgresql://${POSTGRES_USER:-flowsint}:${POSTGRES_PASSWORD:-flowsint}@postgres:5432/${POSTGRES_DB:-flowsint} - NEO4J_URI_BOLT=${NEO4J_URI_BOLT} - NEO4J_USERNAME=${NEO4J_USERNAME} - NEO4J_PASSWORD=${NEO4J_PASSWORD} - AUTH_SECRET=${AUTH_SECRET} - MASTER_VAULT_KEY_V1=${MASTER_VAULT_KEY_V1} - REDIS_URL=${REDIS_URL} - SKIP_MIGRATIONS=true depends_on: postgres: condition: service_healthy redis: condition: service_healthy neo4j: condition: service_healthy api: condition: service_healthy
app: image: ghcr.io/reconurge/flowsint-app:latest container_name: flowsint-app-prod restart: always expose: - "8080" depends_on: api: condition: service_healthy
nginx: image: nginx:alpine container_name: flowsint-nginx-prod restart: always ports: - "5173:80" volumes: - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro depends_on: - app - api
|
启动服务
通过 SSH 登录到群晖,执行以下命令启动:
1 2 3 4 5
| cd /volume1/docker/flowsint
docker-compose --env-file env.txt up -d
|

群晖上 docker 版本比较低,所以 service_healthy 很容易失败

多等一会儿再执行一键启动 docker-compose --env-file env.txt up -d 即可
提示:首次启动可能需要较长时间拉取 Docker 镜像,请耐心等待。
另外容器 neo4j 可能会阵发性的出现高 CPU 占用,系统稳定后就好了

运行
在浏览器中访问 http://<群晖IP>:5173 即可进入登录界面。

第一次要点 Create an account 注册账号

登录成功后的主界面

具体的使用请参考官方的使用说明: https://www.flowsint.io/docs/developers/getting-started
注意事项
- 隐私保护:
OSINT 调查需要高度隐私保护,Flowsint 所有数据都存储在本地
- 端口占用:默认使用
5173 端口,确保该端口未被占用;Neo4j 的 7474 和 7687 端口也一样
- 环境变量安全:
AUTH_SECRET 和 MASTER_VAULT_KEY_V1 是敏感信息,建议在生产环境中修改为随机生成的密钥
- 首次注册:系统没有默认账号,首次访问需要先注册账号
- 资源需求:该平台依赖
PostgreSQL、Redis 和 Neo4j,对资源有一定需求
- 道德使用:请阅读项目自带的
ETHICS.md 文件,了解伦理使用准则
参考文档
Flowsint: A modern platform for visual, flexible, and extensible graph-based investigations
地址:https://github.com/reconurge/flowsint
Flowsint Official Website
地址:https://flowsint.io
reconurge/flowsint-app - Docker Image | Docker Hub
地址:https://ghcr.io/reconurge/flowsint-app