Claude Media
Claude CodeのWSL2 sandbox失敗で無防備に動くときの確認

Claude CodeのWSL2 sandbox失敗で無防備に動くときの確認

WSL2でsandboxを有効にしたのに、bwrapのbind失敗でコマンドが無サンドボックスのまま走る報告があります。起きる条件、見分け方、止め方をまとめます。

WSL2でClaude Codeのsandboxを有効にしても、実際にはサンドボックスの外でコマンドが走り続けている。そんな報告がGitHubのissue #84563にあります。画面に出るのは「Retrying without the sandbox」の一行だけです。気づかないまま使い続ける恐れがあるため、症状の見分け方と止め方を先にまとめます。

何が報告されているのか

報告者の環境は、Windows 11のホストにWSL2のUbuntu 24.04を載せ、その中でClaude Code v2.1.223を動かす構成です。sandbox.enabled: true にしてBashを実行すると、サンドボックスの初期化が次のエラーで失敗します。

bwrap: Can't mkdir /mnt/c/Program Files/ClaudeCode: Permission denied

報告者の見立てでは、WSLではWindows側の管理設定を読むために /mnt/c/Program Files/ClaudeCode をbindマウントする処理があります。Windows側に C:\Program Files\ClaudeCode が無いと、bwrapがマウント先を作ろうとして失敗します。個人利用のWindowsにこのフォルダーが無いのは普通のことです。企業が管理設定を配る場合にだけ作られます。

無防備になる条件は「失敗」と「許可された再試行」の組

エラーだけでは無サンドボックスにはなりません。もう一つの条件が allowUnsandboxedCommands です。

allowUnsandboxedCommands初期化に失敗したときの動き
true初期化に失敗したときの動き「Retrying without the sandbox」と表示し、以降のコマンドも無サンドボックスで実行
false初期化に失敗したときの動きサンドボックス付きの実行が使えず、エラーとして表に出る

issueの報告によると、true の場合は毎回の呼び出しで同じ再試行が起きます。サンドボックスを意図して有効にした人に、恒久的に壊れているという合図が出ません。報告者がセキュリティ上の問題として挙げているのもこの点です。

この症状かどうかを切り分ける

次の三つが重なるなら、この報告と同じ型の可能性があります。

  1. WSL2の中でClaude Codeを動かしている(ネイティブWindowsではない)
  2. C:\Program Files\ClaudeCode がWindows側に存在しない
  3. Bashのたびに「Retrying without the sandbox」が出る、またはbwrapの Can't mkdir が見える

WSL2側から、フォルダーの有無は次のコマンドで見られます。

ls -d "/mnt/c/Program Files/ClaudeCode"

No such file or directory と返れば、条件2に当てはまります。ただしこれは原因の候補を絞るだけです。別の症状でも無サンドボックスの再試行は起きるため、次節の方法で実際に効いているかを確かめます。

サンドボックスが効いているかを確かめる

Claude Codeのドキュメントに、サンドボックスの動作確認が載っています。Claudeに次の二つを実行させます。自分で ! プロンプトに打つと、サンドボックスの外で走るのが普通なので、検査になりません。

コマンドサンドボックス内での結果
touch ~/sandbox-probeサンドボックス内での結果LinuxとWSL2では Read-only file system で失敗
curl --noproxy '*' https://example.comサンドボックス内での結果Could not resolve host で失敗

touch が成功したら、サンドボックスの外で走っています。ホームディレクトリがサンドボックスの書き込み許可先に入っていなければ、作られた ~/sandbox-probe を消します。Claudeが失敗後に「サンドボックスなしで再試行しますか」と尋ねてきたら、確認のときは断ります。承認すると、失敗したコマンドがそのまま外で走り、検査の意味が消えます。

/sandbox を開くと、設定が有効か、依存パッケージが揃っているかも見られます。ただし依存の欠落を表示するタブは、bwrapが実行時にbindで失敗するケースを必ず拾うとは限りません。ドキュメントはこの経路に触れていないため、touch の結果を信頼の基準にしてください。

止め方: 初期化の失敗をエラーとして表に出す設定

無防備な実行を避けるには、再試行の許可を外すのが確実です。

{
  "sandbox": {
    "enabled": true,
    "allowUnsandboxedCommands": false,
    "failIfUnavailable": true
  }
}

allowUnsandboxedCommands: false にすると、dangerouslyDisableSandbox パラメーターが無視され、excludedCommands に載せたもの以外は常にサンドボックス内で走ります。/sandbox のOverridesタブではStrict sandbox modeと表示されます。報告者も、この設定なら初期化の失敗がエラーとして見えると書いています。別の環境でこの設定を使った検証コメントでは、サンドボックスが毎回初期化されました。

failIfUnavailable は、依存パッケージが無い場合やプラットフォームが非対応の場合に、起動時に終了させる設定です。bindの失敗がこの条件に含まれるかは、ドキュメントに記載がありません。allowUnsandboxedCommands: false との併用で、取りこぼしを減らす位置付けで考えてください。

allowUnsandboxedCommands の動作と autoAllowBashIfSandboxed との関係は、autoAllowBashIfSandboxedでBash確認をスキップする条件と無効化にあります。サンドボックスで確認を省いている環境では、無サンドボックスに落ちたときの影響が大きくなる点に注意が必要です。

再試行は誰が承認するのか

issueの「Retrying without the sandbox」と、ドキュメントにある dangerouslyDisableSandbox 付きの再試行は、同じ仕組みなのかどうか。issueには書かれていません。ただ、後者の承認ルールは、無サンドボックスに落ちたときの被害の大きさを左右するので、押さえておく価値があります。

  • bypassPermissions モード: プロンプトなしで再試行が走る
  • 通常モードと acceptEdits モード: 「Bash command (unsandboxed)」という題のプロンプトが出る
  • dontAsk モード: 再試行は拒否される
  • Bash(curl *) のような許可ルールがコマンドに一致する場合: そのルールが再試行も承認し、プロンプトは出ない

Bash(dangerouslyDisableSandbox:true) にaskルールを足すと、autoモードや bypassPermissions モードでも再試行のたびに確認が出ます。承認の経路を残したまま、外で走る瞬間だけは必ず目に入れたいチームには、この書き方が使えます。

直す方法: Windows側のフォルダーかautomountか

issueには二つの回避策が書かれています。どちらも報告者の環境での結果で、Anthropicが推奨する手順ではありません。

フォルダーを作る

管理者権限のPowerShellで、無いフォルダーを作ります。

New-Item -ItemType Directory 'C:\Program Files\ClaudeCode'

報告者の環境では、これでbindマウントが通り、サンドボックスが初期化されました。ドキュメントによると、C:\Program Files\ClaudeCode\ はWindowsの管理設定ファイルやドロップインを置く場所でもあります。wslInheritsWindowsSettings は、WSLがWindowsの管理設定チェーンを読むかを決める管理設定で、この場所かHKLMレジストリからだけ有効にできます。既定は false で、そのときWSLは /etc/claude-code だけを読みます。空のフォルダーを作ってもこの設定は変わりません。

プロファイルの列挙に当たったとき

issueのコメントでは、フォルダーを用意した後に別の失敗が出たと報告されています。

bwrap: Can't create file at /mnt/c/Users/<別のプロファイル>/.claude: Permission denied

コメントの報告者は、WSL側の連携がWindowsの全ユーザープロファイルを列挙し、それぞれの .claude をbindしようとしている、と推測しています。複数のアカウントが C:\Users にある環境で起きるとされ、この報告者は /etc/wsl.conf のautomountを止めて回避しました。

[automount]
enabled=false

Microsoftのドキュメントでは、enabled=false にすると固定ドライブが自動でマウントされず、手動か fstab で行う必要があります。/mnt/c が使えなくなるため、WSLからWindows側のファイルを触る作業にも影響します。変更後はWSLの再起動が必要です。コメントでは、その次に /home/.mcp.json と /.mcp.json の作成失敗が出て、rootで空の {} を置く回避策を取ったと書かれています。

サンドボックスが動き出した後にも、コメントの報告者は二つの衝突を挙げています。node_modules/.bin がサンドボックスにbindされるため、サンドボックス内の npm ci は削除の段階で EBUSY になり、完走できません。また、リポジトリ直下の .mcp.json は、存在しないときの ENOENT ではなく EACCES で隠されます。ENOENT だけを許容してファイルの有無を調べるツールは、この違いで落ちます。いずれもv2.1.223での報告です。

一連の対処はいずれも、サンドボックスが提供する境界を弱める側にも働き得ます。業務環境では、情報システム部門と相談してから適用するほうが安全です。

バージョン差と、まだ分かっていないこと

この報告には、再現しなかったという別の環境からのコメントもあります。v2.1.283、Ubuntu 26.04で C:\Program Files\ClaudeCode が存在しない環境でも、allowUnsandboxedCommands: false を付けた上でサンドボックスは毎回初期化され、$HOME への書き込み、許可外ホストへの通信、cmd.exe の起動が止まったとあります。作業ディレクトリへの書き込みと git status は通りました。

したがって、v2.1.223で見られた症状が新しい版でも続くかどうかは、環境ごとの検証が必要です。報告者の環境と違うのは、Claude Codeのバージョン、Ubuntuのバージョン、WSLのバージョンです。どの差が効いたのかは、issueのコメントからは特定できません。手元で動いているか迷うなら、前節の touch の検査が確実です。

導入の手順そのものはClaude Code WSL2セットアップに、unshare の失敗など別の原因による初期化エラーはunshare(CLONE_NEWUSER)がClaude Codeのサンドボックスで失敗する原因にあります。サンドボックス全体の設計はClaude Codeのサンドボックス設計で扱っています。

確認の順番

症状が出たときは、次の順に見ると無駄が少なくなります。

  1. 設定で sandbox.enabled が true であることを確かめる
  2. Claudeに touch ~/sandbox-probe を実行させ、Read-only file system が返るか見る
  3. 成功してしまうなら、allowUnsandboxedCommands: false にして、エラーが表に出る状態にする
  4. 出たエラーに Can't mkdir /mnt/c/Program Files/ClaudeCode があれば、Windows側のフォルダーの有無を見る
  5. Can't create file at /mnt/c/Users/… や .mcp.json に変わったら、プロファイルの列挙や親ディレクトリの探索に当たっている

3の設定は、無サンドボックスで走ってしまうことを防ぐための変更で、サンドボックスを使えるようにするものではありません。動かすには、4と5の原因に対処する必要があります。

まとめ

サンドボックスの有無は、設定値ではなく挙動で確かめるものです。WSL2でbwrapの初期化が失敗しても、allowUnsandboxedCommands が true のままだと、画面の一行を除いて普段と変わらない見た目で走ります。まず touch ~/sandbox-probe で実際に効いているかを見て、効いていなければ再試行を禁止し、出たエラーを手がかりにWindows側の状態を調べてください。

この記事を共有:XはてブLinkedIn