Tachibana

Neo6502 › 記事 › Prophet

Neo6502 のための Prophet サーバーを作る

Prophet は Neo6502 コミュニティのプログラムリポジトリです:ボード上のクライアントと、どこかにあるサーバー。私たちはサーバーを Go で書き直し、セキュリティを第一に、自分たちのプログラムを載せて prophet.3617.fr を公開しました。

著者 bmarty · Tachibana · 2026 年 9 月 16 日

Neo6502 ではプログラムをコンソールからインストールします。bocianu が Mad Pascal で書いたコミュニティクライアント prophet.neo が、WiFi モデム(AT コマンド)経由でサーバーと話し、ファイルをブロック単位でダウンロードします。上流のサーバー prophet-server は Python/Flask で書かれ、ライセンスファイルなしで公開されています。現行クライアントは TLS を扱えないため、公開サーバーは HTTP で動いています。私たちは自分たちのサーバーが欲しかった — AsteroNeo を公開するため、自作クライアントを書く前にプロトコルを学ぶため、そして自分たちの運用ルールで自前ホストするためです。Neo6502Prophet は Go による独立した再実装で、プロトコル互換、コピーした行は一行もありません。2 日間で 4 スプリント。やったことを記します。

1. 一行書く前にプロトコルを記録する

最初の一歩はサーバーではなくクライアントを読むこと。prophet.pas はヘッダ ResponseFormat: cli 付きで GET を送り、行末 \n\r を含む生テキストを解析します:カテゴリの /cat、ページ分割された /list/<cat>/search、詳細の /app/<id>、ツリーの /dirs/files、そして Range ブロックで 206 を返す /files/<id>/<n>。一覧では 2 つの制御バイト(\x83\x82)が ID を囲みます。/files/prophet/1 はクライアント自身の更新用。データリポジトリは カテゴリ/パッケージ/desc.yaml のフォルダツリーで、旧バージョンは _N/ の下。すべて docs/ANALYSE-AMONT.md に記録しました — クライアント、サーバー、データリポジトリでこれらすべてを可能にしてくれた bocianu に感謝を — 未検証の点(公開サーバーは公開コードと異なるかもしれない)とともに。

2. 私たちのセキュリティ方針

プログラムリポジトリは、ボードが実行するファイルを配布する公開 HTTP サービスです。書き始める前に、この種のサービスの典型的なリスクを列挙し、それぞれに答えることにしました:デバッグモードは決して使わず、既定ではローカル待ち受け;あらゆる操作 — git pull を行うリポジトリの更新 — は認証付き;パラメータは検証と範囲制限、エラーにトレースなし;配布ファイルはフォルダ内に閉じ込め、リンクは無視;ID はフィルタ;ローテーション付きログ;リクエスト間で共有する状態なし;中間ファイルなしでメモリ上にカタログを再読み込み;配布する各ファイルのフィンガープリント。9 項目を SECURITY.md に記し、テストしています。

3. 私たちのサーバー:Go、読み取り専用、セキュリティ第一

標準ライブラリと yaml.v3、静的バイナリ一つ。書き込み API はなし。/refresh は 16 文字以上のトークンを定数時間で比較し、最小間隔を守り、シェルなし・タイムアウト付きで git pull --ff-only を実行 — トークンがなければエンドポイントは存在しません(404)。ID は正規表現でフィルタ、整数は範囲制限、ソートはホワイトリスト、検索キーは長さ制限、リクエストボディも制限。不正な入力はテキストの 400 か 404 で、トレースは決して出しません。ファイルパスはルートから再計算して検証:フォルダ内、通常ファイル、リンクでないこと。カタログはメモリ上でスキャンしアトミックに置換。各ファイルは JSON に SHA-256 を公開。サーバーは既定で 127.0.0.1 を待ち受けます。

クライアント向けテキスト形式はバイト単位で再現し、そのようにテストしています。追加点が一つ:Neo のコンソールは ASCII しか表示できないので、タイトルと説明はクライアント向けに翻字し、JSON は UTF-8 のまま。そして二重待ち受け:現行クライアント向けに 8998 番の HTTP、対応できるモデム向けにネイティブ HTTPS(TLS 1.2 以上) — PicoWiFiModemUSB の Pico W、Neo6502drive 側の「picowifitls」ストーリーです。

4. 何でも配らない

プログラムリポジトリは、人が実行するバイナリを配布します。ガードレールは 2 つ。静的neocheck が各 .neo(ヘッダ、ブロック、境界、カーネル領域)を読み、無効なファイルは配布せず、「生」のファイルには印を付けます(JSON の neo = ok/raw/invalid)。動的neotrace が各プログラムを Phosphoneo で API 呼び出しトレース(--api-log)と各書き込みの実効アドレス付きで再生し、プログラムがカーネルに何をしたかを再構成します。9 月 16 日の再実行:56 プログラム中 56.neo 46、.bas 10)が動作、未解決の書き込みなし、悪意ある挙動なし。注記が一つ:zc.neo はカーネル領域($FC20 基点のテーブル)に書き込むが目に見える影響はなし。監査は Phosphoneo のバグ — 読み込み時に無視されるグラフィックブロック $FFFF — も見つけ、既に修正済みです。

5. クライアントを壊さないウェブインターフェース

/ でブラウザにだけ提供(ResponseFormat: cli なしの Accept: text/html):ジャケット付きカタログのグリッド、検索とフィルタ、説明・バージョン・ファイル・サイズ・.neo の状態・SHA-256・ダウンロードを備えた詳細ページ。HTML・CSS・JS は埋め込み、依存なし、厳格な CSP。ジャケットはスクリプトが Phosphoneo で撮ったスクリーンショット — 42 パッケージ中 42。専用テストで、テキストクライアントが以前と完全に同じ応答を受け取ることを確認しています。

6. 本番:prophet.3617.fr

専用の非特権 Debian 13 コンテナ(1 コア、512 MB)、強化した systemd サービス(systemd-analyze security 露出度 1.3)、リバースプロキシからのみ 8998 番を受け付ける nftables、自動セキュリティ更新。Caddy が TLS を終端し(https://prophet.3617.fr)、ESP8266 クライアント向けに 8998 番の平文 HTTP も中継、Crowdsec 付き。毎時のタイマーがローカルトークンでコミュニティリポジトリのミラーを更新します。複数のデータフォルダを並べて提供:bocianu のミラーと私たち自身のリポジトリ。後者では AsteroNeo 0.2.0 が最初の公開パッケージです(/app/asteroneo、ジャケット込み)。9 月 16 日時点:ゲーム 37、ツール 5、その他 1。

7. 私たちが主張しないこと

サーバーは本物の Neo6502 ボードから一度も呼ばれていません:ボードを持っておらず、Pico W モデム経由のエンドツーエンドテストは Neo6502drive の TLS ストーリー待ちです。上流のクライアントは私たちが公開する SHA-256 を検証しません — 改造したクライアントだけがそうします。動的監査が語るのはエミュレータ内でプログラムが何をしたかであり、別の入力を受けるボード上で何をするかではありません。サーバーのコードにはまだ公開リポジトリがありません。次は Neo6502 向けのネイティブ GUI クライアント(「B」):事前変換したジャケット、TLS、フィンガープリント検証。

出典とリンク

← Neo6502 · AsteroNeo → · Neo6502 →