プロキシ有効時にHTTPS証明書エラーが出る場合の対処法:主な原因と確認手順

ブラウザの証明書エラーは、必ずしもサイト側の問題とは限りません。時刻のずれ、ノードによる改ざん、MITM復号、ローカルファイアウォールなどの原因を切り分けます。

HTTPS証明書エラーは通常、TLSハンドシェイクの段階で発生します。ブラウザはWebページのリクエストを実際に送信する前に、サーバーの証明書が信頼できる認証局によって発行されているか、証明書のドメイン名が現在のアドレスと一致しているか、現在時刻が有効期間内か、証明書チェーンがシステムの信頼するルート証明書まで完全につながっているかを確認します。Clashやmihomoを有効にしてエラーが出ても、接続経路が変わったことを示すだけで、特定のノードが原因だとは限りません。

標準的なHTTP CONNECT、SOCKS5、TUNによる転送では、Webサイトに代わって証明書を発行することはありません。mihomoカーネルは通常、接続の転送、ルールの照合、出口の選択を担うだけで、Webページ内のTLS通信を復号しません。ブラウザに表示される証明書の発行者が、突然ローカルのセキュリティソフト、企業ゲートウェイ、見覚えのない機関になった場合は、HTTPSスキャン、上流プロキシ、公衆ネットワークの認証ページ、システムの証明書ストアを確認してください。プロキシルールを何度も変更するだけでは解決しません。

まずエラーコードで範囲を絞る

証明書エラーの種類によって、確認すべき方向は異なります。Chrome、Edge、Chromiumベースのクライアントでは、通常 NET::ERR_CERT_ で始まるコードが表示されます。Firefoxでは SEC_ERROR_UNKNOWN_ISSUERSSL_ERROR_BAD_CERT_DOMAIN がよく見られます。まずブラウザの「詳細」または「証明書を表示」を開き、下表に照らして対処してください。

エラーコードまたは現象 優先して確認する項目 主な原因
NET::ERR_CERT_DATE_INVALID システムの日付、時刻、タイムゾーンと証明書の有効期間 端末の時刻ずれ、デュアルブートによる時刻差、スリープ復帰後の未同期
NET::ERR_CERT_COMMON_NAME_INVALID アドレスバーのドメインと証明書のSANドメイン DNSが誤ったサーバーを指している、透過型ゲートウェイによるリダイレクト、誤ったドメインへのアクセス
NET::ERR_CERT_AUTHORITY_INVALID 証明書の発行者と完全な証明書チェーン ローカルHTTPSスキャン、企業プロキシ、自己署名証明書、サーバーによる中間証明書の送信漏れ
SEC_ERROR_UNKNOWN_ISSUER Firefoxの証明書ストアとシステムの証明書ストア ブラウザがローカル検査ツールのルート証明書を信頼していない、または証明書チェーンが不完全
一部のアプリだけ失敗する アプリの証明書ピンニング、プロキシ種別、TUNの取り込み範囲 アプリが証明書ピンニングを実行している、または通信が追加のフィルターモジュールを経由している
すべてのHTTPSサイトで同時に失敗する システム時刻、ローカルセキュリティソフト、公衆ネットワークの認証 個別サイトの証明書障害より、システム全体の環境問題である可能性が高い

証明書画面で確認する4項目

  1. 発行先:現在アクセスしているドメインが含まれている必要があります。ワイルドカード証明書 *.example.comwww.example.com をカバーできますが、通常は1階層深い a.b.example.com まではカバーできません。
  2. 発行者:直接接続時は公開認証局なのに、プロキシ経由ではローカルソフト名や組織内CAに変わる場合、経路上でTLS検査が行われています。
  3. 有効期間:「有効開始日時」と「有効期限」を比較する際は、システムのタイムゾーンも同時に確認してください。日付が正しくても、タイムゾーンが数時間ずれていると、証明書更新直後にエラーが発生することがあります。
  4. サブジェクト代替名:最新のブラウザは、旧式のCommon Nameだけでなく主にSANを確認します。証明書に現在のドメインが含まれていないと、ドメイン不一致になります。

手順1:システム時刻と証明書環境を調整する

時刻の誤りは影響範囲が広く、最も少ない手間で確認できます。すべてのHTTPSサイトで失敗する場合や、PCがスリープから復帰した直後、マザーボードの電池を交換した直後、デュアルブート環境では、まず時刻を同期してください。Windows 11では「設定」→「時刻と言語」→「日付と時刻」を開き、「時刻を自動的に設定する」と「タイムゾーンを自動的に設定する」をオンにしてから、「今すぐ同期」をクリックします。

Windowsでは、ターミナルから次のコマンドを実行して時刻サービスの状態も確認できます。結果の Source には利用可能な時刻ソースが表示され、Last Successful Sync Time は現在時刻に近い値になるはずです。

w32tm /query /status
powershell -NoProfile -Command "Get-Date"

macOSでは「システム設定」→「一般」→「日付と時刻」を開き、自動設定をオンにします。Linuxでは timedatectl statusSystem clock synchronized とタイムゾーンを確認できます。Androidの一般的な経路は「設定」→「システム」→「日付と時刻」です。メーカーによっては「その他の設定」に配置されています。

期限切れのローカル証明書による介入を整理する

端末にパケットキャプチャツール、デバッグプロキシ、企業の端末管理ソフト、HTTPSスキャンコンポーネントを導入したことがある場合は、現在も動作していないか確認します。ブラウザを終了するだけでは不十分です。フィルタードライバー、システムサービス、ローカルプロキシのプロセスが接続を引き続き制御している可能性があります。まずソフトウェア自身の設定でHTTPSスキャンまたはTLS復号を無効にし、該当プログラムを完全に終了してからブラウザを再起動します。

  • Windowsでは Win + R を押して certmgr.msc と入力し、現在のユーザー証明書を確認できます。コンピューター単位の証明書は、MMCの「証明書」スナップインで確認します。
  • macOSでは「キーチェーンアクセス」で「システム」と「ログイン」のキーチェーンを確認し、最近追加された証明書署名用途の項目を重点的に調べます。
  • Firefoxでは「設定」→「プライバシーとセキュリティ」→「証明書」→「証明書を表示」を開き、「認証局証明書」の一覧を確認します。
  • Androidでは「設定」→「セキュリティ」→「暗号化と認証情報」から、ユーザーがインストールした認証情報を確認できます。実際のメニュー名はOSのバージョンによって異なります。

手順2:直接接続、システムプロキシ、TUN経路を比較する

証明書問題の切り分けには、条件を管理した比較テストが最も効果的です。ノード、DNS、ルールを同時に変更したり、証明書を再インストールしたりせず、毎回1つの変数だけを変えてください。まず安定したHTTPSサイトでテストし、その後にエラーが出た対象サイトを確認すると、すべてのサイトで失敗しているのか、特定サイトだけなのかを区別できます。

  1. Clashまたはmihomoは起動したまま、システムプロキシとTUNを無効にして直接接続をテストします。
  2. システムプロキシだけを有効にし、同じノードと同じブラウザで再度テストします。
  3. システムプロキシを無効にし、TUNだけを有効にしてもう一度テストします。
  4. モードを変えずに、現在のノードを別経路のノードへ切り替えます。
  5. 最後にルールモード、グローバルモード、ダイレクトモードを切り替え、問題がルールのマッチングに関係しているか確認します。

curlでローカル混合ポートを確認する

ClashのGUIクライアントでは、ローカル混合ポートが 7890 に設定されていることがよくあります。ただし、実際の値は設定の mixed-port またはクライアントの「設定」→「ポート設定」を確認してください。次の2つのコマンドで、直接接続とローカルHTTPプロキシ経由の接続をそれぞれテストできます。-I はレスポンスヘッダーだけを取得し、-v は接続とTLSの過程を表示します。

curl -Iv https://www.cloudflare.com/
curl -Iv --proxy http://127.0.0.1:7890 https://www.cloudflare.com/

直接接続は成功してプロキシ経由だけ失敗する場合は、ノードを切り替えながらmihomoのログを確認します。すべてのノードで失敗し、特定のローカルセキュリティコンポーネントを無効にすると復旧する場合は、まず端末側のTLS検査に対処してください。1つのノードだけが失敗する場合は、ノードの出口ネットワーク、上流DNS、公衆ネットワークの認証、またはサーバーから対象サイトまでの経路に問題がある可能性があります。

OpenSSLを使って、サーバーから送信された証明書チェーンを確認することもできます。新しいバージョンのOpenSSLでは、HTTPプロキシ経由で接続を確立できます。

openssl s_client -proxy 127.0.0.1:7890 -connect www.cloudflare.com:443 -servername www.cloudflare.com -showcerts

-servername はSNIを送信します。SNIがない場合、マルチドメインサーバーがデフォルトサイトの証明書を返し、ドメイン不一致になることがあります。直接接続とプロキシ経由の結果を比較する際は、証明書のサブジェクト、発行者、有効期間、検証結果コードを重点的に確認し、コマンドの最後にTCP接続が確立したかだけで判断しないでください。

手順3:ノード、DNS、プロキシルールを確認する

ノード切り替えで分かること

プロキシ経由のHTTPSでは、クライアントがまずノードへの暗号化トンネルを確立し、その後ノードが対象サイトへ接続するのが一般的です。HTTPプロキシでは、ブラウザが CONNECT example.com:443 でトンネルを確立します。SOCKS5では、ドメイン名または宛先アドレスがSOCKSリクエストで渡されます。正常なトンネル内のTLS接続は、引き続きブラウザと対象サイトの間で行われます。

別のノードに切り替えてすぐ復旧する場合は、失敗したノードのネットワークが対象ドメインを誤ったアドレスへ誘導していないか、通信事業者の認証ページが表示されていないか、対象サイトが現在使用している証明書チェーンを取得できているかを確認します。ノードが証明書を差し替え、かつ端末がその発行証明書を信頼している場合に限り、ブラウザは警告なしで差し替え内容を受け入れられます。信頼されていなければ、通常は証明書エラーが発生します。

DNSエラーが証明書のドメインエラーになる理由

DNSがドメインを誤ったサーバーへ解決すると、ブラウザは元のドメインをSNIとして送信します。誤ったサーバーに該当する仮想ホストがない場合、別サイトの証明書が返され、最終的に NET::ERR_CERT_COMMON_NAME_INVALID が表示されることがあります。この場合、証明書自体は有効期間内でも、適用ドメインがアドレスバーのドメインと一致しません。

mihomoの fake-ip モードでは、まず予約済みアドレスプールからマッピングアドレスを返し、その後カーネル内で元のドメインを復元してルールに従って接続します。Fake-IP自体がWebサイトの証明書を生成することはありません。Fake-IPでのみ問題が発生する場合は、ドメインが誤って fake-ip-filter に追加されていないか、アプリがTUNを迂回していないか、LANのDNSリクエストが確実にmihomoへ入っているかを確認します。

dns:
  enable: true
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  fake-ip-filter:
    - "*.lan"
    - "localhost.ptlogin2.qq.com"

fake-ip-filter は、実アドレスを必要とするLANサービス、デバイス検出用ドメイン、特定の互換性要件がある場合に限定して設定します。広範囲のドメインをまとめて除外するのは避けてください。除外したドメインは実際の名前解決を使うため、解決元とルール経路も変わります。

実際にマッチしたルールを確認する

接続一覧に対応したClashクライアントでは、「接続」または「ログ」画面を開き、エラーが出るサイトにアクセスしてドメインで絞り込みます。マッチしたルール、ポリシーグループ、最終ノードを記録してください。本来は直接接続すべきなのにプロキシへ入る場合は、上位にある DOMAINDOMAIN-SUFFIXGEOSITE とルールセットを確認します。本来プロキシを使うべきなのに直接接続になる場合は、LANルール、プライベートアドレスルール、最後の MATCH を確認します。

rules:
  - DOMAIN-SUFFIX,example.com,PROXY
  - GEOSITE,private,DIRECT
  - GEOIP,private,DIRECT,no-resolve
  - MATCH,PROXY

ルールは上から順に照合され、先にマッチすると後続のルールは処理されません。YAMLを変更したら、まずインデントを確認してから設定を再読み込みします。サブスクリプションのオーバーライド、スクリプト、グローバル拡張設定を併用している場合は、サブスクリプションの原文ではなく、最終的に適用された設定を確認してください。

手順4:MITM、HTTPSスキャン、ファイアウォールの介入を特定する

ここでいうMITMとは、中間コンポーネントが元のTLS接続を終端し、ブラウザ向けに差し替え証明書を発行すると同時に、そのコンポーネント自身が対象サイトとの間に別のTLS接続を確立する仕組みです。企業の監査ゲートウェイ、パケットキャプチャ用デバッグツール、ペアレンタルコントロールソフト、一部のエンドポイントセキュリティ製品がHTTPS通信の検査にこの方式を使うことがあります。

標準的なmihomo設定の proxiesproxy-groupsrulestundns フィールドは、Webサイトの証明書を発行するものではありません。そのため、Clashクライアントの画面に「Webサイト証明書」のような設定項目が見当たらないのは正常です。証明書の発行者がローカルソフトとして表示される場合は、そのソフトのネットワーク保護またはHTTPSスキャン設定を確認してください。

すべてのコンポーネントを一度に削除せず、1つずつ無効にする

  1. ブラウザ拡張機能のプロキシ切り替え、パケットキャプチャ、デバッグ機能を無効にし、ブラウザを完全に終了してから再起動します。
  2. ローカルのパケットキャプチャソフトでシステムプロキシとHTTPS復号を一時的に停止し、Clashのシステムプロキシだけを残します。
  3. セキュリティソフトの「HTTPSスキャン」「暗号化接続の検査」などの機能を一時的に無効にし、比較テストが終わったら元に戻します。
  4. 会社のVPN、ゼロトラストクライアント、リモートワーク用ゲートウェイを切断し、自宅のネットワークとモバイルホットスポットで比較します。
  5. 公衆Wi-Fiの認証が済んでいない場合は、まずプロキシを無効にして、システムが案内するログインページを開きます。認証完了後にプロキシを有効にしてください。

公衆ネットワークによっては、最初のHTTPリクエストを認証ページへリダイレクトします。認証ゲートウェイが返す証明書は元のサイトのものではないため、HTTPSではこのリダイレクトをそのまま受け入れられず、ブラウザにドメイン不一致が表示されます。モバイルホットスポットに切り替えてすぐ復旧する場合、この問題である可能性が高いです。

手順5:ブラウザだけ、または特定アプリだけのエラーに対処する

ChromeとEdgeは正常だが、Firefoxでエラーが出る

ChromeとEdgeは通常、OSの証明書環境に従います。一方、Firefoxの証明書処理はシステムと異なる場合があります。まずFirefoxで「設定」→「プライバシーとセキュリティ」→「証明書」→「証明書を表示」を開き、必要な認証局が存在するか確認します。企業端末では管理者が証明書ポリシーを一括導入すべきで、Webページの案内から一時的に証明書をダウンロードしないでください。

ブラウザは正常だが、デスクトップアプリまたはスマホアプリで失敗する

アプリによっては独自の証明書ストアを使用し、さらに証明書ピンニングを実行するものもあります。これは開発者があらかじめ指定した証明書や公開鍵の関係だけを受け入れる仕組みです。そのため、ブラウザではサイトを開けても、アプリは接続を拒否することがあります。通常は、システムへ証明書を追加するのではなく、そのアプリの通信をTLS復号コンポーネントから迂回させます。

TUNモードでのみ問題が発生する場合は、アプリの通信が別のVPN、セキュリティフィルター、プライベートDNSも同時に経由していないか確認します。AndroidとiOSでは通常、主要なVPNトンネルを1つしか同時に使用できませんが、ローカルDNS、コンテンツフィルター、端末管理ポリシーによって経路が変わることはあります。他のネットワーク拡張機能を無効にし、Clashクライアントだけを起動すると、切り分けやすくなります。

シークレットウィンドウでは正常だが、通常ウィンドウで失敗する

この場合は、ブラウザ拡張機能、キャッシュされたHSTS状態、独立したプロキシ拡張機能、ユーザー設定の違いが原因であることが多いです。まず拡張機能の管理画面でネットワーク関連の拡張機能を無効にし、対象サイトのCookieとサイトデータを削除します。「証明書エラーを無視する」起動オプションを恒久的な対策にしないでください。ブラウザセッション全体の証明書検証能力が低下します。

10分で確認できる再利用可能な切り分け手順

  1. 1分目:エラーコードを書き留め、証明書のドメイン、発行者、有効期間を確認します。
  2. 2分目:システム時刻を同期し、日付、タイムゾーン、時刻サービスの状態を確認します。
  3. 3分目:システムプロキシとTUNを無効にして、直接接続で比較します。
  4. 4分目:システムプロキシだけを有効にし、同じサイトと同じブラウザでテストします。
  5. 5分目:別経路のノードへ切り替え、他の設定は変更しません。
  6. 6分目:接続ログを確認し、ドメインにマッチしたルール、ポリシーグループ、出口を確認します。
  7. 7分目:curl -Iv で、直接接続と 127.0.0.1:7890 プロキシ経由の結果を比較します。
  8. 8分目:HTTPSスキャン、パケットキャプチャ、企業ネットワークコンポーネントを一時停止し、1つずつ比較します。
  9. 9分目:モバイルホットスポットへ切り替え、公衆ネットワークの認証と現在のルーター経路を切り分けます。
  10. 10分目:クライアントのバージョン、mihomoカーネルのバージョン、OSのバージョン、ノード、モード、エラーコードなど、再現条件を整理します。

最終的な判断は比較結果に基づいて行います。すべてのネットワークと端末で同じサイトにエラーが出るなら、サイト側の証明書設定に問題がある可能性が高いです。1台の端末だけで失敗するなら、時刻、証明書ストア、セキュリティソフトを優先して確認します。プロキシ経路だけで失敗するなら、ノード、DNS、ルール、上流ネットワークを調べます。特定のアプリだけが失敗するなら、独自証明書ストア、証明書ピンニング、アプリ通信の取り込み範囲を重点的に確認します。

切り分けが終わったら、一時的に無効にしたセキュリティ機能を1つずつ元に戻し、ブラウザと普段使うアプリを再確認します。Clashまたはmihomoの設定も通常の利用モードに戻し、グローバルプロキシ、広すぎるFake-IP除外、テストのためだけに追加したルールを長期間残さないようにしてください。

クライアントのダウンロードページへ