この記事の要点

サブスクリプションURLはデータの取得先、Base64はテキストのエンコード方式、共有リンクは個別ノード、JSON設定はコアの動作設定を表します。「インポートに失敗する」「変換したらルールが消えた」「クライアントによって結果が違う」といった場合は、まずデータの種類を見分け、適切な方法で取り込みましょう。変換後は転送方式、TLS、DNS、ルーティングの設定が保持されているかも確認してください。

1. サブスクリプションURL・エンコード・ノード設定は別のもの

「V2Rayサブスクリプション」に統一された厳密なファイル形式があるわけではありません。クライアントはまずサブスクリプションURLにアクセスし、サーバーから返された本文を解析します。よくあるのは、共有リンクが複数行並んだ形式、またはそれらをまとめてBase64エンコードした形式です。JSONを直接返すサービスもあります。URLがHTTPSで始まっていても、それは取得方法を示すだけで、本文を特定のインポーターが認識できるとは限りません。

対象主な特徴含まれる内容インポート方法
サブスクリプションURLHTTPSアドレス。アクセストークンが含まれる場合もあるリモートコンテンツの取得先サブスクリプショングループの設定
Base64形式のサブスクリプション本文デコードすると、通常は1行につき1つのリンクノードの一覧。ローカルのポリシー設定は含まれないことがあるサブスクリプション更新時に解析
共有リンクvmess:// または vless://1つのノードとその接続パラメータークリップボードからインポート
JSON設定inbounds、outboundsなどのキーインバウンド、アウトバウンド、必要に応じてDNSやルーティングカスタム設定からインポート

JSONはあくまで構文であり、設定の種類を示すものではありません。add、id、netなどを含むVMess共有オブジェクトは、JSONとして正しくても、そのまま完全なXray設定として実行できるとは限りません。反対に、完全な設定をBase64エンコードしても、クライアントが対応するノードサブスクリプションに自動変換されるわけではありません。

2. Base64サブスクリプション:デコードしてから行ごとに解析

従来のノードサブスクリプションでは、複数の共有リンクを改行で連結し、そのUTF-8テキスト全体をエンコードする形式がよく使われます。クライアントは本文を取得したあと、テキストに戻してから各行のプロトコルを判別します。VMessでは、個々のリンクの中にもBase64エンコードが含まれることがあります。そのため、外側のサブスクリプションをデコードできても、各ノードの情報が有効とは限りません。

  1. 本文を取得:ログイン画面やアクセス制限の案内、サーバーエラーではなく、サブスクリプションの内容が返っていることを確認します。
  2. 外側の形式を確認:本文がすでに共有リンクで始まっている場合は、まずプレーンテキストとして扱い、むやみに再デコードしないでください。
  3. デコード:外側のBase64を戻し、1行に1つのリンクが並ぶテキストになるか確認します。
  4. ノードを解析:各行のプロトコルを判別し、サーバーアドレス、ポート、ユーザー識別子、転送パラメーターを確認します。

標準Base64では+や/が使われ、末尾に=が付くことがあります。URLセーフ形式では-や_が使われたり、末尾のパディングが省略されたりします。インポーターによって許容範囲は異なります。「イコールがない」だけでサブスクリプションが壊れているとは判断できません。また、Base64全体をURLエンコードとして扱わないでください。

// ローカルJavaScriptの例:入力は取得済みの複数行共有リンクテキスト。
// TextEncoder / TextDecoderを使い、日本語のノード名を保持します。
function encodeSubscription(text) {
  const bytes = new TextEncoder().encode(text);
  let binary = "";
  for (const byte of bytes) {
    binary += String.fromCharCode(byte);
  }
  return btoa(binary);
}

function decodeSubscription(encoded) {
  let normalized = encoded.replace(/\s/g, "")
    .replace(/-/g, "+")
    .replace(/_/g, "/");
  normalized += "=".repeat((4 - normalized.length % 4) % 4);
  const binary = atob(normalized);
  const bytes = Uint8Array.from(binary, char => char.charCodeAt(0));
  return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
}

このコードはテキストを変換するだけで、サブスクリプションの取得やノードの接続確認は行いません。デコードに失敗した場合は、内容が途中で切れていないか、説明文まで一緒にコピーしていないかを確認してください。デコードできても、対応プロトコルを扱えるクライアントで解析する必要があります。ブラウザーで日本語をそのままbtoa()に渡すとエラーになることがあるため、この例では先にUTF-8バイト列へ変換します。

3. VMess・VLESS共有リンク:パラメーターを対応づける

よく使われるvmess://共有形式では、プロトコルの接頭辞の後にJSONオブジェクトをBase64エンコードして付けます。以下はエンコード前のオブジェクトです。一般的な共有形式の例であり、完全なコア設定ではありません。ドメインとUUIDは構造を説明するためのもので、実際に利用できるノードではありません。

{
  "v": "2",
  "ps": "VMess WSの例",
  "add": "node.example.org",
  "port": "443",
  "id": "2d1e7e18-49f4-4ab7-8b63-c929d11c5e29",
  "aid": "0",
  "scy": "auto",
  "net": "ws",
  "type": "none",
  "host": "node.example.org",
  "path": "/proxy",
  "tls": "tls",
  "sni": "node.example.org"
}

vは共有オブジェクトの形式を示す値で、クライアントのバージョンではありません。psはメモ、addとportは接続先、net、host、pathは転送方式の情報です。ここでのaidは0ですが、VLESSにも同名のパラメーターがあるという意味ではありません。共有リンクの実装によっては一部の項目が省略されます。インポート後、ノード編集画面で内容を確認してください。

VLESS共有リンクには、URI形式がよく使われます。ユーザー識別子は@の前、サーバーとポートはその後ろに置かれ、クエリパラメーターで転送方式やセキュリティ設定を指定します。#以降はメモです。以下では、後述のJSONと同じパラメーターを使います。

vless://[email protected]:443?encryption=none&security=tls&type=ws&host=node.example.org&path=%2Fproxy&sni=node.example.org#Example-WS

ポイント:プロトコル名ではなく、パラメーターを対応づける

vmess://をvless://に書き換えても、プロトコルは変換できません。別のプロトコルのリンクを作るには、サーバー側がそのプロトコルに対応するパラメーターを提供している必要があります。同じノードを別形式で表す場合も、転送方式、セキュリティ層、認証情報を保持してください。

4. JSON設定:ノード情報に加えて実行環境も含む

ネイティブXray設定は、プロセス全体の動作を記述します。インバウンドはローカルアプリからの接続方法、アウトバウンドはサーバーへのリクエスト送信方法を指定し、ルーティングとDNSは振り分けや名前解決を制御します。以下は項目を比較するための最小構成で、VLESS、WebSocket、TLSを使用しています。例示用のアドレスでは実際に接続できません。

{
  "log": {
    "loglevel": "warning"
  },
  "inbounds": [
    {
      "tag": "local-socks",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": true
      }
    }
  ],
  "outbounds": [
    {
      "tag": "proxy",
      "protocol": "vless",
      "settings": {
        "vnext": [
          {
            "address": "node.example.org",
            "port": 443,
            "users": [
              {
                "id": "2d1e7e18-49f4-4ab7-8b63-c929d11c5e29",
                "encryption": "none"
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "ws",
        "security": "tls",
        "tlsSettings": {
          "serverName": "node.example.org"
        },
        "wsSettings": {
          "path": "/proxy",
          "headers": {
            "Host": "node.example.org"
          }
        }
      }
    }
  ]
}
10808
ローカルSOCKSインバウンドのポート例
443
リモートTLSサーバーのポート例

この2つのポートは役割が異なります。10808はローカルのループバックアドレスにバインドする例で、すべての端末で同じ設定とは限りません。443はリモートサーバーの待受ポートで、サーバー側の設定と一致させる必要があります。ローカルで同じアドレスとポートを別のプロセスが使用していると、2つ目の設定は起動に失敗することがあります。

5. v2rayN・v2rayNG:適切な方法でインポート

画面上のメニュー名は、バージョンや表示言語によって変わります。以下では一般的な中国語(簡体字)メニュー名をもとに説明します。操作前に、クリップボードの内容がサブスクリプションURL、単一ノードのリンク、完全なJSON設定のどれかを確認してください。HTTPSのサブスクリプションURLを通常のノードリンクとしてインポートしないよう注意しましょう。

v2rayN:サブスクリプショングループと単一ノードを分けてインポート

  1. サブスクリプショングループを追加

    メイン画面で「サブスクリプショングループ」→「サブスクリプショングループ設定」を開き、一覧の「追加」を選択します。メモとサブスクリプションURLを入力して保存してください。URLのクエリパラメーターはすべて保持します。

  2. サブスクリプションを更新

    「サブスクリプショングループ」メニューに戻り、現在のサブスクリプションまたはすべてのサブスクリプションを更新します。プロキシ経由・プロキシなしを選べる場合は、現在のネットワークで接続できる方法を選び、更新ログを確認してください。

  3. 単一ノードをインポート

    vmess://またはvless://のリンク全体をコピーし、メイン画面の「サーバー」→「クリップボードから一括URLインポート」を選びます。一般的なショートカットはCtrl+Vです。

  4. 接続設定を確認

    ノード編集画面を開き、アドレス、ポート、UUID、転送方式、パス、TLSサーバー名を確認します。インポート成功は解析が完了したことを示すだけで、サーバーへの接続を保証するものではありません。

v2rayNG:サブスクリプショングループとクリップボードからのインポート

6. 形式の変換:保持したい情報で選ぶ

「変換に成功したか」は、少なくとも3つの基準に分けて考える必要があります。テキストをデコードできるか、クライアントにインポートできるか、期待どおりに接続できるかです。最初の2つを満たしても、ルーティング、DNS、フィンガープリント、拡張された転送パラメーターが失われることがあります。変換ボタンを探す前に、何を移行するのかを決めると、トラブルシューティングを効率よく進められます。

共有リンクでノードを移行

おすすめ

クライアントの共有・リンクコピー機能でエクスポートし、移行先のクライアントにインポートします。完了後、転送方式とTLSの設定を一つずつ確認してください。ローカルのルーティングとDNSは別途移行します。

適した用途:端末間で単一ノードを移行する、少数の接続先を整理する

サブスクリプションURLで一覧を管理

移行先のクライアントにサブスクリプションURLを追加し、解析と更新を任せます。本文を固定のリンク一覧に変換すると、その時点のスナップショットになるだけで、リモートからの自動更新は引き継がれません。

適した用途:ノードが頻繁に変更され、継続的な更新が必要なグループ

JSON設定でポリシーを保持

互換性のあるコア間で設定を移行し、ファイル参照、ポート、システム権限、対応する設定項目を一つずつ確認してください。カスタム設定をインポートした場合、クライアント画面の一部のオプションがその設定に反映されないことがあります。

適した用途:複数のアウトバウンド、カスタムDNS、複雑なルーティングを含む設定

移行後はまずログを確認し、設定の解析エラーや待受エラーがないか調べてから、ノードを1つ選んで実際の接続をテストします。デスクトップでは、システムプロキシまたはアプリ内プロキシが実際のインバウンドを参照しているかも確認してください。Androidでは接続サービスが起動していることを確かめ、システムの案内に従ってVPNインターフェースの権限を許可します。速度測定ができることと、ブラウザーの通信がプロキシを通ることは、別々の確認項目です。

7. インポート・変換に関するよくある質問

サブスクリプションURLを開けるのに、更新するとノードが0件なのはなぜ?

まず、レスポンス本文がHTMLページ、エラーメッセージ、またはクライアント非対応の形式ではないか確認します。ブラウザーでURLにアクセスできても、ノード一覧が返っているとは限りません。トークンの有効期限を確認し、クライアントの更新ログに解析エラーがないか調べてください。

Base64をデコードしてもvmessで始まります。さらにデコードが必要ですか?

外側のサブスクリプションはすでにデコードされています。一般的な形式では、各行のvmess://以降にもエンコードされたデータがありますが、解析するのはプロトコル接頭辞の後ろにあるペイロードだけです。複数行の一覧全体をもう一度まとめてデコードしないでください。通常のインポートでは、クライアントがこの処理を行います。

JSONの検証に通ったのに、コアが起動しないのはなぜ?

構文が正しくても、設定項目が有効とは限りません。まず、VMess共有オブジェクトと完全な設定を区別し、コアがプロトコルや設定項目に対応しているか確認してください。ログに待受失敗が出ている場合は、サブスクリプションのエンコード方式を何度も変えるのではなく、ローカルポートが使用中でないか調べます。

リンクに変換したら、元のルーティングルールが消えたのはなぜ?

単一ノードの共有リンクに含まれるのは、通常、接続パラメーターだけです。ルーティングを戻すには、移行先のクライアントでルーティングとDNSを再設定するか、互換性のある完全な設定を使って移行してください。ローカルのポリシーが含まれないことと、ノードの認証情報が失われることは別の問題です。

インポートは成功しましたが、TLSまたはハンドシェイクエラーが出ます。どうすればよいですか?

ノード編集画面を開き、サーバーの情報と照らし合わせて、ポート、転送方式、SNI、WebSocketのHostとパスを確認します。端末の日時が正しいことも確かめてください。設定項目を修正せずに証明書検証を無効にするのは避けましょう。元のリンクでも接続できない場合は、サーバーの状態とネットワーク接続を引き続き確認してください。