Claude Media
sandboxのallowUnixSocketsとallowLocalBindingはmacOS専用

sandboxのallowUnixSocketsとallowLocalBindingはmacOS専用

sandbox.network.allowUnixSocketsとallowLocalBindingはmacOSでだけ効き、Linux・WSL2では無視されます。代替キーとallowMachLookup、管理設定での扱いを解説します。

allowUnixSocketsとallowLocalBindingはmacOSでだけ効く

sandbox.network.allowUnixSocketsは、サンドボックス化したコマンドが接続してよいUnixソケットのパスを並べる設定です。ところがこのキーは、LinuxとWSL2では読まれません。同じ事情がsandbox.network.allowLocalBindingにもあります。dev serverを立てるためにポートをlistenさせるキーですが、効くのはmacOSだけです。

settings.jsonに書いて「効かない」と感じたとき、原因はたいてい書き方ではなくOSです。Claude Codeのサンドボックスは、macOSとLinux・WSL2で隔離の仕組みが違います。その差が、3つのキーの効き方にそのまま出ています。

3つとは、allowUnixSockets、allowLocalBinding、allowMachLookupです。本記事は、各キーが効くOS、効かないOSで使う代替、管理設定での扱いを順に見ます。

3つのキーが効くOSの早見表

設定リファレンスの記述を、OS別に並べ直すと次のようになります。

キーmacOSLinux・WSL2
allowUnixSocketsmacOS列挙したパスのソケットに接続できるLinux・WSL2無視される
allowLocalBindingmacOSlistenとlocalhostへの接続ができるLinux・WSL2効果なし
allowMachLookupmacOS列挙したXPC・Machサービスを引けるLinux・WSL2説明はmacOSのサンドボックス向け

Linux・WSL2側の代替は、キーごとに違います。

  • Unixソケット: allowAllUnixSocketsを使う
  • localhost: excludedCommandsでそのコマンドをサンドボックスの外に出す
  • XPC・Mach: macOS固有の仕組みなので、Linux側に対応するキーはない

最後の行は、リファレンスの説明がmacOSのサンドボックスを前提に書かれている、という意味です。Linux・WSL2でこのキーが何かをするとは書かれていません。

allowUnixSocketsは列挙したパスだけを通す

型はパスの文字列の配列です。既定は未設定で、その場合macOSのサンドボックスはUnixソケットをすべて遮断します。

{
  "sandbox": {
    "network": {
      "allowUnixSockets": ["~/.ssh/agent-socket"]
    }
  }
}

上の例は、SSHエージェントのソケットだけを通します。パスを個別に書けるのはmacOSの利点です。必要なソケットだけを開けて、残りは閉じたままにできます。

Linux・WSL2ではパスを見られない

Linux・WSL2でこの配列が無視される理由は、リファレンスに書かれています。隔離にseccompフィルターを使っており、そのフィルターはソケットのパスを検査できないためです。フィルターが見られるのはsocket(AF_UNIX, ...)の呼び出し自体で、どのパスに繋ぐかまでは見えません。

その結果、Linux・WSL2のUnixソケットは「全部遮断」か「全部許可」の二択になります。

Linux・WSL2ではallowAllUnixSocketsを使う

sandbox.network.allowAllUnixSocketsは真偽値で、既定はfalseです。

{
  "sandbox": {
    "network": {
      "allowAllUnixSockets": true
    }
  }
}

trueにすると、サンドボックス化したコマンドはどのUnixソケットにも接続できます。falseのときの挙動はOSで分かれます。

  • macOS: allowUnixSocketsに書いたパスを除いて遮断される
  • Linux・WSL2: seccompフィルターが入っていれば、それで遮断される

フィルターが入っていない環境では、サンドボックスはUnixソケットの呼び出しを遮断しません。フィルターの有無は/sandboxのDependenciesタブで確かめられます。入れ方はLinuxとWSL2のセットアップ手順にあります。

WSL2では副作用にも注意が要ります。trueにすると、cmd.exeやpowershell.exeなどWindowsのバイナリを起動するinteropソケットも開きます。WSLがWindows側の実行ファイルの起動をUnixソケットで受け渡すためです。逆に言えば、falseのままフィルターを入れていれば、サンドボックス内からWindowsバイナリは起動できません。

allowLocalBindingはdev serverのlistenを許す

allowLocalBindingは、macOSのサンドボックス化したコマンドに2つのことを許します。

  • 任意のローカルアドレスでポートをlistenする(dev serverの起動など)
  • localhostの任意のポートへ接続する

false(既定)では、macOSのコマンドはポートをlistenできず、localhostのサーバーへ直接接続もできません。

{
  "sandbox": {
    "network": {
      "allowLocalBinding": true
    }
  }
}

開けるものは意外に広い

trueにすると、localhost上の他のサービスにも届くようになります。認証のないデバッガーのようなサービスがあれば、サンドボックスの外にいるそのサービスが、コマンドの代わりに動いてしまいます。

もう一点、非ループバックのアドレスでlistenしたコマンドは、他のマシンからの接続を受け付けます。0.0.0.0でdev serverを起動する習慣がある場合は、LAN内に公開されることになります。

Linux・WSL2ではlocalhostが閉じている

Linux・WSL2では、サンドボックス化したコマンドごとに専用のループバックがあります。コマンドは、自分でlistenしたポートには自分で接続できます。ただしそのlocalhostはコマンドごとに独立しているため、ホスト側で動いているサーバーには届きません。allowLocalBindingを足しても変わりません。

ホストのサーバーに繋ぎたいコマンドは、excludedCommandsでサンドボックスの外に出します。外に出したコマンドにはファイルシステムもネットワークも制限が掛かりません。範囲が広がるので、パターンはできるだけ狭く書くのが無難です。

{
  "sandbox": {
    "excludedCommands": ["npm run test:e2e *"]
  }
}

excludedCommandsの書式と、効かないときの原因はsandbox.excludedCommandsでdockerなど非対応コマンドを対象外にするにまとめています。

allowedDomainsにlocalhostを足しても直接接続は変わらない

allowedDomainsにlocalhostを入れる回避策を試したくなりますが、効きません。このエントリが効くのは、サンドボックスのプロキシを通る接続だけです。Claude Codeは、サンドボックス化したコマンドにlocalhostをプロキシ迂回にするNO_PROXYを設定します。そのためlocalhostへの接続は、元からプロキシを通らず直接行われます。

しかもこのエントリは、プロキシ経由で来るコマンドに対して、ホストのlocalhostの全ポートを見せることにもなります。dev server目的で足すのは割に合いません。

allowMachLookupはXPCサービスを引かせる

allowMachLookupは、macOSのサンドボックスが名前解決してよいXPC・Machサービス名の配列です。iOS SimulatorやPlaywrightのように、XPCで通信するツールは、必要なサービス名をここに書く必要があります。

型は文字列の配列で、既定は未設定です。末尾に*を1つ付けるとプレフィックス一致になり、"*"だけを書くと全サービスに一致します。

{
  "sandbox": {
    "network": {
      "allowMachLookup": ["com.apple.coresimulator.*"]
    }
  }
}

この例は、com.apple.coresimulator.で始まるサービスをまとめて通します。個別のサービス名を1つずつ書くより、プレフィックスでまとめるほうが設定は短くなります。反面、"*"は全サービスを引けるようにするので、隔離を大きく緩めます。必要なプレフィックスを調べて絞るほうが安全側です。

必要なサービス名が分からないときの調べ方は、リファレンスには載っていません。上の例以外の名前は、利用するツール側の資料で確かめることになります。

3つのキーの危険度を並べる

どれも「穴を開ける」設定なので、開ける範囲を比べておきます。

キー開く範囲広がり方
allowUnixSockets開く範囲列挙したパスだけ広がり方パス次第で大きく変わる
allowAllUnixSockets開く範囲全Unixソケット広がり方WSL2ではinteropも開く
allowLocalBinding開く範囲localhostの全ポートとlisten広がり方非ループバックならLANにも公開
allowMachLookup開く範囲列挙したサービス広がり方*だと全サービス

allowUnixSocketsは、パスを絞れても安全とは限りません。/var/run/docker.sockを通すと、サンドボックス化したコマンドがDockerデーモンを操作できます。結果としてホストへの実質的なアクセスを与えることになります。リファレンスはこの点をセキュリティ上の制限として明記しています。

管理設定では書き方によって無視される

組織で管理設定を配る場合、これらのキーはリポジトリ側からどう見えるでしょうか。サンドボックスが管理者要求の状態(admin-required)になると、リポジトリの.claude/settings.jsonと.claude/settings.local.jsonにある一部のキーが無視されます。管理者要求の状態になる条件は2つです。

  • 管理設定でallowUnsandboxedCommandsをfalseにしている
  • 管理設定でnetwork.allowManagedDomainsOnlyをtrueにしている

どちらも、サンドボックス自体を有効にはしません。enabledも併せて設定します。enabledの意味はsandbox.enabledはClaude CodeのBashコマンドを隔離する設定にあります。

この状態でのリポジトリ設定の扱いは、キーの型で分かれます。

キーリポジトリ設定での扱い
network.allowUnixSocketsリポジトリ設定での扱い全エントリを無視
network.allowMachLookupリポジトリ設定での扱い全エントリを無視
network.allowAllUnixSocketsリポジトリ設定での扱いtrueを無視(falseは有効)
network.allowLocalBindingリポジトリ設定での扱いtrueを無視(falseは有効)

配列のキーは中身ごと、真偽値のキーは緩める方向のtrueだけが無視されます。それでも、開発者本人の~/.claude/settings.jsonと--settings、管理設定にある値は有効です。

つまり、承認済みのツールが必要とするソケットやXPCサービスは、管理設定の側に書いておく必要があります。リポジトリには供給できません。この挙動はv2.1.285以降が対象です。v2.1.282からv2.1.284では、同じ設定がexcludedCommandsのリポジトリ側エントリを無視する挙動になっていました。

管理者要求でない場合でも、allowAllUnixSocketsとallowLocalBindingは、管理設定でfalseにして開発者のローカル設定による有効化を止められます。管理設定が設定した真偽値は、開発者のローカルの値より優先されます。

症状から原因を切り分ける

動かないときは、OSとキーの組み合わせを先に見ると早く片付きます。

  • macOSでallowUnixSocketsを書いたのにソケットに繋がらない。管理者要求のサンドボックスで、キーがリポジトリ側にある可能性があります。管理設定か~/.claude/settings.jsonへ移します
  • Linux・WSL2でallowUnixSocketsが効かない。仕様です。allowAllUnixSocketsを使うか、そのコマンドをexcludedCommandsに入れます
  • Linux・WSL2でallowLocalBindingを足してもホストのDBに繋がらない。これも仕様で、キーは何もしません
  • macOSでdev serverがポートをlistenできない。allowLocalBindingがfalseのままです
  • iOS SimulatorやPlaywrightがmacOSで起動に失敗する。XPCサービス名をallowMachLookupに足します

macOSのgitでSSHリモートを使うと失敗する問題は、これらのキーでは解決しません。リモートのSSHトンネルがサンドボックスのプロキシに認証できないことが原因とされ、対処はHTTPSリモートへの切り替えか、gitのネットワークコマンドをexcludedCommandsに入れることです。Unixソケットを開けても直りません。

キー選びの目安

3つのキーは、同じ「サンドボックスに穴を開ける」設定でも、開ける対象と効くOSが別です。要点を一度に並べると次のとおりです。

  • 特定のソケットだけ通したいならmacOSのallowUnixSockets。Linux・WSL2で同じ精度は出せません
  • dev serverのlistenを許すのはmacOSのallowLocalBinding。Linux・WSL2ではコマンドごとにexcludedCommandsで外します
  • XPCで動くツールはmacOSのallowMachLookupで、プレフィックスをできるだけ絞る
  • チームの設定をmacOSとLinuxで共有するなら、同じsettings.jsonに3つのキーを書いておいて問題ありません。効かないOSでは無視されるだけです

最後の点は、設定ファイルを共有する運用で効いてきます。macOSの開発者とLinuxのCI、WSL2の開発者が同じファイルを読んでも、キーが原因でエラーにはなりません。ただし「書いてあるのに効いていない」状態は残るので、OSごとの代替をコメントやドキュメントに添えておくと、後から読む人が迷いません。

なお、プロキシのポートを差し替えるhttpProxyPort・socksProxyPortは、ここで扱ったキーとは別の層の設定です。httpProxyPortとsocksProxyPortで社内検査プロキシを通す設定で説明しています。

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