V2Rayのサブスクリプション形式を解説|Base64・JSON設定・共有リンクの変換

V2Rayのサブスクリプション形式と対応クライアントを解説。Base64のデコード方法、VMess・VLESS共有リンクとJSON設定の違い、インポートできない原因を紹介します。

この記事の概要

サブスクリプションURLは設定情報の取得先、Base64はテキストのエンコード方式、共有リンクは個別ノードの情報、JSONはコアの設定を表します。「サブスクリプションが空」「JSONをインポートできない」といった問題や、ノードの移行に直面している場合は、まずレスポンス形式を確認し、ローカルでデコードしたうえで、プロトコル・通信方式・TLSの各項目を照合しましょう。変換で変わるのは表現形式だけです。不足しているサーバー情報は補えず、異なるコア間で同じ機能が使えるとも限りません。

1. サブスクリプションURL・共有リンク・JSON設定の違い

「V2Rayサブスクリプション」は、特定のファイル拡張子を指す言葉ではありません。クライアントがHTTPSのURLにアクセスすると、Base64テキスト、1行ごとの共有リンク、JSONのほか、ログインページが返ることもあります。形式を判断するときは、URLが.txtや.jsonで終わるかではなく、実際のレスポンス本文を確認してください。

クライアントで利用するサブスクリプションURL

おすすめ

v2rayN、v2rayNG、v2flyNGでノード一覧を取得します。サービス提供元のレスポンス形式がクライアントに対応している必要があります。更新後もグループ分けを維持できるため、ノードを毎回手作業でコピーする必要はありません。

用途:定期更新、複数端末でのサブスクリプショングループ管理

1行ごとの共有リンク

1行につき1つのノード情報が記載され、一般的な接頭辞はvmess://、vless://です。個別ノードのトラブルシューティングに適しています。まとめてインポートした場合は通常、その時点のスナップショットとなり、元のサブスクリプションの更新設定は引き継がれません。

用途:オフラインでの移行、特定ノードの設定項目の確認

コアのネイティブJSON

インバウンド、アウトバウンド、DNS、ルーティングルールなどをまとめて含む場合があります。汎用のノード一覧ではないため、通常はクライアントのカスタム設定から読み込み、使用するコアに合った設定構造にする必要があります。

用途:DNS、ルーティング、複数のアウトバウンド設定を維持

クライアントとコアは分けて考えましょう。v2rayNはデスクトップクライアントです。v2rayNGはXrayコア、v2flyNGはV2Flyコアを使用します。リンクをインポートできても、クライアントがテキストを認識したというだけで、現在のコアがリンクに記載された機能をすべてサポートするとは限りません。特にREALITYや特定のフロー制御を使う場合は、Base64を何度もエンコード・デコードするのではなく、コアの対応状況を確認してください。

2. レスポンス形式を見極めてからデコードする

信頼できるローカルツールでレスポンスを確認し、先頭の空白を取り除いて最初の内容を見ます。サブスクリプションURLのトークンはアカウントへのアクセスに使われることがあります。URL全体やレスポンス本文、QRコードをオンライン変換サービスに送らないでください。ブラウザーに認証画面、ログインフォーム、エラーページが表示された場合は、まずアクセスの問題を解決しましょう。

表示された内容考えられる形式次の手順
vmess:// または vless://プレーンテキストの共有リンク一覧行ごとにインポートし、本文全体はデコードしない
英数字と一部の記号が長く続くBase64でエンコードされた一覧の可能性ローカルで一度デコードし、プロトコルの接頭辞が現れるか確認する
{ または [JSONの可能性まず構造を解析し、APIレスポンス・ノード情報・完全な設定ファイルを見分ける
<!DOCTYPE html> または <htmlWebページまたはアクセス制限のレスポンスURL、ログイン状態、サブスクリプションの有効期限を確認する

HTTPステータスコードが200でも、リクエストが正常に応答したことを示すだけで、本文がノード情報とは限りません。JSONとして正しくても、エラーコードや案内文しか含まれていない場合があります。プロキシを切り替えたりポートを変更したりする前に、内容を確認して適切なインポート方法を選びましょう。

3. Base64のサブスクリプションを1行ごとの共有リンクに戻す

従来の一般的なサブスクリプション生成手順では、複数の共有リンクを改行でつなぎ、UTF-8テキスト全体をBase64でエンコードします。デコードでは逆の手順を実行します。標準Base64の+、/と、URLセーフ形式の-、_の違いに注意してください。また、末尾のパディング=は省略される場合があります。

3 → 4
3バイトをBase64の4文字に変換し、端数はパディングで補う
443
この記事の例で使用するリモートTLSポート
10808
一般的なローカルプロキシポートの例。実際の待ち受けポートはクライアントで確認してください

以下は、ローカルで確認できるネイティブJavaScript関数です。渡された文字列を処理するだけで、ネットワークリクエストは行いません。自分で用意したオフラインHTMLページで実行してください。信頼できないWebページのコンソールに、実際のサブスクリプションを貼り付けないでください。UTF-8でデコードしないと、日本語を含むノード名が文字化けすることがあります。

function base64ToText(source) {
  const normalized = source
    .replace(/\s+/g, "")
    .replace(/-/g, "+")
    .replace(/_/g, "/");

  if (!/^[A-Za-z0-9+/]*={0,2}$/.test(normalized)) {
    throw new Error("入力がBase64の文字形式に一致しません");
  }

  const body = normalized.replace(/=+$/, "");
  if (body.length % 4 === 1) {
    throw new Error("Base64の長さが不正です。全体をコピーしたか確認してください");
  }

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

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

// ローカルでの動作確認。結果は true。
console.log(base64ToText(textToBase64("サブスクリプション形式のテスト")) === "サブスクリプション形式のテスト");
  1. サブスクリプションのレスポンス本文をbase64ToTextに渡します。HTTPSのサブスクリプションURLを渡すのではありません。
  2. デコード結果を改行で分割し、空行と行頭・行末の空白を取り除きます。各リンクの文字列はすべて保持してください。
  3. 各行のプロトコル接頭辞を確認し、まずノードを1つ選んでインポートを試してから、残りをまとめて処理します。
  4. 従来形式のBase64リストを再生成するには、textToBase64(links.join("\n"))で1行ごとのリンクテキストをエンコードします。これだけでアクセス可能なサブスクリプションURLが生成されるわけではありません。

外側のリストを一度デコードしたあとも、vmess://の後ろにBase64文字列が残ることがあります。これはノード単体のエンコード形式であり、デコード失敗ではありません。結果全体を機械的に繰り返しデコードせず、プロトコルごとに処理してください。

4. VMess・VLESS共有リンクとJSONの設定項目

一般的なVMess共有形式は、vmess://の後ろにノードJSONをBase64エンコードした文字列が続きます。主なキーはadd、port、id、net、host、path、tlsです。これは共有用の形式であり、コアにそのまま渡せる完全な設定ではありません。vは共有形式のバージョンを表し、コアのバージョンではありません。

VLESS共有リンクでは通常、ユーザー識別子・アドレス・ポートがURIの本体に、通信パラメーターがクエリ文字列に記載されます。以下は予約済みのサンプルドメインとデモ用UUIDを使った項目の対応例で、実際のノード接続には使用できません。

vless://[email protected]:443?encryption=none&security=tls&type=tcp&sni=edge.example.com#TLS-demo
共有リンクの情報ネイティブ設定での一般的な項目確認ポイント
アドレスとポートsettings.vnext[].address / portリモートポートとローカルの待ち受けポートを混同しない
ユーザーUUIDsettings.vnext[].users[].id値をそのまま保持し、備考をユーザー識別子として扱わない
type=tcpstreamSettings.network使用中のコアがサポートする通信方式名を指定する
security=tlsstreamSettings.securityプロトコル認証情報と通信方式をそれぞれ照合する
snitlsSettings.serverNameサーバー証明書と設定要件に合わせる
WebSocketのhost / pathwsSettings.headers.Host / pathSNIをHostの代わりに指定しない

上記のVLESS例は、以下のXrayアウトバウンド設定に対応します。インバウンド、DNS、ルーティングは含まれていないため、そのまま動作する完全な設定ではありません。完全な設定に組み込む場合は、適切なoutbounds配列に配置し、使用中のコアのドキュメントで各項目を確認してください。

{
  "tag": "proxy",
  "protocol": "vless",
  "settings": {
    "vnext": [
      {
        "address": "node.example.com",
        "port": 443,
        "users": [
          {
            "id": "00000000-0000-4000-8000-000000000001",
            "encryption": "none"
          }
        ]
      }
    ]
  },
  "streamSettings": {
    "network": "tcp",
    "security": "tls",
    "tlsSettings": {
      "serverName": "edge.example.com",
      "allowInsecure": false
    }
  }
}

5. JSON設定を常にサブスクリプションへ完全変換できるとは限らない理由

共有リンクが表すのは主に1つのリモート接続です。完全なJSON設定には、複数のアウトバウンド、ルールマッチング、DNSサーバー、トラフィックのスニッフィング、ローカルの待ち受け設定などが含まれることがあります。アウトバウンドからVLESSリンクを1つ抽出できても、そのリンクからすべてのルーティング設定を復元することはできません。そのため「JSONをサブスクリプションに変換」と言う場合、ノードの抽出なのか、実行環境全体の移行なのかを明確にする必要があります。

変換方針:ノード移行と完全な設定移行を分ける

ノードだけを移行する
  • outboundsから、直接接続やブロック用ではなく、実際のプロキシアウトバウンドを探します。
  • プロトコル、アドレス、ポート、認証、通信方式、TLSの各パラメーターを抽出します。
  • 使用するクライアントが認識できる共有リンクを生成し、1つずつインポートを試します。
  • DNS、システムプロキシ、ルーティングルールは移行先のクライアントで個別に設定します。
完全な設定を維持する
  • 元のJSONをバックアップし、対応するコアと実際のバージョンを記録します。
  • ファイルのパス、待ち受けアドレス、ポートの競合を確認します。
  • クライアントのカスタム設定機能を使い、通常のサブスクリプションとしてインポートしないでください。
  • 起動後にログを確認し、DNSとルーティングが想定どおりに動作するか確かめます。

まとめ:共有リンクはノードの共有に便利で、ネイティブJSONは設定構造の維持に適しています。外側の形式を再エンコードしても、両者の情報量の差は埋まりません。

同様に、XrayとV2FlyのJSONも、ファイル名を変えるだけで互換性が得られるわけではありません。プロトコル拡張、通信方式の項目、DNSオプションには違いがあります。非対応の項目を削除すれば解析を通過する場合もありますが、接続動作が変わる可能性があります。まずサーバー側の要件を確認してから、移行するか判断してください。

6. v2rayNとAndroidクライアントで適切なインポート方法を選ぶ

画面の表示はバージョンによって異なります。以下では一般的な中国語メニュー名をもとに操作の目的を説明します。端末上の名称が異なる場合は、「サブスクリプショングループ」「クリップボードからインポート」「カスタム設定」に相当する機能を探してください。単一ノードの共有リンク専用欄にサブスクリプションURLを貼り付けたり、サーバーアドレス欄にJSON全体を入力したりしないでください。

  1. v2rayNでサブスクリプションを追加:「サブスクリプショングループ」→「サブスクリプショングループ設定」を開き、グループを追加してサブスクリプションURLを入力します。保存後、サブスクリプションメニューから「プロキシを使わずに更新」または同等の項目を選びます。ネットワーク接続にプロキシが必要な場合は、「プロキシ経由で更新」を選択してください。
  2. v2rayNで使い切りのリンクをインポート:1行ごとの共有リンクをすべてコピーし、「サーバー」メニューから「クリップボードからURLを一括インポート」を選びます。インポート後に通信方式、TLS、SNIを確認してから、使用するサーバーに設定してください。
  3. v2rayNGでサブスクリプションを更新:「サブスクリプショングループ設定」を開いてグループを新規作成し、URLを入力して保存します。一覧に戻り、「サブスクリプションを更新」を実行してください。クリップボードのノードは追加メニューの「クリップボードからインポート」を使います。2つの方法を混同しないでください。
  4. v2flyNGの互換性を確認:サブスクリプションまたは共有リンクのインポート機能を使う前に、ノード設定がV2Flyコアに対応しているか確認します。Xray独自の機能が必要なノードについては、サービス提供元から対応する設定を入手してください。エンコード形式の変換では解決できません。

7. サブスクリプション変換・インポートでよくある問題

デコード後もvmess://と長い文字列が残ります。デコードしきれていないのでしょうか?

外側のサブスクリプション一覧はデコード済みです。まず改行でノードごとに分割し、対象のvmess://に続くデータだけを取り出してデコードし、JSONを解析します。一覧全体を再びBase64デコーダーに渡したり、VMessの共有データをコアの設定として扱ったりしないでください。

JSONを開けるのに、クライアントにノードが1つも表示されないのはなぜですか?

まずトップレベルのキーを確認してください。inboundsやoutboundsがある場合は、完全なコア設定の可能性があります。カスタム設定機能から読み込んでください。エラーコードや説明文が含まれている場合は、サブスクリプションへのアクセスを先に修復します。JSONの構文が正しいことと、サブスクリプション形式がサポートされていることは別問題です。

コピー後にインポートできない場合、まず何を確認すればよいですか?

チャットアプリでリンクが途中までしかコピーされていないか、クエリ文字列内の&がHTMLエンティティの文字列に置き換わっていないか、全角のコロンや引用符が混じっていないかを確認します。まずリンクを1つだけ使って試し、ノードの詳細が正しく表示されてから残りをインポートしてください。

ノードをインポートできたのに接続できません。サブスクリプション形式を変えるべきですか?

まずアドレス、443など実際のサーバーポート、UUID、通信パス、SNI、コアの対応状況を確認し、その後で接続ログを確認します。10808などのローカル待ち受けポートをリモートポート欄に入力してはいけません。各項目が正しくインポートされている場合、再エンコードしても通常は接続障害を解決できません。

サブスクリプションをオンラインツールに送ってJSONへ変換してもよいですか?

ローカルツールやクライアントのエクスポート機能を優先してください。サブスクリプションURLとノードの認証情報は、どちらも機密情報として扱う必要があります。すでに漏えいした場合は、サービス提供元の管理画面でサブスクリプショントークンを再発行し、必要に応じてノードの認証情報も変更したうえで、各端末に保存したURLを更新してください。

最終確認は4段階です。レスポンス本文を確認し、形式の階層を見分け、ノードの項目を照合し、コアの動作を検証します。TLS、アウトバウンド、ルーティングの用語は用語集を参照してください。インポート後もインターネットに接続できない場合は、トラブルシューティングガイドでログとネットワーク設定を確認しましょう。

V2Rayクライアントをダウンロード