V2Ray設定ファイルの構造を詳しく解説:inbounds・outbounds・routingを読み解く

最小構成のconfig.jsonを例に、inbounds(受信)、outbounds(送信)、routing(ルーティング)の3つの要素と各フィールドの役割を解説。仕組みが分かれば、設定変更で迷いません。

この記事の概要

ノードのインポートはできるものの、config.jsonを見ても通信の流れが分からない方に向けた解説です。ローカルの10808ポートから始め、inbounds、outbounds、routing、DNS、ログを順に確認し、構文チェックに通るV2Ray 5系の設定例も紹介します。ポート競合や出力タグの誤記、ルール順序の問題を切り分けられるようになります。

まず通信の流れを確認:設定項目はどう連携するのか

V2Rayの設定は、独立したスイッチの集まりではありません。アプリがリクエストを特定のinboundへ渡すと、routingモジュールが宛先ドメイン、宛先IP、ポート、inboundタグを読み取り、指定されたoutboundへ送ります。どのルールにも一致しない場合、通常はoutbounds配列の先頭が使われるため、outboundsの並び順も結果に影響します。

inboundsは「通信がどこから入るか」、outboundsは「通信がどこから出るか」を定義し、routingが両者を結びます。設定で起動できても、JSON構造とフィールドを解析できたことを示すだけです。想定どおりに振り分けるには、タグの参照、ルールの順序、DNSの応答結果も確認する必要があります。

アプリがリクエストを開始inboundポートが受信ルーティングルールを照合outboundタグを選択宛先サーバー
10808
SOCKS inboundの例
10809
HTTP inbound(任意)
3種類
プロキシ・直接接続・ブロックoutbound
上から順に
ルーティングルールの照合順序

最小構成のひな形:完全なJSONから読み解く

以下の例では、ローカルのSOCKS inbound、VMessプロキシoutbound、直接接続outbound、ブロックoutboundを1つずつ使用します。サーバーのドメイン、ポート、ユーザーID、通信方式は構造を示すための例にすぎず、実際にはサーバー側の設定と項目ごとに一致させる必要があります。JSONにはコメントを記述できないため、説明文を正式な設定ファイルへ直接追加してはいけません。

{
  "log": {
    "loglevel": "warning"
  },
  "dns": {
    "servers": [
      "1.1.1.1",
      "localhost"
    ]
  },
  "inbounds": [
    {
      "tag": "local-socks",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": true
      }
    }
  ],
  "outbounds": [
    {
      "tag": "proxy",
      "protocol": "vmess",
      "settings": {
        "vnext": [
          {
            "address": "server.example.com",
            "port": 443,
            "users": [
              {
                "id": "11111111-2222-3333-4444-555555555555",
                "security": "auto"
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "tcp",
        "security": "none"
      }
    },
    {
      "tag": "direct",
      "protocol": "freedom"
    },
    {
      "tag": "block",
      "protocol": "blackhole"
    }
  ],
  "routing": {
    "domainStrategy": "IPIfNonMatch",
    "rules": [
      {
        "type": "field",
        "protocol": [
          "bittorrent"
        ],
        "outboundTag": "block"
      },
      {
        "type": "field",
        "ip": [
          "geoip:private"
        ],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "domain": [
          "geosite:cn"
        ],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "ip": [
          "geoip:cn"
        ],
        "outboundTag": "direct"
      }
    ]
  }
}

この設定では、どのルールにも一致しないリクエストを先頭のoutbound proxyへ渡します。プライベートアドレス、中国本土のドメイン、中国本土のIPはdirectへ、特定のプロトコルはblockへ振り分けます。directをoutbounds配列の先頭に置き、明示的なプロキシルールを追加しない場合、未一致の通信は直接接続になります。

inbounds(受信):アプリからカーネルへ通信を渡す仕組み

inboundは、V2Rayがローカルで開く受信入口です。例では127.0.0.1:10808をSOCKSとして待ち受けます。ブラウザー、ダウンロードツール、またはシステムプロキシにこのSOCKSアドレスを設定すると、リクエストがV2Rayへ入ります。カーネルを起動しただけで、アプリがinboundポートを向いていなければ、通常のアプリ通信が自動的に取り込まれることはありません。

settings.authnoauthにすると、このSOCKS入口ではユーザー名とパスワードを要求しません。そのため、ローカルでの待ち受けを維持してください。udp: trueはSOCKS UDPリクエストの受け入れを許可しますが、後続のoutboundプロトコル、サーバー、ネットワーク環境も対応している必要があります。このフィールドを有効にするだけで、すべてのUDP通信が正常に通るわけではありません。

SOCKS inbound

待受アドレス
127.0.0.1
待受ポート
10808
プロトコル
socks
UDP
true

SOCKS5設定に対応したブラウザー、コマンドラインツール、デスクトップアプリに適しています。

HTTP inbound

待受アドレス
127.0.0.1
推奨例ポート
10809
プロトコル
http
用途
HTTPプロキシ入口

2種類の入口を同時に用意する場合は、待受の競合を避けるため別々のポートを使用してください。

複数のinboundを同時に使用することもできます。たとえば10808をSOCKS用に残し、10809をHTTP用に追加します。各inboundには個別のタグを設定し、ルーティングルールでinboundTagを使って送信元を区別できるようにします。v2rayNのローカルポートを変更する場合は、「設定」→「パラメータ設定」でSOCKSとHTTPのポートを確認してください。アプリ側のプロキシポートも同時に変更する必要があります。

outbounds(送信):プロキシ・直接接続・ブロックの役割

outboundは、リクエストがV2Rayから外へ出る方法を定義します。プロキシoutboundには通常、サーバーアドレス、サーバーポート、ユーザー認証情報、通信設定が含まれます。直接接続outboundにはfreedom、ブロックoutboundにはblackholeを使用します。routingモジュールはリモート接続を直接確立せず、ルールに基づいてoutboundタグを選択します。

VMessの例にあるvnextはサーバー一覧で、各サーバーには複数のユーザーを登録できます。addressportはサーバー側の待受情報と一致させ、idはサーバーが認識するユーザー識別子にします。TCP、WebSocket、TLSなどのトランスポート設定も確認してください。クライアントとサーバーのどれか1項目でも異なると、接続直後に切断されたり、タイムアウトが続いたりする場合があります。

プロキシoutbound proxy

プロトコル
vmess
サーバーポート
443
通信方式の例
TCP
既定の用途
未一致の通信

実際のサーバーパラメータは、有効なノード設定から取得してください。アドレスだけを置き換え、ほかのサンプル値を残すのは避けます。

ローカルポリシーoutbound

direct
freedom
block
blackhole
サーバーへの接続
不要
選択方法
routingタグ

直接接続とブロックもoutboundに含まれるため、ルールから参照する一意のtagが必要です。

フィールド 場所 役割 よくあるミス
protocol outboundオブジェクト outboundハンドラーの種類を決める VMessのパラメータをVLESS outboundに入力する
settings outboundオブジェクト サーバーとユーザーのパラメータを保持する ポート、ユーザー識別子、サーバー側の設定が一致しない
streamSettings outboundオブジェクト 基盤となる通信方式とセキュリティ層を定義する TCP、WebSocket、TLSの設定が一致しない
tag outboundオブジェクト ルーティングルールから参照する 存在しないタグをルールで参照している

結論:まずoutbound単体の動作を確認してからroutingを調整する

一時的にプロキシoutboundを1つだけ残して接続をテストします。サーバーパラメータが有効だと確認できてから、direct、block、routingを追加してください。そうしないとノードの問題と振り分けの問題が同時に発生し、ログから原因を特定しにくくなります。

routing(ルーティング):ルールの順序が最終的な出口を決める

routing.rulesは上から順に確認するルール配列です。リクエストが1つのルールに一致すると、そのルールで指定されたoutboundTagが使われ、後続のルールは処理されません。そのため、対象範囲が狭く優先度の高いルールを前に、範囲の広いルールを後ろに配置します。

domainStrategy: IPIfNonMatchは、まずドメインルールで照合し、一致しなければIPを解決してIPルールを続けて確認する設定です。これによりgeosite:cngeoip:cnを組み合わせられますが、DNSの結果がIPルールの判定に影響します。

  1. まず、明示的にブロックしたいプロトコルや宛先を処理し、後続の広範な直接接続ルールが先に処理しないようにします。
  2. 次にgeoip:privateを処理し、LANアドレスやプライベートアドレスを直接接続にします。
  3. 続いてgeosite:cnを照合し、ドメイン分類に基づいて直接接続へ振り分けます。
  4. ドメインに一致しない場合は、geoip:cnで解決後の宛先IPを確認します。
  5. 残りの通信がどのルールにも一致しなければ、outbounds配列の先頭にあるproxyへ送られます。
照合条件 例の値 宛先outbound 処理結果
protocol bittorrent block ブロックoutboundへ渡す
ip geoip:private direct LAN・プライベートアドレスは直接接続
domain geosite:cn direct 分類内のドメインに一致したら直接接続
ip geoip:cn direct 宛先IPに一致したら直接接続

ルール内のoutboundTagはプロトコル名ではなく、outboundオブジェクトのtagです。outboundタグがproxyなのに、ルールへProxyと書いても同じタグとはみなされません。outboundを削除・改名する場合は、ファイル全体を検索してすべての参照も更新してください。

結論:振り分けを変更するときは、1回に1つのルールだけ動かす

対象ドメインと想定する出口を先に記録し、1つのルールだけ位置を変更してログを確認します。ルールセット全体をコピーすると、ドメイン、IP、既定の出口が同時に変わり、異常の原因を特定しにくくなります。

DNSとログ:設定が正しくても振り分けが不安定になる理由

DNSはドメインをIPに変換するだけではありません。ドメインとIPを組み合わせて照合する場合、解決結果がルーティング判定に使われます。例ではサーバー一覧に1.1.1.1localhostを指定し、特定のDNSを使う方法とローカルのリゾルバーへ任せる方法を示しています。実際の環境では、到達性、解決結果、振り分け先に応じて適切な方法を選んでください。

loglevelwarningにすると、日常運用で警告とエラーを確認できます。ルールを調査するときは一時的にinfoへ変更して、より詳しい実行情報を取得してください。問題を確認したら元に戻し、ログの急増を避けます。JSON文字列は二重引用符で囲み、配列やオブジェクトの最後に余分なカンマを付けないでください。

{
  "log": {
    "access": "access.log",
    "error": "error.log",
    "loglevel": "info"
  },
  "dns": {
    "hosts": {
      "domain:internal.example.com": "192.168.1.20"
    },
    "servers": [
      "1.1.1.1",
      "localhost"
    ]
  }
}

よくある変更トラブル:エラー箇所からフィールドを特定する

設定を手動で変更すると、JSON構文の破損、フィールド階層の誤り、タグ参照の断絶という3種類の問題が起こりがちです。構文エラーは通常カーネルの起動を妨げます。階層を誤ると未知のフィールドと表示される場合があります。タグの誤りは、リクエストが実際にルールへ一致したとき初めて判明することもあります。調査はファイル、入口、通信経路の順に確認しましょう。

ポート変更後、ブラウザーがすぐ接続できなくなった場合は?

config.jsonのinbounds.portとブラウザーのプロキシポートを同時に確認します。たとえばinboundを10808から10818へ変更したのに、ブラウザーが10808を向いたままだと、新しい入口へリクエストを渡せません。

設定テストは通るのに、なぜすべての通信が直接接続になるのですか?

outboundsの先頭がdirectになっていないか確認します。ルールに一致しないリクエストは既定のoutboundを使います。既定でプロキシを使うなら、動作するプロキシoutboundを先頭に置くか、対象を明示したプロキシルールを追加してください。

geositeルールを追加しても、ドメインで振り分けられない場合は?

まず、より広範なIPルールより前に配置されているか確認し、次にdomainStrategyを確認します。アプリがドメイン名を渡さず宛先IPだけを送信している場合、ドメインルールは元のドメイン情報を取得できません。

ログにproxy outboundが見つからないと表示された場合は?

outbounds内でtagを検索し、値がproxyのオブジェクトが実際に存在することを確認します。タグは大文字・小文字を区別し、前後に空白を入れてはいけません。

v2rayNでノードをインポートした後も、JSON全体を手書きする必要がありますか?

通常は必要ありません。v2rayNがノードとパラメータ設定に基づいて実行用設定を生成します。ローカルポートを変更する場合は「設定」→「パラメータ設定」へ進んでください。カスタム設定、複雑なinbound、特殊なルーティングを使う場合に限り、JSONを項目ごとに管理します。

v2rayNGとv2flyNGでも、サブスクリプションや共有リンクからクライアントの実行に必要な設定が生成されます。v2rayNGはXrayカーネル、v2flyNGはv2flyカーネルを使用するため、画面上のフィールド名や利用できる通信機能はカーネルによって異なる場合があります。一方のクライアントが出力した完全な設定を、別のカーネル環境へそのまま上書きしないでください。少なくともプロトコル、通信フィールド、ルーティング用リソースの互換性を確認します。

  1. 現在正常に動作しているconfig.jsonをバックアップし、ローカルinboundポートを記録します。
  2. 毎回1つのブロックだけ変更し、保存後にまず設定テストを実行します。
  3. カーネルを起動し、127.0.0.1:10808が正常に待ち受けていることを確認します。
  4. 単一の宛先でプロキシoutboundをテストし、その後に直接接続ルールとブロックルールを確認します。
  5. ログの宛先アドレス、照合結果、接続エラーを確認し、問題がないことを確かめてから次の変更へ進みます。
V2Rayクライアントをダウンロード Windows、macOS、Android、Linux