Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
atproto — AT Protocol参照実装のフォークで、パフォーマンス最適化されたAppView、Rustベースのfirehoseインデクサー、Redisキャッシング、そして大規模な自己ホスト型ソーシャルネットワーキングのためのコミュニティ機能を備えています。 | Kitploit
ツール/GitHubGitHub/blacksky-algorithms/atproto
クラウドインフラストラクチャセキュリティ構成監査シークレット検出アイデンティティ&アクセス管理 (IAM)認証設定ミスAPIセキュリティデータベースセキュリティログ分析
GitHubblacksky-algorithms/atproto

atproto

AT Protocol参照実装のフォークで、パフォーマンス最適化されたAppView、Rustベースのfirehoseインデクサー、Redisキャッシング、そして大規模な自己ホスト型ソーシャルネットワーキングのためのコミュニティ機能を備えています。

94364日前Kitploit レビュー済み

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有
リポジトリを見る

Blacksky AppView

これは、Bluesky Social PBC による AT Protocol リファレンス実装 の Blacksky フォークです。api.blacksky.community の AppView を動かしています。

透明性のため、そして他のコミュニティがこの作業の恩恵を受けられるように公開しています。このリポジトリはコントリビューション、Issue、PR を受け付けていません。 正規の atproto 実装が必要な場合は、bluesky-social/atproto を使用してください。

変更点

すべての変更は packages/bsky (AppView ロジック)、services/bsky (ランタイム設定)、および1つのカスタムマイグレーションにあります。それ以外はすべて上流です。

組み込みの Firehose Consumer を使わない理由

上流のデータプレーンには、イベントを直接インデックスする TypeScript の firehose consumer (subscription.ts) が含まれています。いくつかの理由から、これを Rust 製のインデクサ rsky-wintermute に置き換えました。

  • 大規模パフォーマンス: TypeScript consumer はイベントを逐次的に処理します。ネットワーク規模(約1,000イベント/秒、総記録数185億)では、約90レコード/秒の完全バックフィルには6.5年かかります。Wintermute は並列キュー処理により10,000+ レコード/秒を目標としています。
  • バックフィルアーキテクチャ: Wintermute はライブインデックスとバックフィルを独立したキュー(firehose_live, firehose_backfill, repo_backfill, labels)に分離します。ライブイベントがバックフィル作業によってブロックされることはありません。
  • 運用ツール: Wintermute は、特定のアカウントの直接インデックス、PLC ディレクトリの一括インポート、ラベルストリームのリプレイ、blob 参照の修復、キュー管理のためのユーティリティを含んでいます。これらはすべて、AppView をゼロからブートストラップする際に必要です。

このリポジトリのデータプレーンと AppView はそのまま動作します。これらは wintermute が書き込む PostgreSQL データベースから読み取ります。組み込みの firehose サブスクリプションを開始しないだけです。

パフォーマンスと運用上の修正

これらは、大規模な AppView をセルフホストするすべての人に広く役立ちます。

LATERAL JOIN クエリ最適化 (packages/bsky/src/data-plane/server/routes/feeds.ts)

  • getTimeline と getListFeed を PostgreSQL の LATERAL JOIN で書き換え、フルテーブルスキャンではなくユーザーごとのインデックス使用を強制。数千のアカウントをフォローしているユーザーにとって大きな改善。

Redis キャッシング層 (packages/bsky/src/data-plane/server/cache/)

  • アクタープロファイル (TTL 60秒)、レコード (5分)、インタラクション数 (30秒)、投稿メタデータ (5分)
  • 本番トラフィック下でのデータベース負荷を軽減
  • 既知の問題: アクターキャッシュには、protobuf のタイムスタンプシリアライズのバグがあり、Redis 経由の JSON ラウンドトリップ後に Timestamp オブジェクトが .toDate() メソッドを失い、キャッシュヒット時にプロファイルのハイドレーションが不完全になります。現在は Redis キャッシュを無効にして運用しています。修正方法は、キャッシュ書き込み時にタイムスタンプを ISO 文字列としてシリアライズし、読み取り時に再構築することです。

通知設定のサーバーサイド強制 (packages/bsky/src/api/app/bsky/notification/listNotifications.ts)

  • クライアントが reasons を指定しない場合、サーバーはユーザーの保存された通知設定を適用します。これがないと、設定はクライアントサイドでのみ強制され、効果がありません。

認証ベリファイアの古い署名鍵修正 (packages/bsky/src/auth-verifier.ts)

  • JWT 検証の再試行時(forceRefresh)に、データプレーンのインメモリ ID キャッシュをバイパスし、PLC ディレクトリから直接 DID ドキュメントを解決します。アカウント移行後に署名鍵がローテーションされたがキャッシュに古い鍵が残っている場合の認証失敗を修正します。

JSON サニタイゼーション (packages/bsky/src/data-plane/server/routes/records.ts)

  • JSON 解析前に、保存されたレコードから null バイト (\u0000) と制御文字を除去します。これらは RFC 8259 では有効ですが、Node.js の JSON.parse() では拒否され、データプレーン内で rowToRecord の解析失敗が静かに発生し、投稿が欠落する結果になります。

コミュニティ投稿 (Blacksky 固有)

個別の PDS ではなく AppView 上に存在するプライベートコミュニティ投稿のためのインフラストラクチャ。Blacksky の仕組みに固有ですが、他のコミュニティの参考になる可能性があります。

  • カスタムレキシコンネームスペース community.blacksky.feed.* と、提出、取得、削除、タイムライン、スレッドビューのエンドポイント
  • 独立した community_post テーブル(マイグレーション: 20260202T120000000Z-add-community-post.ts)
  • データプレーンおよび API 層でのメンバーシップゲーティング
  • 標準投稿とコミュニティ投稿が混在するスレッドのための getPostThreadV2 との統合
  • 別のメンバーシップデータベースが必要 (BLACKSKY_MEMBERSHIP_DB_URL)

アーキテクチャ

root@kitploit:~
Bluesky Relay (bsky.network)
     |
     v
rsky-wintermute -----> PostgreSQL 17 <----- Palomar
  (Rust indexer)            |                (Go search)
  - firehose consumer       |                     |
  - backfiller              |                     v
  - label indexer           |               OpenSearch
  - direct indexer          |
                            v
                    bsky-dataplane (gRPC :2585) <--- Redis (optional)
                            |
                            v
                    bsky-appview (HTTP :2584)
                            |
                            v
                    Reverse proxy (Caddy/nginx)

コンポーネント概要

rsky-wintermute の詳細

Wintermute は、4つの並列処理パスを持つモノリシックな Rust サービスです。

  • Ingester: WebSocket 経由で bsky.network firehose に接続し、イベントを Fjall (組み込みキーバリューストア) キューに書き込む
  • Indexer: キューから読み取り、レコードを解析し、冪等性のために ON CONFLICT を使用して PostgreSQL に書き込む
  • Backfiller: PDS から完全なリポジトリ CAR ファイルを取得し、レコードをバックフィルキューに展開する
  • Label indexer: ラベラーの WebSocket ストリームにサブスクライブし、ラベルの作成/否定イベントを処理する

rsky リポジトリに含まれる追加の CLI ツール:

  • queue_backfill -- CSV、PDS ディスカバリ、または直接の DID リストからバックフィル用の DID をキューに入れる
  • direct_index -- キューをバイパスして特定のリポジトリを取得・インデックス(個別アカウントの修正に有用)
  • label_sync -- カーソル0からラベルストリームをリプレイし、見逃した否定をキャッチアップ
  • plc_import -- PLC ディレクトリからハンドル/DID マッピングを一括インポート
  • palomar-sync -- フォロワー数と PageRank を OpenSearch に同期

rsky-video

PDS が Bluesky の video.bsky.app をサポートしていないユーザー向けのビデオアップロードサービス。独自の DID (did:web:video.blacksky.community) を使用して、サービス認証 JWT 経由でユーザーの PDS に認証します。フロー:

  1. クライアントが PDS からサービス認証トークンを取得(audience: ビデオサービス DID)
  2. クライアントが rsky-video にビデオバイトをアップロード
  3. rsky-video が CID を生成し、blob をユーザーの PDS にアップロード
  4. トランスコードのために Bunny Stream CDN にビデオを転送
  5. 完了後、クライアントが blob を参照する投稿を作成 -- PDS が blob の存在を検証

ラベル処理

モデレーションラベルは、WebSocket サブスクリプションを介してラベラーサービス(例:Bluesky の Ozone)から届きます。Wintermute の ingester は、専用の label_live キュー(低ボリューム、メインの firehose とは別)でラベルを処理します。label_sync ツールは、ラベラーの全ストリームをリプレイして、ラベルを再挿入せずに見逃した否定(ラベルの削除)をキャッチアップできます。

セットアップ

前提条件

  • Node.js 18+ と pnpm(データプレーンと AppView のビルド用)
  • bsky スキーマを持つ PostgreSQL 17
  • Redis(オプション、キャッシュ用 -- 上記の既知の問題を参照)
  • firehose を消費しデータベースを埋める rsky-wintermute
  • OpenSearch(Palomar 検索を実行する場合)

データベース

bsky スキーマはデータプレーンのマイグレーションによって作成されます。初回実行時に、データプレーンはすべてのマイグレーションを自動的に適用します。Blacksky 固有のマイグレーションは 20260202T120000000Z-add-community-post.ts(コミュニティ投稿テーブル)のみです。コミュニティ投稿が必要ない場合は、それを削除できます。

rsky-wintermute は同じスキーマに書き込みます。すべての INSERT 文は ON CONFLICT を使用しているため、wintermute とデータプレーンのマイグレーションを任意の順序で実行しても安全です。

ビルド

root@kitploit:~
pnpm install
pnpm build

データプレーンの実行

root@kitploit:~
node services/bsky/dataplane.js

AppView の実行

root@kitploit:~
node services/bsky/api.js

大規模運用

バックフィルのタイムライン

フルネットワークのバックフィル(全ユーザー約4,200万、記録約185億)は、wintermute の並列処理でも数週間かかります。目安:

  • ライブインデックス: 初日からリアルタイムで追従(約1,000イベント/秒)
  • 完全バックフィル: PDS の応答性とネットワーク状況に応じて、10,000レコード/秒で2〜4週間
  • 部分バックフィル: 一部のユーザー(例:コミュニティメンバーのみ)の場合、数時間から数日

バックフィル中、AppView は機能しますが、まだバックフィルされていないユーザーのデータは不完全に表示されます。ライブイベントはバックフィルの進行に関係なく即座にインデックスされます。

ここに至るまでに解決した問題

これらは、フルネットワークの AppView をブートストラップする際に遭遇した問題です。同じことを行う場合、おそらくこれらのいくつかに直面するでしょう:

COPY テキスト形式の JSON 破損: PostgreSQL の COPY テキストプロトコルは、バックスラッシュをエスケープ文字として扱います。バルクローダーが JSON 文字列内のバックスラッシュをエスケープしない場合、\" は " になり、レコードが黙って破損します。record.json カラムは text 型(jsonb ではない)であるため、PostgreSQL はこれを検出しません。約66,000の破損レコードを発見し、公開 API から再取得して修復する必要がありました。

JSON の null バイト: 一部の AT Protocol レコードには \u0000(null バイト)が含まれており、これは RFC 8259 では有効な JSON ですが、Node.js の JSON.parse() では拒否されます。データプレーンはこれらのレコードに対して黙って null を返します。データベースに書き込む前に null バイトを取り除いてください。

タイムスタンプ形式の感度: データプレーンは、ミリ秒精度と Z サフィックス (2026-01-12T19:45:23.307Z) を持つタイムスタンプを期待します。ナノ秒精度やタイムゾーンオフセット形式 (+00:00) では、ソートや比較に微妙な問題が発生します。

通知テーブルの肥大化: (did, recordUri, reason) に一意制約がないと、通知テーブルは重複で無制限に成長します。当社では、気づく前に13億行(663 GB)に達しました。INSERT に ON CONFLICT DO NOTHING を追加しても、一意インデックスが先に存在する場合にのみ効果があり、インデックスを作成するには既存のデータの重複排除が必要です。

投稿埋め込みテーブル: post_embed_image と post_embed_video テーブルは、インデクサがそれらを処理しない場合、デフォルトでは入力されません。これがないと、getAuthorFeed のメディアフィルターは何も返しません。これらは個別にバックフィルする必要があります。

ラベル否定の順序: ラベルの否定(削除)イベントは、元のラベルをソース、URI、値で参照します。否定が元のラベルより先に到着した場合(バックフィル中によくある)、黙って破棄されます。label_sync ツールは全ストリームをリプレイしてこれらをキャッチします。

Fjall キュー汚染: Fjall 組み込みデータベース(wintermute のキューに使用)は、クラッシュ後に「汚染」状態になり、すべてのキュー操作がブロックされる可能性があります。修正方法は、キューデータベースディレクトリを削除して再起動することです。wintermute はリレーのカーソルから追いつきます(リレーは約72時間の履歴を保持)。

TLS プロバイダの初期化: Rust の rustls は、TLS 接続の前に暗号プロバイダを明示的にインストールする必要があります。起動時に rustls::crypto::aws_lc_rs::default_provider().install_default() がないと、firehose への最初の WebSocket 接続がパニックになります。

アカウント移行後の署名鍵ローテーション: ユーザーが PDS 間を移行する際、署名鍵が変更されます。データプレーンは ID データを staleTTL 1時間でキャッシュします。その間、移行したユーザーの JWT 検証は失敗します。修正方法は、検証再試行時にキャッシュをバイパスし、PLC ディレクトリから直接解決することです。

リソース要件

フルネットワークの AppView(全ユーザー約4,200万、記録約185億)の実行に基づきます。

ストレージ内訳(概算、フルネットワーク):

テーブルグループ

小規模なコミュニティが部分的な AppView(コミュニティメンバーのみインデックス)を実行する場合、要件はインデックスされたアカウント数にほぼ比例します。

上流との同期

root@kitploit:~
git remote add upstream https://github.com/bluesky-social/atproto.git
git fetch upstream
git merge upstream/main

競合は通常、packages/bsky/src/data-plane/server/routes/ と packages/bsky/src/api/ で発生します。上流の変更とともに私たちの追加を保持して解決してください。

ライセンス

上流と同様: MIT および Apache 2.0 のデュアルライセンス。LICENSE-MIT.txt と LICENSE-APACHE.txt を参照してください。

ツールをダウンロード
コンポーネントソース目的
rsky-wintermuteblacksky-algorithms/rskyRust 製 firehose インデクサ: イベントを消費し、リポジトリをバックフィルし、レコードを PostgreSQL にインデックス
rsky-relayblacksky-algorithms/rskyラベラーサービスからのモデレーションラベルを受信するための AT Protocol リレー
rsky-videoblacksky-algorithms/rskyビデオアップロードサービス: Bunny Stream CDN 経由でトランスコードし、blob 参照をユーザーの PDS にアップロード
bsky-dataplaneこのリポジトリ (services/bsky)PostgreSQL 上の gRPC データ層
bsky-appviewこのリポジトリ (services/bsky)app.bsky.* XRPC エンドポイント用 HTTP API サーバー
Palomarblacksky-algorithms/indigo全文検索: フォロワー数ブーストを使用してプロファイルと投稿を OpenSearch にインデックス
palomar-syncblacksky-algorithms/rskyPostgreSQL から OpenSearch へのフォロワー数と PageRank スコアの同期
変数必須説明
DB_PRIMARY_URLはい?options=-csearch_path%3Dbsky 付きの PostgreSQL 接続文字列
DB_REPLICA_URLいいえ読み取りレプリカ接続文字列
BSKY_DATAPLANE_PORTいいえgRPC ポート (デフォルト 2585)
BSKY_REDIS_HOSTいいえキャッシュ用の Redis ホスト:ポート (現在は無効のままにすることを推奨)
BLACKSKY_MEMBERSHIP_DB_URLいいえコミュニティメンバーシップ用の別 DB (Blacksky 固有)
変数必須説明
BSKY_APPVIEW_PORTいいえHTTP ポート (デフォルト 2584)
BSKY_DATAPLANE_URLSはいカンマ区切りのデータプレーン gRPC URL
BSKY_DIDはいAppView の DID (例: did:web:api.example.com)
BSKY_MOD_SERVICE_DIDはいOzone モデレーションサービス DID
BSKY_ADMIN_PASSWORDSはい基本認証用のカンマ区切りの管理者パスワード
リソース最小推奨
CPU16 コア48+ コア
RAM64 GB256 GB
ストレージ10 TB NVMe28+ TB NVMe (RAID)
PostgreSQL専用、同一マシンまたは低レイテンシ同一マシンを推奨
ネットワーク持続 100 Mbps1 Gbps+
サイズ
投稿 + レコード~3.5 TB
いいね~2 TB
フォロー~500 GB
通知~600 GB
インデックス~4 TB
OpenSearch (Palomar)~500 GB