Claude Media
Claude DesktopのSSHセッションでプロキシと社内CAを通す設定

Claude DesktopのSSHセッションでプロキシと社内CAを通す設定

リモートの.profileに書いたプロキシは、Claude DesktopのSSHセッションに届きません。settings.jsonのenvにHTTPS_PROXYとNODE_EXTRA_CA_CERTSを置く手順と確認先をまとめます。

リモートのLinuxサーバーでは、ターミナルからclaudeを叩くと普通に動く。ところがClaude DesktopからSSHでつないだセッションだけが固まったり、「Authentication failed」を出したりする。~/.profileにはプロキシも社内CAも書いてあるのに、です。

原因は、SSHセッションのClaude Codeが~/.profileなどの変数を受け取らないことにあります。リモート側の~/.claude/settings.jsonのenvに書き直せば解消します。以下に、書く内容、証明書の変数の選び方、効かないときの確認先を順に示します。

症状と原因の対応

DesktopのSSHセッションでは、Claude Codeはリモートマシン上で動き、APIへの通信もそのマシンから出ます。そのため、プロキシ越しにしか外へ出られないサーバーでは、リモート側でプロキシと証明書を正しく渡す必要があります。

公式ドキュメントは、プロキシや認証局(CA)の変数を~/.profile・~/.bash_profile・~/.zprofile・~/.zshrcにexportしていても、SSHセッションのClaude Codeはそれらを受け取らないと説明しています。同じマシンのターミナルでclaudeを動かすと通るのは、ログインシェルがこれらのファイルを読むからです。

画面に出る症状は3通りあります。

画面の様子疑うこと
メッセージを送っても応答が返らず固まる疑うことプロキシ経由でないと外に出られないのに、変数が届いていない
「The connection from … to the API failed」疑うこと同上。APIへの接続が失敗している
「Authentication failed」。サインインし直しても直らない疑うこと同上。認証の通信がプロキシか証明書で止まっている

3行目は、サインインの問題に見えて、実際はネットワーク経路の問題だという点が見落とされやすいところです。手元のDesktopでサインインできていても、SSH先のClaude Codeの通信は別の経路で出ます。

設定する場所は~/.claude/settings.jsonのenv

書く先は、SSH先のリモートマシンにあるユーザー設定です。手元のPCの設定ではありません。

{
  "env": {
    "HTTPS_PROXY": "http://proxy.example.com:8080",
    "NODE_EXTRA_CA_CERTS": "/etc/ssl/certs/example-ca.pem"
  }
}

これは公式の例を日本語の環境に置き換えて載せたものです。プロキシのURLと証明書のパスは、自分の環境の値に変えます。HTTPS_PROXYにはhttp://などのスキームが要ります。Claude Codeは起動時にプロキシのURLだけを検査し、解釈できないと起動を止めて、直すべき変数名を出します。

既存の設定を壊さずに追記する

settings.jsonにすでに別のキーがあるなら、ファイルを上書きしないでください。jqが使える環境なら、envだけを足せます。

jq --arg p "http://proxy.example.com:8080" \
   --arg ca "/etc/ssl/certs/example-ca.pem" \
   '.env = ((.env // {}) + {HTTPS_PROXY:$p, NODE_EXTRA_CA_CERTS:$ca})' \
   ~/.claude/settings.json > /tmp/settings.new \
  && mv /tmp/settings.new ~/.claude/settings.json

modelとenv.FOOを持つ設定ファイルに同じ式を当てたところ、modelとFOOは残り、2つの変数だけがenvに加わりました。ファイルが無いときは先にecho '{}' > ~/.claude/settings.jsonで空のJSONを作ります。

手元のPCから現在の設定を確認する

リモートに入り直さなくても、手元のPCから1行で中身を確認できます。

ssh devbox 'cat ~/.claude/settings.json'

devboxは~/.ssh/configのホスト名か、user@hostに置き換えます。

証明書はNODE_EXTRA_CA_CERTSで指定する

社内CAの指定には、SSL_CERT_FILEではなくNODE_EXTRA_CA_CERTSを使います。公式は、Claude Codeが~/.claude/settings.jsonのSSL_CERT_FILEで指した認証局を信頼しないと明記しています。

変数settings.jsonのenvでの扱い
NODE_EXTRA_CA_CERTSsettings.jsonのenvでの扱い指したPEMファイルの証明書を、追加の信頼先として使う
SSL_CERT_FILEsettings.jsonのenvでの扱い認証局として信頼されない

指すファイルは、SSH先のリモートマシン上のパスにします。手元のMacやWindowsに置いた証明書ではありません。社内CAのPEMをリモートにも配置しておく必要があります。

標準の信頼先は変わりません。Claude CodeはMozillaの同梱証明書とOSの証明書ストアの両方を既定で信頼し、NODE_EXTRA_CA_CERTSはそこに足されます。社内のTLS検査プロキシのルート証明書がOSのストアに入っていて、Claude Codeの実行環境が読める状態なら、追加設定は要りません。

変更はいつ反映されるか

settings.jsonのenvを書き換えたあとは、公式の手順どおりに進めます。

手順

設定を足してから確認するまで

  1. 1

    リモートの設定ファイルに変数を書く

    HTTPS_PROXYとNODE_EXTRA_CA_CERTSをenvに入れます。

  2. 2

    同じセッションでメッセージを送り直す

    ~/.claude/settings.jsonで足したり変えたりした変数は、数秒以内に有効になります。

  3. 3

    直らなければ新しいセッションを始める

    送り直しても失敗するときは、セッションを作り直します。

セッションを閉じてDesktopを再起動する手順は、この段階では要りません。再起動が必要になる条件は、次の節にあります。

設定したのに効かないとき

settings.jsonに書いても直らない最大の原因は、同じ変数がリモートの別の場所で既に設定されていることです。DesktopのSSHセッションでは、リモートの環境で決まった値が優先され、設定ファイルのenvの値は無視されます。公式の設定リファレンスも、Desktopがセッションを起動するときは、組み立てた起動環境が先に立ち、起動環境がすでに設定している変数については設定ファイルのenvが無視されると書いています。無視された変数はデバッグログに出ます。

手元からリモートの環境変数を一覧する

まず、リモートが何を設定しているかを見ます。手元のターミナルから次を実行します。

ssh devbox env | grep -i -E 'proxy|ca_|cert'

HTTPS_PROXYやNODE_EXTRA_CA_CERTSが出たら、その値がセッションに使われています。ここで見つかる場所は~/.zshenv、/etc/environment、~/.bashrcなどです。変更は、変数を設定しているそのファイルで行います。

新しい値をセッションに渡し直す

設定元のファイルを直した後は、新しい値をセッションに渡します。公式の案内は2通りです。

  • リモートマシンを再起動する
  • Desktopを終了し、リモートのヘルパー(Desktopが入れる補助プログラム)のプロセスを終了する

どちらも、動作中のタスクを止めます。タスクが走っていない時間に行ってください。ヘルパーのプロセスは、リモートでpgrep -fl "$HOME/.claude/remote/"を実行して確認できます。手順の詳細は、同じSSHセッションの公式ページにある「ヘルパーを削除する手順」の最初の2ステップに従います。

読み込まれたかを確認する

設定したつもりの値が実際に使われているかは、デバッグログで見ます。リモートでclaudeをデバッグ付きで起動し、ログを確認します。

claude --debug

ログは~/.claude/debug/<セッションID>.txtに出ます。証明書が読めていれば、次の形の行が出ます。

CA certs: Appended extra certificates from NODE_EXTRA_CA_CERTS (/etc/ssl/certs/corp-ca.pem)

読めないファイルを指していると、Failed to readかFailed to loadの行が理由つきで出ます。対話画面の/statusにも「Proxy」と「Additional CA cert(s)」の行があります。ただし後者はパスを表示するだけで、ファイルが読めたかは検証しません。証明書は必ずデバッグログで確認します。

このclaude --debugは、ターミナルから直接動かすClaude Codeの確認です。DesktopのSSHセッションがどの値を実際に使ったかは、ログに無視された変数が出ていないかを見るほうが確実です。ターミナルでは通るのにDesktopでだけ失敗するなら、この差が原因の候補です。

管理者が配る場合と対象外の条件

組織の管理者は、同じ変数を管理設定のenvで配れます。公式は、管理設定と~/.claude/settings.jsonのどちらにも全変数を置けると案内し、バックグラウンドで動くセッションにも確実に届く設定は設定ファイルだけだと書いています。シェルのexportに頼る構成は、ここでも避けます。

読み込み元の範囲は、サインインの仕方で変わります。

セッションの状況プロキシ・証明書の変数を読む設定
claude.aiでサインインしたローカル・SSH・WSLのCodeタブプロキシ・証明書の変数を読む設定すべての設定スコープから読む
アプリが接続を管理するセッション(サードパーティプロバイダーのCodeタブ、Cowork)プロキシ・証明書の変数を読む設定管理設定と~/.claude/settings.jsonだけ

アプリが接続を管理するほうでは、リポジトリ内の設定ファイルに書いても無視されます。チェックアウトしたリポジトリが、セッションのプロキシや証明書の経路を勝手に書き換えられないようにするためです。v2.1.217より前は、アプリが接続を管理しているときには、どの設定ファイルの値も無視していました。

また、次の条件も押さえます。

  • 対象OS: 公式の手順は「Linuxのリモートマシン」について書かれています。macOSのリモートについての記載は、この手順にはありません
  • SOCKSは非対応: Claude CodeはSOCKSプロキシに対応していません。HTTPS_PROXYにはHTTPプロキシを指定します
  • NO_PROXY: 除外するホストを書く変数も、同じenvに置けます
  • プロキシに認証が要る場合: http://user:password@proxy.example.com:8080の形で書けますが、パスワードが設定ファイルに平文で残ります

SSHの接続自体が踏み台やProxyCommandを使うなら、それは手元のSSH設定の話です。リモート側でのClaude CodeのAPI通信とは別の経路で、ConnectTimeoutを延ばす方法やMatch hostの食い違いのように、症状ごとに原因が違います。

手元のDesktopが社内プロキシで止まる場合

ここまで扱ったのは、SSH先のリモートマシンから出る通信です。手元のPCのDesktopアプリ自体が社内ネットワークで「Authentication failed」を繰り返すのは別の問題で、プロキシのURLカテゴリ規則やNTLM認証が絡みます。切り分けはClaude DesktopでAuthentication failedが繰り返される原因に載っています。

Claude Code全般(CLI)のプロキシと証明書の設定を一通り知りたいときは、Claude Codeのプロキシ設定が受け皿になります。SSH先で使うホスト許可リストの入口はClaude Codeのリモート運用にあります。

まとめ

DesktopのSSHセッションで通信が止まるときは、リモートの~/.claude/settings.jsonのenvに、HTTPS_PROXYとNODE_EXTRA_CA_CERTSを書き足します。証明書の変数はSSL_CERT_FILEではありません。

それでも変わらなければ、ssh devbox envでリモートが同名の変数を握っていないかを見ます。握っている場合、設定ファイルの値は使われません。変更はその変数を設定しているファイルで行い、止まってよい時間にヘルパーを終了して渡し直します。

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