v2rayNデスクトップ版、v2rayNG、v2flyNGでTLSノードに接続する際に発生するハンドシェイクエラーや証明書エラーが対象です。まずコアのログから失敗した段階を特定し、端末の時刻、ノードアドレス、SNI、証明書チェーン、サーバーの待ち受け設定を順に確認します。証明書検証の無効化は解決策ではありません。通常のTLSとREALITYの設定も区別して解説します。
1. エラーが発生した接続段階を特定する
v2rayNはデスクトップクライアントの画面で、実際に接続を確立してTLSエラーを出力するのは起動したプロキシコアです。v2rayNGはXrayコア、v2flyNGはV2Flyコアを使用します。コアやバージョンによってログの表現は異なりますが、基本の切り分け手順は共通です。まず、失敗したのがサブスクリプションの取得、ノードからの接続、ブラウザーでアクセスしたWebサイトのどれかを確認しましょう。
「サブスクリプションを更新」したときに証明書エラーが表示される場合は、まずサブスクリプションURLのHTTPSサーバーを確認してください。この段階では、特定のノードのSNIを変更しても通常は効果がありません。ブラウザーだけでWebサイトの証明書エラーが表示され、コアのログではノードからの接続に成功している場合は、接続先サイト、端末のHTTPS検査ソフト、ネットワークのログインページを確認しましょう。ノードの証明書が原因と決めつけないでください。
- ログの前後関係を残す:エラーの発生時刻、選択中のノード、コアの名称、エラー前後のログを記録します。共有するときは、サブスクリプションURL、ユーザー識別情報、認証情報を隠してください。
- リクエストは1回だけ実行する:自動速度測定やほかの通信アプリを停止し、ノードを1つ選んで通常のHTTPSページにアクセスします。複数のエラーが混在しないようにしてください。
- まず最も内側のエラーを見る:
failed to process outbound trafficは外側の概要にすぎません。次に続くx509、timeout、connection refusedが次の確認項目を決める手がかりです。
2. ログのキーワードから確認箇所を絞る
ログと照合しやすいよう、よくある英語のエラーメッセージはそのまま記載しています。ドメイン、日付、アドレスなどは環境によって異なるため、ログの行全体が完全に一致する必要はありません。設定を一度に1つだけ変更して接続をやり直し、最も内側のエラーに変化があるか確認してください。
エラー:x509: certificate has expired or is not yet valid
原因と対処:端末の現在時刻が証明書の有効期間外になっています。端末の時計がずれている場合と、サーバー証明書の期限が切れている場合があります。まず端末の時刻を同期し、ログに記録された有効期間と照合してください。時刻が正しいのにエラーが続く場合は、サーバー側で証明書を更新して再読み込みする必要があります。
エラー:x509: certificate is valid for …, not …
原因と対処:証明書に記載された名前と、クライアントが検証する名前が一致していません。ノードのSNI、証明書のSANに記載されたドメイン、サーバーの仮想ホスト設定を確認してください。ノードのIPアドレスを証明書のドメイン名として指定しないでください。
エラー:x509: certificate signed by unknown authority
原因と対処:クライアントが信頼できる証明書チェーンを構築できていません。中間証明書の不足、自己署名証明書、端末の信頼ストアの異常などが原因として考えられます。公開証明書を使用するサービスでは証明書チェーンを正しく設定し、プライベートサービスでは定められたセキュリティ手順に沿って信頼できるルート証明書を導入してください。
エラー:remote error: tls: handshake failure
原因と対処:接続先がハンドシェイクを拒否していますが、このログだけでは具体的な原因は特定できません。サーバーのログと照合し、SNI、TLSバージョン、クライアント証明書の要否、待ち受けプロトコルを確認してください。また、リクエストが想定したサービスに届いているかも確認します。
エラー:tls: first record does not look like a TLS handshake
原因と対処:接続先ポートからTLS以外のデータが返されています。そのポートが実際にTLSを提供しているか、リバースプロキシや転送ルールによって平文のサービスに接続されていないかを確認してください。
EOFやconnection reset by peerだけでは、SNIの誤りとは断定できません。接続が終了またはリセットされたことを示すだけなので、サーバーの接続ログ、ポートへの到達性、別のネットワークから同じノードに接続した場合の結果も確認し、原因を絞り込みましょう。
3. 端末の時刻がずれている場合は同期して有効期間を確認
TLS検証では、端末の実際のシステム時刻を使って証明書の有効期間を判定します。証明書の有効開始日より前、または有効期限を過ぎた時刻では検証に失敗します。タイムゾーンの表示が間違っていても、システム時刻そのものが誤っているとは限りません。自動同期の結果と実際の日付を確認し、タイムゾーンだけを別の地域に変更しないでください。
-
時刻の設定を開く
Windows 11では「設定」→「時刻と言語」→「日付と時刻」を開き、年、日付、時刻を確認します。そのほかのデスクトップOSでは、システム設定の日付と時刻の画面を開いてください。
-
時刻を自動同期する
「時刻を自動的に設定する」を有効にし、「追加設定」の「今すぐ同期」をクリックします。同期に失敗する場合は、ネットワークと時刻サービスへの接続を先に確認してください。時刻を何度も手動で変更して試すのは避けましょう。
-
Androidの時刻を確認する
Androidの「設定」で「日付と時刻」を検索し、「時刻を自動的に設定」と自動タイムゾーンの項目を有効にします。上位メニューの名称はシステムによって「システム」や「その他の設定」など異なる場合があるため、設定内の検索結果を参考にしてください。
-
接続をやり直す
クライアントの接続を停止して再起動し、もう一度アクセスします。有効期間のエラーが続く場合は、ログに記録された現在時刻、証明書の有効開始時刻と有効期限を照合し、サーバー側で証明書の更新が必要か確認してください。
端末をシャットダウンするたびに日付が何年も前に戻る場合は、ハードウェアクロック、電池、システムの時刻サービスも確認してください。端末の時刻が正しく、複数の端末で同じノードの証明書エラーが発生する場合は、各端末のセキュリティ設定を変えるのではなく、サーバー証明書を確認しましょう。
4. SNI、ノードアドレス、Hostを個別に確認
ノードアドレスは接続先のホストを指定します。SNIはTLSハンドシェイクで送信されるサーバー名で、サーバーはこれをもとにサイトや証明書を選択できます。通常のTLS設定にあるserverNameは、証明書名の検証にも使われます。一方、WebSocketのHostはHTTPリクエストヘッダーで、異なる層で機能します。3つともドメイン名のように見えても、同じ値にする必要があるとは限りません。
| フィールド | 役割 | 確認する点 |
|---|---|---|
| アドレスとポート | 実際の接続先を指定 | 名前解決、ポートの待ち受け、転送先 |
| SNI / serverName | TLSの仮想ホストを選択。通常は検証する名前にも使用 | サーバー設定および証明書のSANと一致しているか |
| WebSocket Host | HTTPの仮想ホストまたはルートを選択 | リバースプロキシが受信するHostと一致しているか |
| WebSocket Path | HTTPリクエストのパスを指定 | 大文字・小文字、先頭のスラッシュ、サーバー側の設定との一致 |
v2rayNのメイン画面で対象ノードをダブルクリックし、ノード編集画面のTLS欄にある「SNI」または「ServerName」を確認します。サービス提供元から指定された値を入力してください。バージョンによってフィールド名が多少異なる場合があります。v2rayNG、v2flyNGでは、ノードの編集画面から対応するTLSパラメーターを確認します。まず現在の値を記録し、アドレス、ポート、SNI、通信方式を一度に変更しないでください。
- SNIにはホスト名だけを指定:例:
edge.example.net。https://、ポート、パスは付けません。これは説明用に予約されたドメインです。実際にはサーバーから指定された名前を入力してください。 - アドレスとSNIは異なる場合があります:接続先アドレスにIPを使っていても、証明書がそのIPに対して発行されているとは限りません。サーバーからドメイン名の証明書が提供されている場合は、設定に従って正しいサーバー名を指定してください。
- SANを確認:証明書名は通常、Subject Alternative Name(SAN)を使って検証されます。ワイルドカード名の
*.example.netは通常a.example.netに一致しますが、ルートドメインや複数階層のサブドメインも対象になるとは限りません。 - 「偽装ドメイン」は任意の値ではありません:この名称はSNIを指す場合も、HTTP Hostを指す場合もあります。まずどのフィールドを指しているのか確認し、アクセスできるWebサイトのドメインを適当に代入しないでください。
5. allowInsecureと証明書チェーン:検証を有効に戻し、エラーを回避しない
allowInsecureは、コアのTLS設定でよく使われる証明書検証のスキップ設定です。有効にすると、ドメイン不一致、証明書の期限切れ、信頼チェーンのエラーが一時的に接続を妨げなくなる場合があります。しかし、接続できても相手の身元が信頼できるとは限りません。一般向けの公開TLSノードでは証明書検証を有効に保ち、証明書の問題そのものを修正してください。
- クライアント側:ノードのTLS設定で「証明書の検証をスキップ」が無効になっていることを確認します。対応する設定は通常
allowInsecure: falseです。サブスクリプションを利用している場合は、更新後にこの項目が配信内容で上書きされていないか確認してください。 - サーバー側:実際に読み込まれている証明書チェーンが完全か確認します。通常はリーフ証明書と必要な中間証明書を提供する必要があり、サイト証明書だけでは不十分です。一般に、サーバーから送信するチェーンにルート証明書を含める必要はありません。
- 証明書の更新後:実際にTLSを終端するコンポーネントを確認します。リバースプロキシの場合も、プロキシコア自体の場合もあります。そのコンポーネントに証明書を再読み込みさせてください。ディスク上のファイルが更新されたことだけで完了と判断しないでください。
- プライベート証明書:発行元と導入方針を確認したうえで、システムやコアがサポートする方法で信頼できる証明書を設定してください。発行元が不明なルート証明書を、正体のわからないノードのためにインポートしないでください。
同じノードで古い端末だけにunknown authorityが表示され、新しい端末では正常な場合は、古い端末のシステム更新と信頼ストアを確認してください。ただし、サーバーの中間証明書不足や、別の端末に証明書がキャッシュされている可能性も考慮します。セキュリティソフトのHTTPS検査によって別の発行者が表示される場合もあります。すべての保護機能を無効にするのではなく、組織の管理方針に沿って確認してください。
6. コマンドでポート接続とTLS設定の問題を切り分ける
以下のコマンドは、権限を持つ管理者が通常のTLSサービスを調査する場合にのみ使用してください。例のドメインは実際のノードアドレスとSNIに置き換え、ポートにはノードで設定された値を指定します。これらはプロキシプロトコルの接続テストではありません。WindowsではPowerShellでTCPポートを確認でき、OpenSSLが使える環境ではハンドシェイクと証明書検証の結果も確認できます。
# PowerShell:ノードのTCPポートに接続できるか確認
Test-NetConnection -ComputerName node.example.net -Port 443
# OpenSSL:ノードアドレスに接続し、指定したサーバー名を送信して検証
openssl s_client -connect node.example.net:443 -servername edge.example.net -verify_hostname edge.example.net -verify_return_error -showcerts
TcpTestSucceeded: TrueはTCP接続が確立したことを示すだけで、証明書の信頼性、プロキシ認証の正しさ、ルーティングの可否を証明するものではありません。OpenSSLの-servernameはSNIの送信に使い、-verify_hostnameは検証する名前を明示します。役割は異なるため、前者だけでは完全な名前検証の代わりになりません。
- TCP接続に失敗する場合は、アドレス、ポート、サービスの待ち受け、ファイアウォールを先に確認してください。証明書名を何度も変更する必要はありません。
- TCP接続に成功してもTLS以外のデータが返される場合は、ポートの転送設定やリバースプロキシの接続先を確認してください。
- TLSで名前または信頼チェーンのエラーが返る場合は、証明書のSAN、完全な証明書チェーン、端末の信頼ストアを確認してください。
- TLS検証に成功してもクライアントが失敗する場合は、プロキシプロトコル、認証情報、WebSocketのパス、その他の通信パラメーターを確認してください。
7. 修正後の再テストとよくある質問
再テストでは同じノード、同じネットワーク、同じWebページを使い、自動切り替えを無効にしてから接続を再起動します。新しいログに元の証明書エラーが出ないことを確認してから、通常のルーティング設定に戻してください。サービス提供元に問い合わせる場合は、エラーの発生時刻、エラーのキーワード、使用したコア、実施済みの確認内容を伝えます。サブスクリプションURL全体は送らないでください。
時刻を同期しても証明書の期限切れと表示される場合は?
まずシステム時刻の同期が正常に完了したことを確認し、ログに記録された証明書の有効期限を確認してください。期限が切れている場合は、サーバー側で証明書を更新して再読み込みするよう依頼します。別の仮想ホストの古い証明書を取得していないか、SNIも確認してください。
証明書の検証をスキップすれば接続できます。このまま有効にしてもよいですか?
長期的な設定として使うべきではありません。検証を再び有効にして、有効期間、証明書のSAN、完全なチェーンを個別に確認してください。検証をスキップして接続できたとしても、確認を回避しただけで、想定したサーバーにつながった証拠にはなりません。
遅延テストの結果が出るのに、Webページを開けないのはなぜですか?
テストによってはTCP接続だけを測定したり、実際のアクセスとは異なるリクエスト経路を使ったりします。対象ページへのアクセスに対応するコアのログを確認してください。TLS検証が通っている場合は、システムプロキシ、ルーティングルール、DNSを確認します。詳しくはサイト内のトラブル対処も参照してください。
サブスクリプションを更新したら、修正したSNIが元に戻りました
更新前後のノード設定を比較し、サブスクリプション元から誤った値が引き続き配信されていないか確認してください。一時的な比較用としてノードをコピーし、元の設定を残したうえで、サービス提供元に配信元の修正を依頼します。更新のたびに手動で設定し直す事態を避けられます。
別のクライアントでは正常です。元のクライアントを再インストールすべきですか?
まず両方のクライアントでノードの設定項目、コアのバージョン、システム時刻、信頼ストアを比較します。同じ名前のノードでも、設定値が同じとは限りません。差異を特定してからクライアントを更新するほうが、すぐに再インストールするより原因を見つけやすくなります。
確認する順序は、接続先が正しいこと、システム時刻が正しいこと、SNIと証明書が一致すること、証明書チェーンが信頼できること、プロキシ設定が一致することです。DNS、ポート、ドメイン、セキュリティ設定を同時に変えるより、この順番で一つずつ結果を記録するほうが原因を特定しやすくなります。フィールドの意味は用語集を、ノードを初めて追加する場合はクライアント設定ガイドを参照してください。