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

Base64サブスクリプション、ネイティブJSON設定、vmess://・vless://共有リンクの形式の違いと、手動またはクライアントで相互変換する方法を解説します。

この記事のポイント

サブスクリプションURLはデータの取得先、Base64はテキストのエンコード形式、共有リンクは個々のノード情報、ネイティブJSONはコアの実行設定を表します。「サブスクリプションにデータがあるのにインポートできない」「JSONを共有リンクに変換できない」といった場合は、まず入力形式を見分け、オフラインでデコードしたうえで、クライアントから設定を生成し、項目を照合しましょう。変換時にルーティング、DNS、安全性に関する設定が失われるのを防げます。

1. サブスクリプションURL・本文・ノード設定の違い

https://で始まるサブスクリプションURLはデータを取得するための入口であり、応答の形式を示すものではありません。サーバーから返されるのはBase64テキスト、1行ずつの共有リンク、あるいは特定のクライアント専用設定の場合もあります。インポートできるかどうかは、URLの末尾が.txtや.jsonかではなく、ダウンロードした本文で判断してください。

よくあるBase64サブスクリプションは、複数のノード共有リンクを改行でつなぎ、全体をエンコードしたものです。ここには2段階のエンコードが含まれることがあります。外側はリンク一覧全体、内側は各vmess://の後ろにあるノードJSONです。外側をデコードしても、コアの完全な設定が得られるわけではありません。Base64は可逆エンコードであり、情報を秘匿する機能はありません。

対象よくある形式含まれる情報処理方法
サブスクリプションURLhttps://で始まるアクセス用トークンが含まれることもあるリモートリソースのURLサブスクリプショングループ設定
Base64サブスクリプション本文長いエンコード済みテキスト通常はエンコードされた共有リンクが1行ずつ並ぶサブスクリプションを更新するか、オフラインでデコード
共有リンク一覧vmess://、vless://1つ以上のノード接続情報クリップボードからインポート
ネイティブJSONinbounds、outboundsなどのキーを含むインバウンド、アウトバウンド、必要に応じてDNSやルーティング設定カスタム設定から読み込む

判断のポイント:本文を確認してからインポート方法を選ぶ

本文がすでに1行ずつの共有リンクなら、再度デコードする必要はありません。インバウンドとアウトバウンドを含む完全な設定なら、サブスクリプションURLとして追加しないでください。ログイン画面やエラーページが返された場合は、変換を続けるのではなく、まずサブスクリプションへのアクセスを修正しましょう。

2. VMess・VLESS共有リンクのパラメーター構造

一般的なvmess://共有形式では、ノード情報を表すJSONをエンコードし、プロトコルのスキームの後ろに付けます。デコードすると、add、port、id、net、host、path、tlsなどのフィールドが確認できます。このJSONは共有リンク用の形式であり、コアにそのまま渡して実行できるネイティブJSONではありません。

以下はVMessノード情報の構造を確認するための例です。アドレスとUUIDは説明用で、接続可能なサービスを示すものではありません。v: "2"は共有形式のバージョンを示し、クライアントのバージョンではありません。現在のVMessノードでは通常aid: "0"を使いますが、実際の値はサーバー設定に従ってください。

{
  "v": "2",
  "ps": "VMessサンプル-WS",
  "add": "example.com",
  "port": "443",
  "id": "123e4567-e89b-42d3-a456-426614174000",
  "aid": "0",
  "scy": "auto",
  "net": "ws",
  "type": "none",
  "host": "example.com",
  "path": "/proxy",
  "tls": "tls",
  "sni": "example.com"
}

VLESS共有リンクは一般にURI形式で表されます。ユーザー名の位置にはUUIDが入り、ホストとポートが接続先を示します。クエリパラメーターはトランスポートとセキュリティ層を表し、#以降はノード名です。以下の例はWebSocketとTLSを使用し、追加のフロー制御パラメーターは含みません。

vless://[email protected]:443?encryption=none&security=tls&type=ws&host=example.com&path=%2Fproxy&sni=example.com#VLESSサンプル-WS

3. Base64サブスクリプションをオフラインでデコード・再エンコードする

実際のサブスクリプションを扱う際は、URL、UUID、デコードした本文をすべて機密情報として扱ってください。信頼できないオンライン変換サイトに入力してはいけません。ローカルの空白ページでブラウザーの開発者ツールを使い、内容を確認したコードを実行できます。操作前に、入力内容を読み取る別のスクリプトがページにないことを確認してください。また、開発者ツールに入力履歴が残る場合がある点にも注意が必要です。

以下の関数はローカルで文字列を変換するだけで、ネットワークリクエストは行いません。デコード関数は一般的な標準Base64とURLセーフ文字の両方に対応し、エンコード文字列内の改行を許容して、末尾の不足したパディングも補います。入力がBase64でない場合は、何度もエンコードやデコードを繰り返すのではなく、取得元を確認してください。

function decodeBase64Utf8(input) {
  const normalized = input.trim()
    .replace(/\s+/g, "")
    .replace(/-/g, "+")
    .replace(/_/g, "/");
  if (normalized.length % 4 === 1) {
    throw new Error("Base64の長さが不正です");
  }
  const padded = normalized.padEnd(
    Math.ceil(normalized.length / 4) * 4, "="
  );
  const bytes = Uint8Array.from(atob(padded), c => c.charCodeAt(0));
  return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
}

function encodeBase64Utf8(text) {
  const bytes = new TextEncoder().encode(text);
  let binary = "";
  for (const byte of bytes) binary += String.fromCharCode(byte);
  return btoa(binary);
}
3 → 4
Base64は3バイトを4文字に変換
443
この記事の例で使うリモート側TLSポート
10808
この記事のJSONで使うローカルSOCKSポート

元のサブスクリプション本文を文字列としてdecodeBase64Utf8に渡し、結果にプロトコルのスキームが行ごとに現れるか確認します。従来形式のBase64サブスクリプションを作る場合は、有効な共有リンクを整理してからencodeBase64Utf8(links.join("\n"))を呼び出してください。リンク一覧全体をURLデコードしないでください。ノードパラメーターに含まれる区切り文字が意図せず復元される可能性があります。

  1. テキスト先頭にBOMがあれば削除し、\r?\nで行に分割して空行を取り除きます。
  2. 各行のプロトコルのスキームを確認してください。エラーページ、通信量の説明、告知文などをノード一覧に混ぜないでください。
  3. VMessノードのフィールドを確認する必要がある場合に限り、個々のリンクのvmess://以降をデコードします。
  4. 再エンコード後にもう一度デコードし、ノードの行数と日本語のノード名が変わっていないことを確認してから、クライアントにインポートしてください。

4. クライアントでインポート・エクスポートして設定を生成する

普段の移行では、まずクライアントに共有リンクを解析させ、対応するコア設定を生成する方法がおすすめです。手入力によるミスを減らせますが、トランスポートのパラメーターは必ず確認してください。v2rayNデスクトップ版ではバージョンによってメニュー名が多少異なることがあります。以下では一般的な名称を紹介します。同じ項目が見つからない場合は、無関係なカスタム設定を使うのではなく、同じ機能の項目を探してください。

  1. グループをバックアップ

    現在のアクティブサーバーとサブスクリプショングループを記録し、元のサブスクリプションURLを保存します。テスト用のデータは専用グループに入れ、まとめてインポートした際に普段の設定を上書きしないようにしましょう。

  2. サブスクリプションを追加

    v2rayNで「サブスクリプショングループ」→「サブスクリプショングループ設定」を開き、新しいグループを作成してサブスクリプションURLを入力します。「サブスクリプショングループ」に戻り、「すべてのサブスクリプションを更新(プロキシを使用しない)」を実行してください。URLへのアクセスにプロキシが必要な場合は、プロキシ経由で更新する項目を選びます。

  3. 単一リンクをインポート

    共有リンク全体をコピーし、「サーバー」→「クリップボードから複数のURLをインポート」から取り込みます。ここに貼り付けるのはノードリンクだけです。ローカルのJSONファイルはカスタム設定機能で読み込んでください。

  4. エクスポートして照合

    ノードを選択して右クリックし、使用中のバージョンにある共有URLのエクスポートまたはコピー機能を使います。エクスポートした内容をテスト用グループに再インポートし、編集画面でアドレス、ポート、UUID、トランスポートの種類、SNI、パスを照合してください。

  5. 接続を確認

    テスト用ノードをアクティブサーバーに設定し、コアの起動ログを確認してから実際のリクエストを検証します。ネイティブJSONをエクスポートするのは、「完全な設定をエクスポート」などの機能がクライアントにある場合に限ってください。共有リンクのコピーは、実行設定のエクスポートとは異なります。

Android版v2rayNGでは通常、メイン画面の「+」→「クリップボードからインポート」で操作します。サブスクリプションURLは「サブスクリプショングループ設定」に追加し、サブスクリプションを更新します。v2flyNGでも、画面上でサブスクリプション管理と単一ノードのインポートを使い分けてください。2つのAndroidクライアントは異なる系列のコアを使用しているため、VLESSリンクを解析できても、リンクが必要とするすべてのトランスポート機能に対応するとは限りません。特にREALITYなどの機能を確認してください。

5. 共有リンクからネイティブJSONへの変換

ネイティブJSONの構造は使用するコアによって決まり、ファイルの拡張子では決まりません。完全な実行設定には、リモートノードのほかにローカルのインバウンドと必要なアウトバウンドの選択が必要です。以下はXray形式のVLESS、WebSocket、TLS設定例で、前述のURIから各フィールドへの対応を示しています。例のアドレスは実際のサービスには使えません。ローカルで10808を他のプログラムが使っている場合は、未使用のポートに変更し、呼び出し側の設定も合わせて変更してください。

{
  "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": "example.com",
            "port": 443,
            "users": [
              {
                "id": "123e4567-e89b-42d3-a456-426614174000",
                "encryption": "none"
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "ws",
        "security": "tls",
        "tlsSettings": {
          "serverName": "example.com",
          "allowInsecure": false
        },
        "wsSettings": {
          "path": "/proxy",
          "headers": {
            "Host": "example.com"
          }
        }
      }
    }
  ]
}

VMessの場合、アウトバウンドのプロトコルとユーザーフィールドはVMessの構造に合わせて生成する必要があります。上記のprotocolをvmessに変えるだけでは不十分です。REALITY、特定のフィンガープリント、フロー制御を使うVLESSリンクも、対象コアが対応する構造を使い、公開鍵やショートIDなどの必要なパラメーターを保持してください。JSONの構文が正しいことは、形式として有効であることを示すだけで、コアの対応やサーバーパラメーターの正しさを保証しません。

6. 変換で保持できる情報・できない情報

「JSONをサブスクリプションに変換する」とは、ファイルをBase64でエンコードするだけだと思われがちです。実際には少なくとも2つの手順があります。まず設定から共有可能なプロキシアウトバウンドを見つけ、クライアントが解釈できるURIに変換します。その後、サブスクリプションの受け取り側が求める形式でラップします。JSON全体をそのままエンコードしても、デコード結果はJSONのままであり、ノード一覧にはなりません。

クライアントから共有リンクをエクスポート

おすすめ

クライアントが通常のノードとして認識している項目をエクスポートすれば、フィールド対応のミスを減らせます。エクスポート後も、セキュリティ層、トランスポートのパラメーター、移行先クライアントとの互換性を確認してください。

用途:単一ノードの移行、個人用ノード一覧の整理

ノードのフィールドをオフラインで変換

明確に対応しているプロトコルとパラメーターだけを処理し、認識できないフィールドがあれば中止して記録してください。「インポート成功」のためにフロー制御、SNI、トランスポート設定を黙って破棄してはいけません。

用途:少数ノードの照合、エンコードやURIエスケープの問題調査

ネイティブ設定を完全な状態で保持

インバウンド、DNS、ルーティング、複数アウトバウンドの関係を保持し、対応するコアでカスタム設定として実行します。異なるコアへ移行する場合は、各フィールドを個別に確認してください。

用途:複雑なルーティング、アウトバウンドのチェーン接続、実行環境全体に依存する設定

ネイティブ設定には、直接接続用やブロック用のアウトバウンド、負荷分散、ドメイン別ルーティングのルールが含まれる場合があります。これらは単一ノードのURIでは表現できません。すべてのプロキシサーバーを抽出できても、「どのリクエストをどのアウトバウンドに送るか」という元の設定は共有リンクに引き継がれません。変換後のノードで接続できても、元のルーティングポリシーが復元されたことにはなりません。

判断のポイント:ノードの移行と設定全体の移行を分ける

同じサーバーに接続できればよい場合は、共有リンクをエクスポートして各フィールドを確認します。DNS、ルーティング、複数アウトバウンドの関係を維持する必要がある場合は、設定全体をバックアップし、移行先クライアントで実行ポリシーを別途復元してください。

7. サブスクリプション変換でよくある問題と対処

サブスクリプションの更新は成功したのに、ノード一覧が空なのはなぜ?

まず応答本文にノード情報が含まれているか確認してください。デコード結果がHTMLタグから始まる場合、ログインページやアクセスエラーページを取得している可能性があります。ネイティブJSONの場合は、対応する設定用の入口から読み込んでください。さらにグループの絞り込み条件を確認し、インポート済みのノードが現在の表示で隠れていないか調べます。

Base64のデコード後に日本語のノード名が文字化けする場合は?

バイト列をUTF-8としてデコードしてください。atobが返すバイト文字列をそのまま日本語テキストとして扱ってはいけません。この記事のTextDecoderを使う方法を利用できます。URIの#以降にあるノード名だけがパーセントエンコードされた状態で表示される場合は、そのノード名の部分だけをURIデコードしてください。

JSONから変換したリンクはインポートできるのに、接続できないのはなぜ?

まずアドレス、ポート、UUIDを照合し、次にTLSのSNI、WebSocketのHostとパスを確認します。元の設定でREALITYなど特定の機能を使っている場合は、移行先コアの対応状況と必要なパラメーターが揃っているかも確認してください。変換時の不足を隠すために、証明書の検証を無効にしてはいけません。

以前の中国本土向け直接接続ルールがなくなったのはなぜ?

共有リンクには通常、単一ノードの情報しか含まれず、ルーティング全体は含まれません。移行先クライアントのルーティング設定で振り分けルールを復元するか、互換性のあるネイティブ設定全体を使用してください。デフォルトのアウトバウンドも確認し、直接接続用のアウトバウンドをエクスポート対象のプロキシノードと誤認しないようにしましょう。

サブスクリプションURLを変換サイトに送ってしまった場合は?

相手が入力内容をどのように保存するか確認できない場合は、サービス提供元の管理画面でサブスクリプショントークンを再発行し、クライアントのURLを更新してください。トークンの再発行で既存ノードの認証情報まで同時に変更されるとは限りません。ノードリンクも漏えいした場合は、サービス提供元が対応する範囲で該当する認証情報も変更してください。

最後に「入力形式の確認 → デコード結果の確認 → ノード項目の確認 → コアの対応確認 → 実際のリクエスト成功」の順に検証します。一度に変更するのは1か所だけにし、変換前のテキストもバックアップしてください。インポート失敗、TLSハンドシェイクエラー、ルーティングの変化が起きたときに、形式を何度も変更するのではなく、失われた項目を特定できます。

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