概要

ECSETI は permissionless な P2P 観測網です。 誰の承認も得ずに Node を立て、 ネットワークに参加できます。 中央のアカウント・登録・許可は存在しません。

あなたの Node は起動時に HARDCODED_SEEDS 経由で既存の peer に到達し、 互いに観測 (Layer 1 OBS) と証拠ファイル (Layer 3 .fil / .sigmf-data / .sqlite) を gossip で交換します。 詳細は network-spec.md および p2p-architecture-ja.md 参照。

方針: ECSETI は pre-built binary を配布しません。 1-click インストールも提供しません。 source からビルドする手順自体が operator になる過程の一部です。 ただ眺めるだけなら Live Monitor を開くだけで良く、 何もインストールする必要はありません。

Hardware

SDR Receiver

RTL-SDR V3 / V4 推奨 ($30 程度)。 SoapySDR 対応デバイスであれば何でも可 (HackRF, Airspy, LimeSDR 等)。 V4 は LO リーク改善あり。

Antenna

水素線 (1420 MHz) 観測: ホーンアンテナまたはディスコーンアンテナ推奨 ($50-200 自作可)。 FM テスト用なら付属ダイポールで十分。

Computer

Linux (推奨)、 macOS、 Windows 10/11、 もしくは Raspberry Pi 4/5 (4GB+ RAM)。 常時稼働できるとなお良い (peer-table 永続化が効く)。 OS の差は build 手順だけで、 ネットワーク参加後は完全に等価です。

OS 別 セットアップ

環境ごとの依存と落とし穴を順に説明します。 自分の OS の節だけ読めば OK。

macOS (Apple Silicon / Intel)

# 1. Homebrew (まだなら)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# 2. 依存パッケージ (SDR を使う場合のみ soapysdr 系が必要)
brew install rustup soapysdr soapyrtlsdr

# 3. Rust toolchain 初期化
rustup-init -y
source "$HOME/.cargo/env"

# 4. 動作確認
rustc --version           # 1.85+ を期待
SoapySDRUtil --find       # RTL-SDR を挿してから実行 → デバイスが見えること
rtl_test -t               # 基本動作 (E4000 not found のメッセージは無視可)

Apple Silicon の落とし穴:

Linux (Ubuntu / Debian、 x86_64 サーバ含む)

# 1. 依存パッケージ
sudo apt update
sudo apt install -y \
    build-essential pkg-config curl \
    libsoapysdr-dev soapysdr-module-rtlsdr soapysdr-tools \
    rtl-sdr

# 2. Rust toolchain
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source "$HOME/.cargo/env"

# 3. RTL-SDR の USB 権限を一般ユーザーに付与 (Linux 必須)
# rtl-sdr パッケージで /etc/udev/rules.d/20-rtlsdr.rules が入るはず
# sudo なしで動かすため:
sudo usermod -a -G plugdev $USER
# ↑ 反映には一度ログアウト + 再ログイン

# 4. 動作確認
SoapySDRUtil --find
rtl_test -t

Linux の落とし穴:

Raspberry Pi 4 / 5 (Raspberry Pi OS Lite 64-bit)

# 64-bit OS が前提 (32-bit では tokio-tungstenite ビルド失敗の報告あり)
# Raspberry Pi Imager で "Raspberry Pi OS Lite (64-bit)" を選ぶこと

# 1. 依存パッケージ (Linux 節と同じ)
sudo apt update
sudo apt install -y \
    build-essential pkg-config curl \
    libsoapysdr-dev soapysdr-module-rtlsdr soapysdr-tools \
    rtl-sdr

# 2. Rust toolchain
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source "$HOME/.cargo/env"

# 3. USB 権限
sudo usermod -a -G plugdev $USER

# 4. swap 増設 (RPi 4 / 4GB RAM の場合、 ビルド時に OOM になりがち)
sudo dphys-swapfile swapoff
sudo sed -i 's/^CONF_SWAPSIZE=.*/CONF_SWAPSIZE=2048/' /etc/dphys-swapfile
sudo dphys-swapfile setup
sudo dphys-swapfile swapon

Raspberry Pi の落とし穴:

Windows 10 / 11 (PowerShell)

CLI に不慣れな方も、 以下のコマンドを 1 ブロックずつコピペで実行すれば完了します。 PowerShell を 管理者として実行で開いてください (スタートメニューで PowerShell を右クリック → 「管理者として実行」)。

ステップ 1: Visual Studio C++ Build Tools (rustc がリンカーを必要とするため):

winget install --id Microsoft.VisualStudio.2022.BuildTools `
    --override "--passive --wait --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended"

winget が無い古い Windows の場合: visualstudio.microsoft.com/visual-cpp-build-tools/ からダウンロードして 「Desktop development with C++」 を選択。

ステップ 2: Rust toolchain:

Invoke-WebRequest -Uri "https://win.rustup.rs/x86_64" -OutFile "$env:TEMP\rustup-init.exe"
& "$env:TEMP\rustup-init.exe" -y --default-toolchain stable
$env:Path += ";$env:USERPROFILE\.cargo\bin"
rustc --version

新しい PowerShell window では PATH が再読込されてるはず。 もし rustc が見つからないと言われたら PowerShell を再起動。

ステップ 3: PothosSDR (SoapySDR + RTL-SDR tools をまとめて入れる):

# インストーラをダウンロード
$pothosUrl = "https://downloads.myriadrf.org/builds/PothosSDR/PothosSDR-2021.07.25-vc16-x64.exe"
Invoke-WebRequest -Uri $pothosUrl -OutFile "$env:TEMP\PothosSDR.exe"

# GUI インストーラを起動 (Next を連打、 既定パスでよい)
Start-Process "$env:TEMP\PothosSDR.exe" -Wait

# PATH に C:\Program Files\PothosSDR\bin を追加 (恒久)
$pothosBin = "C:\Program Files\PothosSDR\bin"
[Environment]::SetEnvironmentVariable("Path", "$([Environment]::GetEnvironmentVariable('Path', 'User'));$pothosBin", "User")
$env:Path += ";$pothosBin"

ステップ 4: RTL-SDR の WinUSB ドライバ (Zadig、 GUI 必須):

# Zadig をダウンロードして実行 (winget では配布されていない)
$zadigUrl = "https://github.com/pbatard/libwdi/releases/download/v1.5.0/zadig-2.9.exe"
Invoke-WebRequest -Uri $zadigUrl -OutFile "$env:USERPROFILE\Desktop\zadig.exe"
& "$env:USERPROFILE\Desktop\zadig.exe"

Zadig のウィンドウが開いたら:

  1. RTL-SDR を USB に挿す
  2. Options メニュー → List All Devices にチェック
  3. ドロップダウンから Bulk-In, Interface (Interface 0) (= RTL2832U) を選択
  4. 右側のドライバが WinUSB になっていることを確認
  5. Replace Driver ボタン押下

注意: 元の Realtek DVB-T (TV 視聴用) ドライバを上書きする操作。 RTL-SDR を TV 受信機としても使う場合は、 元に戻すには Zadig で reinstall するかデバイスマネージャから driver rollback。

ステップ 5: 動作確認:

rustc --version              # 1.85+ を期待
SoapySDRUtil.exe --find      # RTL-SDR が見えること
rtl_test.exe -t              # 基本動作確認 (E4000 not found 警告は無視可)

ダウンロード元の信頼性 (なぜこれらを取って来るのか):

初回起動時に Windows SmartScreen が警告を出すことがあります (signed binary でも 「未確認の発行元」 と判断されることあり)。 自分で URL と SHA を確認してから 「詳細情報 → 実行」。

Windows の落とし穴:

ビルド

全 operator が 同じコマンドでビルドします。 Station として観測するか、 aggregator として relay するか、 ただ眺めるだけかは runtime の CLI 引数で決まります。 ビルドプロファイルを役割ごとに分けることは構造的階層を生むため意図的に避けています (network-spec §1.1.1 全運営者が暗号的に同等)。

Tor も default で含めます。 匿名性を担保する仕組みは opt-in ではなく default であるべき、 という設計判断。 検閲国家にいる operator が「特別な build」 を要求されると参加障壁になります。 全 operator が同じ binary に Tor capability を持って、 runtime で --onion-nickname を渡せば即 onion service として動く。 渡さなければ clearnet。 個人の脅威モデルに応じて runtime で選べる。

git clone https://github.com/kmrrj/ecseti-suite.git
cd ecseti-suite

# 全 operator 共通のビルド (sdr / ui / tor 全部入り)
cargo build --release -p starglider

# 成果物
ls -lh target/release/starglider

ビルド時間の目安:

2 回目以降の cargo build は incremental で 10-30 秒程度。

例外: 環境的に SoapySDR や Tor を install できない場合のみ、 escape valve として feature を絞れます。 ただし non-canonical なビルドであることを認識してください:

# 例: SoapySDR 不可、 Tor 不可な VPS で aggregator だけ動かす
cargo build --release -p starglider --no-default-features --features ui

Identity (初回起動時に自動生成)

Node は Ed25519 鍵ペアで識別されます。 初回起動時に自動生成され、 OS の標準 config 場所に永続保存されます:

# 自分の pubkey を確認
./target/release/starglider --print-identity

# 出力例:
# pubkey:      ed25519:YM4Sy60ss-0gW-HyGtiWniPXAtp7lANWWY0Iw3qbUPA
# handle:      muted-ivory-04
# stored at:   /home/you/.config/ecseti/identity.key

重要: identity.key を削除すると新しい pubkey が生成され、 ネットワーク上で別 Station として扱われる。 過去の観測 chain との連続性が切れる。 backup 推奨 (例: cp identity.key identity.key.bak)。 --print-identity で表示される pubkey は公開して問題ないが、 ファイル本体 (秘密鍵) は他人に渡さない。

動作確認 (PPM 校正)

# PPM 誤差を測定 (5-10 分かけて値が安定するまで待つ)
rtl_test -p

# 例: -18 ppm 程度で安定
# Found 1 device(s):
#   0:  Realtek, RTL2838UHIDIR, SN: 00000001
# real sample rate: 2047911 current PPM: -18 cumulative PPM: -18

SDR チップ個体差。 RTL-SDR V3/V4 で典型的に ±50 ppm 以内。 観測精度を上げたい場合は安定値を --soapy "driver=rtlsdr,corr=-18" のように指定して使う。

起動 — モード別

1. ローカル観測 (P2P 参加なし)

まずローカルで動作確認。 HARDCODED_SEEDS に dial しに行って観測も流れ込んできますが、 外部から自分は見えません。

# 水素線観測 (1420.405 MHz)
./target/release/starglider \
  --soapy "driver=rtlsdr,corr=-18" \
  --center-freq-hz 1420405000 \
  --station-id "my-station"

# FM テスト (例: 82.1 MHz、 強い信号があるので CKLT が反応する様子が確認できる)
./target/release/starglider \
  --soapy "driver=rtlsdr,corr=-18" \
  --center-freq-hz 82100000 \
  --station-id "fm-test"

ブラウザで http://127.0.0.1:8080 を開くと dashboard が出ます。

2. P2P ネットワークに peer として参加 (公開 Station)

あなたの Node を他の Node が dial できるようにする場合は外向きに listen します。 ファイヤーウォールで 9001 を開ける必要あり (例: sudo ufw allow 9001)。

./target/release/starglider \
  --soapy "driver=rtlsdr,corr=-18" \
  --center-freq-hz 1420405000 \
  --station-id "my-station" \
  --node-listen "0.0.0.0:9001" \
  --advertised-url "ws://your-domain.example:9001/"

3. Tor onion で参加 (NAT 内側 / 検閲対策)

Tor の onion service として動かすと、 IP アドレスを晒さずに NAT 内側からも参加できます。 デフォルトビルドに tor feature が含まれているので、 追加ビルドは不要です:

./target/release/starglider \
  --soapy "driver=rtlsdr,corr=-18" \
  --center-freq-hz 1420405000 \
  --station-id "my-station" \
  --onion-nickname "my-ecseti-node"

同じ --onion-nickname を使い続ければ .onion アドレスは再起動しても変わらない。 最初の onion service 公開には数分かかる (Tor circuit 構築 + descriptor publish の時間)。

4. Aggregator-only (観測しないホスト)

SDR を持たないが visitor 向けに UI を公開したいホスト (ecseti.org のようなサーバ) は --aggregator-only で SDR pipeline を skip します:

./target/release/starglider \
  --aggregator-only \
  --node-listen "0.0.0.0:9001" \
  --advertised-url "wss://your-aggregator.example/" \
  --ui-bind "0.0.0.0:8080"

aggregator は構造的に privileged ではありません。 誰でも立てられます。 詳しくは network-spec §16.7

常時稼働化 (systemd)

Linux / RPi で 24/7 稼働させる例。 /etc/systemd/system/starglider.service:

[Unit]
Description=ECSETI Node (starglider)
After=network.target

[Service]
Type=simple
User=pi
WorkingDirectory=/home/pi/ecseti-suite
ExecStart=/home/pi/ecseti-suite/target/release/starglider \
    --soapy "driver=rtlsdr,corr=-18" \
    --center-freq-hz 1420405000 \
    --station-id "my-station" \
    --node-listen "0.0.0.0:9001" \
    --advertised-url "ws://your-domain.example:9001/"
Restart=always
RestartSec=5
StandardOutput=append:/var/log/starglider.log
StandardError=append:/var/log/starglider.log

[Install]
WantedBy=multi-user.target
sudo systemctl enable starglider
sudo systemctl start starglider
journalctl -u starglider -f      # ログを追跡

HARDCODED_SEEDS への自己追加 (任意)

長期稼働 + 公開 (clearnet または onion) の Node は、 binary の HARDCODED_SEEDS リストに追加することで新規 Station の bootstrap 候補の 1 つになります。 誰の承認も要りません。

  1. 長期稼働する Node であること (一晩の実験用には足さないでください)
  2. clearnet または Tor onion で reachable であること
  3. HARDCODED_SEEDS.md の手順に従って Pull Request を出す

「creator が消えても続く観測網」 を成立させるためには founder 1 人に依存しない seed 配置が必要。 あなたが追加されることは具体的にこの目的に効きます。

Privacy

デフォルトで観測には 位置情報を含めません。 実名・所属・住所も提供する必要はありません。 Node の identity は Ed25519 公開鍵だけで、 これは仮名です。

位置を共有したい場合のみ --lat-deg --lon-deg --publish-location を opt-in で指定してください。 世界地図上にあなたの station が pin として表示されます。 これは self-reported / unverified で、 UI 表示専用です。

困ったとき

ビルドが通らない:

SDR が認識されない:

peer が見つからない:

その他: