Skip to content

OSSサンドボックス設計

OSS検証エンジンが使用する Docker サンドボックスの詳細設計です。

設計方針

未知のOSSコードを安全に実行するため、以下の原則に従います:

  1. 最小権限 — 必要最小限の権限のみ付与
  2. ネットワーク制限 — パッケージレジストリのみ許可
  3. リソース制限 — CPU、メモリ、時間に上限
  4. 使い捨て — 実行後にコンテナを完全削除

コンテナ仕様

ベースイメージ

マルチ言語対応のカスタムベースイメージを使用します。

dockerfile
FROM ubuntu:24.04

# Node.js 20
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
    && apt-get install -y nodejs

# Python 3.12
RUN apt-get install -y python3.12 python3-pip python3-venv

# Go 1.22
RUN curl -fsSL https://go.dev/dl/go1.22.0.linux-amd64.tar.gz | tar -C /usr/local -xzf -
ENV PATH=$PATH:/usr/local/go/bin

# Rust 1.75
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain 1.75.0
ENV PATH=$PATH:/root/.cargo/bin

# セキュリティツール
RUN pip3 install pip-audit safety
RUN npm install -g npm-audit-resolver

# 非rootユーザー
RUN useradd -m -s /bin/bash sandbox
USER sandbox
WORKDIR /home/sandbox/workspace

対応言語・ランタイム

言語バージョンパッケージマネージャ
Node.js20 LTSnpm, yarn, pnpm
Python3.12pip, poetry
Go1.22go modules
Rust1.75cargo

ネットワークポリシー

mermaid
flowchart LR
    Container["サンドボックス\nコンテナ"] --> Proxy["ネットワーク\nプロキシ"]

    Proxy -->|許可| NPM["registry.npmjs.org"]
    Proxy -->|許可| PyPI["pypi.org"]
    Proxy -->|許可| Go["proxy.golang.org"]
    Proxy -->|許可| Crates["crates.io"]
    Proxy -->|許可| GitHub["github.com\n(clone のみ)"]

    Proxy -->|拒否| Other["その他すべて"]

    style Other fill:#f44336,color:#fff

許可リスト

ドメインポート用途
registry.npmjs.org443npm パッケージ
pypi.org443Python パッケージ
files.pythonhosted.org443Python パッケージ (ファイル)
proxy.golang.org443Go モジュール
crates.io443Rust クレート
static.crates.io443Rust クレート (ファイル)
github.com443リポジトリクローン

実装

Docker の --network オプションとカスタムネットワーク + iptables ルールで制御:

bash
# カスタムネットワーク作成
docker network create --driver bridge sandbox-net

# iptables で許可リスト以外をブロック
iptables -I DOCKER-USER -i sandbox-net -j DROP
iptables -I DOCKER-USER -i sandbox-net -d registry.npmjs.org -j ACCEPT
# ... (他の許可ドメイン)

リソース制限

リソース制限値Docker フラグ
CPU2コア--cpus=2
メモリ2GB--memory=2g
スワップ0--memory-swap=2g
実行時間5分アプリレベルのタイムアウト
ディスク10GB--storage-opt size=10G
プロセス数256--pids-limit=256

実行フロー

mermaid
sequenceDiagram
    participant Engine as 検証エンジン
    participant Docker as Docker Engine
    participant Container as サンドボックス

    Engine->>Docker: コンテナ作成
    Note over Docker: --cpus=2 --memory=2g<br/>--network=sandbox-net<br/>--pids-limit=256

    Docker-->>Container: 起動

    Engine->>Container: git clone {repo_url}
    Container->>Container: 言語検出

    alt Node.js
        Container->>Container: npm install
        Container->>Container: npm run build
        Container->>Container: npm test
    else Python
        Container->>Container: pip install -r requirements.txt
        Container->>Container: python -m pytest
    else Go
        Container->>Container: go build ./...
        Container->>Container: go test ./...
    else Rust
        Container->>Container: cargo build
        Container->>Container: cargo test
    end

    Container-->>Engine: 結果 (exit code, stdout, stderr)

    Engine->>Docker: コンテナ削除
    Engine->>Docker: ボリューム削除

ファイルシステム分離

パス権限説明
/home/sandbox/workspacerw作業ディレクトリ(リポジトリクローン先)
/tmprwテンポラリ
/usr, /bin, /libroシステムバイナリ(読み取り専用)
/proc/sysなしカーネルパラメータへのアクセス禁止
bash
docker run \
  --read-only \
  --tmpfs /tmp:rw,size=1g \
  --tmpfs /home/sandbox/workspace:rw,size=5g \
  ...

ポスト実行クリーンアップ

検証完了後、以下を確実に実行:

  1. コンテナの停止・削除 (docker rm -f)
  2. 匿名ボリュームの削除 (docker volume prune)
  3. ビルドキャッシュの削除(必要に応じて)
  4. ネットワーク接続の切断
bash
# クリーンアップスクリプト
docker stop sandbox-${JOB_ID} 2>/dev/null
docker rm -f sandbox-${JOB_ID} 2>/dev/null
docker volume rm sandbox-vol-${JOB_ID} 2>/dev/null

セキュリティ考慮事項

想定する脅威

脅威対策
コンテナエスケープ非root実行 + seccomp プロファイル
ネットワーク攻撃許可リストベースのファイアウォール
リソース枯渇CPU/メモリ/時間の厳格な制限
データ漏洩ファイルシステム分離 + 使い捨てコンテナ
サプライチェーン攻撃install hooks の事前検査(Step 2で検出)