egressview

EgressView アーキテクチャ

English

本書では、router障害の分離、観測元の保持、databaseの安全性、API securityを支える本番アーキテクチャを説明します。

Application coreはcloud非依存です。local stdio、private HTTP、private OAuth、 public OAuthと将来の完全閉域境界はDeployment profile を参照してください。

システム全体

flowchart LR
  subgraph Network[Home / SOHO network]
    Y[Yamaha RTX routers]
    C[Cisco IOS routers]
    A[任意のASUS AP]
    L[任意のdnsmasq / syslog]
    M[任意のmacOS Agent<br/>プロセス名つき]
  end

  subgraph Server[EgressView Node.js process]
    RM[Router manager / registry]
    PS[Router別のpoll scheduler]
    IN[Agent ingest<br/>認証 / 冪等 / 相関]
    N[Session正規化 / runtime重複排除]
    EN[DNS / RDAP / GeoIP / threat enrichment]
    DB[(SQLite WAL\nconnections + observations + devices\n+ agent_observations)]
    HTTP[Express REST API]
    WS[Socket.IO update]
    MCP[MCP stdio / HTTP]
  end

  Y -->|SSH NAT / ARP| RM
  C -->|SSH NAT / ARP| RM
  RM --> PS --> N
  A -->|HTTP client data| N
  L -->|log event| N
  M -->|HTTPS ingest<br/>Agentから発信| IN
  IN --> N
  IN --> DB
  N --> DB
  N --> EN --> DB
  DB --> HTTP --> UI[Browser UI]
  N --> WS --> UI
  DB --> MCP --> AI[AI assistant]

Agentは同じ正規化経路へ合流します。 これは配線上の都合ではなく必須条件です。脅威照合・宛先の補強・端末追跡・通知はすべてconnectionsを対象に動くため、そこへ入らない観測は照合されないまま一覧に並びます。 利用者から見ると「脅威が0件」と区別がつきません。Agentの観測を別扱いにしないのはこのためです。

収集とrouter障害の分離

各routerは、不変のrouterId、共通poller契約を実装したYamaha/Cisco adapter、独立したscheduler状態を持ちます。Yamaha/Ciscoを任意に混在して最大10台登録できます。

汎用schedulerは初回pollを分散し、1回ごとのtimeout、連続失敗時のbackoff、router単位の開始・停止を管理します。1台が利用不能でも正常なrouterの収集は継続します。Adapterはvendor固有のSSH commandとNAT/ARP出力を共通session形式へ変換し、その後の処理を共有します。

Runtime上の自然keyは(src, dst, dport, proto)です。同じ通信を複数routerが観測した場合、connectionは重複排除し、全観測元をconnection_observationsへ保存して、安定したIDのobservedByとして公開します。削除したrouter IDはtombstoneとして残るため、過去データの帰属は変わりません。

端末Agent

Routerは「何が外へ出たか」を見せますが、どのアプリケーションが出したかは見せません。macOS Agentがその1点を埋めます。

Agentは補助であって代替ではありません。 1台のMacについては取りこぼしが少ない(フロー発生時に受け取るため60秒の隙間が無い)一方、LAN内の他の機器は一切見えません。

Data flow

  1. Router adapterが通常60秒ごとにSSHでNAT sessionとaddress-neighbor情報を取得します。
  2. 任意のINSPECT、DHCPD、dnsmasq、ASUS sourceが短命session、IP/MAC対応、hostname、Wi-Fi metadataを補います。
  3. 任意の端末Agentが、自分が観測したflowをプロセス名つきで送信します(POST /api/agent/ingest)。受理したbatchはrouterのpollと同じ正規化経路へ入ります。
  4. Runtimeが反復観測を統合し、reverse DNS、RDAP、GeoIP、OUI/端末識別、threat intelligenceの付加処理を開始します。
  5. Connection履歴とrouter観測を同じSQLite transactionで一括保存します。BrowserはSocket.IOで差分を受け取り、RESTで永続履歴を検索します。
  6. 検出、beacon、端末、通知moduleが同じ永続データから上位の情報を生成します。観測元がrouterかAgentかを問いません。

永続化と起動

EgressViewは1つのSQLite databaseをWAL modeで使用し、history、sessions、devices、enrichment、beaconsが個別のconnectionを持ちます。db-bootstrap.jsが明示的な起動境界です。Schema migrationを所有するhistoryを最初に開き、migration成功後にだけ他の利用者を開きます。

Migrationは末尾追加方式でfail-closedです。データ変更を伴うmigrationの前に空き容量を検査し、整合性を検証したbackupを作成してからtransactionを実行し、完了後のdatabaseも検証します。Restoreも同じ原則で、復元元検査、安全backup必須、置換、全利用者の再接続、復元後検査を行い、どこかで失敗すればrollbackします。

Backup cleanupのpreviewと実行は専用worker threadで行います。SQLiteのintegrity checkは同期処理で数GBを走査する可能性があるためです。Main processはcleanupを同時1件に制限し、進捗、cancel、timeout状態を公開します。Workerでも検証済み世代の最低保持条件と削除直前の再検証を維持し、event loopから分離してもfail-closed条件は緩めません。

Schema v5ではrouterの観測情報をconnection_observationsだけに保存し、旧connections.source columnは削除済みです。APIの互換用source値は、観測したrouterのkindから導出します。Observation consistency診断では観測漏れ、孤立した観測、router metadataの欠落を検査します。Schema v6はappend-only AI会話、v7はproviderが返したtoken使用量と呼び出し時点のUSD概算、v8は定期・脅威発火・手動・通知テストのAI通知eventをappend-only保存します。検証済みsrc/data/ai-pricing.jsonが版管理単価と根拠情報を提供し、各usage行は呼び出し時点の単価を保持します。過去会話、未知model、usage未返却の料金は推測しません。

Interface

Security boundary

Code map

責務 主な実装
Process wiring / readiness / lifecycle server.js, src/health-state.js
HTTP構成と保護 src/http-app.js, src/routes/
複数router lifecycle src/router-manager.js, src/router-registry.js
Poll scheduling src/router-poll-scheduler.js
Vendor adapter src/pollers/yamaha-adapter.js, src/pollers/cisco-adapter.js
Runtime正規化・重複排除 src/runtime.js
端末Agentの登録・承認 src/agent-identities.js, src/routes/agents.js
Agent ingestの保存と相関 src/agent-ingest-store.js, src/agent-correlation.js, src/agent-ingest-schema.js
macOS Agent本体 apps/agent-macos/
履歴・観測のread/write src/history.js
DB bootstrap / migration src/db-bootstrap.js, src/db-migrate.js
Backup inventory・worker job・prune・restore src/backup-inventory.js, src/backup-prune-runner.js, src/backup-prune-worker.js, src/backup.js, src/routes/backup.js
Browser module public/js/