{"id":32675470,"url":"https://github.com/dn9uy3n/bbot-osint-mcp","last_synced_at":"2026-05-16T17:05:49.625Z","repository":{"id":321089128,"uuid":"1084337174","full_name":"dn9uy3n/bbot-osint-mcp","owner":"dn9uy3n","description":"Deploy a secure OSINT service based on BBOT with FastAPI API, Neo4j for full-fidelity storage (events, hosts, domains, IPs, URLs, emails), and MCP server for Cursor integration. Optimized for continuous low-concurrency scanning to reduce blocking risk.","archived":false,"fork":false,"pushed_at":"2025-11-07T08:46:31.000Z","size":393,"stargazers_count":7,"open_issues_count":1,"forks_count":2,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-05T03:07:09.314Z","etag":null,"topics":["bbot","cursor-ai","mcp","osint","osint-tool","redteam","redteam-tools"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dn9uy3n.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-27T14:46:44.000Z","updated_at":"2025-11-18T22:55:36.000Z","dependencies_parsed_at":null,"dependency_job_id":"4f37d91f-027b-417f-aa0b-4e5a286b30a0","html_url":"https://github.com/dn9uy3n/bbot-osint-mcp","commit_stats":null,"previous_names":["dn9uy3n/bbot-osint-mcp"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/dn9uy3n/bbot-osint-mcp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dn9uy3n%2Fbbot-osint-mcp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dn9uy3n%2Fbbot-osint-mcp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dn9uy3n%2Fbbot-osint-mcp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dn9uy3n%2Fbbot-osint-mcp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dn9uy3n","download_url":"https://codeload.github.com/dn9uy3n/bbot-osint-mcp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dn9uy3n%2Fbbot-osint-mcp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33111497,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-16T04:41:52.686Z","status":"ssl_error","status_checked_at":"2026-05-16T04:41:52.009Z","response_time":115,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bbot","cursor-ai","mcp","osint","osint-tool","redteam","redteam-tools"],"created_at":"2025-11-01T06:01:36.400Z","updated_at":"2026-05-16T17:05:49.618Z","avatar_url":"https://github.com/dn9uy3n.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"## 1. BBOT OSINT Continuous Monitoring Stack (Docker)\n\n\u003e **English version:** [README_EN.md](README_EN.md)\n\nHệ thống giám sát OSINT liên tục dựa trên BBOT với FastAPI, Neo4j để lưu trữ kết quả đầy đủ, và MCP server để query từ Cursor.\n\n**GitHub Repository:** [https://github.com/dn9uy3n/bbot-osint-mcp](https://github.com/dn9uy3n/bbot-osint-mcp)\n\n**Tài liệu tham khảo:**\n- [GitHub BBOT](https://github.com/blacklanternsecurity/bbot)\n- **[📝 Hướng dẫn viết init_config.json](docs/INIT_CONFIG_GUIDE.md)** ⭐\n- [Hướng dẫn cài đặt chi tiết](docs/INSTALLATION.md)\n  - Cài đặt nhanh: chạy `./scripts/quick-install.sh` (thiết lập DNS Docker, tạo thư mục runtime, sinh secrets, build \u0026 up)\n### 1.1 Cài đặt nhanh (Quick Install)\n\n```bash\ncd /opt\nsudo git clone https://github.com/dn9uy3n/bbot-osint-mcp.git\ncd bbot-osint-mcp\n\n# (tuỳ chọn) đặt sẵn file init_config.json của bạn vào thư mục repo\n# nano init_config.json\n\nchmod +x scripts/quick-install.sh\n./scripts/quick-install.sh\n\n# Kiểm tra logs\nsudo docker logs -f bbot_osint\n```\n\nScript sẽ:\n- Thiết lập DNS cho Docker daemon (1.1.1.1, 8.8.8.8) để tránh lỗi name resolution\n- Tạo thư mục runtime: `logs/`, `cache/`, `scans/`, `secrets/`\n- Sinh secrets nếu thiếu (API_TOKEN, Neo4j password)\n- Build và khởi động toàn bộ stack\n\n- [Hướng dẫn sử dụng API](docs/API_USAGE.md)\n- [Tích hợp Cursor MCP](docs/MCP_INTEGRATION.md)\n- [Mô hình dữ liệu (Data Model)](docs/DATA_MODEL.md)\n- [Importer (đọc output.json)](docs/IMPORTER.md)\n- [Triển khai phân tán đa VPS](docs/DISTRIBUTED.md)\n- [Giải thích Sleep Parameters](SLEEP_PARAMETERS.md)\n- [Troubleshooting](docs/TROUBLESHOOTING.md)\n- [Quản lý \u0026 Gỡ cài đặt](docs/UNINSTALL.md)\n\n### 1.2 Mô tả dự án\n\nHệ thống **continuous monitoring** tự động quét targets theo chu kỳ, lưu dữ liệu đầy đủ vào Neo4j (DNS records, open ports, technologies, events), với API và MCP để query. Tối ưu để chạy 24/7 với ít luồng, giảm nguy cơ bị chặn.\n\n### 1.3 Tính năng chính\n\n- **Automatic Continuous Scanning**: Tự động quét tất cả targets theo chu kỳ được cấu hình, không cần trigger thủ công.\n- **2 loại Sleep Time**:\n  - `target_sleep_seconds`: Nghỉ giữa mỗi target trong cùng chu kỳ (tránh quét liên tục).\n  - `cycle_sleep_seconds`: Nghỉ sau khi quét xong tất cả targets trước khi bắt đầu chu kỳ mới.\n- **Full Data Fidelity**: Lưu đầy đủ dữ liệu BBOT vào Neo4j (DNS_NAME, OPEN_TCP_PORT, TECHNOLOGY, Event raw data).\n- **Incremental Updates**: Các lần quét sau chỉ cập nhật/thêm mới, không xóa dữ liệu cũ (trừ cleanup theo retention policy).\n- **MCP Query Interface**: Cursor có thể kết nối qua MCP để query dữ liệu (`osint.query`, `osint.events.query`, `osint.status`).\n  - Đường dẫn shim hiện tại: `/mcp/tools/osint.query`, `/mcp/tools/osint.events.query`, `/mcp/tools/osint.status`.\n- **REST API**: Query hosts và events qua HTTP API.\n- **Automatic Cleanup**: Xóa events quá hạn, hosts offline lâu, và orphan nodes sau mỗi chu kỳ.\n- **Telegram Notifications**: Thông báo sau mỗi chu kỳ quét hoàn thành.\n- **Centralized Configuration**: Tất cả cấu hình trong `init_config.json` (targets, API keys, sleep times).\n- **Distributed Workers**: Hỗ trợ nhiều worker BBOT chạy trên các VPS khác nhau, gom dữ liệu qua endpoint `/ingest/output` với token riêng; worker có thể auto-upload ngay sau mỗi lần quét.\n\n### 1.4 Kiến trúc\n\n- `docker-compose.yml`: Neo4j và service OSINT (FastAPI + MCP).\n- `init_config.json`: cấu hình đầu vào (targets, API keys, Telegram, tham số scan).\n- `services/osint`: mã nguồn API, BBOT runner, MCP server.\n- `reverse-proxy/Caddyfile`: cấu hình Caddy với Let's Encrypt tự động.\n\n#### Sơ đồ kiến trúc\n\n```mermaid\ngraph TB\n    subgraph \"Client Layer\"\n        A[Cursor IDE\u003cbr/\u003eMCP Query Only]\n        B[Monitoring Dashboard]\n        C[API Client/Script]\n    end\n    \n    subgraph \"VPS Server\"\n        D[Caddy Reverse Proxy\u003cbr/\u003ePort 80/443\u003cbr/\u003eLet's Encrypt TLS]\n        \n        subgraph \"Internal Network\"\n            E[FastAPI Service\u003cbr/\u003ePort 8000\u003cbr/\u003e+ Continuous Scanner]\n            F[Neo4j Database\u003cbr/\u003ePort 7687]\n            \n            E --\u003e|Ingest Data| F\n            E --\u003e|Auto Scan Loop| E\n        end\n        \n        D --\u003e E\n    end\n    \n    subgraph \"External Services\"\n        G[BBOT Modules\u003cbr/\u003eSecurityTrails, Shodan,\u003cbr/\u003eVirusTotal, etc.]\n        H[Telegram Bot API]\n    end\n    \n    A --\u003e|MCP Query HTTPS| D\n    B --\u003e|HTTPS API| D\n    C --\u003e|HTTPS API| D\n    E --\u003e|Continuous Scan| G\n    E --\u003e|Cycle Complete Notify| H\n    \n    style D fill:#f9f,stroke:#333,stroke-width:2px\n    style E fill:#bbf,stroke:#333,stroke-width:2px\n    style F fill:#bfb,stroke:#333,stroke-width:2px\n```\n\n#### Continuous Monitoring Flow\n\n```mermaid\nsequenceDiagram\n    participant S as Continuous Scanner\n    participant B as BBOT\n    participant N as Neo4j\n    participant T as Telegram\n    \n    Note over S: Service starts\n    S-\u003e\u003eS: Load targets from init_config.json\n    \n    loop Every Cycle\n        Note over S: Cycle Start\n        \n        loop For each target\n            S-\u003e\u003eB: Scan target[i]\n            B--\u003e\u003eS: Events stream\n            S-\u003e\u003eN: Ingest events (incremental)\n            \n            alt Not last target\n                Note over S: Sleep target_sleep_seconds\n            end\n        end\n        \n        S-\u003e\u003eN: Cleanup old/offline data\n        S-\u003e\u003eT: Send cycle summary\n        Note over S: Sleep cycle_sleep_seconds\n    end\n```\n\n#### Luồng dữ liệu Neo4j\n\n```mermaid\ngraph LR\n    subgraph \"BBOT Events\"\n        E1[DNS_NAME]\n        E2[OPEN_TCP_PORT]\n        E3[TECHNOLOGY]\n        E4[URL]\n        E5[EMAIL]\n    end\n    \n    subgraph \"Neo4j Nodes\"\n        N1[Host]\n        N2[Domain]\n        N3[DNS_NAME]\n        N4[OPEN_TCP_PORT]\n        N5[TECHNOLOGY]\n        N6[IP]\n        N7[URL]\n        N8[Email]\n        N9[Module]\n        N10[Event]\n    end\n    \n    E1 --\u003e N3\n    E2 --\u003e N4\n    E3 --\u003e N5\n    E4 --\u003e N7\n    E5 --\u003e N8\n    \n    N1 --\u003e|PART_OF| N2\n    N3 --\u003e|RESOLVES_TO| N1\n    N4 --\u003e|ON_HOST| N1\n    N1 --\u003e|USES_TECH| N5\n    N10 --\u003e|ABOUT| N1\n    N10 --\u003e|ABOUT| N2\n    N10 --\u003e|EMITTED_BY| N9\n    \n    style N1 fill:#bbf,stroke:#333,stroke-width:2px\n    style N2 fill:#bfb,stroke:#333,stroke-width:2px\n    style N3 fill:#fbb,stroke:#333,stroke-width:2px\n    style N4 fill:#fbf,stroke:#333,stroke-width:2px\n    style N5 fill:#ffb,stroke:#333,stroke-width:2px\n```\n\n---\n\n## 2. Hướng dẫn cài đặt từ đầu (Step-by-Step)\n\n### 2.1 Chuẩn bị chung (áp dụng cho mọi node)\n\n#### 2.1.1 Yêu cầu hạ tầng\n\n- VPS Ubuntu 22.04/24.04 (tối thiểu 2 vCPU, 4 GB RAM khuyến nghị)\n- Quyền `sudo`\n- Máy chủ trung tâm cần domain đã trỏ A-record về IP (ví dụ: `osint.example.com`)\n- Cổng mạng mở theo vai trò:\n  - Central: 80/443 (reverse proxy) và 8000 (tùy chọn nếu truy cập trực tiếp API)\n  - Worker: chỉ cần 22/8000 hoặc port nội bộ tùy chính sách\n\n#### 2.1.2 Cập nhật hệ thống và cài Docker\n\n```bash\nsudo apt-get update -y \u0026\u0026 sudo apt-get upgrade -y\nsudo apt-get install -y ca-certificates curl gnupg lsb-release git\n\nsudo install -m 0755 -d /etc/apt/keyrings\ncurl -fsSL https://download.docker.com/linux/ubuntu/gpg \\\n  | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg\n\necho \\\n  \"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \\\n   https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable\" \\\n  | sudo tee /etc/apt/sources.list.d/docker.list \u003e /dev/null\n\nsudo apt-get update -y\nsudo apt-get install -y docker-ce docker-ce-cli containerd.io \\\n  docker-buildx-plugin docker-compose-plugin\n\nsudo systemctl enable --now docker\nsudo docker --version\nsudo docker compose version\n```\n\n#### 2.1.3 Clone repository\n\n```bash\ncd /opt\nsudo git clone https://github.com/dn9uy3n/bbot-osint-mcp.git\ncd bbot-osint-mcp\nsudo chown -R $USER:$USER .\n```\n\n#### 2.1.4 Sinh secrets mạnh\n\n```bash\nbash scripts/init-secrets.sh\ncat secrets/credentials.txt\n```\n\nLưu lại `API_TOKEN` và `NEO4J_PASSWORD` để cấu hình ở các bước tiếp theo.\n\n### 2.2 Triển khai trung tâm (central, có domain)\n\n#### 2.2.1 Tạo file `.env` cho central\n\n```bash\ncp .env.example .env\nnano .env\n```\n\nCác biến:\n\n```env\nLE_DOMAIN=osint.example.com\nLE_EMAIL=admin@example.com\nPUBLIC_BASE_URL=https://osint.example.com\nNEO4J_USERNAME=neo4j\nRATE_LIMIT_PER_MINUTE=120\nMAX_CONCURRENT_SCANS=2\nCLEANUP_ENABLED=true\nEVENT_RETENTION_DAYS=30\nOFFLINE_HOST_RETENTION_DAYS=30\nORPHAN_CLEANUP_ENABLED=true\n```\n\n- **Ví dụ tạo nhanh `.env`** (sử dụng giá trị từ `init_config.json` và thư mục `secrets/`):\n\n```bash\ncat \u003c\u003c'EOF' \u003e .env\nLE_DOMAIN=osint.example.com\nLE_EMAIL=admin@example.com\nNEO4J_PASSWORD=\"$(tr -d '\\n' \u003c secrets/neo4j_password)\"\nEOF\n```\n\nSau đó mở file để bổ sung thêm các biến khác nếu cần (`PUBLIC_BASE_URL`, `RATE_LIMIT_PER_MINUTE`, ...).\n\n- `API_TOKEN` và `NEO4J_PASSWORD` sẽ được Docker secrets tự đọc từ thư mục `secrets/`.\n- Có thể thêm `TELEGRAM_BOT_TOKEN` / `TELEGRAM_CHAT_ID` nếu muốn nhận thông báo.\n\n#### 2.2.2 Cấu hình `init_config.json` cho central\n\n```bash\ncp init_config.json.example init_config.json\nnano init_config.json\n```\n\n```json\n{\n  \"targets\": [\"evilcorp.com\", \"target2.com\"],\n  \"deployment_role\": \"central\",\n  \"scan_defaults\": {\n    \"presets\": [\"subdomain-enum\"],\n    \"flags\": [\"safe\"],\n    \"max_workers\": 2,\n    \"target_sleep_seconds\": 300,\n    \"cycle_sleep_seconds\": 3600\n  },\n  \"bbot_modules\": {\n    \"securitytrails\": { \"api_key\": \"YOUR_SECURITYTRAILS_KEY\" },\n    \"shodan_dns\": { \"api_key\": \"YOUR_SHODAN_KEY\" },\n    \"virustotal\": { \"api_key\": \"YOUR_VIRUSTOTAL_KEY\" }\n  },\n  \"workers\": [\n    { \"id\": \"worker-hcm\", \"token\": \"\u003cchuỗi-ngẫu-nhiên-64-bytes\u003e\" },\n    { \"id\": \"worker-hn\", \"token\": \"\u003cchuỗi-khác\u003e\" }\n  ]\n}\n```\n\n- `workers` là danh sách cho phép upload từ các worker.\n- Token nên ≥64 ký tự (hex/base64). Khi thu hồi quyền, chỉ cần xóa entry tương ứng rồi `docker compose restart osint`.\n\n#### 2.2.3 Khởi động stack central \u0026 mở firewall\n\n```bash\nsudo ufw allow 80/tcp\nsudo ufw allow 443/tcp\nsudo ufw allow 22/tcp\nsudo ufw allow 8000/tcp comment 'bbot-osint API (tùy chọn)'\nsudo ufw enable\nsudo ufw status\n\nsudo docker compose up -d --build\nsudo docker logs -f bbot_caddy\n```\n\n- Caddy sẽ tự xin chứng chỉ Let's Encrypt cho `LE_DOMAIN`.\n- Đợi log `certificate obtained successfully` để xác nhận HTTPS hoạt động.\n\n- Nếu muốn hạn chế tài nguyên: \n\n```bash\ndocker ps -q | xargs -r -I{} docker update --cpus 0.8 {}\n```\n\n#### 2.2.4 Kiểm tra dịch vụ trung tâm\n\n```bash\nAPI_TOKEN=$(grep '^API_TOKEN:' secrets/credentials.txt | awk '{print $2}')\n\ncurl -s -H \"X-API-Token: $API_TOKEN\" https://osint.example.com/healthz\ncurl -s -H \"X-API-Token: $API_TOKEN\" https://osint.example.com/status\n```\n\nNgoài ra có thể theo dõi tiến trình quét:\n\n```bash\nsudo docker logs -f bbot_osint\n```\n\n### 2.3 Triển khai worker (không cần domain)\n\n#### 2.3.1 Chuẩn bị `.env` tối giản\n\n```bash\ncp .env.example .env\nnano .env\n```\n\n- Để trống `LE_DOMAIN` và `LE_EMAIL` hoặc comment hai dòng này.\n- `PUBLIC_BASE_URL` có thể để `http://127.0.0.1:8000` (chỉ phục vụ nội bộ).\n- Giữ nguyên các thông số giới hạn (rate limit, cleanup) để scheduler hoạt động.\n\n#### 2.3.2 Cấu hình `init_config.json` cho worker\n\n```json\n{\n  \"targets\": [\"acme.example\"],\n  \"deployment_role\": \"worker\",\n  \"scan_defaults\": {\n    \"presets\": [\"subdomain-enum\"],\n    \"flags\": [\"safe\"],\n    \"max_workers\": 2,\n    \"target_sleep_seconds\": 300,\n    \"cycle_sleep_seconds\": 3600\n  },\n  \"central_api\": {\n    \"url\": \"https://osint.example.com/ingest/output\",\n    \"worker_id\": \"worker-hcm\",\n    \"worker_token\": \"\u003cchuỗi-ngẫu-nhiên-64-bytes\u003e\",\n    \"auto_upload\": true,\n    \"compress\": true,\n    \"verify_tls\": true,\n    \"timeout\": 180\n  }\n}\n```\n\n- `central_api.url` có thể dùng domain hoặc IP reverse proxy trung tâm.\n- Khi cần upload thủ công, đặt `auto_upload` thành `false` rồi dùng CLI `python -m app.worker_ingest ...`.\n\n#### 2.3.3 Khởi chạy container worker\n\nWorker chỉ cần dịch vụ `osint`:\n\n```bash\nsudo docker compose up -d --build --no-deps osint\nsudo docker logs -f bbot_osint\n```\n\n- Các service `neo4j` và `proxy` không cần chạy trên worker.\n- Nếu muốn hạn chế tài nguyên: \n```bash\ndocker ps -q | xargs -r -I{} docker update --cpus 0.8 {}\n```\n\n#### 2.3.4 Xác nhận upload thành công\n\nTrong log `bbot_osint` sẽ xuất hiện dòng:\n\n```\n[INFO] Uploaded 4373 records for acme.example from new scan dirs: [...]\n```\n\nTrên trung tâm kiểm tra log `bbot_osint` để thấy `Imported N records` cho `worker_id` tương ứng.\n\n### 2.4 Các tham số scan quan trọng\n\n1. **targets**: Danh sách target quét tự động.\n2. **target_sleep_seconds** (mặc định 300): nghỉ giữa các target trong cùng chu kỳ.\n3. **cycle_sleep_seconds** (mặc định 3600): nghỉ sau khi hoàn thành toàn bộ danh sách.\n\n📖 Xem thêm: [SLEEP_PARAMETERS.md](SLEEP_PARAMETERS.md)\n\n**workers** (chỉ cho trung tâm): cấu hình danh sách được phép upload bằng `init_config.json`.\n\n**central_api** (chỉ cho worker): xác định endpoint, credential và hành vi upload.\n\n### 2.5 Kịch bản cấu hình điển hình\n\n**1. Chỉ dùng máy chủ trung tâm (không có worker)**\n- Giữ `deployment_role` là `central` (mặc định nếu không khai báo).\n- Bỏ hẳn khóa `workers` hoặc để mảng rỗng nếu không muốn chấp nhận upload từ bên ngoài.\n- Scanner nội bộ sẽ quét các target trong `targets`, import trực tiếp vào Neo4j.\n\n**2. Trung tâm + nhiều worker**\n- Máy trung tâm: `deployment_role: \"central\"`, khai báo danh sách `workers` với `id/token` riêng cho từng worker.\n- Worker: `deployment_role: \"worker\"`, cấu hình `central_api` bằng đúng `worker_id/worker_token` tương ứng, bật `auto_upload` để sau mỗi target sẽ tự gọi `/ingest/output`.\n- Đảm bảo firewall chỉ cho phép IP worker gọi endpoint trung tâm; token bị lộ có thể xoá khỏi `workers` để vô hiệu.\n\n**3. Worker tạm thời / gửi thủ công**\n- `deployment_role: \"worker\"`, nhưng đặt `central_api.auto_upload = false`.\n- Sau khi scan hoàn tất, chạy CLI: `python -m app.worker_ingest --file ... --url ... --worker-id ... --worker-token ... --domain ...` để đẩy dữ liệu bất cứ lúc nào.\n- Phù hợp khi cần kiểm soát quy trình gửi hoặc khi worker đang ở môi trường hạn chế.\n\n### 2.6 Preset \u0026 Flag (Cập nhật)\n- Preset hỗ trợ: `subdomain-enum`, `spider`, `email-enum`, `web-basic`, `cloud-enum`.\n- Flag hỗ trợ: `safe`, `active`.\n- Preset không hợp lệ sẽ bị bỏ qua và mặc định `subdomain-enum`.\n- Flag không hợp lệ sẽ bị loại bỏ tự động.\n- Image đã cài sẵn Node.js/JRE/openssl và một số Python deps phổ biến để hỗ trợ modules nặng; container chạy root để cho phép cài deps bổ sung khi cần.\n\n### 2.7 Vô hiệu hóa module từ `init_config.json`\nCó thể tắt các module không cần (ví dụ gowitness trên server không cần screenshot):\n```json\n\"bbot_disable_modules\": [\"gowitness\"]\n```\n\n### 2.8 Theo dõi quá trình scan\n\nContinuous scanner tự động bắt đầu khi service khởi động (central và worker). Theo dõi logs:\n\n```bash\nsudo docker logs -f bbot_osint\n# Filter chỉ xem scanner logs\nsudo docker logs -f bbot_osint 2\u003e\u00261 | grep -E \"Scanning|Sleep|Cycle\"\n```\n\n**Output mẫu:**\n```\n[INFO] === Starting scan cycle at 2025-10-27 14:30:00 ===\n[INFO] [1/2] Scanning target: evilcorp.com\n[INFO] ✓ Target evilcorp.com completed: 1247 events\n[INFO] Sleeping 300s before next target...\n[INFO] [2/2] Scanning target: target2.com\n[INFO] ✓ Target target2.com completed: 892 events\n[INFO] Running cleanup...\n[INFO] === Cycle completed in 1534s, total events: 2139 ===\n[INFO] Sleeping 3600s until next cycle...\n```\n\n**Telegram notification**: Sau mỗi chu kỳ, bạn sẽ nhận tin nhắn tóm tắt.\n\n---\n\n## 3. Giải thích chi tiết về Cleanup (Dọn dẹp)\n\n### Cleanup hoạt động như thế nào?\n\n**Cleanup KHÔNG xóa toàn bộ dữ liệu**, chỉ xóa:\n\n1. **Events quá hạn**: Events cũ hơn `EVENT_RETENTION_DAYS` (mặc định 30 ngày)\n   - Ví dụ: Event scan từ 31 ngày trước sẽ bị xóa\n   - **Dữ liệu quan trọng như Host, Domain vẫn được giữ**\n\n2. **Host offline quá hạn**: Host có `status=offline` và `last_seen_ts` cũ hơn `OFFLINE_HOST_RETENTION_DAYS`\n   - Chỉ xóa host đã offline quá lâu\n   - Host online hoặc mới offline vẫn được giữ\n\n3. **Orphan nodes** (node mồ côi): Nodes không có quan hệ nào\n   - Ví dụ: Module không liên kết với Event nào\n   - Giúp giữ database gọn gàng\n\n### Cấu hình cleanup\n\nTrong `.env`:\n\n```env\n# Bật/tắt cleanup\nCLEANUP_ENABLED=true\n\n# Giữ events trong 30 ngày\nEVENT_RETENTION_DAYS=30\n\n# Xóa host offline sau 30 ngày\nOFFLINE_HOST_RETENTION_DAYS=30\n\n# Xóa nodes mồ côi\nORPHAN_CLEANUP_ENABLED=true\n```\n\n**Lưu ý quan trọng:**\n- Host **online** và Domain **KHÔNG BAO GIỜ** bị xóa tự động\n- Chỉ xóa dữ liệu \"rác\" và dữ liệu cũ theo chính sách\n- Cleanup chạy sau mỗi lần scan\n\n### Ví dụ\n\nScan lần 1 (ngày 1):\n- Thu về 100 subdomains, 1000 events\n- Database: 100 hosts, 1000 events\n\nScan lần 2 (ngày 35):\n- Thu về 120 subdomains mới\n- Cleanup xóa: 1000 events cũ (\u003e30 ngày), 10 hosts offline (\u003e30 ngày)\n- Database sau cleanup: 110 hosts online, 1200 events mới\n\n---\n\n## 4. Sử dụng API\n\n### Các endpoint chính\n\n**1. Healthcheck \u0026 Status**\n\n```bash\n# Kiểm tra service health\ncurl -H \"X-API-Token: $API_TOKEN\" \"https://osint.example.com/healthz\"\n\n# Xem trạng thái scanner chi tiết\ncurl -H \"X-API-Token: $API_TOKEN\" \"https://osint.example.com/status\"\n```\n\n**Response mẫu `/status`:**\n```json\n{\n  \"scanner_running\": true,\n  \"targets\": [\"evilcorp.com\", \"target2.com\"],\n  \"scan_config\": {\n    \"presets\": [\"subdomain-enum\"],\n    \"max_workers\": 2,\n    \"target_sleep_seconds\": 300,\n    \"cycle_sleep_seconds\": 3600\n  },\n  \"cleanup_enabled\": true\n}\n```\n\n**2. Query hosts**\n\n```bash\ncurl -X POST \"https://osint.example.com/query\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-Token: $API_TOKEN\" \\\n  -d '{\n    \"domain\": \"evilcorp.com\",\n    \"online_only\": true,\n    \"limit\": 100\n  }'\n```\n\n**3. Query events (full fidelity)**\n\n```bash\ncurl -X POST \"https://osint.example.com/events/query\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-Token: $API_TOKEN\" \\\n  -d '{\n    \"types\": [\"DNS_NAME\", \"OPEN_TCP_PORT\", \"TECHNOLOGY\"],\n    \"modules\": [\"subfinder\", \"httpx\"],\n    \"domain\": \"evilcorp.com\",\n    \"since_ts\": 1729000000,\n    \"limit\": 200\n  }'\n```\n\n**Lưu ý**: Không có endpoint `/scan` để trigger scan thủ công. Scanner tự động chạy theo chu kỳ với targets trong `init_config.json`.\n\n---\n\n## 5. Tích hợp vào Cursor (MCP Client)\n\n### Bước 1: Cài đặt MCP trong Cursor\n\n1. Mở Cursor Settings\n2. Tìm phần MCP configuration\n3. Thêm cấu hình server:\n\n```json\n{\n  \"mcpServers\": {\n    \"bbot-osint\": {\n      \"type\": \"http\",\n      \"url\": \"http://osint.example.com/mcp\",\n      \"headers\": {\n        \"X-API-Token\": \"YOUR_API_TOKEN_FROM_SECRETS\"\n      }\n    }\n  }\n}\n```\n\n### Bước 2: Restart MCP client\n\nTrong Cursor:\n1. Command Palette (Ctrl+Shift+P / Cmd+Shift+P)\n2. Gõ \"MCP: Restart\"\n3. Chọn \"MCP: Restart Client\"\n\n### Bước 3: Sử dụng tools\n\nBạn sẽ thấy 3 tools (chỉ để query, không trigger scan):\n\n1. **osint.query**: Query hosts từ Neo4j\n2. **osint.events.query**: Query events chi tiết\n3. **osint.status**: Xem trạng thái scanner\n\n**Các endpoint MCP hữu ích (cho agent / kiểm thử):**\n\n- `GET /mcp/`: Handshake metadata, khai báo capabilities.\n- `GET /mcp/tools`: Danh sách tool + JSON Schema input.\n- `POST /mcp/tools/\u003ctool\u003e`: Gọi trực tiếp từng tool với payload JSON.\n- `POST /mcp/invoke`: Gọi tool bất kỳ dạng `{\"tool\": \"osint.query\", \"arguments\": {...}}`.\n- `GET /mcp/healthz`: Kiểm tra nhanh tình trạng shim.\n\n**Ví dụ trong Cursor chat:**\n\n```\nCall MCP tool: osint.query {\"domain\":\"evilcorp.com\",\"online_only\":true}\n```\n\n```\nCall MCP tool: osint.events.query {\"types\":[\"DNS_NAME\",\"OPEN_TCP_PORT\"],\"limit\":100}\n```\n\n```\nCall MCP tool: osint.status {}\n```\n\n**Lưu ý**: MCP **KHÔNG có** tool `osint.scan`. Scan tự động chạy theo chu kỳ từ service backend.\n\n---\n\n## 6. Neo4j Data Model\n\n### Nodes\n\n- `Domain {name}`: Domain chính\n- `Host {name, status, last_seen_ts, sources, ports}`: Subdomain/host\n- `IP_ADDRESS {addr}`: Địa chỉ IP\n- `URL {value}`, `URL_UNVERIFIED {value}`: URLs\n- `EMAIL_ADDRESS {value}`: Email addresses\n- `DNS_NAME {name, last_seen_ts}`: DNS records từ BBOT\n- `OPEN_TCP_PORT {endpoint, port, host, last_seen_ts}`: Cổng mở (ví dụ: `example.com:443`)\n- `TECHNOLOGY {name}`: Công nghệ phát hiện được (ví dụ: `nginx`, `PHP`, `WordPress`)\n- `Module {name}`: BBOT modules\n- `Event {id, type, ts, raw}`: Events từ BBOT (lưu đầy đủ raw data)\n\n### Relationships\n\n- `(:Host)-[:PART_OF]-\u003e(:Domain)`: Host thuộc domain\n- `(:DNS_NAME)-[:ON_HOST]-\u003e(:Host)`: DNS name thuộc host\n- `(:OPEN_TCP_PORT)-[:ON_HOST]-\u003e(:Host)`: Port mở trên host nào\n- `(:Host)-[:USES_TECH]-\u003e(:TECHNOLOGY)`: Host sử dụng công nghệ gì\n- `(:EVENT)-[:ABOUT]-\u003e(:Domain|:Host|:IP_ADDRESS|:URL|:URL_UNVERIFIED|:EMAIL_ADDRESS|:DNS_NAME|:OPEN_TCP_PORT|:TECHNOLOGY)`: Event về entity nào\n- `(:Event)-[:EMITTED_BY]-\u003e(:Module)`: Event từ module nào\n\n### Sơ đồ Mermaid\n\n```mermaid\ngraph LR\n  subgraph Entities\n    D[DOMAIN]\n    H[HOST]\n    DN[DNS_NAME]\n    OP[OPEN_TCP_PORT]\n    U[URL]\n    UU[URL_UNVERIFIED]\n    EML[EMAIL_ADDRESS]\n    MA[MOBILE_APP]\n    TEC[TECHNOLOGY]\n    ASN[ASN]\n    FND[FINDING]\n    SB[STORAGE_BUCKET]\n    SOC[SOCIAL]\n    CR[CODE_REPOSITORY]\n    IP[IP_ADDRESS]\n    SC[SCAN]\n    EV[EVENT]\n  end\n\n  SC -- TARGETS --\u003e D\n  EV -- ABOUT --\u003e SC\n  DN -- ON_HOST --\u003e H\n  OP -- ON_HOST --\u003e H\n  U -- ON_HOST --\u003e H\n  EML -- ON_HOST --\u003e H\n  SB -- ON_HOST --\u003e H\n  FND -- ON_HOST --\u003e H\n  H -- PART_OF --\u003e D\n  H -- USES_TECH --\u003e TEC\n  U -- RESOLVES_TO --\u003e IP\n  OP -- RESOLVES_TO --\u003e IP\n  H -- RESOLVES_TO --\u003e IP\n  FND -- RELATED_URL --\u003e U\n  SB -- EXPOSED_AT --\u003e U\n  MA -- OF_DOMAIN --\u003e D\n  U -- OF_DOMAIN --\u003e D\n  FND -- OF_DOMAIN --\u003e D\n  SB -- OF_DOMAIN --\u003e D\n  SOC -- OF_DOMAIN --\u003e D\n  CR -- OF_DOMAIN --\u003e D\n  ASN -- OF_DOMAIN --\u003e D\n  IP -- OF_DOMAIN --\u003e D\n```\n\n### Truy vấn Neo4j\n\nNeo4j đã được publish cục bộ trên VPS ở 127.0.0.1:7474 (HTTP) và 127.0.0.1:7687 (Bolt). Truy cập an toàn từ máy local qua SSH Tunnel (không cần chạy socat):\n\n```bash\n# Từ máy local\nssh -N -L 7474:127.0.0.1:7474 -L 7687:127.0.0.1:7687 user@VPS_IP\n```\n\nSau đó mở: `http://localhost:7474` (Bolt: `bolt://localhost:7687`)\nUser: `neo4j`, Password: từ `secrets/neo4j_password`.\n\n**Ví dụ queries:**\n\n```cypher\n// Tìm tất cả subdomains của evilcorp.com\nMATCH (h:Host)-[:PART_OF]-\u003e(d:Domain {name: \"evilcorp.com\"})\nWHERE h.status = \"online\"\nRETURN h.name, h.last_seen_ts, h.ports\nORDER BY h.last_seen_ts DESC\n\n// Tìm tất cả open ports của một domain\nMATCH (op:OPEN_TCP_PORT)-[:ON_HOST]-\u003e(h:Host)-[:PART_OF]-\u003e(d:Domain {name: \"evilcorp.com\"})\nOPTIONAL MATCH (op)-[:RESOLVES_TO]-\u003e(i:IP_ADDRESS)\nRETURN h.name, op.port, collect(distinct i.addr) AS ips\nORDER BY op.port\n\n// Tìm công nghệ được sử dụng\nMATCH (h:Host)-[:USES_TECH]-\u003e(t:TECHNOLOGY)\nWHERE h.name CONTAINS \"evilcorp.com\"\nRETURN h.name, collect(t.name) as technologies\n\n// Tìm DNS records\nMATCH (dn:DNS_NAME)-[:ON_HOST]-\u003e(h:Host)-[:PART_OF]-\u003e(d:Domain {name: \"evilcorp.com\"})\nRETURN dn.name, h.name, dn.last_seen_ts\nORDER BY dn.last_seen_ts DESC\n\n// Tìm events liên quan đến một host\nMATCH (ev:EVENT)-[:ABOUT]-\u003e(h:Host {name: \"www.evilcorp.com\"})\nRETURN ev.type, ev.raw\nORDER BY ev.ts DESC\nLIMIT 50\n```\n\n---\n\n## 7. Bảo mật\n\n### Các biện pháp đã áp dụng\n\n1. **API Token**: Bắt buộc header `X-API-Token` cho mọi endpoint\n2. **Docker Secrets**: Credentials lưu trong Docker secrets, không hardcode\n3. **Internal Network**: Neo4j chỉ lộ trên mạng nội bộ Docker\n4. **HTTPS Only**: Caddy tự động redirect HTTP → HTTPS\n5. **Container Hardening**: Read-only filesystem, drop capabilities, no-new-privileges\n6. **Rate Limiting**: Giới hạn request per IP\n\n### Khuyến nghị bổ sung\n\n1. **Firewall**: Chỉ mở 80/443 public, SSH qua IP whitelist\n2. **VPN**: Truy cập Neo4j và quản trị qua VPN\n3. **Monitoring**: Theo dõi logs và cảnh báo 429/401\n4. **Secrets Rotation**: Xoay vòng API_TOKEN định kỳ\n5. **Backup**: Backup Neo4j data volume thường xuyên\n\n```bash\n# Backup Neo4j\nsudo docker compose exec neo4j neo4j-admin database dump neo4j \\\n  --to-path=/data/backups/backup-$(date +%Y%m%d).dump\n```\n\n---\n\n## 8. Quản lý và Bảo trì\n\n### Tạm dừng để sửa config\n\nKhi cần thêm targets mới, cập nhật API keys, hoặc thay đổi sleep times:\n\n```bash\ncd /opt/bbot-osint-mcp\n\n# Dừng OSINT service\nsudo docker compose stop osint\n\n# Sửa config\nnano init_config.json\n\n# Khởi động lại\nsudo docker compose start osint\n\n# Xem logs\nsudo docker logs -f bbot_osint\n```\n\n**Hoặc hot reload (không cần stop):**\n\n```bash\n# Sửa config trực tiếp\nnano init_config.json\n\n# Restart để apply\nsudo docker compose restart osint\n```\n\n### Các thao tác thường dùng\n\n```bash\n# Xem logs realtime\nsudo docker logs -f bbot_osint\n\n# Xem chỉ scanner logs\nsudo docker logs -f bbot_osint 2\u003e\u00261 | grep -E \"Scanning|Sleep|Cycle\"\n\n# Kiểm tra status\ncurl -H \"X-API-Token: $(cat secrets/api_token)\" \\\n  https://osint.example.com/status\n\n# Restart services\nsudo docker compose restart osint\n\n# Update code\ngit pull\nsudo docker compose up -d --build\n\n# Xem resource usage\nsudo docker stats bbot_osint bbot_neo4j\n```\n\n### Backup dữ liệu\n\n```bash\n# Backup Neo4j volume\nmkdir -p ~/backups\nsudo docker run --rm \\\n  -v bbot-osint-mcp_neo4j_data:/data \\\n  -v ~/backups:/backup \\\n  ubuntu tar czf /backup/neo4j-$(date +%Y%m%d).tar.gz /data\n\n# Backup config\ncp init_config.json ~/backup-init_config.json\ncp secrets/credentials.txt ~/backup-credentials.txt\n```\n\n**Chi tiết đầy đủ:** [docs/UNINSTALL.md](docs/UNINSTALL.md) (bao gồm tạm dừng, sửa config, backup, restore)\n\n---\n\n## 9. Gỡ cài đặt\n\nXem hướng dẫn chi tiết: **[docs/UNINSTALL.md](docs/UNINSTALL.md)**\n\n### Gỡ nhanh (xóa tất cả)\n\n```bash\ncd /opt/bbot-osint-mcp\nsudo docker compose down -v\nsudo docker rmi bbot-osint-mcp-osint:latest neo4j:5.23.1 caddy:2.8-alpine\ncd /opt \u0026\u0026 sudo rm -rf /opt/bbot-osint-mcp\n```\n\n### Hoặc dùng script tự động\n\n```bash\ncd /opt/bbot-osint-mcp\nchmod +x scripts/uninstall.sh\n./scripts/uninstall.sh\n```\n\nScript cung cấp 3 tùy chọn:\n1. Gỡ hoàn toàn (xóa tất cả)\n2. Gỡ nhưng giữ dữ liệu (có thể cài lại sau)\n3. Chỉ reset database Neo4j\n\n---\n\n## 10. Troubleshooting\n\n### 1. Let's Encrypt không ra cert\n\n**Kiểm tra:**\n```bash\n# DNS đã trỏ đúng?\ndig +short osint.example.com\n\n# Firewall đã mở 80/443?\nsudo ufw status\n\n# Logs Caddy\nsudo docker logs bbot_caddy\n```\n\n**Giải pháp:**\n- Đảm bảo DNS trỏ về IP VPS\n- Tắt Cloudflare proxy (mây xám) trong quá trình xin cert lần đầu\n- Kiểm tra port 80/443 không bị chặn\n\n### 2. API trả về 401 Unauthorized\n\n**Nguyên nhân**: Sai hoặc thiếu `X-API-Token`\n\n**Giải pháp:**\n```bash\n# Kiểm tra token đúng\ncat secrets/credentials.txt | grep API_TOKEN\n\n# Test với token đúng\ncurl -H \"X-API-Token: $(grep '^API_TOKEN:' secrets/credentials.txt | awk '{print $2}')\" \\\n  \"https://osint.example.com/healthz\"\n```\n\n### 3. Scan bị block/rate limit\n\n**Nguyên nhân**: Quét quá nhanh\n\n**Giải pháp:**\n- Giảm `max_workers` xuống 1-2\n- Tăng `sleep_after_scan_seconds`\n- Sử dụng API keys cho các module (trong `init_config.json`)\n\n### 4. Database đầy\n\n**Giải pháp:**\n- Giảm `EVENT_RETENTION_DAYS` và `OFFLINE_HOST_RETENTION_DAYS`\n- Chạy cleanup thủ công:\n\n```bash\n# Vào container\nsudo docker exec -it bbot_osint bash\n\n# Python shell\npython3 -c \"\nfrom app.repository import cleanup_graph\nimport time\nstats = cleanup_graph(int(time.time()))\nprint(stats)\n\"\n```\n\n---\n\n## 11. Tips vận hành\n\n1. **Xem logs realtime:**\n```bash\nsudo docker compose logs -f\n```\n\n2. **Restart services:**\n```bash\nsudo docker compose restart osint\n```\n\n3. **Update code:**\n```bash\ngit pull\nsudo docker compose up -d --build\n```\n\n4. **Xem stats Neo4j:**\n```cypher\n// Trong Neo4j Browser\nMATCH (n) RETURN labels(n) as type, count(*) as count\n```\n\n5. **Export dữ liệu:**\n```bash\n# Query và export JSON\ncurl -X POST \"https://osint.example.com/query\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"X-API-Token: $API_TOKEN\" \\\n  -d '{\"domain\":\"evilcorp.com\",\"limit\":10000}' \\\n  | jq '.results' \u003e export.json\n```\n\n---\n\n**Chúc bạn triển khai thành công!** 🎉\n\nNếu gặp vấn đề, vui lòng mở issue trên GitHub hoặc liên hệ.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdn9uy3n%2Fbbot-osint-mcp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdn9uy3n%2Fbbot-osint-mcp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdn9uy3n%2Fbbot-osint-mcp/lists"}