設定項目ガイド · 各フィールドと実行時の役割

V2Ray設定ファイルガイド

JSON、inbounds、outbounds、ルーティング、DNS、policyを項目ごとに確認できます。各項目が接続にどう影響するかを解説するページで、クライアントの初期設定を案内するものではありません。インストール、サブスクリプションの追加、システムプロキシの設定がまだの場合は、まずクイックスタートガイドをご覧ください。接続できていて、ルールの変更や設定の問題を調べたい場合は、左側の目次から該当する項目をお探しください。

ここではV2Fly / Xrayで一般的なJSON構造を扱います。sing-boxは別の設定構造を使うため、そのまま流用できません。特記のない限り、完全な設定例はローカル直結とルールの検証用で、リモートプロキシサーバーの認証情報は含みません。

JSON構造と設定の読み込み元

まず編集する設定レイヤーを確認

V2Rayの設定は、クライアント画面に表示される設定全体と同じではありません。v2rayNはサブスクリプションのグループ、画面上のオプション、ルーティングのプリセットを保存し、選択中のサーバーとカーネルに応じて実行用の設定を生成します。v2rayNGやv2flyNGにも、それぞれ独自のアプリ設定があります。編集前に、サブスクリプションの元データ、クライアントが保存する設定、カーネルが実際に読み込むJSONを区別しましょう。同じノードを表していても、同じファイルに保存されているとは限りません。

クライアントが一時的に生成したファイルを直接編集すると、「保存直後は有効なのに、次回起動で元に戻る」ことがあります。多くの場合、原因はカーネルによる項目の無視ではなく、クライアントが設定を再生成したことです。まずはクライアントのルーティング、カスタム設定、ノード編集機能から変更してください。完全なJSONを管理する場合は、完全な設定に対応した明示的な機能を使い、別途コピーを保存して使用中のカーネルを記録しましょう。一時ファイルだけを唯一の設定元にしないでください。

トップレベルのオブジェクトと入れ子構造

一般的なトップレベル項目にはlog、inbounds、outbounds、routing、dns、policyがあります。inboundsとoutboundsは配列で、各要素が1つの待ち受け口または送信先を表します。routingオブジェクト内のrulesも配列で、記載順にルールが評価されます。項目名だけでなく階層も重要です。有効な項目でも、誤ったオブジェクトに配置すれば期待どおりに動作しません。

{
  "log": {
    "loglevel": "warning"
  },
  "inbounds": [
    {
      "tag": "local-socks",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": true
      }
    }
  ],
  "outbounds": [
    {
      "tag": "direct",
      "protocol": "freedom",
      "settings": {}
    }
  ]
}

これはローカルにSOCKSの待ち受け口を用意し、その後は接続先へ直接アクセスする基本設定です。リモートプロキシのoutboundは含みません。待ち受けとローカル接続経路の確認に使えますが、リクエストが成功してもサブスクリプションのサーバーが正常とは判断できません。ポート番号はこの例で指定したものです。クライアントが同じアドレスとポートを使用中の場合、別の設定を起動すると競合します。既存のプロセスを停止するか、テスト用コピーで待ち受けポートとアプリ側のプロキシ設定を両方変更してください。

構文が正しくても設定の意味が正しいとは限らない

標準JSONではキー名と文字列を二重引用符で囲み、配列やオブジェクトの最後の要素の後にカンマを付けません。カーネルに渡すファイルへ説明用のコメントを入れるのも避けてください。真偽値はtrueまたはfalse、ポートは通常、数値で指定します。文字列内のバックスラッシュはエスケープが必要です。特にWindowsのログパスを手入力するときは注意してください。JSON構文を検査できるローカルエディターを使えば、括弧の不一致や引用符の抜けを先に見つけられます。

次に、項目間の参照関係を確認します。ルール内のoutboundTagは、対応するoutboundのtagと一致している必要があります。ルールで参照するinboundのタグも、実際に定義されていなければなりません。タグは設定内で使う名前であり、それだけでプロキシ機能が作られるわけではありません。混乱を避けるため、短く明確な英語名を付け、重複しないようにしましょう。タグを変更するときは、ルーティングや統計設定を含め、すべての参照箇所を検索してください。

設定が受け付けられたことと、実際に反映されたことは別です。カーネルによっては一部の項目を省略値で補ったり、実装の違いから特定の項目を拒否したりします。保存後は編集画面にエラーがないかだけでなく、実際の起動ログと使用中のカーネルを確認してください。JSONの整形で確認できるのは構文の形だけです。通信パラメーター、サーバー証明書、リモート側のプロトコルが一致する保証はありません。こうした点は後続の項目を順に確認する必要があります。

変更は「ルーティングの順序だけ調整する」「DNSリゾルバーだけ変更する」など、目的を1つに絞るのがおすすめです。元の設定を別途保存し、変更理由と期待する結果を簡潔に記録してください。inbound、outbound、名前解決を同時に変更すると、失敗の原因を特定しにくくなります。設定を整理する目的はファイルを短くすることではなく、各項目の所属、参照先、適用条件を説明できる状態にすることです。

inbounds:アプリの通信をカーネルへ渡す仕組み

待ち受けアドレス、ポート、プロトコル

inboundsは、アプリからカーネルへ渡される通信を受け取ります。デスクトップ環境では、ローカルSOCKSまたはHTTPプロキシが一般的です。アプリ側で対応するアドレス、ポート、プロキシの種類を指定する必要があります。listenは接続を受け付けるローカルアドレス、portは待ち受けポート、protocolは入口で解釈するリクエストの種類を指定します。ポート番号が同じでも、HTTPクライアントがSOCKSサービスとして使えるわけではありません。

このPCだけで使う場合は、127.0.0.1での待ち受けを優先してください。これはIPv4のループバックアドレスで、他のデバイスからPCのLANアドレス経由で接続することはできません。0.0.0.0はすべてのIPv4インターフェースで待ち受ける指定です。接続可能な範囲が大きく広がるため、「自動的に安全になる」という意味ではありません。IPv6で待ち受ける場合はアドレスとファイアウォールのルールを個別に確認してください。全インターフェースのアドレスにすれば、すべてのネットワークスタックに適切に対応できるとは限りません。

{
  "inbounds": [
    {
      "tag": "local-socks",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": true
      }
    },
    {
      "tag": "local-http",
      "listen": "127.0.0.1",
      "port": 10809,
      "protocol": "http",
      "settings": {}
    }
  ]
}

この例では、アプリの対応状況に応じて2種類のプロキシプロトコルを選べます。udp: trueはSOCKS inboundでUDPリクエストを処理できるようにしますが、アプリがSOCKSのUDP機能に対応し、outboundから接続先までの経路全体もUDPに対応している必要があります。すべてのシステムUDP通信が自動的にinboundへ取り込まれるわけではありません。また、システムプロキシを無視するアプリの動作が変わるわけでもありません。入口の対応機能と、システム通信の取り込みは別の問題です。

項目確認ポイントよくある誤解
listenローカルループバックまたは指定したインターフェースすべてのインターフェースでの待ち受けは、ローカル専用を意味しない
portアプリ側の設定値と一致しているかポートが開いていてもプロトコルが一致するとは限らない
tagルールやログで入口を識別するタグは待ち受けアドレスの代わりにならない
settingsinboundのプロトコルに合わせて項目を選ぶ異なるプロトコルですべての設定を共用できるわけではない

スニッフィングと接続先アドレスの関係

スニッフィングは、一部の接続からプロトコル情報を読み取り、ドメイン名などを取得する機能です。一般的な情報源にはHTTPのHostやTLSハンドシェイクに含まれるサーバー名があります。アプリから最初にIPアドレスが渡された場合でも、ルーティングでドメイン名を使って判定できることがあります。ただし、すべての通信に読み取り可能なドメイン名が含まれるわけではなく、スニッフィングは完全な復号機能ではありません。「スニッフィングを有効にする」だけで正しいDNS設定を代替することはできず、すべてのアプリからドメイン名を取得できる保証もありません。

{
  "sniffing": {
    "enabled": true,
    "destOverride": ["http", "tls"],
    "routeOnly": true
  }
}

この設定は個別のinboundオブジェクト内に記述します。対応する実装でのrouteOnlyは、スニッフィングで得た情報をルーティングに使い、接続先そのものは置き換えないことを意味します。使用前に、選択中のカーネルが対応しているか確認してください。項目が受け付けられない場合、同義語らしい名前を次々に試すのは避けましょう。まずスニッフィングなしの基本設定で入口を確認し、使用中のカーネルの項目定義に沿って追加します。未対応の項目とリモート接続の失敗は分けて考えてください。

LAN共有とシステム通信の取り込み

同じネットワーク内の別のデバイスからPCのプロキシを使う場合は、待ち受けアドレスの変更に加え、PCの実際のLAN IPアドレス、ファイアウォール、ネットワーク分離、認証設定を確認してください。プロキシポートをインターネットに公開したり、信頼できないネットワークで認証なしの入口を開いたりしないでください。共有する場合、別のデバイスにはPCのLANアドレスを設定します。各デバイスのループバックアドレスは、それぞれ自身を指します。

システムプロキシは、その設定に従うアプリにプロキシの使用を通知するだけで、すべてのアプリのネットワーク動作を変更するものではありません。TUNでは仮想ネットワークインターフェース、ルーティングテーブル、権限、DNSの取り込みが関係するため、通常はクライアントの専用機能で設定します。あるカーネル向けのTUN項目を、別のJSON構造にそのまま加えないでください。システムプロキシが使えても特定のアプリが直接接続する場合は、そのアプリがシステムプロキシに対応しているかを先に調べ、必要に応じてTUNを検討します。

inboundの問題を調べるときは、まずクライアントが起動しているか、次にログにアドレス使用中のエラーがないか、最後にアプリ側で正しいプロキシの種類を選んでいるか確認します。ブラウザーではHTTP入口を使えても、別のプログラムでSOCKSが失敗する場合は、すぐにクライアントを再インストールせず、そのプログラムの認証、名前解決方法、UDPの必要性を個別に調べてください。LANでの詳しい手順はLAN接続を許可してプロキシを共有する方法をご覧ください。

outbounds:接続先、プロトコル、トランスポート層

outboundのタグとデフォルトの送信先

outboundsは、カーネルが受け取った接続を接続先へ送ります。接続先へ直接アクセスする、リモートプロキシサーバーへ通信を渡す、ルールに応じてリクエストを拒否する、といった処理ができます。代表的なfreedomは直接接続、blackholeは破棄を表します。VMess、VLESS、Trojanなどは、リモート側と通信するためのプロトコルです。プロトコル名だけで接続先サーバーが用意されるわけではありません。実際に利用できるアドレス、ポート、認証情報が必要です。

別のoutbound選択機能が働かない場合、ルーティングルールに一致しなかった通信には、通常outbounds配列の先頭が使われます。そのため、配列の順序変更は単なるファイル整理ではなく、デフォルトの接続経路を変える可能性があります。デフォルトoutboundを明確にし、ルーティングの項目で分かりやすいフォールバックルールを設定してください。proxyというタグを定義しただけでは、通信が自動的にプロキシ経由になるわけではありません。タグは参照用の名前であり、実際の動作はそのオブジェクトのプロトコルと設定で決まります。

{
  "outbounds": [
    {
      "tag": "direct",
      "protocol": "freedom",
      "settings": {}
    },
    {
      "tag": "block",
      "protocol": "blackhole",
      "settings": {}
    }
  ]
}

このoutboundの組み合わせは、ローカルでルールをテストするためのものです。通常のリクエストは直接接続し、ブロックルールに一致したリクエストは破棄します。プロキシサーバーもproxyというタグのoutboundもありません。他のガイドのルーティング例を読むときは、参照先のタグがすでに定義されているか確認してください。定義されていないタグを指すルールをそのままコピーすると、設定チェックに失敗することがあります。クライアントが不足しているサーバー設定を自動で補うとは限りません。

プロトコル設定とトランスポート設定を分けて確認

リモートoutboundは一般に、プロトコルのパラメーターとトランスポートのパラメーターに分けられます。サーバーアドレス、ポート、ユーザー識別子、パスワードなどのプロトコル設定は、該当するsettings構造に記述します。トランスポートとセキュリティのネゴシエーションは、通常streamSettingsで指定します。両方ともサーバー側の設定と一致している必要があります。アドレスと認証情報だけを確認しても、トランスポート方式、TLS、パスまで一致していなければ、ポートへ接続できてもプロトコルのハンドシェイクが完了しないことがあります。

サーバーアドレス、TLSのサーバー名、トランスポートによってはHostが、常に同じ値とは限りません。アドレスは最初の接続先を指定し、サーバー名はTLSでの識別や証明書検証に使われます。Hostやパスがリバースプロキシの振り分けに使われる場合もあります。すべてを同じ値にして見た目をそろえないでください。サブスクリプションから読み込む場合は、提供元のパラメーターを維持したうえで、ログから項目の欠落や互換性の問題を確認してください。

設定レイヤー主な項目確認方法
プロトコル認証ユーザー識別子、パスワード、暗号化オプションサーバー設定と項目ごとに照合
トランスポート方式TCP、WebSocket、gRPCなど使用中のカーネルが対応し、サーバー側と一致しているか確認
TLSセキュリティサーバー名、証明書の検証ハンドシェイクエラーとシステム時刻を合わせて確認
アプリケーション層パス、サービス名、Host大文字・小文字、プレフィックス、リバースプロキシのルールを確認

検証要件を緩めて問題を隠さない

証明書エラーが出た場合は、まずシステム時刻を合わせ、サーバー名、有効期限、証明書チェーンを確認してください。証明書検証を省略すると接続の信頼条件が変わるため、通常の解決策として使うべきではありません。宛先へ直接接続できてもリモートプロキシのハンドシェイクに失敗するなら、inboundとローカルネットワークの一部はすでに機能しています。次はリモートプロトコルとトランスポートに絞って確認し、すべてのローカルポートを変更したり、ルーティングテーブル全体を消去したりする必要はありません。

一部のプロトコルは、追加のハンドシェイク項目や専用のセキュリティ設定を必要とします。こうした項目はカーネルの実装によって異なります。クライアントにプロトコル名が表示されるからといって、すべてのカーネルが同じパラメーターに対応するとは限りません。読み込み後に未対応プロトコルや不明なセキュリティタイプのエラーが出る場合は、使用中のカーネルがノードの要件に合っているか先に確認してください。カーネルを切り替えた後は、クライアントが生成するトランスポート項目も変わっていないか確認しましょう。

多重化、コネクション維持、その他の最適化オプションは、多く設定するほどよいとは限りません。接続の構成が変わり、長時間接続、サーバーのリソース、中継するネットワーク機器に影響する可能性があります。基本接続が確立するまでは、提供元の推奨設定を使ってください。明確な問題があり、再現可能なテストとサーバー側の対応を確認できた場合に限り調整します。短いリクエストが一度成功しただけで、長時間の通信、UDP、すべての接続先が使えると判断しないでください。

outboundのトラブル対処は、アドレスへの到達、トランスポートのハンドシェイク、プロトコル認証、接続先へのアクセスの4段階に分けて考えます。1つの段階で成功しても、後続の確認を省略できるわけではありません。ノードに接続できずタイムアウトする場合は、システム時刻・ポート・トランスポート層の確認方法をご覧ください。認証情報を扱う場合、ログや設定を共有する前にユーザー識別子、パスワード、完全なサブスクリプションURLを削除し、プロトコルの種類とエラー分類だけを残してください。

routing:ルールの評価順と振り分けの範囲

1つの接続からルールの適用を確認

ルーティングは単なるドメイン名の一覧ではありません。接続に含まれる宛先アドレス、inboundタグ、ポートなどの情報からoutboundを選ぶ仕組みです。一般的なフィールドルールではtype: "field"を使います。ルールは記載順に評価され、最初に一致したルールでoutboundが決まります。そのため、具体的な例外は前方に置くのが基本です。広範囲のルールを先に置くと、後続の細かいルールが評価されない場合があります。ルールがあるのに効かないように見える原因の一つです。

同じルール内では、異なる条件項目は通常すべて満たす必要があります。一方、同じドメインやIPの配列に複数の値を指定した場合は、いずれかに一致すればよいのが一般的です。たとえばinboundTagとdomainを同時に指定すると、特定のinboundから来た特定のドメインを表し、個別の2つの条件にはなりません。「このinboundのすべての通信を特定のoutboundへ送る」場合と「指定したドメインを特定のoutboundへ送る」場合を表したいなら、条件を分けて2つのルールを作ってください。

{
  "routing": {
    "domainStrategy": "AsIs",
    "rules": [
      {
        "type": "field",
        "domain": ["full:example.com"],
        "outboundTag": "block"
      },
      {
        "type": "field",
        "ip": ["geoip:private"],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "network": "tcp,udp",
        "outboundTag": "direct"
      }
    ]
  }
}

この例は、すでに定義されたdirectとblockのoutbound、および実行環境から対応する地理データを読み込めることを前提とします。最初のルールは完全一致するドメインをブロックし、次のルールはプライベートアドレスを処理します。最後のルールで、それ以外のTCPとUDPを明示的に直接接続します。これはルールの順序を示す例であり、一般的な本番用ポリシーではありません。実際にプロキシoutboundを追加する場合は、先に定義してから、プロキシ経由にしたいルールをそのタグに向けてください。

ドメインルールとIPルールは別の条件

full:example.comは完全一致するドメインを指定します。domain:example.comは通常、そのドメインとサブドメインを対象にします。プレフィックスのない文字列、正規表現、分類データにも、それぞれ異なる一致条件があります。混同しないようにしてください。メインのドメインをブロックしても、別のリソース用ドメインが対象になるとは限りません。また、サイトが読み込めない原因は、複数のリクエストのうち1つがルールに一致したことかもしれません。確認時はアドレスバーだけでなく、実際のリクエスト先ドメインを調べてください。

geosite:とgeoip:はデータセットを参照する記法で、カーネルがリアルタイムにインターネットを検索する機能ではありません。分類項目の有無、収録内容、データファイルの読み込み可否は、使用中のデータリソースによって異なります。分類やデータファイルが見つからないというログが出た場合は、まずリソースとパスを確認してください。タグ名を何度も変えるだけでは解決しません。分類ルールの適用範囲が変わった場合は、ルールの順序ではなくデータの更新が原因のこともあります。

{
  "type": "field",
  "domain": ["geosite:category-ads-all"],
  "outboundTag": "block"
}

このルールを使えるのは、データファイルに該当する分類が含まれている場合だけです。追加する前に、既存ルールに対象範囲の広いドメイン指定や全通信対象のルールがないか確認してください。同じ項目をルール一覧に重複して追加しても効果は上がらず、設定の説明が複雑になるだけです。順序だけを試したい場合は、先に完全一致する例示用ドメインで確認します。ログに表示される宛先タグの変化を見てから、外部データに依存する分類ルールを追加してください。

domainStrategy:照合時に名前解決するタイミング

AsIsは、接続に含まれるアドレスをそのまま使って照合します。IPIfNonMatchは、ドメインが一致しない場合に名前解決を試し、そのIPアドレスをIPルールの判定に使えます。IPOnDemandは、ルール判定にIPが必要になった時点で、より早く名前解決します。これらはルーティング判定時の名前解決タイミングを指定するもので、アプリ側のDNS、システムDNS、outbound接続先のアドレスファミリーに関する設定すべてを指すわけではありません。より積極的な名前解決を選ぶと、問い合わせや待ち時間が増える場合もあります。

アプリからIPアドレスが渡され、利用できるドメイン情報がない場合、ドメインルールは一致しないことがあります。アプリがドメイン名を渡していても、ポリシーが名前解決を行わなければ、IPルールの判定に必要な情報が得られない場合があります。まずinboundが受け取った宛先の種類を確認し、その後でスニッフィングや名前解決ポリシーの変更を検討してください。ルールに一致しない原因をすべて構文の問題と決めつけないでください。判定に使える情報がなければ、ドメイン条件をいくら正確に書いても宛先名が自動的に得られるわけではありません。

整理する際は、ローカルサービスと必要な例外を先頭に置き、outboundを明示的に選ぶルールを中央に配置し、最後にデフォルトの動作を記述すると分かりやすくなります。プライベートネットワーク向けのルールは接続環境に合わせてください。特殊用途のアドレスをすべて一般的なインターネット接続先と見なすことはできません。検証時は、一致するはずの宛先と一致しないはずの宛先の両方をテストし、対象範囲が広すぎないか確認します。分流設定の問題についてはよくある質問とトラブル対処もご覧ください。

dns:名前解決の参照先、問い合わせ経路、接続先アドレス

まず3種類の名前解決を区別する

DNSを設定する前に、アプリ自身による名前解決、カーネル内蔵DNSによる名前解決、システムによる名前解決を区別してください。アプリが先にIPアドレスを取得してからプロキシへ渡すこともあれば、ドメイン名をカーネルへ渡し、後続の処理で名前解決することもあります。ブラウザーが独自のセキュアDNSを有効にしている場合もあります。カーネルのdnsオブジェクトを変更しても、すべてのアプリやシステムの問い合わせが自動的に切り替わるわけではありません。どこから問い合わせが始まるかを把握しないと、設定がどの経路に影響するのか判断しにくくなります。

カーネル内蔵DNSは、ルーティングでIPアドレスを照合する場合や、一部outboundの名前解決ポリシーから呼び出す場合に使われます。項目を記述しただけで、システム全体向けのDNSサービスが自動的に起動するわけではありません。システムや他のデバイスからカーネルへDNSリクエストを送るには、対応するinboundと転送設定も必要です。利用できる機能や項目は、使用するカーネルに応じて確認してください。クライアントでTUNを有効にした際のDNS取り込みは別のレイヤーです。このオブジェクトだけでシステムのDNS問い合わせが取り込まれているとは判断できません。

{
  "dns": {
    "queryStrategy": "UseIPv4",
    "servers": [
      "1.1.1.1",
      {
        "address": "8.8.8.8",
        "port": 53,
        "domains": ["domain:example.org"]
      }
    ]
  }
}

これは内蔵リゾルバーを設定する部分的な例です。パブリックDNSリゾルバーのアドレスは構造を示すためのもので、実際に接続できるかはネットワーク環境によります。domainsは指定したドメインに対して使用するリゾルバーを選ぶもので、そのドメインへのアクセス用プロキシルートを作る設定ではありません。フォールバック動作にも注意してください。他のサーバーが問い合わせに使われるかどうかは、優先順位、一致状況、フォールバック設定によって異なります。ドメインの選択条件だけで、問い合わせ経路を完全に分離できるとは限りません。

名前解決ポリシーとoutboundのポリシーは別々に設定

queryStrategyは、IPv4のみを問い合わせる、対応状況に応じてIPv4とIPv6を扱うなど、内蔵DNS問い合わせで使うアドレスファミリーに影響します。ルーティングのdomainStrategyとは別の項目です。また、outboundごとのドメインポリシーとも異なります。IPv6接続の問題を調べるときは、名前解決の結果、システムのIPv6経路の有無、outboundがアドレスをどう使うかを合わせて確認してください。スイッチを1つオフにするだけでは十分ではありません。

ネットワークに安定したIPv6経路がないのに到達できないIPv6アドレスへの接続を優先すると、待ち時間の後に成功することがあります。反対にIPv4を無条件に制限すると、IPv6しか利用できないリソースに影響する可能性があります。まず接続に失敗する宛先の名前解決結果と接続エラーを確認し、その後でアドレスファミリーのポリシーを決めてください。デュアルスタックのサイトが1つ開けても、あらゆるネットワーク環境で問題がないとは限りません。宛先ごとの記録、接続時のフォールバック、アプリのキャッシュも異なります。

設定場所主な役割自動では行わないこと
dns.queryStrategy内蔵DNS問い合わせのアドレスファミリーすべてのアプリのDNSを取り込む
routing.domainStrategyルーティング判定時の名前解決タイミングすべてのoutboundの名前解決方法を統一する
outboundのドメインポリシー該当するoutboundが接続先アドレスを選ぶシステムのネットワークルーティングを置き換える
クライアントによるDNSの取り込みクライアントの実装に応じて問い合わせを捕捉または転送する独立した暗号化DNS問い合わせをすべて取り込む

問い合わせ経路にも到達性が必要

リゾルバーを選ぶ際は、アドレスだけでなく、問い合わせがどう到達するかも確認してください。通常のUDP問い合わせ、暗号化DNSリクエスト、ローカルシステムの名前解決では、経路が異なる場合があります。ローカル名前解決を使うモードでは、通常のルーティング処理を迂回することもあります。プロトコル名だけを根拠に、問い合わせが指定したプロキシを経由すると判断しないでください。カーネルが対応するDNS送信方式を調べ、ログとネットワーク環境で検証しましょう。想定した経路と実際の経路を混同しないことが重要です。

ドメイン名で指定する暗号化DNSアドレスを使う場合は、起動時の依存関係も考慮してください。リゾルバーへ接続するためにリゾルバーのドメイン名を解決する必要があるのに、その処理がまだ使えない同じリゾルバーに完全に依存すると、循環依存が起きる可能性があります。プロキシサーバーのアドレスを解決する必要があり、その問い合わせをまだ確立していないプロキシ経由に指定した場合も同様です。起動時にも利用できる、明確で到達可能な名前解決経路を用意してください。

キャッシュの影響で、DNS設定を変更してもすぐ反映されないことがあります。システム、ブラウザー、アプリ、カーネルはいずれも結果を保持する場合があり、どれか1つを再起動しても他のキャッシュは消えないことがあります。検証時は既存の接続を閉じ、必要に応じて関連アプリを再起動し、期待する結果が明確な宛先を使ってください。リゾルバーを次々に切り替えて、Webページを1回更新するだけでは判断できません。既存の長時間接続では新しい問い合わせが発生しないことがあり、観察結果だけでは新設定の使用有無を確認できません。

ドメイン名では接続できず、接続先IPアドレスへ直接アクセスできる場合、名前解決やドメイン関連のハンドシェイクが原因の可能性があります。ただしTLS証明書はドメイン名に依存するため、IPアドレスへの直接接続が同等のテストとは限りません。DNS問い合わせの応答、返されたアドレスへの到達性、プロトコルのハンドシェイクを個別に確認するほうが確実です。名前解決元またはアドレスファミリーのいずれか1つだけを変更し、変更前後のログを保存してください。複数の変更を1つの原因としてまとめないようにします。

policy:ユーザーレベル、タイムアウト、統計の範囲

ユーザーレベルに応じてポリシーを適用

policyは接続処理の方針と一部の統計設定を定義するもので、ドメインによる振り分けや、リモートサーバーが認証を受け付けるかどうかは決定しません。一般的な構造にはlevelsとsystemがあります。前者ではユーザーレベルごとにタイムアウトや統計項目を設定し、後者ではシステムレベルのinboundやoutboundの統計を扱います。レベルは設定項目を関連付ける値であり、料金や速度のランクではありません。数値が大きいほど接続が速いという意味でもありません。

一部のプロトコルでは、ユーザーオブジェクトにlevelを設定し、levels内の同じ数字を文字列にした項目と対応させます。明示されていない場合は、プロトコルとカーネルの既定レベルに従って解釈してください。ユーザーから参照されないレベルを定義しても、すべての接続に自動適用されるわけではありません。ポリシーの適用状況を調べるときは、設定にオブジェクトが存在するだけで適用済みと判断せず、まず接続に使うユーザーとレベルを確認してください。

{
  "policy": {
    "levels": {
      "0": {
        "handshake": 4,
        "connIdle": 300,
        "uplinkOnly": 2,
        "downlinkOnly": 5,
        "statsUserUplink": false,
        "statsUserDownlink": false
      }
    },
    "system": {
      "statsInboundUplink": false,
      "statsInboundDownlink": false,
      "statsOutboundUplink": false,
      "statsOutboundDownlink": false
    }
  }
}

時間の単位は秒です。これは動作を説明するための設定例で、あらゆる用途に最適な値という意味ではありません。handshakeは該当するハンドシェイク段階の制限を設定し、connIdleはアイドル状態の接続を対象とします。上下方向の片側だけが終了した後の待ち時間は、接続をどれだけ維持するかを表します。総ダウンロード時間の制限ではなく、アプリ自身の再試行やタイムアウト設定の代わりにもなりません。現在の接続に各項目が適用されるかは、プロトコルの実装に応じて確認してください。

タイムアウトを延ばしてもプロトコルの不一致は解消しない

ハンドシェイクの失敗には、認証情報の不一致、トランスポート方式の誤り、証明書エラー、接続先に到達できないなど、さまざまな原因があります。ハンドシェイクの時間を延長しても、正常だが時間のかかるネゴシエーションを待てるだけで、誤ったプロトコルが正しくなるわけではありません。認証拒否や未対応項目がログに明示されている場合、時間を延ばすと失敗が遅くなるだけです。まず確実なエラーを解決してから、待ち時間が適切か検討してください。

アイドル接続の切断も、アプリの動作に合わせて考える必要があります。インスタントメッセージ、リモートセッション、ストリーミング応答、時折しかデータを送らない接続では、必要なアイドル時間が異なります。しきい値を小さくしすぎると、バックグラウンド接続が何度も確立されることがあります。大きくしすぎると、より多くのリソースを保持する可能性があります。調整の前に、切断が本当にアイドル接続の回収で起きたのか確認してください。ネットワークの切り替え、省電力機能、サーバーによる切断、中継機器のタイムアウトが原因の場合もあります。

項目確認対象調整する条件
handshakeプロトコルのハンドシェイク段階パラメーターは正しいが、ネゴシエーションに時間がかかることを確認済み
connIdle通信のない接続アイドル接続の回収が実際に業務へ影響していると確認済み
uplinkOnly該当する一方向の通信段階一方向が終了した後の接続動作を把握している
statsUserUplinkユーザーの上り通信量の統計統計モジュールとユーザー識別設定がそろっている

統計の有効化は統計画面の表示を意味しない

統計用の真偽値を有効にしても、グラフ付きレポートが自動生成されるわけではありません。カーネルの統計を使うには通常、統計モジュール、識別可能なユーザー、対応する問い合わせ用インターフェースなども必要です。クライアントに表示される通信量は、独自の方法で収集されている場合もあります。カーネルのユーザー統計、クライアントプロセスの通信量、ネットワークインターフェース全体の通信量を同じ値と見なさないでください。転送、プロトコルのオーバーヘッド、集計範囲、再起動後のカウント期間によって結果が異なることがあります。

通信量を表示するためにAPI用inboundや制御インターフェースを手動で追加する場合は、特に注意してください。制御インターフェースは信頼できる範囲に制限し、読み取りを簡単にするためにすべてのアドレスで公開しないでください。通常はクライアントにあるログや状態確認機能で十分で、別途問い合わせ用インターフェースを構築する必要はありません。このページの例で統計を無効にしているのは、接続とルールに焦点を当てるためです。すべての環境で機能を無効にすべきという意味ではありません。

Androidでバックグラウンドに移行した後に接続が切れる場合、カーネルのアイドルポリシーではなく、アプリのバックグラウンド動作に対するシステム制限が関係していることがあります。v2rayNGのVpnServiceの許可、バックグラウンド実行権限、メーカー独自の省電力設定を個別に確認してください。詳しい手順はVpnService、省電力の例外設定、アプリごとのプロキシをご覧ください。システム側で正しく許可する代わりに、タイムアウトを極端に大きくしないでください。

policyを調整する場合は、再現条件を明確にしてください。使用したアプリ、アイドル時間、ネットワーク切り替えの有無、通信が続いている方向を記録し、調整後の差を観察します。こうした条件がなければ、設定変更の効果と環境が偶然回復したことを区別しにくくなります。一般的なブラウジングやサブスクリプションの利用では、クライアントが生成する妥当な初期値のままにするほうが管理しやすいことが多いでしょう。まずは接続の成否に直接影響するinbound、outbound、ルーティングを確認してください。

クライアントが生成する設定とカーネルの違い

同じ画面項目でも、生成されるJSONが同じとは限らない

v2rayNはデスクトップ環境向けです。クライアントのシステムプロキシ、TUN、ルーティングのプリセット、カーネル切り替えは、それぞれ異なる実行方式に反映されます。v2rayNGは主にXrayカーネルを使用し、v2flyNGはV2Flyカーネルを使うAndroid向けの代替クライアントです。3つのクライアントで似たノードの概念を扱えても、アプリのデータ保存先、読み込み方法、バックグラウンド動作、設定の生成方法は異なります。あるクライアントのデータフォルダー全体を別のクライアントに上書きしないでください。

V2FlyとXrayには共通の設定の流れがあり、一部のJSON項目も似ていますが、独自拡張、対応プロトコル、項目の変更内容が完全に一致するわけではありません。sing-boxは別の構造を採用しており、inboundの種類、outboundの定義、DNS、ルーティングのアクションも独自の仕様に従って記述します。プロトコル名が同じでも、設定をそのままコピーできるとは限りません。移行時は機能の意味を照らし合わせて、項目を組み直してください。プロトコル名を機械的に置き換えるだけでは不十分です。

対象適用範囲移行時の確認点
v2rayNWindows、macOS、Linuxのデスクトップ環境使用中のカーネル、ルーティングのプリセット、システム権限
v2rayNGAndroid、XrayカーネルVpnService、アプリごとのルール、バックグラウンド制限
v2flyNGAndroid、V2Flyカーネルの代替クライアントプロトコルの対応状況と項目の互換性
完全なカスタム設定利用できる機能はクライアントの設定画面によって異なる生成された設定や自動管理項目を上書きするか

システムプロキシ、ルーティング、TUNを別々のレイヤーとして理解する

システムプロキシは、対応するアプリがリクエストをローカルのinboundへ渡す方法を決めます。カーネルのルーティングは、カーネルに届いたリクエストをどのoutboundへ送るか決めます。TUNは、仮想ネットワークインターフェースを通じて、より広い範囲のシステム通信を受け取ります。この3つは異なるレイヤーで動作します。ルーティングルールを変更しても、カーネルに届いていないアプリの通信は制御できません。TUNを有効にしても、すべてのカーネルルールが正しいとは限らず、リモート認証情報の誤りも直りません。

クライアントに表示される「グローバル」は、あるレイヤーでのデフォルトoutboundや通信の取り込み範囲を指すことが多く、実際の意味は選択中のモードによって異なります。カーネルのルーティングが変わる場合もあれば、システムプロキシのモード名にすぎない場合もあります。ボタンの表示だけに頼らず、生成された設定、実際のinbound、ログを確認してください。LAN上のサービスへ接続できなくなった場合は、カーネルがプライベートアドレスを誤ったoutboundへ送っていないか、TUNのシステムルートによってローカルネットワークへの接続方法が変わっていないかを調べます。

TUNには適切な権限が必要で、他の仮想ネットワークソフトウェアと競合することもあります。有効にした後でネットワーク全体が切断された場合は、まずTUNを無効にして基本的な接続を復旧し、権限、仮想インターフェース、DNS、ルートの競合を確認してください。リモートサーバーの設定を同時に変更しないでください。システムプロキシモードで接続できていれば、基本的な接続経路の一部は機能しています。そのノードは変更せず、通信の取り込みレイヤーに絞って確認するほうが、サブスクリプションをすべて再読み込みするより効率的です。

サブスクリプション、カスタムルール、更新時の上書き

サブスクリプションが提供するのは通常ノード情報で、ローカルのルーティング、システムプロキシ、DNSまで含むとは限りません。より完全な設定を含む形式もあるため、読み込む前にデータの種類を確認してください。更新後にノード情報が変わるのは通常の同期動作ですが、ノードに加えた手動変更が上書きされることがあります。長期的に維持する例外は、クライアントが対応するローカルルールや独立した設定に記述してください。更新のたびに同じ項目を手作業で変更することを避けられます。

完全なカスタム設定がどう扱われるかも確認が必要です。クライアントがその設定を直接実行する場合もあれば、待ち受けポート、ログ、制御インターフェース、統計設定などを追加する場合もあります。ファイルの内容が最終的な実行設定だと決めつけないでください。問題を調べるときは、設定の読み込み元、クライアントでの選択内容、実際の起動ログを記録します。設定をエクスポートしても、そのまま公開共有できるわけではありません。サーバーアドレス、認証情報、サブスクリプションURLが含まれていることがあるため、共有前に個別に取り除いてください。

macOS、Windows、Linuxでは、同じJSONを使ってもファイルパス、ディレクトリ権限、ファイアウォール、システムプロキシの設定方法が異なります。ログファイルは、クライアントが書き込み可能な場所に保存してください。別のOSの絶対パスをそのまま貼り付けないでください。初回インストール時に必要なディレクトリや実行環境についてはv2rayNの初回インストールと初期設定をご覧ください。起動に失敗する場合は、プロセスのクラッシュと設定の読み込み拒否を区別して確認します。

クライアントのインストールや変更が必要な場合は、インストーラーのダウンロードページでOSとプロセッサーのアーキテクチャを選んでください。デスクトップではv2rayNを優先して利用します。項目を1つ試すためだけにクライアントやカーネルを頻繁に変更すると、設定と環境の差が重なって原因を特定しにくくなります。元に戻せる小さな手順に分け、最後に正常動作した設定を保存しておくと、どの機能や設定レイヤーが変化したのか確認しやすくなります。

完全な設定例とレイヤーごとの検証

ローカル直結と特定ドメインのブロックを確認する基本設定

以下は、ローカルでの検証用に使える完全なJSONです。ループバックアドレス上でSOCKSとHTTPのポートを待ち受け、通常の通信は直接接続し、完全一致する例示用ドメインへのリクエストはblock outboundへ送ります。リモートプロキシの認証情報や分類データファイルに依存しないため、ルーティングの基本確認に適しています。クライアントが同じポートを使用中の場合は、先にカーネルを停止するか、独立したテスト用コピーで未使用のポートを設定し、アプリ側の設定も合わせて変更してください。

{
  "log": {
    "loglevel": "warning"
  },
  "inbounds": [
    {
      "tag": "local-socks",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": true
      }
    },
    {
      "tag": "local-http",
      "listen": "127.0.0.1",
      "port": 10809,
      "protocol": "http",
      "settings": {}
    }
  ],
  "outbounds": [
    {
      "tag": "direct",
      "protocol": "freedom",
      "settings": {}
    },
    {
      "tag": "block",
      "protocol": "blackhole",
      "settings": {}
    }
  ],
  "routing": {
    "domainStrategy": "AsIs",
    "rules": [
      {
        "type": "field",
        "domain": ["full:example.com"],
        "outboundTag": "block"
      },
      {
        "type": "field",
        "network": "tcp,udp",
        "outboundTag": "direct"
      }
    ]
  }
}

検証には、クライアントが対応する完全な設定向けの機能を選び、対象のカーネルが現在実行中であることと、設定の読み込み結果を確認してください。起動直後に失敗する場合は、まず構文、未対応項目、ポートの使用状況を調べます。起動してもアプリのリクエストが記録されない場合は、アプリが本当にローカルのinboundへ接続しているか確認してください。リクエストがまだ届いていない可能性があるため、この段階でDNSやリモートのトランスポートを変更する必要はありません。

順番に正常系と逆方向のテストを行う

最初に、HTTPプロキシ対応が明確なアプリを使い、アドレスを127.0.0.1、ポートを10809に設定します。現在のネットワークから直接接続できる宛先にアクセスしてください。次に、完全一致でブロックする例示用ドメインへアクセスし、ルールどおりに失敗するか確認します。最後にブロックルールを一時的に削除して設定を再読み込みし、結果を比較します。リクエストがドメイン名のままプロキシへ渡されることを確認してください。アプリが事前にIPアドレスへ名前解決している場合、ドメインルールの判定材料が得られないことがあります。

逆方向のテストも重要です。ブロック対象外の宛先には通常どおり接続できる必要があります。1つの宛先で失敗しただけでは、ルールが正しいとは証明できません。inbound全体が動作していない可能性もあります。テスト時はアプリの既存接続を閉じ、ブラウザーのキャッシュ、セキュアDNS、独自のプロキシ拡張機能によって経路が変わっていないか確認してください。アプリの動作が不明な場合は、まず1つのアプリで比較テストを完了して環境要因を減らし、その後、他のプログラムにも広げます。

接続段階に沿ってログを読む

ログは、量を増やすためではなく、まず失敗した段階を特定するために使います。普段はノイズの少ないログレベルにし、問題を再現するときだけ一時的に詳細度を上げてください。inboundタグ、宛先アドレス、適用されたoutbound、最終エラーが同じリクエストに関するものか確認します。複数のアプリが同時に通信している場合、ログ上で隣り合う2行が同じ接続を表すとは限りません。同じ接続が大量に繰り返し記録される場合は、テストの対象を絞り、バックグラウンドアプリの通信を検証対象と混同しないようにしましょう。

症状優先して確認後回しにする項目
カーネルが起動しないJSON構文、項目の対応状況、待ち受けポートの使用状況リモートサイト向けのルーティング分類
inboundにリクエストが届かないアプリのプロキシ種類、アドレス、ポートpolicyのタイムアウト
誤ったoutboundが選択される宛先の種類、ルールの順序、タグサーバーの認証情報
正しいoutboundが選ばれるがハンドシェイクに失敗時刻、証明書、トランスポート、プロトコルの設定同じルーティングルールの重複追加

ログにはアクセス先のドメイン、LANアドレス、サーバー情報が含まれることがあります。トラブル対処が終わったら、普段使うログレベルに戻し、不要な詳細ログを削除してください。他の人に問題を説明する際は、エラーの種類と発生段階を残し、認証情報、完全なサブスクリプションURL、個人のアクセス履歴を取り除きます。クライアントのデータディレクトリ全体をそのまま公開しないでください。実行設定に加え、過去のノード、グループ情報、アカウントに関するデータが保存されている可能性があります。

基本設定から実際の設定へ段階的に戻す

ローカルの基本設定で問題がないことを確認したら、まず有効なリモートoutboundを1つだけ戻し、複雑なルーティングは同時に追加しないでください。リモート経路を確認した後、明確な分流ルールを1つ加えます。次に分類データとDNSを導入し、最後にpolicyの調整を検討します。各段階で、一致するはずのリクエストと一致しないはずのリクエストの両方をテストしてください。問題が起きたら、複数の変更を重ねた設定を続けて調整するより、最後に動作したコピーへ戻すほうが原因を見つけやすくなります。

サブスクリプションの更新、カーネルの切り替え、クライアントのアップデート後も、同じ検証手順を使えます。画面が開くことだけで設定全体が有効だと判断しないでください。1つのWebページが表示できても、すべてのプロトコルが正常とは限りません。inbound、outbound、ルール、名前解決をそれぞれ確認し、期待どおりの結果が得られて初めて、現在の用途に合った設定だと判断できます。普段の操作についてはクイックスタートガイドを、個別の問題についてはよくある質問とトラブル対処をご覧ください。

v2rayN をダウンロード