v2rayNやv2rayNGで通常のTLSノードを使う際に発生する、証明書エラーやハンドシェイクエラーを対象に解説します。まずログから証明書検証の失敗とネットワークのタイムアウトを切り分け、システム時刻とSNIを確認したうえで、証明書チェーンとALPNを調べます。設定は一度に一項目だけ変更して再接続すると、サーバー証明書の問題をクライアント設定の問題と取り違えにくくなります。
1. 証明書エラーとハンドシェイクのタイムアウトを切り分ける
TLSハンドシェイクは、プロキシプロトコルでデータをやり取りする前に行われます。クライアントはまずサーバーに接続し、ハンドシェイクのパラメーターを送信してサーバーの身元を確認し、暗号化接続を確立します。どの段階で失敗しても、ログには「接続失敗」とだけ表示されることがあります。最後の1行だけで判断せず、x509、tls、または具体的なネットワークエラーを含む原因の記録まで遡って確認してください。
v2rayNではメイン画面下部のログ欄で、失敗した接続の時刻とノード名を記録します。v2rayNGではメイン画面のメニューから「ログ」を開き、再接続後に追加された記録を確認してください。バージョンによってメニュー名は多少異なりますが、調べるポイントは同じです。「すべての再試行に失敗しました」という概要ではなく、同じ接続に関する最も具体的な低レベルのエラーを探します。
エラー:x509: certificate has expired or is not yet valid
原因と対処:端末の時刻が証明書の有効期間外か、サーバー証明書が実際に期限切れになっています。まず端末の時刻を同期し、ログに記録された有効期間を確認してください。このメッセージだけで、どちら側に問題があるかは判断できません。
エラー:x509: certificate is valid for example.com, not edge.example.net
原因と対処:例では、検証に使われた名前と証明書が対象とするドメイン名が一致していません。ノードで指定されたSNIを確認し、サーバーが正しいサイトの証明書を返しているかも調べてください。
エラー:x509: certificate signed by unknown authority
原因と対処:証明書から信頼されたルート証明書までの検証チェーンを構築できていません。サーバーの中間証明書がそろっているか、端末の信頼ストアが古くないか、ネットワーク上で証明書が差し替えられていないか確認してください。
エラー:i/o timeout
原因と対処:ネットワークの読み書きが待機時間を超えています。前後のログから接続開始時とハンドシェイク時のどちらで発生したかを確認し、アドレス、ポート、ファイアウォール、サービスの稼働状況を調べてください。SNIが原因だと決めつけないようにしましょう。
2. システム時刻がずれている場合:同期してから再接続
証明書には有効期間の開始日時と終了日時があります。端末の日付が数か月前にずれていると「有効期間前」、未来にずれていると「期限切れ」と判定されることがあります。TLSの検証では実際の時刻が基準です。表示されるタイムゾーンが異なっていても、必ずしもシステム時計が間違っているとは限りません。ただし、タイムゾーンを手動で変更したうえで時刻も手動調整すると、実際の時刻がずれることがあります。
- Windows 11:「設定」→「時刻と言語」→「日付と時刻」を開き、「時刻を自動的に設定する」をオンにします。タイムゾーンを確認してから「今すぐ同期」をクリックしてください。同期後、年・月日・分まで正しいことを確認します。
- 同期状態を確認:ターミナルで以下の確認コマンドを実行し、時刻ソースと最後に同期が成功した時刻を確認します。すぐに再同期する場合は、2つ目のコマンドを管理者権限で実行してください。
- Android:システムの「設定」→「システム」→「日付と時刻」を開き、「日時を自動設定」と「タイムゾーンを自動設定」をオンにします。機種によっては「詳細設定」内にあります。ネットワークに再接続して、時刻が更新されたことを確認してください。
- 再テスト:現在のノードを切断してから再接続し、新しいリクエストを1回実行します。時刻を合わせても失敗済みの接続は自動で直りません。新しいログで結果を確認してください。
w32tm /query /status
w32tm /resync
Windowsで時刻サービスが起動していないと表示された場合は、「サービス」でWindows Timeの状態を確認してください。組織管理のPCでは、管理者が設定した時刻ソースに従い、独自の時刻ソースに変更しないでください。シャットダウンのたびに日付が戻る場合は、デバイスのファームウェア時計とハードウェアの状態も確認します。時刻が正しいのに期限切れの証明書エラーが続く場合は、サーバー側で証明書を更新し、サービスを再読み込みする必要があります。
判断の目安:時刻を直しても期限切れなら、サーバー側を確認
端末の現在時刻が証明書の有効期間外で、時刻同期も正常な場合は、ログに記録された有効期限をノードの管理者に伝えてください。ローカルのルーティングルールを変更しても、証明書の有効期間は延長できません。
3. SNIとserverName:接続先IPをそのまま入力しない
SNIは、ハンドシェイク時にクライアントが送信するサーバー名です。同じアドレス上で複数のサービスを運用している場合、適切な証明書やサイトを選ぶために使われます。一般的な設定では、tlsSettings.serverNameがSNIの送信と証明書名の検証の両方に使われます。ノードの接続先アドレスやWebSocketのHTTP Hostとは別の項目です。3つの値が同じ場合もあれば、サーバーの構成によって異なる場合もあります。
| 項目・概念 | 役割 | 確認ポイント |
|---|---|---|
| サーバーアドレス | 実際に接続するホスト名またはIPアドレスを指定 | 名前解決できること。ポートがノードの説明と一致していること |
| SNI / serverName | TLSサイトの選択と証明書名の検証に使用 | ノードで指定されたドメイン名を使用。プロトコルやパスは付けない |
| 証明書のSAN | 証明書の検証に使える名前を列挙 | クライアントが検証する対象名を含んでいること |
| WebSocket Host | HTTPリクエストとリバースプロキシの振り分けに使用 | トランスポート設定に従って入力。SNIの代わりにはなりません |
v2rayNでは対象サーバーの行をダブルクリックしてノード編集画面を開き、TLS関連項目の「SNI」または「サーバー名」を確認します。v2rayNGではノードの編集アイコンをタップし、TLS欄の該当項目を確認してください。項目名はバージョンやノードの種類によって異なるため、サブスクリプションで提供された設定を基準にします。接続先アドレス、偽装ドメイン、SNIを機械的に同じ文字列へ変更しないでください。
edge.example.comのようにドメイン名だけを入力します。https://edge.example.com/のようなURLや、:443は付けないでください。- ノードへの接続にIPアドレスを使い、証明書がドメイン名用に発行されている場合でも、通常は提供元が指定したドメイン名を入力します。そのIPアドレスをSNIにそのまま設定しないでください。
- ワイルドカード証明書
*.example.comは通常、edge.example.comをカバーしますが、example.comやa.edge.example.comはカバーしません。 - サブスクリプションの更新で手動変更が上書きされることがあります。一時的なテストの前にノードを複製し、テスト用だと分かる名前を付けておくと、次回の更新後も調査記録を残せます。
以下は通常のTCP + TLSで使うstreamSettingsの一部であり、単独で動作する完全な設定ではありません。例のドメイン名は項目を説明するためのものです。実際にはノードで指定された値に置き換えてください。WebSocketなど別のトランスポートを使う場合は、既存のトランスポート種別と関連設定を維持します。
{
"streamSettings": {
"network": "tcp",
"security": "tls",
"tlsSettings": {
"serverName": "edge.example.com",
"allowInsecure": false
}
}
}
4. allowInsecureと証明書チェーン:証明書の検証を維持する
allowInsecureは「互換モード」や「高速化」のための設定ではありません。通常のTLS設定でこれをtrueにすると、証明書の重要な検証が省略され、期限切れ、名前の不一致、信頼されていない証明書が通常どおりブロックされなくなります。問題を見えにくくするだけで、意図したサーバーに接続できている証明にはならず、ネットワークのタイムアウトも解決しません。
ノードの編集画面で「証明書の検証をスキップ」または「安全でない接続を許可」がオフになっていることを確認してください。通常の設定ではオフにし、allowInsecure: falseにします。以前の設定でこの項目を有効にしていた場合、検証を有効に戻して証明書エラーが出ても、エラーの原因を調べてください。長期的な対処として再び有効にするのは避けましょう。
- 名前が一致しない:まずSNIを確認します。値が正しい場合、サーバーがデフォルトサイトの証明書を読み込んでいる可能性があるため、仮想ホストの設定を確認してください。
- 発行者が不明:サーバーから中間証明書を含む完全な証明書チェーンを提供する必要があります。公的に信頼された証明書なら、通常、利用者が独自のルート証明書を追加でインポートする必要はありません。
- 古い端末1台だけで失敗する:システムとサポート対象のクライアントを更新し、システムの信頼ストアを確認してください。特定のノードのために、出所不明のルート証明書をインポートしないでください。
- ネットワークを切り替えると証明書が変わる:公衆Wi-Fiのログイン画面、企業プロキシ、セキュリティソフトのHTTPS検査機能を確認し、必要に応じてネットワーク管理者に問い合わせてください。
5. ALPNとタイムアウト:サーバーのトランスポート要件に合わせる
ALPNはTLSハンドシェイクでアプリケーション層のプロトコルをネゴシエートする仕組みで、よく使われる値はh2とhttp/1.1です。ノードのプロトコル名ではなく、値を増やせばよいというものでもありません。HTTP/2ベースのgRPCトランスポートには、対応するHTTP/2サポートが必要です。従来のWebSocket UpgradeではHTTP/1.1が使われることが一般的ですが、実際の要件はサーバーとリバースプロキシの構成によって異なります。
- まずノードのトランスポート種別を確認し、提供元の説明に従ってALPNを設定してください。明確な指定がない場合は、試しに単一のプロトコルへ無理に固定しないでください。
- ログに
tls: no application protocolと出る場合は、クライアントが提示するALPNとサーバーが許可するプロトコルに共通のものがあるか確認してください。 - ログにタイムアウトしか記録されていない場合は、まず実際のサーバーポートを確認してください。ノードの設定が
8443なら、443への接続テストが成功しても、そのノードが使えることの証明にはなりません。 - ノードの設定を変えずに、現在のネットワークと別の利用可能なネットワークでそれぞれ再テストしてください。結果が異なる場合は、ネットワーク経路やアクセス制限を優先して調べます。
Windowsでは、以下のコマンドで指定ポートへのTCP接続をテストできます。例のドメイン名とポートはコマンド形式を示すためのものなので、ノードの実際の値に置き換えてください。TcpTestSucceeded: Trueが示すのはTCP接続が確立できたことだけです。TLS証明書、ALPN、プロキシ認証が正しいことまでは確認できません。
Test-NetConnection -ComputerName edge.example.com -Port 443
判断の目安:TCP接続できても、TLSが使えるとは限りません
ポートテストが成功しても証明書エラーが出る場合は、時刻、SNI、証明書チェーンを再確認してください。ポートテストに失敗した場合は、まずアドレスとネットワークを調べます。ALPN、トランスポート経路、認証パラメーターを同時に変更しないでください。
6. よくある質問と修正後の確認
PCの時刻が数分ずれているだけでも失敗しますか?
証明書の有効期間の開始時刻や終了時刻に近い場合は、数分のずれでも検証に影響することがあります。まず時刻を同期して再接続し、新しいログを確認してください。期限切れの証明書を回避するために、時刻を手動で遅らせないでください。
ブラウザーではドメインを開けるのに、ノードでエラーが出るのはなぜですか?
ブラウザーが別のポート、別のアドレス、別のサイトにアクセスしている可能性があります。ノードが実際に接続するアドレス、ポート、SNIを照合してください。ブラウザーで証明書が正常でも、それは手がかりにすぎず、ノードのハンドシェイク検証の代わりにはなりません。
v2rayNを再インストールすれば証明書の問題は直りますか?
再インストールしても、サーバー証明書の期限切れ、SNIの入力ミス、端末の時刻ずれは直りません。まず具体的なエラーを記録してください。古いバージョンとの互換性やローカルファイルの異常が確認できた場合に限り、クライアントの更新と正しい設定のインポートを検討しましょう。
Androidでは失敗し、PCでは正常です。まず何を変更すればよいですか?
まず両方で同じノード、同じSNI、同じトランスポート設定を使っていることを確認し、自動時刻設定とシステムの更新状況を比較してください。同じネットワークに接続して両方を再テストすると、ネットワークの違いによる影響を切り分けやすくなります。
修正後はノードに再接続して実際にアクセスし、新しいログに証明書検証やハンドシェイクのエラーがないことを確認してから、アプリでのアクセスが復旧したか調べてください。TLSが完了してもアクセスできない場合は、プロキシプロトコルの認証、トランスポート経路、ルーティング設定を引き続き確認します。正しいと確認できたSNIを何度も変更しないでください。
- 調査記録を残す:クライアントのバージョン、コアのバージョン、失敗した時刻、ネットワーク環境、具体的なエラーを記録します。「接続できない」だけで済ませないでください。
- 安全な設定に戻す:証明書検証のスキップがオフになっていることを確認し、試行錯誤のために追加した根拠のないパラメーターを削除してください。
- 必要な情報を共有する:管理者には証明書エラーとポートの状況を伝えてください。ログを共有する前に、サブスクリプションURL、認証情報、個人のネットワークアドレスを伏せてください。