「OpenClaw、ホストに直で動かしてるけど...まあ大丈夫でしょ」
その気持ち、わかります。私たちもそうでした。Slack AIアシスタントとして便利に使えてるし、わざわざDocker化する理由もないかな、と。
CVE-2026-25253、CVE-2026-24763、CVE-2026-25157 — 2026年初頭に公開されたこの3つの脆弱性を見るまでは。
AI開発ツールをホストOSで直接実行するということは、そのプロセスがファイルシステムにもネットワークにも自由にアクセスできるということ。Skills経由でシェルコマンドを実行できる環境で脆弱性が見つかったら? ホスト全体が攻撃面になります。「docker compose upするだけ」で安心...と思いたいところですが、デフォルト設定のDockerコンテナにはroot権限が残っています。つまり、コンテナ脱出(container escape)のリスクはゼロじゃない。
この記事では、OpenClawをホスト直接実行からDockerコンテナに移行し、本気のセキュリティハードニングを施すまでの全手順を、実際に運用しているdocker-compose.ymlとともに公開します。
この記事で学べること
- OpenClawのDocker化で防げるCVEリスクの具体像
cap_drop: ALL・read_only・no-new-privilegesの3点セットが効く理由- Docker Composeセキュリティハードニングの実践パターン(コピペで使える設定)
- AI開発ツール特有のボリュームマウント設計とtmpfs活用
- ホスト環境からのデータ移行手順
前提知識
- Dockerの基本操作(
docker compose up -dがわかる程度) - OpenClawの基本を把握している
- Linuxのケーパビリティ(capabilities)の概念をぼんやり知っている(知らなくても読めます)
なぜ「ただDocker化する」だけでは足りないのか
「Dockerコンテナに入れれば安全でしょ?」という認識、半分正しくて半分間違っています。
デフォルトのDockerコンテナには、実は14個のLinuxケーパビリティが付与されています。NET_RAW(生パケット送信)、SYS_CHROOT(chrootの変更)、MKNOD(デバイスファイル作成)...。OpenClawのようなAIアシスタントに、これらの権限が必要でしょうか?
答えはNO。必要なのはネットワーク接続(API呼び出し)とファイルの読み書き(Skills実行、メモリ永続化)だけ。それ以外の権限は、攻撃者にとっての「武器」にしかなりません。
CVE-2026シリーズが突きつけた現実
2026年初頭に公開された3つのCVEは、AI開発ツールのセキュリティ意識を変えるきっかけになりました:
| CVE | 影響 | ホスト直接実行時のリスク |
|---|---|---|
| CVE-2026-25253 | リモートコード実行 | ホスト全体へのアクセス |
| CVE-2026-24763 | 権限昇格 | root権限の奪取可能性 |
| CVE-2026-25157 | 情報漏洩 | APIキー・トークンの流出 |
ホストで直接動かしている場合、1つのCVEで全部持っていかれる可能性がある。コンテナ化+ハードニングで、被害範囲を「コンテナ内部」に閉じ込めることが目的です。
Docker Compose セキュリティハードニング
ここからが本題。私たちが実際に運用しているdocker-compose.ymlを、セキュリティ設定ごとに分解して解説します。
ハードニングの3本柱
完全版 docker-compose.yml
services:
openclaw:
image: ghcr.io/openclaw/openclaw:2026.3.2
container_name: openclaw
restart: unless-stopped
# --- セキュリティ設定 ---
user: '1000:1000' # 非rootユーザーで実行
read_only: true # ファイルシステム読み取り専用
security_opt:
- no-new-privileges:true # 権限昇格の禁止
cap_drop:
- ALL # 全ケーパビリティを削除
# --- ネットワーク ---
ports:
- '127.0.0.1:18789:18789' # localhost限定バインド
# --- 環境変数 ---
env_file:
- .env
# --- ボリューム ---
volumes:
# 設定ファイル(読み取り専用)
- ./config/openclaw.json:/home/node/.openclaw/openclaw.json:ro
- ./cron:/home/node/.openclaw/cron:ro
# データディレクトリ(読み書き)
- ./data/credentials:/home/node/.openclaw/credentials:rw
- ./data/identity:/home/node/.openclaw/identity:rw
- ./data/memory:/home/node/.openclaw/memory:rw
- ./data/agents:/home/node/.openclaw/agents:rw
- ./data/media:/home/node/.openclaw/media:rw
- ./data/logs:/home/node/.openclaw/logs:rw
- ./data/browser:/home/node/.openclaw/browser:rw
- ./data/canvas:/home/node/.openclaw/canvas:rw
- ./data/devices:/home/node/.openclaw/devices:rw
- ./workspace:/home/node/.openclaw/workspace:rw
# Skills(読み取り専用)
- skills:/home/node/.openclaw/skills:ro
# --- 一時領域 ---
tmpfs:
- /tmp:size=512M
- /home/node/.npm:size=256M
# --- リソース制限 ---
deploy:
resources:
limits:
memory: 2G
# --- ヘルスチェック ---
healthcheck:
test:
[
'CMD',
'wget',
'--no-verbose',
'--tries=1',
'--spider',
'http://127.0.0.1:18789/healthz',
]
interval: 30s
timeout: 10s
retries: 3
start_period: 15s
長い? はい。でもこの1ファイルが、CVEが公開されたときに「うちは大丈夫」と言える根拠になります(その安心感、プライスレス)。
各設定の解説
1. cap_drop: ALL — ケーパビリティの全削除
cap_drop:
- ALL
Linuxケーパビリティを全部落とす。これが最も効果的なハードニング。DockerのデフォルトではCHOWN、NET_RAW、SYS_CHROOTなど14個のケーパビリティが有効ですが、OpenClawにはどれも不要です。
「全部落として動くの?」と心配になりますが、Node.jsアプリケーションの大半は特権ケーパビリティなしで問題なく動作します。実際、OpenClawはcap_drop: ALLで3ヶ月間、一度もケーパビリティ関連のエラーを出していません(ゼロ。本当にゼロ)。
2. read_only: true — ファイルシステムの読み取り専用化
read_only: true
コンテナのルートファイルシステムを読み取り専用にします。攻撃者がコンテナ内でコードを実行できたとしても、バイナリの改ざんやマルウェアの書き込みが不可能になる。
「でも書き込みが必要なディレクトリあるでしょ?」...はい、あります。だからボリュームマウントとtmpfsでピンポイントに書き込み可能領域を設ける設計です。
3. no-new-privileges — 権限昇格の禁止
security_opt:
- no-new-privileges:true
setuid/setgidビットを利用した権限昇格を完全にブロック。コンテナ内のプロセスが、起動時より高い権限を取得することを防ぎます。
CVE-2026-24763のような権限昇格脆弱性は、この設定だけで攻撃経路を潰せる。設定1行で防げるリスクを放置する理由がない。
4. user: "1000:1000" — 非rootユーザー
user: '1000:1000'
コンテナプロセスを非rootユーザーで実行。Dockerのデフォルトはrootなので、明示的に指定しないとroot実行になります。知ってました?(私は恥ずかしながら、コンテナ化するまで意識してませんでした)
ネットワークの閉じ込め
ports:
- '127.0.0.1:18789:18789'
ポートバインドを127.0.0.1に限定。外部ネットワークからGatewayにアクセスできなくなります。「LANからもアクセスしたい」場合は0.0.0.0にしますが、その場合はGatewayトークン認証が必須。
{
"gateway": {
"auth": {
"mode": "token",
"token": "${OPENCLAW_GATEWAY_TOKEN}"
}
}
}
ボリューム設計 — 書き込み権限の最小化
read_only: trueを設定した上で、書き込みが必要な領域だけを個別にマウントするのがポイントです。
マウント権限マトリクス
| パス | マウントモード | 理由 |
|---|---|---|
openclaw.json | :ro(読み取り専用) | 設定ファイルの改ざん防止 |
cron/ | :ro | ジョブ定義の保護 |
skills/ | :ro | Skillsコードの改ざん防止 |
credentials/ | :rw | APIキーの読み書き |
memory/ | :rw | エージェントの記憶永続化 |
workspace/ | :rw | エージェントの作業領域 |
/tmp | tmpfs | 一時ファイル(再起動で消失) |
/home/node/.npm | tmpfs | npmキャッシュ(再起動で消失) |
tmpfsの活用
tmpfs:
- /tmp:size=512M
- /home/node/.npm:size=256M
一時領域にtmpfsを使う理由は2つ:
- コンテナ再起動で自動クリーンアップ(ゴミが溜まらない)
- ホストのディスクに書き込まない(永続化すべきでないデータの流出防止)
sizeでサイズ上限を設けるのも忘れずに。無制限にすると、一時ファイルでメモリを食い潰すリスクがあります(OpenClawがSkills実行時に大量の一時ファイルを作ることがあるので、512MBは安全マージン込みの数値)。
Skills — 読み取り専用マウントの設計
volumes:
skills:
driver: local
driver_opts:
type: none
o: bind
device: ${SKILLS_PATH:-~/skills}
Skillsディレクトリは名前付きボリュームで:roマウント。ホスト側でSkillsを編集・追加して、コンテナから読み取り専用で参照する設計です。
コンテナ内のプロセスがSkillsコードを書き換えられないことが重要。サードパーティSkillsのセキュリティリスクは以前の記事でも触れましたが、読み取り専用マウントなら「Skillsを改ざんして別のSkillsを汚染する」攻撃パターンを防げます。
リソース制限とヘルスチェック
メモリ制限
deploy:
resources:
limits:
memory: 2G
メモリ制限を設けない場合、OpenClawが暴走した際にホストマシンのメモリを食い尽くします。2GBは通常運用で十分な値ですが、大量のSkillsを並行実行する場合は調整が必要。
ヘルスチェック
healthcheck:
test:
[
'CMD',
'wget',
'--no-verbose',
'--tries=1',
'--spider',
'http://127.0.0.1:18789/healthz',
]
interval: 30s
timeout: 10s
retries: 3
start_period: 15s
30秒間隔でGatewayの/healthzエンドポイントをチェック。3回連続で失敗したらunhealthy判定。restart: unless-stoppedと組み合わせて、異常時の自動復旧を実現しています。
start_period: 15sは「起動直後の15秒間はヘルスチェック失敗を許容する」設定。OpenClawの初期化(モデルのロード、Slack接続)には数秒かかるので、この猶予が必要です。
ホスト環境からの移行手順
既存のホスト直接実行環境からDockerに移行する場合、データ移行が必要です。
移行スクリプト
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
DATA_DIR="${PROJECT_DIR}/data"
OPENCLAW_SOURCE="${HOME}/.openclaw"
# 移行対象ディレクトリ
DIRS=(credentials identity memory agents media
browser canvas devices logs)
for dir in "${DIRS[@]}"; do
src="${OPENCLAW_SOURCE}/${dir}"
dst="${DATA_DIR}/${dir}"
if [[ -d "${src}" ]]; then
mkdir -p "${dst}"
cp -rp "${src}/." "${dst}/"
echo "[OK] ${dir}/"
else
mkdir -p "${dst}"
echo "[SKIP] ${dir}/ (created empty)"
fi
done
移行後のセキュリティチェック
移行が完了したら、必ず以下を実施してください(ここ手を抜くと移行の意味が半減します):
- Gatewayトークンの再生成
openssl rand -hex 32
# → .env の OPENCLAW_GATEWAY_TOKEN に設定
- Slackトークンの再確認 — ホスト環境が侵害されていた可能性がある場合は、Slack Bot Token / App Tokenもローテーション
- ファイル権限の確認
# data/ 以下が uid 1000 で読み書きできることを確認
ls -la data/
設定の検証 — 本当にハードニングされているか確認する
設定を書いて満足しがちですが(わかる)、実際に検証しないと意味がありません。
# コンテナの起動
docker compose up -d
# ケーパビリティの確認(空であるべき)
docker exec openclaw cat /proc/1/status | grep Cap
# read_onlyの確認(Permission denied が正常)
docker exec openclaw touch /test-write
# 非rootの確認(node ユーザーであるべき)
docker exec openclaw whoami
# ヘルスチェック状態の確認
docker inspect --format='{{.State.Health.Status}}' openclaw
CapEff: 0000000000000000 が返ってくれば、ケーパビリティが全て落ちている証拠。この数字を見ると「ちゃんと守られてるな」という安心感があります(セキュリティの数値化、心の栄養)。
CLIラッパーにもハードニングを
メインサービスだけでなく、CLI実行用のサービスにも同じセキュリティ設定を適用するのを忘れずに:
openclaw-cli:
image: ghcr.io/openclaw/openclaw:2026.3.2
profiles:
- cli
user: '1000:1000'
read_only: true
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
env_file:
- .env
volumes:
- ./config/openclaw.json:/home/node/.openclaw/openclaw.json:ro
- ./cron:/home/node/.openclaw/cron:ro
- ./data/credentials:/home/node/.openclaw/credentials:rw
- ./data/identity:/home/node/.openclaw/identity:rw
- ./data/memory:/home/node/.openclaw/memory:rw
- ./data/agents:/home/node/.openclaw/agents:rw
- ./workspace:/home/node/.openclaw/workspace:rw
- skills:/home/node/.openclaw/skills:ro
tmpfs:
- /tmp:size=512M
- /home/node/.npm:size=256M
entrypoint: ['openclaw']
CLIは--profile cliで必要なときだけ起動するので、常駐しません。でもセキュリティ設定は手を抜かない。
# CLI経由でコマンド実行
docker compose --profile cli run --rm openclaw-cli status
# ショートカットスクリプト
./scripts/oc status
AI開発ツール運用とコンテナセキュリティの考え方
OpenClawに限らず、AI開発ツールをセルフホスティングするときのセキュリティ設計には共通のパターンがあります。
なぜAI開発ツールは「特別に」危険なのか
普通のWebアプリケーションと違って、AI開発ツールにはシェルコマンドの実行能力があります。Skills経由でファイルの読み書き、API呼び出し、さらにはコード実行まで可能。これはつまり、脆弱性が見つかった場合の攻撃面が通常のアプリより桁違いに広いということ。
コンテナ化で閉じ込められるリスク
| リスク | ホスト直接実行 | コンテナ(ハードニング済み) |
|---|---|---|
| ファイルシステムアクセス | ホスト全体 | マウントしたディレクトリのみ |
| ネットワーク | 制限なし | ポートバインドで制御 |
| 権限昇格 | OS依存 | no-new-privilegesで阻止 |
| リソース消費 | 制限なし | memory/CPU limitsで制御 |
| 他プロセスへの影響 | 可能 | PID名前空間で隔離 |
防御の層を重ねる
完璧なセキュリティは存在しません。だからこそ、複数の防御層を重ねる:
- コンテナ隔離(この記事の内容)
- アプリケーションレベルのサンドボックス — OpenClawのsandboxモード
- ネットワーク制限 — localhost限定バインド、Gatewayトークン認証
- Skillsの制限 — 読み取り専用マウント、
allowBundledによる許可リスト - 監視 — ヘルスチェック、ログ、異常検知
どれか1つが破られても、次の層で止められる設計を目指す。セキュリティは「これで完璧」と言い切れない世界ですが、攻撃者のコストを上げ続けることはできます。
まとめ
OpenClawのDocker化とセキュリティハードニングの全手順を解説しました。
やることは実はシンプルで、docker-compose.ymlに3つの設定を足すだけ:
cap_drop: ALL— 不要な権限を全部落とすread_only: true— ファイルシステムを読み取り専用にno-new-privileges:true— 権限昇格をブロック
これに加えて、非rootユーザー実行、localhost限定ポートバインド、tmpfs活用、メモリ制限、ヘルスチェック。やることリストは多く見えますが、一度設定すれば「次のCVEが公開されたとき」の精神的余裕が段違いです(深夜にCVEアラートが来ても、翌朝対応できる程度の余裕。これが健全な運用)。
AI開発ツールのセキュリティは、「便利だから」で後回しにしがちな領域。でもCVE-2026シリーズが示したように、リスクは確実に存在します。この記事のdocker-compose.ymlをベースに、自分の環境に合わせてカスタマイズしてみてください。
あわせて読みたい
- 【2026年版】AIコーディングツール完全比較 — Claude Code・Codex・Antigravityの選び方
- 【OpenClaw】Docker構築・モデル切替・Skills開発 実践ガイド — Skills開発とモデル設定の実践
- 【OpenClaw × Slack】AIアシスタント構築実践 — OpenClawの基本とGeminiハイブリッド構成
- 【Claude Code × Codex × Antigravity】AIコーディングツールのSkillsを統一管理する方法 — マルチツール環境のSkills共有



