サブスクリプションURLはデータの取得先、Base64はテキストのエンコード方式、共有リンクは通常1つのノード情報、XrayのJSONはコアの実行設定を表します。「URLにはアクセスできるのにインポートできない」「JSONをサブスクリプションに追加できない」といった問題に向けて、形式の判別、適切なインポート方法、オフラインでのデコード、フィールドの確認を順に解説します。変換だけで済むケースと、設定の補完が必要なケースも紹介します。
1. サブスクリプションURL・レスポンス本文・ノード設定を区別する
クリップボードにコピーした内容が、必ずしもノード情報とは限りません。https://で始まるサブスクリプションURLはリソースの場所を示すもので、クライアントがURLにアクセスして初めて実際の本文を取得します。本文は共有リンクが1行ずつ並んだ形式の場合もあれば、各行をBase64でエンコードした形式や、別の設定ファイルの場合もあります。URLの拡張子だけでは形式を判断できません。
| データの種類 | よくある形式 | 用途 |
|---|---|---|
| サブスクリプションURL | https://で始まり、アクセストークンが含まれる場合もある | リモートのノード一覧を取得・更新するためのもの。ノードのプロトコルを直接示すものではない |
| Base64形式のサブスクリプション本文 | 印字可能な文字が長く続き、末尾に=が付く場合もある | 通常は複数の共有リンクをまとめたもの。内容を確認するにはデコードが必要 |
| 単一ノードの共有リンク | vmess://、vless://、trojan://、ss:// | サーバー、認証情報、一部の通信パラメーターを記述 |
| XrayのJSON設定 | トップレベルのフィールドは通常inbounds、outbounds、routing | コアの受信接続、出力先、トラフィック処理ルールを定義 |
Base64に暗号化の効果はありません。本文を入手した人は通常、ノードのアドレスや認証情報を復元できます。サブスクリプションURL内のトークンも、同等のアクセス権を持つ場合があります。トラブルシューティングの際は、サブスクリプションURL全体、QRコード、ノードのエクスポート内容を公開の場に投稿しないでください。スクリーンショットを共有するときは、パス、クエリパラメーター、ノードの認証情報をすべて隠してください。
2. Base64形式のサブスクリプションとVMessのエンコード階層
従来よく使われるサブスクリプション形式では、複数の共有リンクを改行でつなぎ、全体をUTF-8テキストとしてBase64エンコードします。1回デコードすると、1行に1つのノードが並んだ内容になります。行末にはLFまたはCRLFが使われる場合があります。インポーターは通常、空行を無視しますが、余分な空白やバイト順マークをすべてのバージョンが処理できるとは限りません。
- 外側:サブスクリプション本文全体をBase64エンコード。デコードすると複数行のURIが得られます。
- ノード部分:一般的な
vmess://形式では、後半部分もBase64でエンコードされています。デコードするとノード情報のJSONが得られます。 - フィールド部分:VLESSなどのURIでは、名前、パス、クエリパラメーターがパーセントエンコードされている場合があります。たとえば
%20は空白を表します。
そのため、VMessノードではBase64のデコードが2回必要な場合がありますが、対象となるデータは階層ごとに異なります。長い文字列だからといって、読めるテキストに見えるまで何度もデコードしないでください。vless://の場合、通常はURIとして解析し、後半全体をさらにBase64として扱うことはありません。
一般的なVMess共有JSONには、v、ps、add、port、id、net、tlsなどのフィールドがあります。vの値としてよく使われる"2"は、この共有形式のバージョンを示すもので、クライアントやコアのバージョンではありません。また、Xrayでそのまま実行できるネイティブ設定でもありません。
- 標準Base64では
+と/を使用します。URLセーフ形式では-と_が使われる場合があります。 - 末尾の
=はパディング文字です。付いているか省略されているかだけでは、本文が有効かどうかを判断できません。 - ノード名に日本語が含まれる場合は、UTF-8としてデコードする必要があります。
atob()の戻り値をUnicodeテキストとしてそのまま扱うと、文字化けすることがあります。
3. 共有リンクから復元できるフィールド
以下では、予約済みのサンプルドメインと全ゼロのUUIDを使ってVLESS URIを示します。構造の説明用であり、実際の接続には使えません。ポート443はリモート側のサンプルポートで、クライアントのローカル待ち受けポートとは異なります。
vless://[email protected]:443?encryption=none&security=tls&type=tcp&sni=node.example.invalid#TLS%20example
| URIの部分 | 設定項目 | 確認ポイント |
|---|---|---|
| ホストとポート | settings.vnext[].address、port | ポートは数値に変換し、ノード名などの文字列を含めない |
| ユーザー情報内のUUID | settings.vnext[].users[].id | サーバー側の設定と一致していること |
encryption=none | users[].encryption | トランスポート層でTLSが使われていないことを意味するわけではない |
security=tls | streamSettings.security | TLSやREALITYなどの通信セキュリティ方式とは別に確認する |
sni | tlsSettings.serverName | TLSのサーバー名に使用。任意に変更しない |
#以降の部分 | クライアント上のノード名 | 通常、認証やネットワーク接続には使われない |
複雑なトランスポート設定を変換するときは、flow、alpn、トランスポートパス、HTTP Host、関連するセキュリティパラメーターも確認してください。共有形式やクライアントのバージョンによって、パラメーター名の仕様が異なる場合があります。アドレス、ポート、UUIDが同じだからといって、2つの設定が同等とは限りません。
変換時の確認ポイント:インポート後にトランスポート設定を照合
元のリンクとノード編集画面を項目ごとに照合し、まずトランスポートの種類、TLSのサーバー名、flowを確認してから接続テストを行います。これらのフィールドが不足している場合、サブスクリプション本文を再エンコードしても接続は直りません。
4. XrayのJSON設定はノード一覧ではない
XrayのJSON設定は実行環境を記述します。inboundsはローカルでトラフィックを受け取る方法、outboundsはリモートへの接続方法を定義し、routingではリクエストごとに異なる出力先を指定できます。以下の最小構成例は前節のVLESSノードに対応し、ローカルのSOCKS待ち受けを127.0.0.1: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": "node.example.invalid",
"port": 443,
"users": [
{
"id": "00000000-0000-0000-0000-000000000000",
"encryption": "none"
}
]
}
]
},
"streamSettings": {
"network": "tcp",
"security": "tls",
"tlsSettings": {
"serverName": "node.example.invalid"
}
}
}
]
}
この例ではroutingとdnsを明示的に設定せず、単一の受信接続と出力先の構成だけを示しています。待ち受けアドレスはループバックに限定され、LANには公開されません。udp: trueは、このSOCKS受信接続で該当するリクエストを処理できるようにする設定にすぎず、アプリ、リモート側、ネットワーク経路のすべてでUDP通信が利用できることを保証するものではありません。
変換の範囲:ノード情報の抽出と実行設定の保持
共有リンクからJSON設定へ
- アドレス、ポート、認証情報、トランスポート設定を解析する。
- ローカルの受信接続と待ち受けポートを追加する。
- 実際の用途に合わせてDNS、ログ、ルーティングを設定する。
JSON設定から共有リンクへ
- URIで表現できるプロキシ出力先を1つ選ぶ。
- 使用する共有形式がすべてのトランスポート設定を保持できるか確認する。
- 受信接続、ルーティング、DNSの設定は別途バックアップする。
単一ノードのURIでは通常、実行設定全体を保持できません。複数の出力先、チェーン接続、ルーティングルールがノードと一緒に移行されるとは限りません。
5. v2rayN、v2rayNG、v2flyNGのインポート方法
形式を解析できることと、使用するコアがそのプロトコルを実行できることは別の条件です。v2rayNはデスクトップクライアント、v2rayNGはXrayコア、v2flyNGはv2flyコアを使用します。インポート前に、クライアントのインポート方法、コアの種類、必要なトランスポート機能を確認してください。あるクライアントで保存できる設定が、別のクライアントでも実行できるとは限りません。
サブスクリプションURL:ノード一覧を継続的に管理
おすすめv2rayNの「サブスクリプショングループ」→「サブスクリプショングループ設定」でURLを追加し、「すべてのサブスクリプションを更新(プロキシを経由しない)」または該当するプロキシ経由の更新を実行します。メニューの表記はバージョンによって多少異なるため、実際の画面を確認してください。
おすすめの用途:ノードが更新されるため、継続して更新できる状態を保ちたい場合。
共有リンク:単一ノードのインポート
v2rayNでは「サーバー」→「クリップボードから一括URLをインポート」を使います。一般的なショートカットキーはCtrl+Vです。v2rayNGでは追加メニューから「クリップボードからインポート」を選択します。v2flyNGでは共有リンクのインポート機能を使い、コアが該当するプロトコルとトランスポートに対応していることを確認してください。
おすすめの用途:一時的なテスト、単一ノードの移行、パラメーターの個別確認。
JSON設定:実行設定全体を保持
サブスクリプションURLの入力欄ではなく、クライアントのカスタム設定インポート機能を使います。v2rayNGではカスタム設定のインポート機能を、v2rayNではカスタム設定サーバーの追加機能を使います。v2flyNGではv2flyコアに対応する設定が必要です。Xray専用のフィールドをそのまま適用することはできません。
おすすめの用途:固定の受信接続、DNS、複雑なルーティングが必要で、設定を自分で管理できる場合。
サブスクリプションをデコードして手動でインポートしても、通常はノードのスナップショットが作成されるだけで、元のサブスクリプションとの更新連携は維持されません。カスタムJSONも、画面から管理する通常のノードとは異なります。システムプロキシが参照するポートは、実際の受信接続と一致している必要があります。上の例はSOCKSの10808だけを待ち受けるため、HTTPの10809も使えると決めつけないでください。
6. オフラインでのデコードと再エンコード手順
エンコードの状態を確認するだけなら、オンライン変換サービスにサブスクリプションを送らず、ローカルの空白ページでブラウザーの開発者ツールを使って処理できます。以下ではブラウザー標準のAPIだけを使い、ネットワークリクエストは送信しません。まず固定テキストでテストし、環境がTextEncoderとTextDecoderに対応していることを確認してから、信頼できるローカル環境で取得済みの本文を処理してください。見知らぬWebページのコンソールに実際のサブスクリプションを貼り付けないでください。
function decodeBase64Text(input) {
const normalized = input.trim()
.replace(/\s+/g, "")
.replace(/-/g, "+")
.replace(/_/g, "/");
if (normalized.length % 4 === 1) {
throw new Error("Base64の長さが無効です");
}
const padded = normalized
+ "=".repeat((4 - normalized.length % 4) % 4);
const bytes = Uint8Array.from(
atob(padded),
character => character.charCodeAt(0)
);
return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
}
function encodeBase64Text(text) {
const bytes = new TextEncoder().encode(text);
const parts = [];
for (const byte of bytes) {
parts.push(String.fromCharCode(byte));
}
return btoa(parts.join(""));
}
decodeBase64Text("5rWL6K+V"); // テスト
encodeBase64Text("テスト"); // 5rWL6K+V
- まず形式を判別:本文がすでにURIの行リストなら、外側のデコードは不要です。JSONオブジェクトで始まる場合は、まずフィールド構造を確認してください。
- デコードは1回だけ:Base64形式だと確認できた本文にデコード関数を使い、結果がエラーページではなくノードの行になっているか確認してください。
- ノードの元データを保持:URI全体に対してパーセントデコードを繰り返さないでください。パス内の予約文字が変わり、意味が変わるおそれがあります。
- 行ごとに整理:空行だけを削除し、各共有リンク内の文字はそのまま残します。再エンコードするときは、各ノードを改行でつないでください。
- インポートを検証:まず単一ノードでテストし、その後に一覧全体を処理します。再エンコードが有効な修正方法なのは、エンコードに問題がある場合だけです。
上記の関数はエンコードとデコードだけを行います。VMessをVLESSに変換したり、JSON設定からサブスクリプションを自動生成したりするものではありません。プロトコルの変換には、サーバー側で対応する接続方法が提供されている必要があり、文字列の接頭辞を変えるだけでは実現できません。同様に、JSON設定をBase64で包んでも、一般的な「URIが1行ずつ並んだノード一覧」形式のサブスクリプションにはなりません。
7. インポート失敗や変換時のフィールド欠落を調べる
サブスクリプションURLを開けるのに、クライアントにノードがないと表示されるのはなぜ?
ステータスコードだけでなく、実際のレスポンス本文を確認してください。ログインフォーム、アクセス制限の案内、HTMLページが表示される場合は、まずサブスクリプションのアクセス権を修正します。JSON設定の場合はカスタム設定のインポート機能を使い、サブスクリプション欄への追加を繰り返さないでください。
デコード後もvmess://のままですが、失敗ですか?
通常は、外側のサブスクリプションが正しくデコードされています。まずVMessリンク全体をクライアントにインポートしてください。フィールドを確認する必要がある場合だけ、後半のノード情報を個別にデコードします。生成された共有JSONをコアの完全な設定と混同しないでください。
ノードのインポートに成功したのに接続できないのはなぜ?
ノード編集画面でリモートポート、UUID、トランスポートの種類、TLSのサーバー名、flowを確認してから、コアのログを確認してください。インポートの成功は、パーサーがデータを受け付けたことを示すだけです。リモートへの到達、認証の有効性、アプリでのローカルプロキシの利用までは保証しません。
変換したらルーティングルールとDNSがなくなったのはなぜ?
単一ノードの共有リンクに含まれるのは、通常プロキシ出力先のパラメーターだけです。元のJSONバックアップからrouting、dns、必要な受信接続を個別に移行してください。ノード名にこれらの実行ルールを追加しても、クライアントが完全な設定を復元することはありません。
プロキシ経由でのサブスクリプション更新がタイムアウトします。まず形式を変えるべきですか?
まずリクエストが完了しているか確認してください。使用可能なノードがある場合は、v2rayNの「サブスクリプショングループ」からプロキシ経由の更新を試せます。接続可能なノードがない場合は、ローカルネットワークとサブスクリプションURLのアクセス権を確認してください。レスポンス本文の解析前に発生するタイムアウトは、Base64の形式を変えても解決しません。
最終確認は3段階で行います。サブスクリプションを取得できたか、ノードのパラメーターがすべて解析されたか、トラフィックが想定した出力先を通っているかを確認してください。形式を変更する前に元データをバックアップします。カスタムJSONでは特に、待ち受けアドレスとポートが変わっていないことを確認してから、アプリのプロキシ設定を検証してください。
- 自動更新が必要:サブスクリプションURLを保持し、サブスクリプショングループで管理します。
- ノードだけを移行:移行先クライアントが対応する元の共有リンクを優先します。
- 設定全体の動作を維持:元の設定を移行し、ノード数だけでなくルーティングとDNSも項目ごとに検証します。