Claude Media
sandbox.allowNestedUserNamespacesでChromiumのsandboxを残す条件

sandbox.allowNestedUserNamespacesでChromiumのsandboxを残す条件

Linuxのsandboxで「No usable sandbox!」が出たときの3つの直し方を比べます。allowNestedUserNamespacesの書き場所、手放す防御、Podmanに効かない理由をまとめます。

Chromiumが「No usable sandbox!」で落ちるのはsandboxの既定動作

LinuxとWSL2では、Claude Codeのsandbox内のコマンドは既定でuser namespaceを作れません。ChromiumやElectronは自前のsandboxを作るためにuser namespaceを使うので、ここで落ちます。

sandbox.allowNestedUserNamespacesは、この制限を外すBoolean型のキーです。Claude Code v2.1.305で追加されました。既定はfalseです。

ただし、名前から想像する「ChromiumとPodmanをsandbox内で動かす設定」とは少し違います。設定リファレンスでは、このキーが解決するのはChromium、Electron、入れ子のbubblewrap、unshareです。rootlessのPodmanとBuildahは、このキーだけでは動きません。

対象

このキーの守備範囲

  • 動く

    Chromium・Electron自身のsandbox、入れ子のbubblewrap、unshareが使うuser namespaceの作成です。

  • 足りない

    rootlessのPodmanとBuildahです。sandboxは別の経路でも止めるため、excludedCommandsで扱います。

症状から3つの直し方を選ぶ

sandboxのトラブルシューティングは、同じ症状に3つの直し方を並べています。どれも何かの隔離を手放します。手放すものが違うので、選ぶ基準は「何を残したいか」です。

直し方対象手放すもの
ブラウザを--no-sandboxで起動対象Chromium、Electron手放すものブラウザ自身のsandbox。Claude Codeのsandboxはそのまま
sandbox.excludedCommandsに追加対象rootless Podman、Buildah、ブラウザやunshareを呼ぶスクリプト手放すもの一致したコマンドは、sandbox外でフルアクセスになる
sandbox.allowNestedUserNamespacesをtrue対象Chromium・Electron自身のsandboxを残したい場合、入れ子のbubblewrap、unshare手放すものsandboxの防御そのもの(次の節)

見分けに使える失敗メッセージは、次の3つです。

  • ChromiumがNo usable sandbox!で終了する
  • unshare -U trueがunshare: unshare failed: Operation not permittedを出す。allowAllUnixSocketsが有効だと、代わりにNo space left on deviceが出ることもある
  • rootless Podmanがcannot clone: Operation not permittedを出す。もっと手前で、Podman自身のフォルダについてread-only file systemと出て止まることもある

Can't mount proc on /newroot/procのようなbwrapのエラーは別の問題です。コンテナ内でsandboxが起動しないケースで、enableWeakerNestedSandboxの領分になります。Docker内でsandboxを動かす設定で扱っています。

設定は~/.claude/settings.jsonに書く

書き方はsandboxオブジェクトの中に1行足すだけです。

{
  "sandbox": {
    "enabled": true,
    "allowNestedUserNamespaces": true
  }
}

大事なのは置き場所です。~/.claude/settings.jsonに書く指示になっていて、プロジェクトの.claude/settings.jsonは不可です。理由は設定リファレンスのScope欄にあります。

書いた場所trueの扱い
~/.claude/settings.jsontrueの扱い有効
--settingsで渡したJSONtrueの扱い有効
管理設定(managed settings)trueの扱い有効
プロジェクトの.claude/settings.jsontrueの扱い無視される
プロジェクトの.claude/settings.local.jsontrueの扱い無視される
CLAUDE_CODE_SUBPROCESS_ENV_SCRUB=1のセッションtrueの扱いどの場所のtrueも無視される

falseは逆に、どのファイルに書いても有効です。設定の優先順位に従います。

つまり、リポジトリを開いただけで、そのリポジトリの設定ファイルから勝手にuser namespaceが解禁されることはありません。チームで共有したくなる設定ですが、共有リポジトリには置けない作りです。環境変数のscrubを使う構成との関係はCLAUDE_CODE_SUBPROCESS_ENV_SCRUBの解説にあります。そのセッションでは、ChromiumやElectronに--no-sandboxを付け、ほかのツールはClaude Codeの外で実行します。

効いたかどうかを確かめる

症状表に沿うなら、unshare -U trueが確認コマンドになります。Operation not permittedが出なくなれば、user namespaceを作れる状態です。ただしunshareで始まるコマンドは、excludedCommandsに何を書いてもsandbox内に留まります。unshareが任意のプログラムを起動できるためです。つまりこの確認コマンドは、除外設定に関係なく常にsandbox内で走ります。

設定を入れたら、新しいセッションでClaude Codeに確認を頼む形が手軽です。

sandbox内で `unshare -U true` を実行して、終了コードと出力をそのまま報告して。
成功したら、Chromiumを起動するテストコマンドも1回だけ実行して。

失敗した場合は、設定ファイルの置き場所(上の表)を先に疑ってください。プロジェクト側に書いていると、値がtrueでも無視されます。

有効にすると手放す防御

このキーには強い警告が付いています。trueにすると、sandbox内のコマンドが実行したコードが、sandboxの外で動いてしまうことがあります。

落とし穴

保護パスや認証情報の隠蔽が当てにならなくなる

有効にした状態では、保護パスとcredentials.filesのエントリを含め、sandboxの制限のどれも悪意あるコマンドを止める根拠にできません。auto-allowモードでは、そのコマンドが許可の確認なしで動くこともあります。組織にセキュリティチームがあるなら、有効にする前に相談する前提の設定です。

auto-allowモードとcredentials.filesで何が変わるか

sandboxのauto-allowモードは、sandbox内で動くコマンドを許可の確認なしで通すモードです。「sandboxが囲っているから確認は要らない」という理屈で成り立っています。このキーをtrueにすると、その囲いが信用できなくなるのに、確認の省略だけは残ります。

credentials.filesは、認証情報のファイルをsandbox内のコマンドから隠すための設定です。denyなら読み取りを止め、maskならトークンの代わりに見せかけの値(sentinel)を読ませ、実際の値はプロキシが送信時に差し替えます。どちらもsandboxの境界が破れていないことが前提で、境界が破れると隠したはずの認証情報の保護も当てにできません。

そのため、認証情報をcredentials.filesで隠している環境ほど、このキーを入れる前に影響を見積もる価値があります。

なお、auto-allowモードでも、Bash(git push *)のような内容を指定したaskルールは、sandbox内のコマンドにも確認を出します。Bashのdenyルールに一致する形のコマンドも止まります。確認を残したい操作があるなら、このキーを入れる前にaskルールかdenyルールで押さえておく手があります。

変更履歴の側にも、同じ趣旨の一文があります。v2.1.305の項目は「sandboxのファイル保護を回避できる」と明記しています。リリースの全体像はv2.1.305のリリースノートにあります。

保護パスの記述自体にも、allowNestedUserNamespacesをtrueにしたときは保護パスをあてにしないという注意書きがあります。「保護パスで.gitの中身を守っているから大丈夫」という前提は、このキーを入れた時点で崩れます。

Podman・Buildahは別の道で動かす

名前の印象と違い、rootlessのPodmanとBuildahにこのキーは足りません。設定リファレンスは、これらにはexcludedCommandsを使うよう書いています。sandboxは別の方法でも両者を止めるためです。

{
  "sandbox": {
    "enabled": true,
    "excludedCommands": ["podman *"]
  }
}

この書き方は、パターン例に沿った形です。注意点は3つあります。

  • パターンの末尾は *にする。podmanだけだと引数なしのpodmanしか一致しない
  • 一致したコマンドはsandbox外で、あなたのフルアクセスで動く。作業ディレクトリのスクリプトをClaudeが書き換えてから実行できる点にも注意
  • パターンはClaudeが実行するコマンドの文字列と照合される。ブラウザなら、ブラウザそのものでなくテストコマンドに一致させる

書き方の細かい規則と既知の落とし穴は、excludedCommandsの解説にあります。

組織で止めるには

管理者の側から見ると、このキーは「開発者が自分で弱められる設定」の一つです。管理者向けの節には、enableWeakerNestedSandboxなどと並んでallowNestedUserNamespacesが載っています。管理設定がこれらを設定していなければ、開発者はユーザー設定や--settingsでtrueにできます。

使わせたくないなら、管理設定でfalseを書きます。管理設定がBoolean系のキーに値を持つと、ローカルで設定された値は無視されるからです。

{
  "sandbox": {
    "enabled": true,
    "allowNestedUserNamespaces": false
  }
}

管理者向けの節は、このキーをallowAppleEventsと並べて「リポジトリからは有効にできない」と書いています。管理設定の全体像は組織管理ガイドを参照してください。

allowNestedUserNamespacesとenableWeakerNestedSandboxはどこが違うか

どちらもsandboxを弱める設定で、管理者向けの節に並んで載っています。名前が似ていますが、直す症状も、書ける場所も違います。

比較軸allowNestedUserNamespacesenableWeakerNestedSandbox
直す症状allowNestedUserNamespacesChromium・ElectronのNo usable sandbox!など、user namespaceが作れないenableWeakerNestedSandbox特権のないコンテナ内でbwrapが/procをマウントできない
書ける場所allowNestedUserNamespacesユーザー設定、--settings、管理設定。リポジトリの設定は無視enableWeakerNestedSandboxどのファイルでも書ける。ただし管理者が必須にしたsandboxでは、リポジトリのtrueは無視
手放す防御allowNestedUserNamespacessandboxの境界そのもの。保護パスやcredentials.filesも当てにできないenableWeakerNestedSandboxコンテナの/procを見せるため、プロセス情報が隠れなくなる。外側のコンテナの隔離が前提
管理設定での止め方allowNestedUserNamespacesfalseを書くenableWeakerNestedSandboxfalseを書く

見分け方は症状です。Can't mount procならコンテナの問題で、後者です。No usable sandbox!やunshareの失敗なら、user namespaceの問題で、前者です。前者がリポジトリの設定を最初から受け付けないのに対し、後者はリポジトリからも書けるため、管理設定でfalseを置く意味が大きくなります。

WSL2でも同じ症状が出る

このキーが対象とするのはLinuxとWSL2です。WSL2はLinuxと同じbubblewrapでsandboxを作るので、ChromiumやPodmanの症状も、設定の書き方も同じになります。ネイティブWindowsではコマンドがsandboxなしで動くため、このキーの出番がありません。WSL1ではsandbox自体が起動せず、Sandboxing requires WSL2と出ます。

WSL2でbubblewrap自体が起動しない場合は、AppArmorがuser namespaceを制限していることがあります。sysctl kernel.apparmor_restrict_unprivileged_usernsが1を返すなら制限が有効です。このキーとは別の話なので、混同しないようにしてください。

どれを選ぶか

迷ったときの組み合わせを、症状別にまとめます。

状況候補補足
E2Eテストで自分が管理するChromiumを動かす候補--no-sandbox補足Claude Codeのsandboxは残るが、ブラウザは無防備になる
ブラウザ自身のsandboxも残したい候補allowNestedUserNamespaces補足代わりにClaude Codeのsandboxの防御を当てにできない
rootless PodmanやBuildah候補excludedCommands補足このキーだけでは足りない
CLAUDE_CODE_SUBPROCESS_ENV_SCRUB=1のセッション候補ブラウザに--no-sandbox、他は手元で実行補足このキーもexcludedCommandsも効かない
管理下のマシン候補管理設定でfalse補足開発者の判断に任せない

Ubuntu 24.04以降でbubblewrap自体が動かない場合は、AppArmorの設定が原因のことがあります。これはsandboxの導入手順の話なので、sandboxの有効化の解説と、全体の選び方をまとめたsandbox環境の選び方に当たってください。

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