V2Rayのサブスクリプション形式を解説:Base64・JSON・共有リンクの変換方法

V2Rayのサブスクリプションで使われるBase64リスト、JSON設定、vmess://共有リンクの違いと、クライアントごとの読み込み方・変換方法を解説します。

この記事の要点

サブスクリプションURLは接続先を取得する入口、Base64はデータの表現方法、共有リンクは単一サーバーの接続情報、JSON設定は実行環境全体を含む場合があります。「更新できたのにサーバーが表示されない」「JSONを読み込めない」「クライアントを移行したい」といった場合は、まず応答内容を見分け、適切な読み込み方法を選びましょう。変換できる項目と個別に引き継ぐ設定を把握することも大切です。

1. サブスクリプションURL・応答内容・プロトコルを区別する

一般にサブスクリプションリンクとは、HTTPSでデータを取得するためのURLです。クライアントがURLにアクセスし、サーバー一覧や設定テキストを取得して解析します。URLにアクセストークンが含まれることもありますが、URL自体がVMessやVLESSのプロトコルというわけではありません。末尾の文字列だけで応答形式を判断することもできません。同じURLでも、リクエストのパラメーターやクライアントの識別情報によって異なる内容が返る場合があります。

よくあるサーバー一覧は、vmess://やvless://で始まる共有リンクを複数並べたものです。1行に1つずつ記載したリストは、そのまま返すことも、全体をBase64でエンコードすることもできます。一方、JSON形式で応答するケースもあります。ただし、JSONとして解析できることは構文が正しいというだけで、クライアントがサーバー一覧として扱うのか、完全な設定として扱うのかは別の問題です。

形式見分けるポイント一般的な内容使う読み込み方法
プレーンテキストの共有リンク一覧各行がプロトコルの接頭辞で始まる複数サーバーの接続情報共有リンクまたはクリップボードから読み込む
Base64リストデコードすると複数行の共有リンクになるプレーンテキストのリストと同じ内容その形式に対応した方法でサブスクリプションを更新
JSON形式のネイティブ設定トップレベルのキーはinbounds、outboundsなどインバウンド、アウトバウンド、DNS、ルーティングなどの設定カスタム設定または設定ファイルから読み込む

2. Base64は表現方法を変えるだけで、プロトコルの機能は変わらない

Base64はバイト列を扱いやすいテキストに変換する方式であり、データを秘匿するものではありません。日本語を含む文字列は、まずUTF-8のバイト列に変換してからBase64にエンコードします。元に戻すときは、先にバイト列を復元し、その後UTF-8としてデコードします。日本語を含む文字列に対してブラウザーのbtoa()を直接実行すると、エラーになったり誤った結果になったりすることがあります。

3 → 4
3バイトを4文字に変換し、末尾にパディングが付く場合がある
2段階
外側のリストと内側のVMessデータがそれぞれエンコードされている場合がある
443
以下のTLS例にあるポート番号は説明用で、形式を見分ける条件ではない

標準Base64では+や/が使われ、末尾に=が付くことがあります。URLセーフ形式では前者が-と_に置き換わり、パディングが省略されることもあります。こうした違いに対応するクライアントもありますが、空白や欠落、余分な引用符まで自動で修正されるとは限りません。

要点:まず1段階デコードし、結果を見て読み込み方法を選ぶ

デコード結果が複数行の共有リンクなら、リンク一覧の読み込み方法を使います。インバウンド、アウトバウンド、ルーティングを含むオブジェクトなら、カスタム設定から読み込めるか確認してください。エンコードの段数は、プロトコルの互換性を示すものではありません。

3. VMess共有リンクのJSONとネイティブ設定は別の形式

従来形式のVMess共有リンクは通常、「vmess://にBase64エンコードしたJSONを続ける」形式です。以下は形式を説明するための例であり、接続可能なサーバー情報でも、コアで実行できる設定でもありません。ドメインには予約済みの例示用ドメインを使い、ポート443はTLSの例として記載しています。

{
  "v": "2",
  "ps": "形式の例",
  "add": "example.invalid",
  "port": "443",
  "id": "123e4567-e89b-42d3-a456-426614174000",
  "aid": "0",
  "scy": "auto",
  "net": "ws",
  "type": "none",
  "host": "example.invalid",
  "path": "/edge",
  "tls": "tls",
  "sni": "example.invalid"
}

ここでのvは共有リンク形式の識別子で、クライアントのバージョンではありません。psはメモ、add、port、idはそれぞれアドレス、ポート、ユーザー識別情報に対応します。netは通信方式を表し、この例ではhostとpathがWebSocket用、sniがTLSのサーバー名に使われます。それぞれ役割が異なるため、値が同じでも同じフィールドとはみなせません。

共有リンク側のフィールドネイティブ設定での主な配置先変換時の注意点
add、portoutbounds[].settings.vnext[]内のアドレスとポートネイティブ設定ではポートは通常数値で指定します。文字列のままコピーしないでください。
id、scyVMessアウトバウンドのユーザー項目にあるid、securityフィールド名は完全には一致しないため、コアの設定仕様に合わせて対応付ける必要がある
net、pathstreamSettingsと対応する通信設定対応する通信方式に合ったフィールドだけが解釈される
tls、snistreamSettings.securityとTLS設定プロトコルの暗号化パラメーターとTLS設定は別のレイヤーに属する

ネイティブJSONには複数のアウトバウンドが定義され、ルーティングルールによって出口が選択される場合があります。そのうち1つのノードだけを書き出しても、DNS、振り分けルール、インバウンドの待ち受けアドレス、アウトバウンド間の経路などは通常引き継がれません。そのため「ネイティブJSONから共有リンクへの変換」は、接続情報の抽出にすぎず、完全な設定を可逆的に圧縮するものではありません。

4. ローカルで形式を変換する:まずテキストを処理し、次に設定の意味を確認

「共有リンク一覧をBase64に変換する」「Base64から一覧を復元する」といった処理は、ローカルで完結するエンコード操作です。以下のJavaScriptはテキスト処理関数を定義するだけで、ネットワークへのリクエストは行いません。自分で用意したローカルの空白ページで開発者ツールを使って実行してください。見知らぬサイトのコンソールに実際のサブスクリプション内容を貼り付けたり、提供元不明の変換スクリプトを実行したりしないでください。

function encodeUtf8Base64(text) {
  const bytes = new TextEncoder().encode(text);
  const binary = Array.from(bytes, byte =>
    String.fromCharCode(byte)
  ).join("");
  return btoa(binary);
}

function decodeUtf8Base64(input) {
  let text = input.trim()
    .replace(/\s+/g, "")
    .replace(/-/g, "+")
    .replace(/_/g, "/");

  if (!/^[A-Za-z0-9+/]*={0,2}$/.test(text)) {
    throw new Error("想定したBase64テキストではありません");
  }

  if (text.length % 4 === 1) {
    throw new Error("長さが不正です。コピーが完全か確認してください");
  }

  text += "=".repeat((4 - text.length % 4) % 4);
  const binary = atob(text);
  const bytes = Uint8Array.from(binary, char =>
    char.charCodeAt(0)
  );
  return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
}

function packShareList(links) {
  return encodeUtf8Base64(links.join("\n"));
}

function makeClassicVmessLink(shareObject) {
  return "vmess://" + encodeUtf8Base64(JSON.stringify(shareObject));
}

// UTF-8の往復変換だけを確認し、実際のサブスクリプション認証情報は使わない。
const sample = "日本語のメモ\n2行目";
console.assert(
  decodeUtf8Base64(encodeUtf8Base64(sample)) === sample
);
  1. リストを復元:応答テキストにdecodeUtf8Base64()を実行し、出力が本当に1行ずつの共有リンクになっているか確認します。この関数はプロトコルの判定や、破損した内容の修復は行いません。
  2. リストをエンコード:完全なURIを1つずつ配列に入れ、packShareList()に渡します。各項目の区切りは改行です。複数のURIを区切りなしで連結してはいけません。
  3. VMessリンクを生成:入力オブジェクトが従来形式のVMess共有フィールドに合致する場合に限り、makeClassicVmessLink()を使います。任意のネイティブ設定から正しいノードを自動生成する関数ではありません。
  4. 結果を確認:まずクライアントにテスト用の項目として読み込み、アドレス、ポート、UUID、通信方式、TLS、サーバー名を1つずつ照合してから接続を試してください。

ネイティブ設定を共有リンクに変換するには、意味を理解したうえで変換する仕組みが必要です。書き出すアウトバウンドを選び、プロトコルと通信方式を判別してフィールドを対応付け、変換先の共有形式ですべてのパラメーターを表現できるか確認します。表現できないフィールドがあれば変換を中止するか、欠落項目を記録してください。無言で削除して変換成功とみなしてはいけません。

5. 3種類のクライアントで適切な読み込み方法を選ぶ

まず用途に合わせて選びます。継続的に更新するサーバー一覧にはサブスクリプション、単一ノードの一時的な移行には共有リンク、DNS、ルーティング、アウトバウンドを細かく制御する場合はネイティブJSONが適しています。クライアントの画面は読み込みや管理を担い、コアはプロトコルを実行します。それぞれの対応範囲を確認してください。

サブスクリプションから読み込む

おすすめ

サブスクリプションURLを保存し、クライアントから定期的または手動でサーバー一覧を取得します。更新しやすい一方、サーバー側の応答形式が現在の読み込み機能に対応している必要があります。

おすすめの用途:日常的に更新されるサーバー一覧の管理。

共有リンクから読み込む

クリップボードからURIを1つまたは複数読み込めるため、パラメーターの確認に便利です。通常、元のサブスクリプションとの更新関係は引き継がれません。

おすすめの用途:一時的なテスト、単一ノードの移行、形式のトラブル調査。

カスタム設定から読み込む

クライアントが提供するカスタム設定機能を使って、ネイティブJSONを読み込みます。実際に使うコアに合った設定が必要です。ルーティングやDNSをどのように適用するかも個別に確認してください。

おすすめの用途:完全な設定をすでに持っていて、高度なアウトバウンドやルーティングを維持したい場合。

v2rayNはデスクトップ向け、v2rayNGはXrayコアを使うAndroidクライアント、v2flyNGはv2flyコアを使うAndroidクライアントです。VMess共有リンクは広く使われる交換形式ですが、通信方式や拡張パラメーターへの対応はバージョンによって異なります。特にXray向けの拡張設定が、v2flyコアでもそのまま動くとは限りません。

  1. 元の設定を残す

    現在使えている項目と元の応答内容を先に保存してください。トラブル調査には独立したサブスクリプショングループを使い、サーバーをすべて削除するのは避けましょう。

  2. デスクトップでサブスクリプションを追加

    v2rayNでは一般に「サブスクリプショングループ」→「サブスクリプショングループの設定」→「追加」の順に進み、メモとURLを入力して保存します。その後、「サブスクリプショングループ」メニューから更新します。プラットフォームやバージョンによって画面やボタンの表記が多少異なる場合があります。

  3. Androidでサブスクリプションを追加

    v2rayNGでは通常、右上のメニュー「⋮」→「サブスクリプショングループの設定」→「+」の順に進みます。保存後、メイン画面に戻り、「⋮」→「サブスクリプションを更新」で項目を取得します。サブスクリプションURLをサーバーアドレス欄に入力しないでください。

  4. 単一リンクで比較する

    v2rayNでは「サーバー」メニューからクリップボード経由の読み込みを選びます。v2rayNGでは通常、メイン画面の「+」→「クリップボードからインポート」を使います。同じ共有リンクを試すと、サブスクリプションの取得障害とノードの解析障害を切り分けられます。

  5. コアの対応状況を確認

    v2flyNGでは、サブスクリプション設定またはクリップボードからの読み込み機能を使い、該当パラメーターがv2flyでサポートされているか確認します。ネイティブJSONは、そのバージョンで提供されているカスタム設定機能から読み込みます。サブスクリプションURLの欄に直接貼り付けてはいけません。

6. 読み込みに失敗したら、取得・解析・実行の段階ごとに確認

更新完了の表示から分かるのは、更新処理が最後まで進んだことだけです。すべての項目が正常に解析されたとは限りません。反対に、項目が一覧に表示されても、通信方式やTLSのパラメーターが正しいとは限りません。エラーが起きた段階を特定するほうが、エンコード方式を何度も変えるより効果的です。

症状まず確認すること次に行うこと
サブスクリプションの取得に失敗するURLが完全か、トークンが無効になっていないか、401や403が返っていないかサービス提供元で利用権限を確認します。権限を回避する目的で変換を試してはいけません。
200が返るのに項目がないログイン画面、エラーJSON、非対応形式が応答に含まれていないか応答本文の形式を判別し、適切な読み込み方法に切り替えます。
Base64のデコードでエラーになるテキストが途中で切れていないか、引用符が混入していないか、その形式に対応しているか元のテキストを再コピーし、長さと実際の応答内容を確認します。
JSONを解析できるのに読み込めない共有オブジェクト、設定ファイル、APIのエラーオブジェクトを混同していないかトップレベルのキーと、クライアントが想定する構造を確認します。
項目は表示されるが接続できないポート、UUID、通信方式、TLS、SNI、パス元の設定と各項目を照合し、ネットワークに到達できるか確認します。
ネイティブJSON全体をBase64にすれば、汎用サブスクリプションになる?

なりません。エンコードしてもデータ構造は変わりません。デコード後もネイティブ設定のままです。共有リンク一覧しか受け付けないクライアントでは、引き続き一覧として解析できません。その設定に対応した読み込み方法を使うか、表現可能なノード情報だけを選んで取り出してください。

共有リンクを読み込んだら、元のルーティングルールが消えるのはなぜ?

共有リンクが表すのは通常、単一ノードであり、ルーティング全体は含まれません。クライアント側の振り分け設定とネイティブ設定内のルールも、別々の管理レイヤーに属する場合があります。移行する前に、DNS、ルーティング、インバウンド、その他のアウトバウンド設定をそれぞれ保存してください。

サブスクリプション更新後に、手動で変更した項目が元に戻るのはなぜ?

サブスクリプションの項目はリモート側の内容が優先されることが多く、更新時にローカルの項目が再作成または上書きされる場合があります。長期的に残したい変更は別の設定として保存し、元のサブスクリプションに連動して更新されないことを把握しておきましょう。

要点:変換の手軽さより、必要な項目を漏れなく保つ

サービス提供元が明示的に対応しているサブスクリプション形式を優先してください。移行が必要な場合は、まず1つのノードで変換結果を検証し、ルーティングとDNSは別に保存します。正常に使えることを確認してから、まとめて処理しましょう。

v2rayN をダウンロード対応プラットフォームとインストーラーを確認