まず、サブスクリプションURL、サーバー共有リンク、完全な設定ファイルを区別し、変換できるかを確認しましょう。Base64形式のサブスクリプションは通常、複数の共有リンクをエンコードしたものです。一方、JSON設定にはローカルの待ち受け、DNS、ルーティングも含まれるため、拡張子を変えるだけではサブスクリプションになりません。「サブスクリプションを認識できない」「JSONをインポートできない」といった場合や、別のクライアントへ移行する場合に役立つ、ローカルでのエンコード方法、項目の対応関係、インポート後の確認手順を紹介します。
内容を見分ける:URLとサブスクリプション形式は別物
一般に「V2Rayのサブスクリプション」と呼ばれるものは、すべてのクライアントで使える統一ファイル規格ではありません。https://で始まるURLは、クライアントが特定のエンドポイントにアクセスすることを示すだけです。実際にリンク一覧、Base64テキスト、設定ファイルのどれが返るかは、レスポンス本文で決まります。同じエンドポイントでも、リクエストのパラメーターやクライアント識別情報によって異なる内容が返る場合があるため、URLの末尾だけで対応可否を判断することはできません。
| 内容の種類 | よくある形式 | 実際に保存されている内容 | 適した取り込み方法 |
|---|---|---|---|
| リンク一覧形式のサブスクリプション | 複数行のプロトコルリンク、または1つのBase64文字列 | 複数サーバーの接続パラメーター | サブスクリプショングループと更新機能 |
| 単一の共有リンク | vmess:// または vless:// | 1台のサーバーの接続パラメーターとメモ | クリップボードからサーバーをインポート |
| 完全なJSON設定 | inbounds、outboundsなどの項目を含む | コアの実行設定一式 | コアに対応したカスタム設定の読み込み方法 |
サブスクリプション本文を取得したら、まずエラーページが返っていないか確認してください。HTMLタグやログイン案内、「有効期限切れ」といった文言が先頭にある場合、期待したノード情報を取得できていません。エラーページを再度Base64でエンコードしても、エンコードされたエラーページになるだけで、問題は解決しません。
用途に合わせて形式を選ぶ:日常の更新と設定全体を分けて管理
v2rayN、v2rayNG、v2flyNGでは、サーバー一覧と実行設定は別のレイヤーです。クライアントはサーバー情報からコア設定を生成できますが、完全な設定ファイルに含まれるローカルポートやルーティングルールを、共有リンク1つにそのまま反映できるとは限りません。形式を選ぶ前に、移行したいのが「ノード」だけか、「ノードとローカル設定」なのかを決めましょう。
クライアント対応のリンク一覧形式サブスクリプション
おすすめリモートのサブスクリプションURLを登録し、クライアントから定期的または手動でサーバー一覧を取得します。提供元がノードを変更した場合も、サブスクリプションを更新すれば新しい内容を取り込めます。
向いている用途:複数のサーバーを日常的に管理し、ノード一覧を継続して更新したい場合
単一のVMess / VLESS共有リンク
サーバーを1台だけ取り込む場合や、接続パラメーターを項目ごとに確認する場合に便利です。インポート後は通常、ローカルのサーバー情報として保存され、元のサブスクリプションとは自動で連動しません。
向いている用途:ノードを一時的にテストする場合、少数のサーバーを手動で移行する場合
コアに対応した完全なJSON設定
インバウンド、アウトバウンド、DNS、ルーティングなどを設定できます。対象のコアが該当項目に対応しているか確認してください。ファイルの拡張子だけでは判断できません。
向いている用途:独自ルーティング、固定のローカル待ち受け、複数アウトバウンドを管理する場合
v2rayNGはXrayコア、v2flyNGはV2Flyコアを使用します。v2rayNで利用できる機能は、選択中のコアによって異なります。JSON形式だからといって設定をそのまま共用できるわけではなく、VLESSだからといって、すべてのトランスポートやセキュリティ設定を移行先のバージョンが認識できるわけでもありません。変換前に、移行先のクライアントとコアが実際に対応している範囲を確認してください。
Base64サブスクリプションのデコード方法:外側のエンコードを解除して各行を確認
Base64形式のサブスクリプションは、複数の共有リンクを改行でつなぎ、テキスト全体をエンコードして作られることがよくあります。外側のエンコードを解除すると、vmess://とvless://が混在している場合があります。注意点として、従来形式のVMess共有リンク自体にもBase64が使われています。そのため、サブスクリプションの外側をデコードしただけでは、各VMessノードまでデコードしたことにはなりません。
Base64はエンコード方式であり、暗号化ではありません。標準形式では+、/と末尾の=がよく使われます。URLセーフ形式では-、_を使い、出力によってはパディングが省略されます。日本語のメモはUTF-8として扱ってください。文字コードを考慮せずに変換すると、文字化けすることがあります。
以下は、ローカルのブラウザーで空白ページを開き、開発者ツールから実行できる関数です。入力されたテキストだけを処理し、ネットワークにはアクセスしません。例のドメイン名、UUID、ポートは構造を示すためのもので、接続可能なサーバーではありません。
function decodeBase64Utf8(input) {
let text = input.trim().replace(/\s+/g, "")
.replace(/-/g, "+").replace(/_/g, "/");
if (text.length % 4 === 1) {
throw new Error("Base64の長さが無効です");
}
text = text.padEnd(Math.ceil(text.length / 4) * 4, "=");
const bytes = Uint8Array.from(atob(text), ch => ch.charCodeAt(0));
return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
}
function encodeBase64Utf8(input) {
const bytes = new TextEncoder().encode(input);
const binary = Array.from(bytes, byte => String.fromCharCode(byte)).join("");
return btoa(binary);
}
const exampleLink = "vless://[email protected]:443?encryption=none&security=tls&type=tcp&sni=example.com#TLS-demo";
const encodedList = encodeBase64Utf8(exampleLink + "\n");
console.log(decodeBase64Utf8(encodedList));
- まず本文にプロトコルリンクがすでに平文で並んでいるか確認してください。平文なら、一覧を直接確認すればよく、デコードは不要です。
- 本文が1つのエンコード文字列なら、デコード関数で外側のエンコードを解除し、改行で分割して空行を除きます。
- 各行のプロトコルプレフィックスを確認します。従来形式のVMessエンコード構造だと明確に判断できる場合に限り、プレフィックスより後ろをさらにデコードしてください。
- デコードに失敗した場合は、原文を残して、途中で切れていないか、HTMLが混入していないか、文字が置換されていないかを確認します。何度もむやみにデコードしても修復にはなりません。
VMessとVLESSの共有リンク:構造が異なるため、プレフィックスは置き換えられない
従来形式のVMessリンク:JSONを再エンコード
従来形式のVMess共有リンクは、vmess://の後ろにノードJSONをBase64エンコードして付ける形式が一般的です。このノードJSONはコアの完全な設定ではなく、ローカルのすべてのインバウンドやルーティングを記述していません。以下はエンコード前の一般的な項目構成です。vは共有形式のバージョンを示すもので、クライアントやコアのバージョン番号ではありません。
{
"v": "2",
"ps": "VMess TLSの例",
"add": "example.com",
"port": "443",
"id": "11111111-1111-4111-8111-111111111111",
"aid": "0",
"scy": "auto",
"net": "tcp",
"type": "none",
"host": "",
"path": "",
"tls": "tls",
"sni": "example.com"
}
このオブジェクトをシリアライズし、前述のエンコード関数を使えば、従来形式のリンクを生成できます:"vmess://" + encodeBase64Utf8(JSON.stringify(node))。ここでnodeは上記のオブジェクトです。逆に解析する場合は、プレフィックスを除いてからデコードし、JSON.parseで読み込みます。ここでのaid: "0"は一般的なVMess AEAD設定に対応します。古い解説を参考に、別の値へ変更しないでください。
VLESSリンク:URIの項目とクエリパラメーター
VLESSでは通常、URI形式を使います。ユーザー識別情報は@の前、サーバーアドレスとポートは後ろに置き、トランスポートとセキュリティの設定はクエリ部分、メモは#の後ろに記述します。日本語のメモはパーセントエンコードが必要です。各項目に含まれる特殊文字もURI用のツールで正しくエンコードし、未処理のテキストをそのまま連結しないでください。
vless://[email protected]:443?encryption=none&security=tls&type=tcp&sni=example.com#TLS-demo
encryption=noneはVLESSプロトコル層の設定で、TLSを無効にするという意味ではありません。TLSの有効化はsecurity=tlsなどで指定します。sniはTLSハンドシェイクで使うサーバー名です。WebSocketのHTTP Hostや接続先アドレスと、安易に混同しないでください。type=tcpは例で指定しているトランスポートの種類です。別の種類に変更する場合は、そのトランスポート用のパラメーターとサーバー側の対応も必要です。- VMessとVLESSでは認証方式と設定構造が異なります。
vmess://をvless://に変えても、プロトコルもサーバーも変換されません。
JSON設定の変換方法:ノードを取り出すのであり、設定全体の動作を保つわけではない
完全な設定には、「ローカルでどのようにトラフィックを受け取るか」と「トラフィックをどのようにリモートへ転送するか」の両方が含まれます。以下はXray形式の簡略例です。ローカルのループバックアドレスでSOCKSポートを待ち受け、VLESS 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": "example.com",
"port": 443,
"users": [
{
"id": "11111111-1111-4111-8111-111111111111",
"encryption": "none"
}
]
}
]
},
"streamSettings": {
"network": "tcp",
"security": "tls",
"tlsSettings": {
"serverName": "example.com"
}
}
}
]
}
| JSONの項目 | 共有リンク内の位置 | 例の値 |
|---|---|---|
settings.vnext[0].address | ホスト名 | example.com |
settings.vnext[0].port | リモートポート | 443 |
settings.vnext[0].users[0].id | URIのユーザー情報 | 例示用UUID |
streamSettings.security | securityクエリパラメーター | tls |
tlsSettings.serverName | sniクエリパラメーター | example.com |
inbounds[0].port | サーバー共有リンクには含まれない | 10808はローカルポート |
上表のアウトバウンド内の各項目は、outbounds[0]からの相対位置です。手動で取り出す場合は、実際に使うプロキシのアウトバウンドを選び、そのプロトコルとトランスポートのパラメーターを確認します。常に配列の先頭を選ぶのは避けてください。実際の設定では、最初の項目が直接接続用だったり、複数のプロキシ、チェーン接続、負荷分散が設定されていたりすることがあります。
- JSONから共有リンクへ:対象のアウトバウンドからリンク形式で表現できる項目を取り出し、対応するプロトコルの仕様に従ってリンクを生成します。DNS、ルーティング、ローカル待ち受け、その他のアウトバウンドは別に保存してください。
- 共有リンクからJSONへ:まずクライアントにノードをインポートし、現在の設定に基づいてコアの実行設定を生成します。手動で作成する場合は、リモート側の項目だけでなく、ローカルのインバウンドとデフォルトのアウトバウンドの動作も明示してください。
- リンク一覧からBase64形式のサブスクリプション本文へ:有効な共有リンクを改行でつなぎ、UTF-8のテキストを一度Base64エンコードします。生成されるのはサブスクリプション本文であり、リモート更新に使えるサブスクリプションURLではありません。
- Base64から完全なJSON設定へ:まずデコードして内容を判別し、ノードごとに変換します。エンコードされたテキストをそのまま
outboundsに入れても、コアの設定構造にはなりません。
クライアントへのインポートと移行:先にバックアップし、ノード1つで検証
手動で変換する前に、現在の設定をエクスポートまたはバックアップし、元のサブスクリプションURLも残してください。使用中のサブスクリプショングループを直接上書きせず、新しいテスト用グループに少数のノードをインポートすると、「形式の解析失敗」と「サーバーへの接続失敗」を切り分けられます。以下は一般的な中国語UIの表記をもとにしており、実際のメニュー名はクライアントのバージョンによって異なる場合があります。
移行方法:サーバー情報とローカル設定を分けて扱う
デスクトップ版:v2rayN
- リモートURLは「サブスクリプショングループ」→「サブスクリプショングループ設定」から追加し、対象グループを更新します。
- 単一リンクは「サーバー」→「クリップボードからURLを一括インポート」から取り込み、結果を確認します。
- ローカルの待ち受けポート、選択中のコア、ルーティング設定を確認してください。リモートの443番ポートをローカルのプロキシポートと取り違えないようにしましょう。
Android版:v2rayNG / v2flyNG
- リモートサブスクリプションはサブスクリプショングループ設定から追加します。単一リンクはメイン画面のクリップボードインポートから取り込みます。
- v2rayNGではXrayの対応状況を、v2flyNGではV2Flyの対応状況を基準にパラメーターを確認します。
- VPNの許可設定とアプリごとの設定をあらためて確認してください。これらのローカル設定は通常のノードリンクでは移行されません。
同じサブスクリプションを両方の端末で共通の情報源として使えますが、更新のタイミング、プロトコル対応、ローカル設定はそれぞれ確認が必要です。
インポート後はノードの編集画面を開き、アドレス、ポート、ユーザー識別情報、トランスポート、TLSのパラメーターを元データと照合してから、接続を開始してログを確認します。ノード一覧は表示されるのにハンドシェイクに失敗する場合は、接続パラメーターとサーバーの状態を確認してください。ノード数が0の場合は、まずレスポンス本文とインポート方法を調べ、ルーティングを変更するのはその後にします。
- ローカル接続:システムプロキシを使うアプリや、プロキシを手動指定するアプリは、クライアントが実際に待ち受けているアドレスとポートに接続します。例にある
127.0.0.1:10808が、すべての環境での標準値とは限りません。 - リモート接続:接続タイムアウト、認証失敗、TLSの名前不一致はそれぞれ別の問題です。ログに基づいて個別に対処し、すべての項目を一度に変更しないでください。
- 更新との連動:クリップボードからインポートした固定ノードは、元のサブスクリプションURLを更新しても自動で同期されるとは限りません。自動更新が必要な場合は、サブスクリプションURLと所属グループを保存してください。
サブスクリプション変換でよくある疑問:デコードできても接続できるとは限らない
Base64をデコードしたのにvmessで始まります。まだデコードが必要ですか?
外側のサブスクリプションをデコードした結果として、リンク一覧が表示されるのは通常の動作です。まず改行ごとに分割してください。従来形式のVMessリンクは、vmess://より後ろを取り出してデコードするとノードJSONになります。リンクが混在する一覧全体を繰り返しデコードしないでください。URIの記号までエンコード内容として処理されてしまいます。
JSONを入手したのに、「クリップボードからインポート」でサーバーがないと表示されるのはなぜですか?
まずトップレベルの項目を確認してください。inboundsやoutboundsが含まれる場合は、コアの完全な設定である可能性があります。移行先のバージョンが対応するカスタム設定の読み込み方法を使うか、この記事の手順でプロキシのアウトバウンドを1つ取り出してください。クリップボードの共有リンク用インポート機能は、汎用JSONインポーターではありません。
Base64に変換してもクライアントにインポートできないのはなぜですか?
まずデコードして元の内容が壊れていないことを確認し、各行が移行先クライアントに対応したプロトコルリンクかを調べます。Base64はテキストの表現を変えるだけです。不足しているユーザー識別情報を補ったり、ウェブページをノードに変換したり、コアにないプロトコル対応を追加したりはできません。
変換後のノードは使えるのに、ルーティングルールが引き継がれないのはなぜですか?
一般的な共有リンクが表すのは主にリモートノード1つであり、DNS、ルーティング、アプリごとの設定全体を移行するものではありません。移行先クライアントでローカル設定を確認してください。ルーティング一式を再現する必要がある場合は、ネイティブ設定を保持し、コアの各項目が対応しているか確認します。ノードに接続できたことを、設定移行の完了と見なさないでください。
確認は、正しい本文を取得できたか、エンコードの階層が正しいか、ノードの各項目が一致するか、移行先のコアとローカルの通信経路に問題がないか、の順に進めます。サブスクリプション、共有リンク、ネイティブJSONにはそれぞれ用途があります。各段階で何が保持され、何が失われるかを把握すれば、手動変換時に接続の問題と設定の問題を混同せずに済みます。関連用語は用語集、ルーティングやコアの設定は応用設定ガイドをご覧ください。