v2rayNやv2rayNGを使っていて、ノードへの接続タイムアウト、Webページが開かない、接続が頻繁に切れるといった問題に悩む方向けです。まずクライアントの表示とXrayコアのログを区別し、ローカルの待ち受け、DNS、外向き接続、セキュリティハンドシェイク、プロトコル認証の順に原因を絞り込みます。エラー文を暗記するのではなく、同じリクエストで最も根本にある失敗原因を見つけ、再現可能なテストで変更の効果を確かめることが大切です。
まずログの出どころを確認し、リクエストがどの段階で止まったかを見る
v2rayNはGUIクライアントで、Xrayはプロキシ通信を実際に処理するコアです。サブスクリプションの取得失敗、画面の起動異常、プロキシの外向き接続失敗は、必ずしも同じログに記録されるとは限りません。「サービスを起動しました」と表示されても、起動処理がある段階まで進んだことが分かるだけです。ノード認証の成功や、接続先のWebページへの到達を意味するものではありません。
まず起動ログに表示されたコアの名称とバージョンを確認し、現在のノードが実際にどのコアを使っているかを調べます。v2rayNGはXrayを使用し、v2flyNGはV2Flyを使用します。両者で対応する設定項目を同じものとして扱うことはできません。特にVLESSやREALITYの問題は、クライアントのインストールパッケージのバージョンだけでなく、実際に動作中のコアを基準に確認してください。
この経路はログを読む順序の目安であり、すべての通信が必ず6つの独立した段階に分かれるわけではありません。たとえば、認証とハンドシェイクをまとめて処理するプロトコルや、サーバー側で接続先ドメインを解決する構成もあります。原因を調べるときは、エラーに記録されたアドレスがローカルの待ち受け先、ノード、最終的な接続先のどれなのかを確認してください。同じポート443でも、どの段階で使われているかによって調べる箇所は異なります。
ログを有効にする:リクエストを1回実行して再現可能な記録を取る
通常はwarningで十分です。接続の流れを確認するときは、まずinfoに設定し、情報が足りなければ一時的にdebugへ切り替えます。Xrayのloglevelにはdebug、info、warning、error、noneを指定できます。これはエラーログの出力レベルを制御する設定です。アクセスログの記録はaccessの設定にも左右されます。ログレベルを上げても、接続の問題が自動的に解決するわけではありません。
-
コアを確認する
v2rayNのメイン画面にある実行情報で起動ログを確認し、実際に呼び出されたコアの名称とバージョンを控えます。コアの起動ログ自体が見当たらない場合は、リモートノードを調べる前に起動失敗への対処が必要です。
-
ログレベルを変更する
v2rayNでは「設定」→「パラメータ設定」を開き、「ログレベル」をinfoに変更します。v2rayNGではサイドメニューの「設定」→「ログレベル」から変更できます。バージョンによってメニューの分類や表記が異なることがあります。見つからない場合は、まずクライアントのバージョンを確認してください。他のコア向けの設定をそのまま適用しないようにしましょう。
-
再起動して問題を再現する
設定を保存したらプロキシサービスを再起動し、新しい設定が反映されたことを確認します。自動更新を続けるWebページは閉じ、テスト用の固定URLを1つだけ開きます。操作した時刻を記録し、その前後約10秒のログを保存してください。
-
ログレベルを元に戻す
原因が分かったら、ログレベルをwarningに戻します。ログを共有する前に、アカウント識別情報、サブスクリプションURL、ノードのアドレス、アクセス先のドメインを伏せてください。時系列、プロトコル名、ポート番号、エラーの連なりは残します。
Xrayの設定を自分で管理している場合は、以下のログ設定例を確認できます。これは設定内の1項目であり、そのまま実行できる完全な設定ではありません。クライアントが設定を生成するモードでは、クライアント側の設定から変更してください。一時ファイルを直接編集すると、次回起動時に上書きされることがあります。
{
"log": {
"loglevel": "info"
}
}
failed to dial:エラーの連なりから失敗箇所を特定する
failed to dialは、接続先への発信や接続の確立に失敗したことを示しますが、多くの場合は上位の処理が付けた包括的なエラーです。その後に続くlookup、connection refused、i/o timeoutのほうが、原因に近い情報を含んでいます。エラー全体を読んでから、DNS、ポート、ルーティングのどれを見直すか判断してください。dialという語だけを見てUUIDを入れ直すのは避けましょう。
failed to dial
原因:接続処理の失敗をまとめた表現です。アドレス解決、TCP接続、トランスポートのカプセル化などが関係している可能性があります。
対処:後に続く入れ子のエラーを確認し、接続先アドレスと送信先タグを照合します。この語句だけしか記録されていない場合は、まず同じ行のログ全体を確認してください。
lookup ...: no such host
原因:名前解決で利用可能なアドレスを取得できていません。ドメインの入力ミス、上流DNSの応答、DNSルーティングなどが考えられます。これだけでDNS汚染が起きていると判断することはできません。
対処:解決しようとしているのがノードのドメインか接続先のドメインかを確認し、それぞれに対応するDNS上流へ到達できるか、ノードのドメインを解決するための経路が正しいかを調べます。
connect: connection refused
原因:接続が明示的に拒否されています。ポートでサービスが待ち受けていない、アドレスやポートの入力が間違っている、または中継機器が拒否を返している場合によく見られます。
対処:サブスクリプションに記載されたポートを確認します。自分で構築したサーバーなら、待ち受けアドレスとファイアウォールも確認してください。ポートが待ち受けていない状態では、同じ設定で再試行しても解決しません。
i/o timeout
原因:ネットワーク処理が制限時間内に完了しませんでした。前後のログを見て、名前解決、接続確立、データ受信のどの段階かを判断する必要があります。
対処:ノードと設定は変えずにネットワークだけ切り替えて再テストします。特定のネットワークだけでタイムアウトする場合は、ノードのパラメータを変更する前に、そのネットワークの接続経路を確認してください。
たとえば、ノードへのTCP接続(ポート443)がタイムアウトしたと明記されている場合、VLESSのユーザー認証が原因だと判断する根拠はまだありません。反対に、ノードへの接続が確立した後で接続先からの読み取りに失敗したなら、ローカルからノードまでの疎通だけを調べても不十分です。アドレス、処理段階、発生時刻をあわせて確認してください。
TLS handshakeとinvalid user:セキュリティ層と認証層を分けて確認する
TLSハンドシェイクのエラーは、接続がセキュリティのネゴシエーションに進んだ後に発生することが多いものの、証明書の問題とは限りません。通常のTLSノードでは、serverName、証明書チェーン、システム時刻、トランスポート設定を確認します。VLESS + REALITYでは、公開鍵、shortId、serverName、サーバー側の設定も確認が必要です。「検証を無効にする」という同じ対処を、両方のノードに当てはめないでください。
| キーワード | 優先して確認する項目 | 決めつけてはいけないこと |
|---|---|---|
TLS handshake | エラーにEOF、証明書エラー、タイムアウトが含まれるか。クライアントのセキュリティ方式がサーバーと一致しているか | この2つの語だけで証明書の期限切れとは断定できない |
x509: certificate has expired or is not yet valid | クライアントの日付・タイムゾーン、証明書の有効期間、サーバーへの証明書の設定 | 証明書検証を安易にスキップしない |
x509: certificate is valid for | 後続に表示される証明書のドメイン名が、検証対象のserverNameと一致するか | 接続先IPと証明書のドメイン名が異なっていても、必ずしも設定ミスとは限らない |
invalid user | ログの出所、プロトコルの種類、ユーザー識別情報、対応するサーバー側のユーザー設定 | クライアントの認証失敗がすべてこの文言で表示されるわけではない |
EOF | 相手側が接続を切断したタイミングと、ハンドシェイク・トランスポート・認証情報の有無 | この情報だけでアカウントが無効だとは判断できない |
invalid userは、サーバー側の受信接続に関する認証ログで手がかりが得られることが多いものの、表現はプロトコルやバージョンによって異なります。クライアント側にはEOFや接続切断しか表示されない場合もあります。サーバーのログを確認できるなら、両側の記録を時刻で照合し、UUIDが一致するか、該当ユーザーが読み込まれているか、接続先ポートが想定した受信設定に割り当てられているかを確認してください。VMessを使う場合はシステム時刻も確認します。VLESSにVMessのalterId設定を流用しないでください。
- VLESS + TLS:UUID、トランスポートの種類、ポート、serverName、サーバーが要求するflowを確認します。WebSocketを使う場合はパスとHostも照合してください。TCPノードの設定を流用することはできません。
- VLESS + REALITY:UUID、サーバーに対応する公開鍵情報、shortId、serverName、フィンガープリント、flowを確認します。クライアントによって項目名が異なる場合があるため、同じノードの設定情報と照合してください。
- システム時刻:Windowsでは「設定」→「時刻と言語」→「日付と時刻」から時刻を同期します。Androidではシステムの「設定」で「日付と時刻」を検索し、自動設定を有効にしてください。メーカーによってメニューの分類が異なる場合があります。
context canceled:リクエストがキャンセルされただけかを確認する
context canceledは、その処理に紐づくコンテキストがキャンセルされたことを示します。タブを閉じた、ブラウザーが先に接続を開始して後から使わなくなった、ノードを切り替えた、コアを再起動したといった場合にも記録されます。「ノードが必ず使えない」という意味ではなく、この表示だけでDNSや証明書の異常を証明することもできません。
Webページが開くのにcontext canceledが記録されるのはなぜ?
まずページの再読み込みを止め、余分なタブを閉じて、ページを1つだけ開いてください。ページの読み込み完了後やタブを閉じた後にキャンセルログが出ていて、その後も失敗が続いていないなら、付随して記録されたこのログだけを理由にノード設定を変更する必要はありません。
Webページを開くとすぐキャンセルされる場合、原因を調べるには?
同じ時刻の前後にあるログを切り出し、リクエスト識別子で関連する記録を確認します。そのバージョンに識別子がない場合は、時刻、接続先アドレス、送信先タグを手がかりにします。キャンセルより前に発生した名前解決エラー、ハンドシェイクエラー、接続タイムアウトを優先して探してください。
ノード切り替え後にキャンセルが大量に出た。再インストールが必要?
ノードを切り替えると、それまでの接続は終了します。新しいコアの起動が完了してから、新しいリクエストを実行してください。分析するのは新しい起動時刻以降のログだけです。古い接続のキャンセルログから、新しいノードが使えるかどうかは判断できません。
サブスクリプションの更新に失敗した場合も、このログを確認する?
まずクライアントに表示されるサブスクリプション更新結果を確認してください。更新リクエストが実際に現在のプロキシを経由した場合に限り、コアのログから手がかりを得られる可能性があります。リクエストがコアに届いていないなら、外向き接続のログを調べてもサブスクリプションサーバーが返した具体的なエラーは分かりません。
ローカルポートとルーティング:リクエストが実際にプロキシへ届いているか確認する
コアの起動直後にaddress already in useやWindowsのOnly one usage of each socket addressが出た場合は、まずローカルの待ち受けポートの競合を解消します。別のクライアントが起動したままになっていないかを確認してから、ポートを使用しているプロセスを調べてください。プロキシのポートを変更した場合は、ブラウザーの手動プロキシ設定とシステムプロキシ設定も合わせて変更します。クライアント側だけを変更しても不十分です。
以下ではWindowsのローカルポート10808を例にします。コマンドはポートの使用状況を確認するためのもので、確認せずに他のプログラムのPIDを終了しないでください。ポート番号は固定の既定値ではありません。現在の設定で実際に待ち受けているポートに置き換えてください。
netstat -ano | findstr :10808
ポートでSOCKS受信接続を提供している場合は、以下のコマンドを使ってプロキシ経由のリクエストを明示的に1回実行できます。Windowsではcurl.exeを使うと、一部のターミナルでcurlという名前が別のコマンドに割り当てられる問題を避けられます。socks5hでは接続先のドメイン名をプロキシ側に渡して解決するため、curlがローカルで先に名前解決することはありません。受信接続がHTTPプロキシのみの場合は、対応するHTTPプロキシ用の引数を使ってください。SOCKSのコマンドをそのまま使うことはできません。
curl.exe --proxy socks5h://127.0.0.1:10808 --connect-timeout 10 --max-time 20 -I https://example.com/
- ローカルで接続を拒否される:プロキシサービスが起動しているか、待ち受けポートが正しいか、受信プロトコルが一致しているかを確認します。この時点ではまだリモートノードに接続していません。
- リクエストは届くが送信先が違う:ルーティングタグと適用されたルールを確認します。接続先が直接接続に振り分けられていると、ノード自体が正常でもWebページを開けないことがあります。
- コマンドは成功するのにブラウザーでは失敗する:ブラウザーで実際に使われているプロキシ設定、拡張機能による制御、独自のDNS設定と、テストコマンドの名前解決経路を比較します。
- 一部のドメインだけ失敗する:接続できるドメインとできないドメインを1つずつ選び、ドメインルール、名前解決の結果、送信先を比較します。すべての設定をすぐに変更するのは避けてください。
トラブル対処の記録をまとめる:一度に変更する項目は1つだけ
原因の特定に何千行ものログは必要ありません。コアのバージョン、問題が起きた時刻、操作方法、エラー全体を記録すれば、「接続できない」とだけ伝えるより判断しやすくなります。DNS、flow、ポート、トランスポートを一度に変更すると、たまたま復旧しても、どの変更が効いたのか分かりません。次回の問題でも同じ調査を繰り返すことになります。
- 環境を記録する:OS、クライアントのバージョン、実際に使っているコアのバージョンに加え、システムプロキシ、アプリごとの手動プロキシ、TUNのどれを使用しているかを記載します。
- 期待する動作を記載する:「リクエストがSOCKS 10808で受信され、指定したVLESSの外向き接続を通じてテスト先へアクセスする」のように書きます。「接続済み」だけでは不十分です。
- 前後の状況を残す:起動完了の記録、リクエストを実行した時刻、その前後約10秒のログを共有します。エラーの最後の1行だけでなく、入れ子になったエラー全体を残してください。
- 変更内容を1つずつ記録する:1回に変更する項目は1つだけにし、再起動後に同じテストを繰り返します。効果がなければ元の値に戻してから、次の項目を確認してください。
- 最後に再確認する:日常使用時のログレベルに戻し、ブラウザーとテストコマンドの両方が想定どおり動作することを確認します。基本操作の詳細はクライアントの使い方ガイドを参照してください。
Xrayのログを読むうえで重要なのは、どこで処理が失敗したかを特定することです。ローカルで待ち受けていなければ、まずローカルの設定を直します。ノードのアドレスを解決できなければ、名前解決を確認します。TCP接続後にハンドシェイクが失敗したら、セキュリティとトランスポートの設定を調べます。認証後に問題が起きた場合は、接続先へのアクセスを確認してください。エラーをリクエストの処理経路に沿って読むほうが、特定のキーワードを見て設定を何度も試すより確実です。