v2rayN、v2rayNG、v2flyNGで通常のTLSを使うノードのトラブルシューティングを解説します。まずログから接続がどの段階で止まっているかを確認し、端末の時刻、サーバーアドレス、SNI、証明書チェーンの順にチェックしましょう。クライアント側の設定とサーバー側の証明書の問題を切り分ける手順や、よくあるエラーの見分け方に加え、allowInsecureを恒久的な解決策にしてはいけない理由も説明します。
1. TLSハンドシェイクに失敗したら、接続段階を切り分ける
GUIクライアントはノード情報の保存と設定の生成を担い、実際の接続はXrayやV2Flyなどのコアが行います。v2rayNGはXrayコア、v2flyNGはV2Flyコアを使用します。v2rayNで使用中のコアは、現在の設定とログで確認してください。コアやバージョンによってログの先頭部分は異なるため、原因を特定するには、最上位の「接続失敗」だけでなくエラーの末尾まで確認します。
TLSを有効にしたVLESS、VMess、Trojanのノードでは、通常、まずサーバーアドレスを名前解決し、リモートのTCPポートに接続してからTLSハンドシェイクを行います。成功後に、プロキシプロトコルのやり取りへ進みます。プロトコル名だけでは通常のTLSが有効かどうかは判断できないため、セキュリティ層の設定も確認してください。REALITYには独自のパラメーターと検証方式があるため、この記事の証明書に関する手順をそのまま適用しないでください。
| ログの手がかり | 接続のおおよその段階 | 優先して確認する項目 |
|---|---|---|
no such host | アドレスの名前解決 | サーバーアドレスの入力ミス、DNS応答 |
connection refused | TCP接続 | リモートの待ち受けポート、ファイアウォール、サービスの状態 |
x509: | 証明書の検証 | 端末の時刻、証明書名、信頼チェーン |
tls: handshake failure | TLSネゴシエーション | SNI、TLSサービスの設定、サーバーログ |
EOF または i/o timeout | 状況に応じて判断 | ハンドシェイクの前後どちらでエラーが発生したか |
たとえば、リモートポートが 443 に設定されているのに、ハンドシェイク開始前に connection refused が出る場合、証明書の設定を変更しても解決しません。443 はよく使われるポートにすぎず、サービス提供者が指定した実際のポートとは限りません。また、ここで指定するのはローカルのプロキシポートではなく、リモートのポートです。
2. 端末の時刻と証明書の有効期間を確認する
証明書には有効開始日時と有効期限が記録されています。クライアントは端末の現在時刻をもとに、証明書が有効期間内かどうかを判定します。日付が過去にずれていると「まだ有効ではない」、未来に進んでいると「有効期限切れ」と判定される場合があります。時刻は実際の正確な時刻に合わせてください。タイムゾーンを変更するだけでは、システム時計のずれは通常解消しません。
-
エラーを記録する
クライアントのログから今回の接続に該当するエラーを見つけ、現在時刻と証明書の有効期間に関する表示を記録します。古いログと新しいログが混在しないよう、まず連続したテストを止めてください。
-
時刻を同期する
Windows 11では「設定」→「時刻と言語」→「日付と時刻」を開き、「時刻を自動的に設定する」をオンにしてから「今すぐ同期」をクリックします。端末がインターネットに接続できることを先に確認してください。
-
Androidの設定を確認する
Android標準の画面では通常、「設定」→「システム」→「日付と時刻」で「日時を自動的に設定」をオンにします。メーカーによって項目名が異なる場合は、設定画面で「日付と時刻」を検索し、自動設定が反映されているか確認してください。
-
再接続する
クライアントに戻り、もう一度接続して新しいログを確認します。端末の時刻が正しいのに証明書の有効期限が切れている場合は、クライアントの日付を変更し続けるのではなく、サーバー側で証明書を更新して再読み込みしてください。
証明書の有効期間は明確な境界であり、「5分程度のずれなら許容される」といった一律の猶予はありません。たとえば証明書がUTC 00:00に有効になっても、端末の時計が実際より遅れて前日の23:50を示していれば、検証に失敗する場合があります。ログと証明書ツールでタイムゾーンが異なることがあるため、比較前にUTCまたは同じ現地時間に統一してください。
3. サーバーアドレス、SNI、証明書名の違い
サーバーアドレスは接続先を指定します。SNIはTLSハンドシェイクで接続先ホスト名をサーバーに伝えるもので、サーバーはこれをもとにサイトや証明書を選択する場合があります。一般的なコア設定の serverName は、検証対象のサーバー名を指定する役割もあるため、任意のメモとして入力する項目ではありません。
サービス提供者が接続先アドレス edge.example.com、リモートポート 443、TLS名 tls.example.com を指定しているとします。クライアントでは、それぞれ別の項目に指定どおり入力してください。接続先とTLS名が異なること自体は必ずしも誤りではありませんが、サーバー側の設定が対応している必要があります。検索結果から適当なドメインを選んでSNIに指定しないでください。
- サーバーアドレス:ノードに指定されたドメイン名またはIPアドレスを入力します。
https://やWebページのパスは付けません。 - SNI / serverName:サービス提供者が指定したTLSホスト名を入力します。通常、ポート番号、プロトコルヘッダー、スラッシュは含めません。
- 証明書のSAN:証明書のサブジェクト代替名(SAN)に、検証対象の名前が含まれている必要があります。証明書に表示される組織名だけで判断しないでください。
- WebSocket Host:後続のHTTPリクエストで使う項目であり、TLSのSNIとは異なります。Hostだけを変更しても、証明書名の不一致は解消しません。
ワイルドカード証明書にも適用範囲があります。*.example.com は通常 node.example.com には一致しますが、example.com や a.node.example.com も対象になるとは限りません。サーバーアドレスにIPアドレスを指定し、検証対象の名前を明示していない場合、コアがそのIPを検証しようとすることがあります。ドメイン名だけが記載されたSANでは、この検証を満たせません。
要点:サーバーの指定値に合わせ、アドレスからSNIを推測しない
接続先がIPアドレスで、証明書がドメイン名に発行されている場合は、サービス提供者が指定したserverNameを必ず確認してください。正しい接続先アドレスを維持し、証明書に含まれる検証対象名を設定するほうが、証明書検証を無効にするより確実です。
4. よくある証明書エラーと原因の特定
以下に、ログでよく見られるエラーの主要部分を示します。ログの前後には、送信元名、接続番号、アドレスなどが付く場合があります。ログ末尾の汎用的なメッセージだけを唯一の原因と判断しないでください。証明書関連のエラーでは、x509 に続く説明を省略せずに確認します。サービス提供者に問い合わせる際は、サブスクリプションのトークン、ユーザー識別情報、個人のアドレスを伏せてください。
エラー:x509: certificate has expired or is not yet valid
原因:端末の時刻が不正確か、サーバー証明書が実際に有効期間外です。対処:まず端末の時刻を同期し、ログに表示された有効期間を確認してください。端末の時刻が正しい場合は、サーバー側で証明書を更新するか、正しく再配置します。
エラー:x509: certificate signed by unknown authority
原因:証明書チェーンがクライアントの信頼するルート証明書につながっていません。中間証明書の不足、自己署名証明書、端末側の信頼環境の異常などが考えられます。対処:サービス提供者に証明書チェーン全体を確認してもらい、システムの信頼ストアも更新してください。出所の不明なルート証明書はインストールしないでください。
エラー:x509: certificate is valid for
原因:このエラーの後には通常、証明書が対象としている名前と、一致しなかった接続先の名前が表示されます。対処:ノードのserverNameと証明書のSANを確認してください。SNIの誤りでサーバーがデフォルトサイトの証明書を返している場合は、仮想ホストの設定も修正します。
エラー:tls: first record does not look like a TLS handshake
原因:現在のポートからTLSではないデータが返されています。TLSを使わないサービスに接続している場合によく起こります。対処:リモートポート、セキュリティ層、リバースプロキシの接続先を確認してください。証明書検証の設定を変更しても、ポートの問題は解決しません。
エラー:remote error: tls: handshake failure
原因:接続先がTLSネゴシエーションを拒否しています。SNI、プロトコルのバージョン、サーバーのポリシーなどが関係している可能性があります。このメッセージだけでは、証明書の期限切れとは断定できません。対処:サービス提供者の指定したTLSパラメーターに戻し、同じ時間帯のサーバーログも確認して原因を特定してください。
EOF だけでは、「証明書が信頼されていない」とは判断できません。接続先による早期切断、接続先設定の不一致、ネットワーク機器による切断などでも発生します。まず、それ以前にTLSの詳細なエラーがないか確認し、必要に応じてサービス提供者に問い合わせてください。
5. allowInsecureの役割とリスク
一般的な通常TLSの設定で allowInsecure は、サーバー証明書の検証をスキップするかどうかを制御します。「互換性を高める」ための汎用スイッチではありません。検証をスキップすると、接続先が別のサーバーに誘導されたり、中間者による干渉を受けたりしても、通常の証明書検証によって接続を拒否できなくなる場合があります。通信が暗号化されていても、接続先の身元が確実に確認されたとは限りません。
以下は、コアのアウトバウンド設定 streamSettings に含まれるTLS項目の例です。そのままインポートできる完全なノード設定ではありません。tls.example.com は説明用のドメイン名です。実際にはサービス提供者が明示したTLS名を使ってください。GUIクライアントは通常これらの項目を生成するため、ノード編集画面から変更することをおすすめします。
{
"security": "tls",
"tlsSettings": {
"serverName": "tls.example.com",
"allowInsecure": false
}
}
- 通常の接続:証明書検証は有効のままにします。「証明書の検証をスキップ」「安全でない接続を許可」など、逆の意味の設定項目がある場合はオフにしてください。
- 管理された環境での診断:まず証明書チェーンとサーバーログを確認します。一時的な比較がどうしても必要な場合に限り、管理されたテスト環境で実施してください。その間はアカウント情報、トークンなどの機密情報を送信せず、テスト後すぐに検証を元に戻します。
- 結果の見方:検証をスキップして接続できても、スキップした検証が失敗に関係していたことしか分かりません。サーバーの身元が正しいことや、原因がドメイン名の不一致だけだったことの証明にはなりません。
- プライベート証明書を使う環境:管理者が、対象のシステムとコアに適した信頼の仕組みを、信頼できる方法で設定してください。すべての利用者に検証を恒久的にスキップさせるべきではありません。
6. v2rayN・v2rayNGで確認する手順
画面の表記はバージョンによって変わるため、トラブルシューティングの前にクライアントと実際に使用中のコアのバージョンを記録してください。一般的なノード編集方法は、v2rayNではサーバー一覧の対象ノードをダブルクリック、v2rayNGでは対象設定の右側にある編集アイコンをタップします。開いた画面で、同じノードのアドレス、ポート、セキュリティ層、SNI、証明書検証の状態を確認してください。全体設定とノードごとの設定を混同しないようにしましょう。
-
対象を絞る
確認するノードを1つだけ選び、備考と登録元のグループを記録します。ログがそのノードに対応していることを確認し、自動切り替えされた別のアウトバウンドのログと取り違えないでください。
-
接続先を確認する
ノードの編集画面で、サーバーアドレス、リモートポート、伝送方式、セキュリティ層がTLSかどうかをサービス提供者の指定値と照合します。例にある443を実際の設定値として流用しないでください。
-
名前を確認する
「SNI」または「serverName」欄を確認し、プロトコルヘッダー、ポート番号、前後の空白が含まれていないことを確かめます。Host欄がある場合は、サービス提供者の指定に従って別々に入力し、相互に置き換えないでください。
-
検証を有効にする
「証明書の検証をスキップ」または同様の設定をオフにして保存します。メイン画面に戻って再接続してください。必要に応じて、クライアントのコア再起動機能を使って変更を反映します。
-
ログを比較する
実際にリクエストを1回送信し、変更前後のエラーを比較します。TLSエラーが消えて認証や伝送のエラーが出る場合は、ユーザー識別情報、パス、サーバー側のプロトコル設定を確認してください。
サブスクリプションから追加したノードでは、更新による上書きにも注意が必要です。サブスクリプション由来の項目を直接変更しても、次回の更新で元に戻ることがあります。トラブルシューティングのために変更する場合は、クライアントが対応していればノードを複製して独立した項目にし、用途を記録してください。恒久的な修正は、サービス提供者にサブスクリプションの設定を直してもらいましょう。ノード設定全体、JSON、サブスクリプションURLを公開の質問ページに貼り付けないでください。
7. よくある質問:ブラウザーでは開けるのに、クライアントが失敗するのはなぜ?
ブラウザーでは同じドメインを開けるのに、ノードで証明書エラーが出るのはなぜ?
まず、ブラウザーで開いたドメインとノードのserverNameが一致しているかを確認し、ポートも照合してください。ブラウザーとコアでは信頼ストアや証明書チェーンの構築方法が異なる場合があります。Webページが正常に表示されても、サーバーから中間証明書が不足している可能性は残ります。サービス提供者に、実際のTLS接続先を確認してもらってください。
サーバーのIPアドレスに変更したら、証明書名の不一致が出るのはなぜ?
サービス提供者が利用を許可している接続先IPはそのまま使い、TLSのserverNameを別に指定する必要があるか確認してください。ドメイン名用の証明書は通常、任意のIPアドレスの検証には使えません。接続先をIPに変えたからといって、SNIもIPに変更しないでください。
時刻を同期したのに、証明書の期限切れが表示されるのはなぜ?
同期後の新しいログを確認し、証明書の有効期限と照合してください。実際に期限切れなら、サーバー側で証明書を更新し、サービスを再読み込みしたうえで、接続先が新しい証明書を返していることを確認します。管理画面で更新が成功していても、稼働中のサービスが新しい証明書を使っているとは限りません。
検証をスキップすれば接続できます。このまま有効にしてもいいですか?
日常的な設定として使うのは避けてください。状況を記録したら検証を元に戻し、時刻の誤り、名前の不一致、信頼チェーンの異常を切り分けます。サーバー側の設定が原因なら、正確な時刻、コアのバージョン、個人情報を伏せたx509エラーをサービス提供者に送って対応を依頼してください。
ノードがREALITYの場合も、証明書のドメイン名を確認する必要がありますか?
通常のTLS向け証明書のトラブルシューティング手順を当てはめないでください。まずセキュリティ層がREALITYであることを確認し、サービス提供者の指定に従ってserverName、公開鍵、shortIdなどを照合します。クライアントとコアの対応状況も確認してください。自己判断でTLSに切り替えないでください。
要点:一度に変更するのは1項目だけ。検証は有効に保つ
「時刻 → 接続先 → 名前 → 証明書チェーン」の順で確認し、項目を1つ変更するたびに再接続して新しいログを保存します。TLSの検証に成功した後でプロキシプロトコルとルーティングを確認すれば、異なる段階の問題を混同せずに済みます。