OSSサンドボックス設計
OSS検証エンジンが使用する Docker サンドボックスの詳細設計です。
設計方針
未知のOSSコードを安全に実行するため、以下の原則に従います:
- 最小権限 — 必要最小限の権限のみ付与
- ネットワーク制限 — パッケージレジストリのみ許可
- リソース制限 — CPU、メモリ、時間に上限
- 使い捨て — 実行後にコンテナを完全削除
コンテナ仕様
ベースイメージ
マルチ言語対応のカスタムベースイメージを使用します。
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.js | 20 LTS | npm, yarn, pnpm |
| Python | 3.12 | pip, poetry |
| Go | 1.22 | go modules |
| Rust | 1.75 | cargo |
ネットワークポリシー
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.org | 443 | npm パッケージ |
pypi.org | 443 | Python パッケージ |
files.pythonhosted.org | 443 | Python パッケージ (ファイル) |
proxy.golang.org | 443 | Go モジュール |
crates.io | 443 | Rust クレート |
static.crates.io | 443 | Rust クレート (ファイル) |
github.com | 443 | リポジトリクローン |
実装
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 フラグ |
|---|---|---|
| CPU | 2コア | --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/workspace | rw | 作業ディレクトリ(リポジトリクローン先) |
/tmp | rw | テンポラリ |
/usr, /bin, /lib | ro | システムバイナリ(読み取り専用) |
/proc/sys | なし | カーネルパラメータへのアクセス禁止 |
bash
docker run \
--read-only \
--tmpfs /tmp:rw,size=1g \
--tmpfs /home/sandbox/workspace:rw,size=5g \
...ポスト実行クリーンアップ
検証完了後、以下を確実に実行:
- コンテナの停止・削除 (
docker rm -f) - 匿名ボリュームの削除 (
docker volume prune) - ビルドキャッシュの削除(必要に応じて)
- ネットワーク接続の切断
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で検出) |