HTTPS証明書エラーが示す意味

ブラウザでHTTPSサイトにアクセスすると、まず対象サーバーとのTLS接続が確立されます。サーバーは証明書チェーンを返し、ブラウザは証明書の有効期間、発行元、対象ドメイン、失効状態を確認します。いずれかの条件を満たさないと、接続が中断されて証明書エラーが表示されます。Clashは通信経路上で転送を行いますが、通常のシステムプロキシ、HTTPプロキシ、SOCKS5プロキシ、TUN転送だけでウェブページの内容を自動的に復号することはありません。

HTTPプロキシを例にすると、ブラウザがHTTPSサイトへアクセスする際は、通常まずローカルのプロキシポートへCONNECTリクエストを送信します。たとえば 127.0.0.1:7890 に接続し、example.com:443 へのトンネル確立を要求します。トンネル確立後もTLSハンドシェイクはブラウザとリモートサーバーの間で行われます。途中でHTTPS復号が実行されていなければ、Clashがウェブページの平文を見ることも、サイトに代わって証明書を発行することもありません。

ブラウザのエラーコード別チェック項目

エラーコード 一般的な意味 優先して確認する項目
NET::ERR_CERT_DATE_INVALID 証明書の有効期間外、または端末の時刻が大きくずれている システムの日付、タイムゾーン、自動時刻合わせ、サイト証明書の有効期間
NET::ERR_CERT_COMMON_NAME_INVALID 証明書の対象ドメインとアクセス中のドメインが一致しない DNS汚染、ノードのハイジャック、誤ったhosts設定
NET::ERR_CERT_AUTHORITY_INVALID 証明書チェーンを信頼されたルート証明書までたどれない ローカルのパケットキャプチャ用証明書、企業ゲートウェイ、証明書ストアの異常
ERR_SSL_PROTOCOL_ERROR TLSハンドシェイクが中断され、TLSデータではない内容が返された ノードの可用性、ポート転送、プロトコル設定、ネットワークによる遮断
SEC_ERROR_UNKNOWN_ISSUER Firefoxが証明書の発行者を信頼できない Firefox独自の証明書ストア、ローカルの中間証明書

Clashを起動してからエラーが出る理由

Clashを起動すると、通信に使われる出口、DNSの解決経路、ルーティングルールが変わります。プロキシを有効にした後でエラーが出たとしても、新しい経路に問題が関係していることを示すだけで、Clashコアが証明書を変更したとは限りません。実際の切り分けでは、ブラウザ、ローカルプロキシ、ルール適用、ノード、リモートDNS、対象サーバーの6段階に分けて確認します。

ノードがリクエストを誤ったサーバーへ転送している

ノードの出口で異常なDNSが使われていたり、経路上でドメインのハイジャックが起きていたりすると、対象ドメインが誤ったIPアドレスに解決されることがあります。ブラウザは本来 account.example.com にアクセスしているのに、リモート側から別サイトの証明書が返されるため、ドメイン不一致が発生します。この問題は一部のドメインだけに影響することが多く、別のノードへ切り替えるとすぐに解消する場合があります。

証明書の詳細にある「発行先」フィールドも確認できます。現在のドメインと証明書のSubject Alternative Nameがまったく関係していない場合は、ノードとDNSを重点的に確認し、ブラウザの「続行」を直接クリックしないでください。ログインページ、決済ページ、アカウント管理画面でドメイン不一致が表示された場合は、アカウントやパスワードの入力を中止します。

ローカルソフトがHTTPS復号を実行している

Charles、Fiddler、mitmproxy、一部のデバッグプロキシ、企業向け端末管理ソフト、セキュリティソフトは、ローカルルート証明書をインストールしてHTTPS通信を中間者復号できます。設定が正しければ、ブラウザはローカルで発行された一時証明書を信頼します。ルート証明書がない、期限切れ、または誤った証明書ストアにだけインストールされている場合は、発行元が無効と表示されます。

よくある経路は、ブラウザがまずClashに接続し、Clashが別のローカルプロキシへ通信を転送する構成です。また、OSに古いPACアドレスが残っている場合もあります。Clashの画面でシステムプロキシが有効になっていても、通信が複数のプロセスを経由することがあります。Windowsでは「設定」→「ネットワークとインターネット」→「プロキシ」で手動プロキシとセットアップスクリプトを確認します。macOSでは「システム設定」→「ネットワーク」→現在のネットワーク→「詳細」→「プロキシ」で、ウェブプロキシ、安全なウェブプロキシ、自動プロキシ構成を確認します。

システム時刻によって証明書が未発行または期限切れに見える

TLS証明書には明確なNot BeforeとNot Afterの時刻が含まれます。パソコンの日付が1日ずれている、タイムゾーンの選択を誤っている、スリープ後に時計が同期されていないといった状況では、NET::ERR_CERT_DATE_INVALID が発生することがあります。プロキシの有効化と時刻の誤りは、単に同時に起きているだけかもしれません。特に、OSの再インストール直後、マザーボードの電池残量低下、仮想マシンのスナップショット復元時に起こりやすくなります。

Windows 11では「設定」→「時刻と言語」→「日付と時刻」を開き、「時刻を自動的に設定する」と「タイムゾーンを自動的に設定する」を有効にしてから、「今すぐ同期」をクリックします。macOSでは「システム設定」→「一般」→「日付と時刻」を開き、自動設定を有効にします。同期後は現在のタブを更新するだけでなく、ブラウザを完全に終了してから再起動してください。

手順どおりに進めるClash証明書エラーの切り分け

以下の順番で確認すると、原因の範囲をすばやく絞り込めます。各手順では変更する変数を1つだけにして、結果を記録してください。ノード変更、DNS変更、証明書の再インストール、ブラウザデータの消去を同時に行うと、復旧後に本当の原因を特定できません。

  1. 完全なエラーコードを記録する。 「接続は安全ではありません」だけで済ませないでください。アドレスバーのドメイン、ブラウザのエラーコード、証明書の発行者をコピーし、エラーが発生した時刻も確認します。
  2. システムプロキシを無効にして再テストする。 Clashクライアントで「システムプロキシ」を無効にし、ブラウザを完全に終了してから同じURLへアクセスします。直接接続では正常でプロキシ経由だけエラーになる場合、問題をルール、ノード、プロキシ経路に絞り込めます。
  3. 異なる経路のノードへ切り替える。 別の地域、別のサービス事業者、または別のプロトコルのノードを優先します。切り替え後は古い接続が閉じるまで3~5秒待ち、プライベートウィンドウでテストします。
  4. 一時的にプロキシモードをグローバルに変更する。 グローバルモードでは正常でルールモードだけエラーになる場合、同じページに必要なメインドメイン、APIドメイン、静的リソースのドメインが異なる出口に振り分けられている可能性があります。テスト後はルールモードに戻してください。
  5. システム時刻を確認する。 年月日、時刻、分、タイムゾーンを確認します。中国本土では通常UTC+08:00を使用します。タスクバーの時刻が現在時刻に近いかどうかだけで判断しないでください。
  6. 証明書の発行者を確認する。 ブラウザのアドレスバーから証明書の詳細を開きます。発行者名がローカルのデバッグツール、企業ゲートウェイ、セキュリティソフトを示している場合は、該当するプログラムとルート証明書を引き続き確認します。
  7. 追加のプロキシ層を停止する。 パケットキャプチャソフト、ブラウザのプロキシ拡張機能、その他のプロキシクライアントを終了し、システム上で想定したポートをリッスンしているプログラムが1つだけであることを確認します。
  8. DNSと設定ファイルは最後に確認する。 一部のドメインだけで誤った証明書が返される場合は、直接接続とプロキシ経由で得られる解決先アドレスを比較し、ルールが対象ドメインを誤った出口へ送っていないか確認します。

ポート、プロキシチェーン、ローカルのリスニング状態を確認する

クライアントによって初期ポートは異なります。設定でよく使われる混合ポートは 7890、SOCKSポートは 7891、外部コントロールポートは 9090 であることが多いです。ただし、これらは一般的な値にすぎず、実際の結果は現在の設定とクライアントの設定画面に従ってください。ブラウザやシステムプロキシが古いポートを参照していると、まだ稼働中の別プロセスへ接続することがあります。

Windows PowerShellでは、一般的なポートをどのプロセスがリッスンしているか確認できます。

Get-NetTCPConnection -State Listen |
  Where-Object LocalPort -In 7890,7891,9090 |
  Select-Object LocalAddress,LocalPort,OwningProcess

Get-Process -Id <OwningProcess の数値>

macOSまたはLinuxでは、次のコマンドを使用できます。

lsof -nP -iTCP:7890 -sTCP:LISTEN
lsof -nP -iTCP:7891 -sTCP:LISTEN
lsof -nP -iTCP:9090 -sTCP:LISTEN

7890 が旧バージョンのクライアント、デバッグプロキシ、その他のサービスに使用されている場合、現在のClashクライアントが別のポートへ自動的に変更されるか、起動に失敗することがあります。その場合はまず競合しているプロセスを終了し、クライアントの「設定」→「ポート設定」または「設定」→「Clash設定」に戻って、Mixed Port、HTTP Port、SOCKS Portを確認します。メニュー名はクライアントによって異なりますが、ポート番号はシステムプロキシに入力した値と一致していなければなりません。

上流プロキシの有無を確認する

mihomoの設定では、プロキシプロバイダー、プロキシチェーン、dialer-proxy などの仕組みによって、接続を別のプロキシ経由にできます。ブラウザ拡張機能がシステムプロキシを上書きする場合もあります。切り分けではまず最短の経路にします。ブラウザはシステムプロキシを使用し、システムプロキシはClashのMixed Portを直接参照し、Clashは確実に利用できる通常のノードを1つ選択する構成です。経路が復旧したら、中継や拡張機能を1つずつ追加します。

コマンドラインでテストする場合は、直接接続とローカルプロキシ経由で返される証明書情報を比較できます。以下の例はリクエストヘッダーだけを送信し、アカウント情報は送信しません。

curl -I https://example.com/
curl -I --proxy http://127.0.0.1:7890 https://example.com/

直接接続は成功するのにプロキシ経由で証明書エラーが表示される場合は、ノードを切り替えて2つ目のコマンドを再実行します。1つのノードだけが失敗するなら、通常はシステムの証明書ストアを変更する必要はありません。そのノードを無効にし、ドメイン、発生時刻、エラーコードをノード提供元へ伝えてください。

DNS、ルールモード、TUNが証明書の結果に与える影響

証明書の検証対象はドメインですが、最終的な接続先はIPアドレスです。ClashのDNSモジュール、Fake-IPモード、ルールによる振り分け、ノード側のリモート解決によって、実際の接続先が決まります。設定に不整合があると、ブラウザのアドレスバーに表示されるドメインは変わらなくても、別のドメイン向け証明書がサーバーから返されることがあります。

ルールモードで出口が一致していない

現在のウェブページは通常、メインサイト、ログインAPI、CDN、サードパーティーリソースへ同時にリクエストします。メインドメインをプロキシ経由、APIドメインを直接接続にしても、それだけで証明書エラーになるわけではありません。ただし、地域制限、企業内ネットワークの名前解決、地域別CDNが関係する環境では、出口が異なることで別のアドレスが返されることがあります。クライアントの接続ログを開き、エラー発生時刻から対象ドメインを探して、適用されたルールとプロキシグループを確認します。

一時的にグローバルモードへ切り替えて復旧する場合は、同じサービスのドメインに一貫したルールを追加できます。メインドメインとサブドメインを同じプロキシグループ経由にする必要がある場合は、実際のドメインに応じてルールを追加します。

rules:
  - DOMAIN,login.example.com,PROXY
  - DOMAIN-SUFFIX,example.com,PROXY
  - MATCH,DIRECT

ルールは上から順に照合されます。より具体的なドメインルールを、広範なルールより前に置いてください。例示用ドメインを正式な設定へそのまま記述せず、接続ログで実際のリクエストドメインを確認してください。

Fake-IPとDNSハイジャック

Fake-IPモードでは、端末にマッピング用アドレスを返し、コアがドメインに基づいてルール適用と実際の名前解決を行います。ブラウザに 198.18.0.0/16 の範囲にあるアドレスが表示されても、証明書が置き換えられたことを意味しません。これはClashで一般的な内部マッピング方式です。本当に確認すべきなのは、通信がコアに正しく引き継がれているか、対象ドメインが不適切なFake-IP除外リストに入っていないかです。

TUNモードは通常、より多くのアプリの通信を引き継ぎ、DNSハイジャックと組み合わせて53番ポートの問い合わせをコアへ渡せます。システムで企業VPN、ゲーム用アクセラレーター、仮想マシンのネットワーク、別のTUNドライバーも動作していると、ルーティングやDNSが競合することがあります。テストではクライアントの「設定」→「TUNモード」を開き、一時的にTUNを無効にしてシステムプロキシだけを残します。証明書エラーが消えた場合は、出所不明のルート証明書をインポートするのではなく、ルーティングテーブル、DNSハイジャック、他の仮想ネットワークアダプターを確認してください。

ドメインの名前解決結果を比較する

Windowsでは Resolve-DnsName、macOSとLinuxでは dig を使用できます。まずClashを無効にした状態で1回検索し、その後Clashを有効にして再度検索します。Fake-IPモードで結果が異なるのは想定内です。Clashの接続ログと照合して実際の接続先を確認してください。Redir-Hostモードでまったく異なるパブリックアドレスが返る場合は、nameserver、fallback、ノード側のリモート解決、本機のhostsファイルを確認します。

Resolve-DnsName example.com
nslookup example.com

dig example.com A
dig example.com AAAA

証明書ストアとブラウザの違いへの対処

ChromeとEdgeは通常、OSの証明書機能を使用しますが、プラットフォームによって実装の細部は異なります。Firefoxは独自の証明書ストレージを使用できるため、Chromeでは正常なのにFirefoxだけ SEC_ERROR_UNKNOWN_ISSUER が表示されることがあります。1つのブラウザだけでエラーが出る場合は、まずそのブラウザの拡張機能、プロキシ設定、証明書ストア、セキュリティポリシーを確認します。

Windowsの証明書を確認する

Win + R を押して certmgr.msc と入力すると、現在のユーザーの証明書を確認できます。「信頼されたルート証明機関」→「証明書」で、使用を停止したパケットキャプチャツールの証明書が残っていないか確認します。システムのルート証明書をまとめて削除したり、不明な手順に従って証明書を安易にインポートしたりしないでください。証明書がアンインストール済みのデバッグツールに属することが明確な場合も、まずツールのアンインストール手順を確認してから該当証明書を削除します。

macOSのキーチェーンを確認する

「アプリケーション」→「ユーティリティ」→「キーチェーンアクセス」を開き、「ログイン」と「システム」のキーチェーンをそれぞれ確認します。エラーページの証明書詳細に表示された発行者名を検索し、証明書の有効期間と信頼設定を確認してください。企業や学校が管理する端末では、構成プロファイルによって証明書がインストールされていることがあります。このような証明書は自分で削除せず、ネットワーク管理者に確認してください。

Firefoxを個別に確認する

「設定」→「プライバシーとセキュリティ」→「証明書」→「証明書を表示」を開き、「認証局」一覧を確認します。また、「設定」→「一般」→「ネットワーク設定」で、Firefoxがシステムプロキシ、手動プロキシ、自動プロキシ設定のどれを使用しているか確認してください。システムプロキシがすでにClashを参照しているのに、Firefoxが別のポートを手動で参照している場合、他のブラウザとは異なる経路になります。

Clashのログから障害箇所を判断する

証明書の検証がブラウザ側で行われている場合、Clashのログに「certificate invalid」と直接表示されるとは限りません。ログには、接続先、適用されたルール、ノード名、低レベルのハンドシェイクエラーが記録されることが多いです。切り分け中はログレベルを一時的に info または debug に変更し、1回再現したらすぐに元へ戻してください。長時間有効にすると大量のログが発生します。

  • i/o timeout:接続またはハンドシェイクがタイムアウトしています。ノードの品質、対象への到達性、ファイアウォールを優先的に確認します。
  • connection refused:対象ポートまたは上流プロキシが接続を拒否しています。ポート、プロトコル、サービスの状態を確認します。
  • tls handshake timeout:TLSハンドシェイクが制限時間内に完了していません。経路上のパケット損失、ノードの異常、対象側の制限が原因の可能性があります。
  • remote error: tls:リモート側がTLSセッションを終了しました。前後のログと対象ドメインを合わせて判断します。
  • no such host:ドメインの名前解決に失敗しています。DNS設定、ネットワークの到達性、ドメイン名の入力ミスを重点的に確認します。

ログ上で想定したルールに一致し、別のノード経由なら接続に成功するのに、ブラウザにはローカル発行者の証明書が表示される場合、問題はブラウザとClashの間にある可能性が高くなります。逆に、特定のノードだけでハンドシェイクのタイムアウトや誤った接続先アドレスが発生する場合は、そのノードを無効にし、ブラウザのセキュリティ設定を下げて回避しないでください。

復旧後に設定を整える

原因が判明したら、切り分け中に行った一時的な変更を元に戻します。グローバルモードをルールモードへ戻し、通常のログレベルに戻し、不要になった手動プロキシを無効にし、TUNとシステムプロキシが普段の用途に合っているか確認します。ルールを変更した場合は、少なくともホームページ、ログインAPI、よく使うリソースのドメインをテストし、想定したプロキシグループに一致することを確認してください。

動作確認済みの設定コピーを1つ保存し、クライアント名、コアのバージョン、Mixed Port、DNSモード、問題が発生したノードを記録しておくと便利です。次に証明書エラーが起きたときは、すべての設定を消去したり再インストールしたりするより、まずこれらの項目を比較するほうが差異を見つけやすくなります。