V2RayのTLS証明書エラー対処法:システム時刻のずれとSNIの設定ミス

x509やcertificateのエラーが出る場合は、システム時刻のずれ、SNIと証明書名の不一致、証明書検証の無効化を順に確認し、TLSハンドシェイク失敗の原因を特定しましょう。

この記事の要点

v2rayN、v2rayNG、v2flyNGのログに証明書検証エラーが表示される場合に役立つ内容です。まず詳細なエラーを確認し、システム時刻を合わせてから、TLSのSNIと証明書名、サーバー側の証明書チェーンを順に調べます。証明書検証は有効のまま、設定を一度に一つずつ変更し、一時的につながっただけで解決したと判断しないようにしましょう。

まずログを確認:証明書エラーと接続タイムアウトを見分ける

ノードが接続できなくても、TLSが原因とは限りません。TLSハンドシェイクは基盤となる接続の確立後、プロキシプロトコルのデータを送る前に行われます。ログにx509、certificate、または具体的なハンドシェイクの原因が記録されている場合に、証明書の問題として調べましょう。context deadline exceededだけでは、待ち時間を超過したことしか分からず、証明書の期限切れとは判断できません。

接続ログを確認システム時刻を確認証明書名を確認証明書チェーンを確認再接続して検証

v2rayNではメイン画面下部のログ欄を確認します。使用中のバージョンでログが別画面にある場合は、「ログ」を開いてから再接続してください。v2rayNGではメイン画面のサイドメニューから「ログ」を開き、サービスを停止して再起動した後、直近の記録を確認します。v2flyNGでも今回の接続に関するコアのログを確認し、以前の失敗記録と混同しないようにしましょう。画面の構成はバージョンによって異なるため、実際の表示に従ってください。

x509エラーの内容から確認箇所を絞り込む

以下はよく見られる実際のエラー例です。完全なログにはコア名の接頭辞、証明書名、日付などが含まれ、表現もコアのバージョンによって異なる場合があります。詳細な原因を確認してください。特に有効期間に関するエラーは、ログの現在時刻と証明書の有効期間を照らし合わせて判断します。「期限切れ」という表示だけでノードの交換を求めないようにしましょう。

エラー:x509: certificate has expired or is not yet valid

原因と対処:クライアントが証明書を有効期間外と判断しています。まずシステム時刻を確認してください。時刻が正確でも再発する場合は、サーバー管理者に証明書の有効開始日・終了日と、更新後の反映状況を確認してもらいましょう。

エラー:x509: certificate signed by unknown authority

原因と対処:証明書チェーンを信頼できるルート証明書までたどれない状態です。中間証明書の不足、プライベート証明書、システムの信頼ストアなどが原因として考えられます。証明書の発行元とサーバー側の証明書チェーン全体を確認してください。管理対象の端末では、ネットワークによる証明書置き換えポリシーも確認しましょう。

エラー:x509: cannot validate certificate for 192.0.2.1 because it doesn't contain any IP SANs

原因と対処:クライアントが、対応するIPアドレス型のSANを含まない証明書をIPアドレスで検証しています。ここに示したアドレスは説明用です。実際にはサーバーの案内に従い、証明書の対象となるTLS名を設定してください。適当なドメイン名に置き換えてはいけません。

エラー:remote error: tls: handshake failure

原因と対処:接続先がTLSハンドシェイクを中断しています。端末側の証明書検証エラーとは限りません。SNI、ポート、TLS設定、サーバーの接続要件を確認し、管理者に同じ時刻のサーバーログを照合してもらいましょう。

ログに、証明書が別の名前には有効だが現在の名前には適用されないと表示される場合は、SNIと検証名を優先して確認してください。EOFや接続リセットだけの場合は、指定ポートのサービスが現在のハンドシェイクを受け付けていない可能性もあります。すぐにシステム時刻の問題と決めつけないでください。

システム時刻を同期する:証明書の期限を調べる前に時計を合わせる

証明書には有効開始日時と有効期限があります。端末の時刻がその範囲外だと、サーバー側の設定に問題がなくても、証明書は未有効または期限切れと判定されます。デュアルブート、マザーボードの電池切れ、長期間のオフライン、手動での日付変更などにより、時刻がずれることがあります。タイムゾーンは主に表示に関係します。タイムゾーンを正しく設定しただけでは、システムが記録する実際の時刻まで正しくなるとは限りません。

  1. 日付と時刻を確認

    まず年、月、日、時刻を確認します。Windows PowerShellでGet-Date -Format oを実行し、タイムゾーンのオフセットを含む時刻を信頼できる時計と照らし合わせてください。

  2. 時刻を同期

    Windows 11では「設定」→「時刻と言語」→「日付と時刻」を開き、「時刻を自動的に設定する」を有効にします。「その他の設定」にある「今すぐ同期」をクリックしてください。同期できない場合は、まずネットワークまたは時刻サービスの問題を解決します。

  3. Androidの設定を確認

    Androidでは通常、「設定」→「システム」→「日付と時刻」から設定できます。「日時を自動的に設定」と「タイムゾーンを自動的に設定」を有効にしてください。メーカーによってメニューが異なる場合は、設定内で「日付と時刻」を検索し、表示時刻が更新されたことを確認します。

  4. 再接続

    同期後、クライアントの接続を停止して再起動し、新しいログを確認します。現在時刻が正確で、証明書の有効期限も過ぎている場合は、サーバー側で証明書を更新して再読み込みする必要があります。

Windowsではw32tm /query /statusを実行して、時刻同期の参照元と状態を確認できます。コマンドの結果がサービス停止を示す場合は、プロキシのコアを何度も再起動するのではなく、まずWindows Timeサービスを確認してください。組織のポリシーで管理されている端末では、指定された時刻源の修正を管理者に依頼し、管理ポリシーを勝手に上書きしないでください。

SNIと偽装ドメイン:接続先、名前、Hostを分けて確認

SNIはTLSハンドシェイクで接続先の名前をサーバーに伝える拡張機能です。サーバーはこれをもとに証明書や仮想ホストを選択できます。通常、設定したTLSサーバー名は証明書名の検証にも使われますが、コアによっては検証名を個別に指定できるため、明示的な上書き設定がないかも確認してください。サーバーの案内にある「偽装ドメイン」は、項目の定義が統一されていません。SNI、HTTP Host、その他の転送パラメーターのどれを指すのか、必ず確認しましょう。

設定項目役割確認ポイント
アドレスとポート接続先のサーバー入口を指定します。アドレスにはドメイン名またはIPアドレスを指定できます。ポートはサーバー側の設定に合わせてください。TLSを使うからといって、必ず443に変更する必要はありません。
SNI / serverName通常、TLS名の送信と証明書名の検証に使われます。サーバーの指定に従い、プロトコル、パス、ポートを含めずドメイン名だけを入力します。
証明書のSAN証明書で検証できるDNS名またはIPアドレスが記載されています。検証する名前が含まれている必要があります。ワイルドカードの*.example.comは通常、example.comやさらに深い階層のサブドメインには適用されません。
WebSocket HostTLS確立後のHTTPリクエストのルーティングに使われます。転送設定に従って入力してください。Hostを変更しても、それ以前に発生した証明書名の不一致は解決できません。
WebSocket PathHTTPアップグレードリクエストのパスを指定します。サーバーから案内されたパスを設定してください。パスの誤りは通常、証明書検証の問題ではありません。

v2rayNでは対象ノードをダブルクリックして編集画面を開き、TLS欄の「SNI」または該当するサーバー名の項目を確認します。v2rayNGではノード右側の編集アイコンをタップし、TLS設定の「SNI」を確認してください。項目名はバージョンによって異なる場合があります。TLS欄を確認し、転送設定の「Host」と混同しないようにしましょう。v2flyNGでも、使用中のコアとノードのプロトコルに対応する項目を使ってください。

たとえば、サーバーからTLS名としてedge.example.comを指定されている場合、この欄にhttps://edge.example.com/と入力してはいけません。ここに記載したドメイン名は形式の説明用であり、実際に使えるノード設定ではありません。サーバーアドレスがIPアドレスでも、必ずしも誤りではありません。接続先が正しく、TLSで証明書に含まれる正当な名前を使っていれば、アドレス欄までそのドメイン名に変更する必要はありません。

ポイント:転送パラメーターを変える前にTLS名を確認

ログに名前の不一致が明記されている場合は、まずサーバーから指定されたSNIと証明書のSANを照合してください。証明書の検証後もHTTPやアップグレードに失敗する場合に限り、Hostとパスを確認します。

証明書検証を有効に保つ:サーバーの証明書チェーンとネットワークを確認

「証明書検証をスキップ」は、allowInsecureなどの項目で設定される場合があります。有効にすると、クライアントが証明書チェーンや名前を正しく検証しなくなる可能性があります。これではサーバーの身元を確認できず、元の設定ミスも解決しません。トラブル対処中は無効のままにしてください。以前に有効にしていた場合は検証を再び有効にし、改めて表示された正確なエラーをもとに原因を調べましょう。

この記事では一般的なTLS証明書の検証を扱っています。ノードのセキュリティ方式がREALITYの場合は、サーバーから指定されたサーバー名、公公開鍵、ショートID、クライアントコアの対応状況を確認してください。通常の証明書更新と同じ方法では対処できません。v2rayNGはXrayコア、v2flyNGはV2Flyコアを使用します。対応するプロトコルやセキュリティパラメーターは完全には同じではないため、クライアント名だけを変えて互換性があると判断しないでください。

接続復旧後の確認とよくある質問

設定を変更するたびに接続をやり直し、新しいログを確認してください。以前の接続が残っていたり、サブスクリプションの更新で手動設定が上書きされたりすると、結果に一貫性がないように見えることがあります。時刻、SNI、DNS、ルーティングを一度に変更しないでください。変更内容と新しいエラーを手順ごとに記録すると、どの設定が影響したのか特定できます。

時刻を同期したのに、証明書が期限切れと表示されるのはなぜですか?

エラーに記載された現在時刻と証明書の有効期限を照らし合わせてください。端末の時刻が正しく、証明書も実際に期限切れの場合は、マスキングしたエラーと発生時刻を管理者に伝え、更新状況と現在使用中の証明書を確認してもらいましょう。

ブラウザーではドメインを開けるのに、クライアントでエラーになるのはなぜですか?

ブラウザーは別のポートや接続先に接続している場合があり、信頼ストアも異なることがあります。ノードのアドレス、ポート、SNIを照合してください。ブラウザーでトップページが開けるだけでは、プロキシ接続先の証明書が正常だとは限りません。

SNIを変更して接続できたのに、サブスクリプション更新後に失敗した場合は?

ノードを再編集し、サブスクリプションの更新で設定項目が上書きされていないか確認してください。サブスクリプションのTLSパラメーターについて提供元に問い合わせましょう。一時的に比較する場合は独立したテスト設定を残しても構いませんが、最終的には修正済みのサブスクリプションを使用してください。

証明書検証を無効にすると接続できる場合、問題は解決したといえますか?

いいえ。「証明書検証をスキップ」を再び無効にし、エラーの種類に応じて時刻、名前、信頼チェーンを修正してください。通常の検証を有効にした状態でも再接続できて、初めて証明書の問題が解決したといえます。

  1. システムの時刻自動同期が有効で、日付とタイムゾーンが正しく表示されることを確認します。
  2. ノードのTLS名がサーバーの案内と一致し、証明書検証が無効化されていないことを確認します。
  3. 接続を停止してから再接続し、新しいログに同じ種類の証明書エラーが出ないことを確認します。
  4. 解決しない場合は、クライアントとコアのバージョン、発生時刻、確認済みの項目、マスキングした詳細エラーを添えて問い合わせてください。サブスクリプション全体をそのまま送るのは避けましょう。
クライアントをダウンロード