この記事の概要

ノードを追加済みで、実際に使われる設定を理解したい方に向けた記事です。ローカルポートからinboundsを確認し、routingのタグからoutboundsをたどり、ノード情報・通信方式・クライアント設定を整理します。読み終えると、接続がどの段階で失敗しているか、「設定を読み込める」ことと「ノードに接続できる」ことの違いが分かります。

1. クライアント設定とコアの実行設定を区別する

config.jsonは通常、コアが読み込むJSONファイルを指します。ファイル名だけで中身が決まるわけではありません。v2rayNが保存するサーバー一覧、サブスクリプショングループ、画面設定はクライアント側の管理データです。コアの起動時には、選択中のサーバーやルーティング設定をもとに、クライアントが実行用の設定を生成します。共有リンクを1つだけエクスポートしても、inboundsやroutingを含む完全な設定にはなりません。

確認するときは、実際に使われている設定ファイルを基準にしてください。v2rayNはバージョンによってエクスポート方法や生成ファイルの保存場所が異なる場合があります。エクスポート対象がサーバー共有情報ではなく、完全な設定であることを確認しましょう。Android版のv2rayNGはXrayコア、v2flyNGはV2Flyコアを使用します。基本構造は似ていますが、拡張項目まで共通とは限りません。

アプリからのリクエストローカルinboundsルールに基づく振り分けoutboundsの選択接続先サービス

2. 個人情報を除いたconfig.jsonの全体例

以下はクライアントが出力する完全な設定の構成をもとにした例です。ローカルinboundsを2つ、outboundsを3つ、routingルールを2つ含み、アドレスや認証情報は例示用に置き換えています。完全なJSONドキュメントですが、接続可能なノードではありません。example.com:443にVMessサーバーが存在するわけではないため、このままネットワーク接続のテストには使えません。

{
  "log": {
    "loglevel": "warning"
  },
  "dns": {
    "servers": ["localhost"]
  },
  "inbounds": [
    {
      "tag": "socks-in",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": true
      }
    },
    {
      "tag": "http-in",
      "listen": "127.0.0.1",
      "port": 10809,
      "protocol": "http",
      "settings": {}
    }
  ],
  "outbounds": [
    {
      "tag": "proxy",
      "protocol": "vmess",
      "settings": {
        "vnext": [
          {
            "address": "example.com",
            "port": 443,
            "users": [
              {
                "id": "11111111-1111-4111-8111-111111111111",
                "alterId": 0,
                "security": "auto"
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "tcp",
        "security": "tls",
        "tlsSettings": {
          "serverName": "example.com"
        }
      }
    },
    {
      "tag": "direct",
      "protocol": "freedom",
      "settings": {}
    },
    {
      "tag": "block",
      "protocol": "blackhole",
      "settings": {}
    }
  ],
  "routing": {
    "domainStrategy": "AsIs",
    "rules": [
      {
        "type": "field",
        "domain": ["full:example.org"],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "ip": ["geoip:private"],
        "outboundTag": "direct"
      }
    ]
  }
}

3. inbounds:待ち受けアドレス・ポート・プロキシ方式

1つ目のinboundは127.0.0.1:10808でSOCKSリクエストを受け付け、2つ目は127.0.0.1:10809でHTTPプロキシリクエストを受け付けます。これらはこの記事のサンプルで指定したポートであり、お使いのクライアントと同じとは限りません。アプリに設定するポートは、アプリで選んだプロキシ方式によって決まります。接続先サイトがHTTPかHTTPSかで決まるものではありません。

SOCKS inbound

識別名
socks-in
待ち受けアドレス
127.0.0.1
ポート
10808
プロトコル
socks

アプリでSOCKS5を選んだ場合はこのポートを指定します。UDPを使うには、アプリから後続の接続経路まで対応している必要があります。

HTTP inbound

識別名
http-in
待ち受けアドレス
127.0.0.1
ポート
10809
プロトコル
http

アプリでHTTPプロキシを選んだ場合はこのポートを指定します。HTTPSサイトへの接続では、通常CONNECTでトンネルを確立します。

listenがループバックアドレスの場合、接続できるのは同じ端末上だけです。LAN内で共有するために0.0.0.0へ変更すると、待ち受け範囲が広がります。認証とファイアウォールもあわせて検討し、アドレスだけを変更しないでください。この例のSOCKS inboundにあるauth: "noauth"は認証を要求しない設定です。ローカル利用の範囲で使ってください。

udp: trueはSOCKS inboundでUDPを使えるようにする設定です。システム全体のUDP通信を自動でプロキシに送る機能ではなく、HTTP inboundにも同じ機能があるという意味ではありません。アプリがこのポートを使っていなければ、コアが起動しても期待するプロキシ接続は行われません。

4. outbounds:ノード情報・通信方式・出口タグ

outboundsは複数の出口を登録できる配列です。この例では、1つ目の出口にproxyというタグを付け、プロトコルにVMessを指定しています。vnext内のaddressとportは接続先サーバーのアドレスとポート、users内のidはユーザー認証情報です。ここでの443はリモートサーバーのポートで、ローカルの10808や10809とは役割が異なります。

項目この例の値確認ポイント
protocolvmessプロキシのプロトコルとsettingsの構造を決めます。
users[].securityautoVMessのユーザー設定における暗号化オプションです。TLSの設定ではありません。
users[].alterId0VMess AEADでよく使われる設定です。サーバー側の要件に合わせてください。
streamSettings.networktcpこの例で使う通信方式です。名称や指定できる値はコアのバージョンによって異なります。
streamSettings.securitytls通信層のTLSを有効にします。ユーザー層のsecurityとは役割が異なります。
tlsSettings.serverNameexample.comTLSで使うサーバー名と、証明書名の検証に使用します。

directはfreedomで接続先へ直接アクセスし、blockはblackholeで通信を拒否します。これらは単なるタグ名で、実際の動作はprotocolで決まります。freedomのタグを「proxy」に変えても、リモートプロキシにはなりません。この例ではblockを参照するルールがないため、outboundを定義しただけではリクエストは遮断されません。

設定の互換性を判断する:まずプロトコル、次にコアの項目を確認

VMessのprotocolをVLESSに変更して、そのまま実行しないでください。両者ではユーザー情報や暗号化に関するフィールド構造が異なります。REALITYなどの拡張機能を使う場合は、ファイル名だけで判断せず、実行中のXrayコアが該当フィールドに対応していることも確認してください。

5. routing:ルールの順序・tagの参照・デフォルトの出口

routingルールは上から順に確認され、条件に一致すると、そのルールで指定した出口が選ばれます。この例の1つ目のルールは、完全一致するドメインexample.orgだけをdirectへ送ります。full:はドメイン全体との完全一致を表し、サブドメインには一致しません。2つ目のルールは、プライベートアドレス範囲に一致する接続先を同じ出口へ送ります。どのルールにも一致しない接続には、outboundsの先頭にあるproxyが使われます。

  1. 接続先がドメインexample.orgの場合:1つ目のルールに一致し、tag: "direct"のoutboundが選ばれます。
  2. 接続先が192.168.1.20の場合:2つ目のプライベートアドレスルールに一致し、LAN内の接続先へ直接アクセスします。
  3. 接続先がほかのルールに一致しないドメインの場合:先頭のoutboundproxyが選ばれ、サンプルのVMessサーバーへの接続を試みます。

outboundTagはoutboundのtagと大文字・小文字も含めて完全に一致させる必要があります。inboundのタグは、ルールのinboundTag配列で条件に使えます。たとえば["socks-in"]からの接続だけを対象にできます。inboundとoutboundのタグが自動で対応付けられるわけではなく、同じ名前にする必要もありません。

この例ではdomainStrategy: "AsIs"を指定しているため、ルーティング時にIPルールを適用する目的でドメイン名を積極的にIPアドレスへ解決しません。接続がドメイン名のまま渡される場合、2つ目のプライベートIPルールでは、最終的な接続先がLAN内のアドレスかどうかを判定できないことがあります。この動作が必要な場合は、IPIfNonMatchやIPOnDemandで名前解決が行われるタイミングを理解し、DNS設定と合わせて調整してください。すべてのドメインリクエストに接続先IPがあると決めつけないようにしましょう。

ルーティングを変更する前に、先頭のoutboundを記録する

directを配列の先頭へ移動すると、どのルールにも一致しない接続のデフォルト出口が変わります。ルールの変更とoutboundの並べ替えは分けて行い、一度に1か所だけ変更してください。デフォルトが直接接続になった状態を、ルールが機能していないと誤解しないためです。

6. dnsとlog:「読み込める」ことと「接続できる」ことは別

この例のdns.serversではlocalhostを指定しています。名前解決が必要な場合に、内蔵DNSからシステムの名前解決機能を利用できる設定です。ローカルでDNSサーバーのポートを開く設定ではなく、アプリからほかのDNSサーバーへ送られるリクエストを自動で引き受けるものでもありません。ルーティング用、outbound用、アプリ自身の名前解決はそれぞれ異なる段階で行われるため、実際のinbound方式とあわせて確認してください。

loglevel: "warning"では、通常の接続情報が少なくなります。問題を調べる間だけinfoに変更し、コアを再起動して失敗するリクエストを一度再現してください。確認後は元に戻します。ログにはアクセス先のドメイン、接続先アドレス、設定ファイルのパスが含まれる場合があります。公開の場で相談する前に、サブスクリプションURL、ユーザー認証情報、個人用のパスを削除してください。

7. config.jsonのよくある質問

ファイルを開けるのに、コアが設定エラーを出すのはなぜ?

テキストエディターで開けても、正しいJSONとは限りません。末尾のカンマ、二重引用符、括弧を確認し、ログを手がかりに問題の項目を特定してください。構文が正しくても、現在のコアが対応している形式か確認が必要です。たとえばoutboundのオブジェクトを誤ってinbounds配列に入れることはできません。

HTTPプロキシの設定に10808を入力すると、接続に失敗するのはなぜ?

この例では10808がSOCKS用、10809がHTTPプロキシ用です。アプリでSOCKS5を選び10808を指定するか、HTTPのまま10809を使ってください。実際に設定する前に、ご自身の実行設定でポート番号を確認してください。

設定にproxyがあるのに、通信が直接接続されるのはなぜ?

まず、アプリがローカルinboundに実際に接続しているか確認し、次に一致したルールがdirectを指定していないか確認してください。proxyはタグ名にすぎず、システムプロキシを自動で有効にするものではありません。クライアントのシステムプロキシ設定と、コアのルーティング設定は別々に確認します。

デスクトップの完全な設定をAndroidクライアントにそのまま読み込める?

まず、移行先のクライアントが対応するコアの項目とインポート方法を確認してください。デスクトップ向けの待ち受けポート、ログの保存先、ルーティングデータは、Android環境でそのまま使えない場合があります。サーバー情報だけを同期するなら、サブスクリプションまたはノード共有情報を読み込み、移行先のクライアントでローカル待ち受けとルーティングを設定してください。実行設定全体を上書きするのは避けましょう。