· 구독 형식 · 약 12분

V2Ray 구독 링크 형식 가이드: Base64, JSON 설정, vless:// 링크 변환

Base64 구독, JSON 설정, vmess/vless 공유 링크의 차이와 v2rayN·v2rayNG에서 가져오고 서로 변환하는 방법을 알아봅니다.

이 글 미리보기

먼저 구독 URL, 구독 응답, 노드 공유 링크를 구분한 뒤 VLESS + WebSocket + TLS 예제로 URI와 Xray JSON 필드를 비교합니다. 구독 주소는 열리지만 가져오기에 실패하거나, Base64를 디코딩해도 설정 파일이 나오지 않는 경우, 노드를 옮겨야 하는 경우에 유용합니다. 어떤 가져오기 메뉴를 써야 하는지 판단하고 변환 과정에서 라우팅, DNS, 로컬 리스너 설정이 누락되는 이유도 확인할 수 있습니다.

구독 URL, Base64, JSON의 차이

구독 URL은 보통 HTTPS 주소이며, 클라이언트가 여기에 접속해야 노드 데이터를 받을 수 있습니다. URL 자체는 Base64나 노드 설정이 아닙니다. 확인해야 할 대상은 서버가 반환하는 응답 본문입니다. 같은 구독 URL이라도 요청 매개변수나 클라이언트 식별 정보에 따라 응답이 달라질 수 있으므로 주소의 확장자만 보고 형식을 판단해서는 안 됩니다.

구독 URL응답 본문형식 확인노드 파싱코어 실행
내용 형식식별 방법사용할 메뉴와 제한 사항
구독 URLhttps://로 시작하며 액세스 토큰이 포함될 수 있음구독 설정에 추가하면 이후에도 업데이트 가능
Base64 구독 본문디코딩하면 줄마다 공유 링크가 표시되는 경우가 많음일반적으로 클라이언트의 구독 업데이트 기능으로 처리하며, 완전한 실행 설정은 아님
단일 노드 공유 링크vless:// 또는 흔히 vmess://로 시작클립보드에서 노드를 가져올 때 적합하며, 보통 로컬 라우팅은 포함하지 않음
코어 네이티브 JSONinbounds, outbounds 등의 필드가 있음해당 코어용 사용자 지정 설정 메뉴에서 가져오며, 지원되는 필드만 사용할 수 있음

Base64는 바이트를 표현하는 인코딩 방식이지 암호화가 아닙니다. 구독 본문을 가진 사람은 보통 서버 주소와 사용자 정보를 확인할 수 있습니다. JSON 역시 데이터 형식일 뿐입니다. 중괄호로 시작하는 텍스트가 노드 정보일 수도, API 오류 메시지일 수도, 코어에서 바로 실행할 수 있는 완전한 설정일 수도 있습니다. 내부 필드를 확인해야 하며, 유효한 JSON이라고 해서 바로 실행할 수 있는 것은 아닙니다.

Base64 구독 디코딩 및 다시 인코딩하기

흔한 Base64 구독은 여러 공유 링크를 줄바꿈 문자로 이어 붙인 다음 전체 UTF-8 텍스트를 인코딩한 형태입니다. 디코딩 결과에 여러 줄의 vless:// 또는 vmess://가 보이면 구독의 바깥 인코딩은 이미 풀린 것입니다. 각 VLESS 링크를 다시 Base64로 디코딩할 필요는 없습니다. 일부 서비스는 링크 목록을 평문으로 반환하므로, 이 경우 바깥 인코딩을 디코딩하지 않아도 됩니다.

  1. 가져온 내용이 실제 응답 본문인지 먼저 확인하세요. 브라우저 로그인 페이지, 액세스 제한 안내, 상태 코드가 포함된 오류 메시지일 수 있습니다.
  2. Base64로 의심되는 본문에서 공백과 줄바꿈을 제거하고, URL 안전 변형의 -, _ 문자를 처리한 다음 끝부분에 패딩을 채우세요.
  3. 디코딩한 바이트를 UTF-8로 읽고, 각 줄의 프로토콜 접두어를 확인하면서 링크에 포함된 매개변수를 그대로 유지하세요.
  4. 다시 인코딩하기 전에 클라이언트가 실제로 Base64 목록을 요구하는지 확인하세요. 로컬에서 인코딩한 결과는 정적 텍스트일 뿐, 자동 업데이트되는 HTTPS 구독 서비스를 만들어 주지 않습니다.

아래는 로컬 브라우저 개발자 도구에서 사용할 수 있는 순수 JavaScript 함수입니다. 바이트 배열로 처리하므로 한글 메모를 포함할 수 있으며, 한글을 btoa로 바로 인코딩할 때 발생하는 오류를 피합니다. 함수는 전달받은 텍스트만 변환하고 네트워크 요청은 보내지 않습니다. 신뢰할 수 있는 내용만 입력하세요.

function decodeSubscription(source) {
  const compact = source.trim().replace(/\s+/g, "")
    .replace(/-/g, "+").replace(/_/g, "/");
  if (!/^[A-Za-z0-9+/]*={0,2}$/.test(compact)) {
    throw new Error("유효한 Base64 문자 시퀀스가 아닙니다");
  }
  const padded = compact + "=".repeat((4 - compact.length % 4) % 4);
  const bytes = Uint8Array.from(atob(padded), ch => ch.charCodeAt(0));
  return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
}

function encodeSubscription(linkText) {
  const bytes = new TextEncoder().encode(linkText);
  let binary = "";
  for (const byte of bytes) binary += String.fromCharCode(byte);
  return btoa(binary);
}

const sampleText = "예시 노드";
console.log(decodeSubscription(encodeSubscription(sampleText)));

디코딩 함수에서 오류가 나더라도 여러 번 중첩해 변환하지 마세요. 먼저 본문이 잘렸는지, 따옴표나 HTML 태그가 포함됐는지 확인한 다음 평문 목록인지 살펴보세요. 디코딩에 성공했더라도 각 링크의 프로토콜, 필수 필드, 전송 설정은 클라이언트에서 확인해야 합니다.

vless://와 vmess://의 필드 구조

VLESS 공유 링크는 보통 URI 형식입니다. 사용자 정보 위치에는 UUID가 들어가고, 호스트와 포트는 서버를 나타내며, 쿼리 매개변수는 전송 방식과 보안 계층을 지정합니다. 해시 기호 뒤에는 노드 메모가 들어갑니다. 아래 예시의 도메인과 UUID는 문서 설명용이며 실제로 연결되는 서비스가 아닙니다.

vless://[email protected]:443?encryption=none&security=tls&type=ws&host=example.net&path=%2Fws&sni=example.net#WS-TLS-demo
443
이 예시에서 서버가 사용하는 TLS 포트
10808
아래 설정에서 사용하는 로컬 SOCKS 포트

path=%2Fws를 디코딩하면 /ws입니다. 쿼리 매개변수의 경로, 메모, 특수 문자는 퍼센트 인코딩해야 합니다. URI 전체를 한꺼번에 인코딩하거나, 전체 URI를 먼저 디코딩한 뒤 직접 나누지 마세요. 경로 안의 & 같은 문자가 매개변수 구분자로 잘못 처리될 수 있습니다. IPv6 주소를 호스트 위치에 쓸 때는 대괄호로 감싸야 합니다.

VLESS 공유 링크

인증 정보
UUID는 @ 앞에 위치
전송 방식
type=ws
보안 계층
security=tls
경로
path=%2Fws

이 예시는 WebSocket과 TLS를 사용하며 Vision flow를 추가하면 안 됩니다.

일반적인 VMess 공유 형식

외부 형식
vmess:// 뒤에 Base64가 이어짐
서버
JSON의 add, port
인증 정보
JSON의 id
전송 방식
JSON의 net, path

이는 일반적인 클라이언트 공유 규약이며, 코어에서 바로 실행할 수 있는 JSON은 아닙니다.

일반적인 VMess 공유 JSON에서 v는 공유 형식의 버전을 뜻하며 VMess 프로토콜 버전이 아닙니다. ps는 보통 메모입니다. 이 구조는 코어 아웃바운드의 settings.vnext와 다릅니다. VMess 공유 규약에도 여러 변형이 있으므로 노드를 옮길 때는 모든 vmess:// 내용이 동일한 내부 구조를 가진다고 가정하지 말고 양쪽 클라이언트의 가져오기 및 내보내기 기능을 우선 사용하세요.

VLESS 링크에서 Xray 네이티브 JSON 만들기

공유 링크를 완전한 JSON으로 바꾸려면 링크에 없는 로컬 인바운드와 아웃바운드 태그를 추가해야 합니다. 아래 설정은 앞서 나온 VLESS 예시에 대응하는 Xray 설정이며, 로컬에서만 127.0.0.1:10808을 수신합니다. 실제 사용 전에는 사용 권한이 있는 서버의 실제 매개변수로 바꾸세요. 예시 도메인으로는 프록시 서비스를 이용할 수 없습니다.

{
  "log": {
    "loglevel": "warning"
  },
  "inbounds": [
    {
      "tag": "socks-in",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": true
      }
    }
  ],
  "outbounds": [
    {
      "tag": "proxy",
      "protocol": "vless",
      "settings": {
        "vnext": [
          {
            "address": "example.net",
            "port": 443,
            "users": [
              {
                "id": "9f2a54d1-8bc6-4d71-a903-0be458e623fd",
                "encryption": "none"
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "ws",
        "security": "tls",
        "tlsSettings": {
          "serverName": "example.net"
        },
        "wsSettings": {
          "path": "/ws",
          "headers": {
            "Host": "example.net"
          }
        }
      }
    }
  ]
}

v2rayN·v2rayNG에서 가져오기 메뉴 선택하기

먼저 구독 관계를 유지할지, 단일 노드만 가져올지 결정하세요. 구독을 디코딩한 뒤 링크를 하나씩 가져오면 노드는 만들 수 있지만, 보통 구독 출처와 자동 업데이트 연결이 사라집니다. 이후에도 서버 목록을 업데이트하려면 현재 내보낸 공유 링크만 저장하지 말고 원래 구독 URL을 보관하세요.

v2rayN: 구독, 클립보드 링크, 사용자 지정 설정 구분하기

  1. 구독 URL: 「구독 그룹」→「구독 그룹 설정」을 열고 새 그룹을 추가한 다음 메모와 URL을 입력하고 저장하세요. 이후 「구독 그룹」의 구독 업데이트 기능을 사용하세요. URL을 단일 노드 주소로 입력하지 말고 업데이트가 완료되면 새 노드가 추가됐는지 확인하세요.
  2. 공유 링크: 전체 vless:// 또는 vmess:// 텍스트를 복사한 다음 「서버」→「클립보드에서 URL 일괄 가져오기」를 사용하세요. 가져온 뒤 노드를 편집해 주소, 포트, TLS, SNI, 전송 경로를 확인하세요.
  3. 완전한 JSON: 「서버」→「사용자 지정 설정 서버 추가」와 같은 사용자 지정 설정 메뉴에서 파일에 맞는 코어를 선택한 뒤 화면 안내에 따라 설정 파일을 지정하세요. JSON 전체를 구독 URL 입력란에 붙여 넣지 마세요.

v2rayNG: 구독 그룹을 만든 뒤 업데이트하기

  1. 메인 화면 메뉴에서 「구독 그룹 설정」으로 이동하고 추가 버튼을 눌러 구독 이름과 주소를 입력하세요. 저장한 뒤 메인 화면으로 돌아와 「구독 업데이트」를 실행합니다.
  2. 단일 공유 링크는 전체 텍스트를 복사한 뒤 메인 화면에서 「+」→「클립보드에서 가져오기」를 누르세요. 생성된 설정 유형이 원본과 일치하는지 확인한 다음 연결하세요.
  3. Xray 네이티브 JSON은 「+」 메뉴의 사용자 지정 설정 가져오기를 사용하고, 설치된 버전에 따라 파일 또는 클립보드 방식을 선택하세요. 일반적인 VMess 공유 JSON을 완전한 사용자 지정 설정으로 가져오지 마세요.

버전에 따라 메뉴 이름이 조금 다를 수 있으므로 「구독 그룹」, 「클립보드 링크」, 「사용자 지정 설정」에 해당하는 메뉴를 찾으세요. v2flyNG를 사용할 때는 구독의 프로토콜과 전송 방식이 호환되는지도 따로 확인해야 합니다. v2rayNG에서 인식되는 Xray 노드가 다른 코어를 사용하는 클라이언트에서도 실행된다는 뜻은 아닙니다.

JSON 역변환 및 변환 과정에서 정보가 손실되는 이유

세 형식이 언제나 완벽하게 서로 변환된다는 뜻은 아닙니다. 단일 노드 링크는 주로 원격 연결 정보를 담지만, 완전한 JSON에는 여러 인바운드와 아웃바운드, DNS, 라우팅, 정책, 로그 설정이 들어갈 수 있습니다. JSON을 VLESS 링크 하나로 내보내는 것은 아웃바운드 하나를 선택해 연결 매개변수만 추출하는 작업입니다. 나머지 로컬 동작은 보통 링크에 담을 수 없습니다.

변환 방향대체로 유지되는 항목별도 처리가 필요한 항목
링크 목록과 Base64 간 변환원본 링크 텍스트와 순서문자 인코딩, 줄바꿈, URL 안전 변형
VLESS 링크에서 JSON으로 변환주소, 인증 정보, 일반적인 전송 및 보안 매개변수인바운드, 아웃바운드 태그, 로컬 라우팅 추가
JSON 아웃바운드에서 공유 링크로 변환대상 클라이언트가 지원하는 단일 노드 필드아웃바운드 선택, 확장 필드 처리, DNS 및 분기 규칙 별도 저장
VMess에서 VLESS로 변환주소와 전송 정보 중 공통 항목만 참고 가능서버에서 실제로 VLESS를 제공해야 합니다. 접두어만 바꿔서는 프로토콜을 전환할 수 없습니다.

노드를 옮길 때는 원본 클라이언트에서 노드를 선택하고 공유 링크로 내보낸 뒤 대상 클라이언트에서 필드를 확인하는 방법이 가장 좋습니다. 아웃바운드가 여러 개인 JSON만 가지고 있다면 먼저 outbounds의 tag와 protocol을 확인해 대상 아웃바운드를 찾으세요. 직접 연결이나 차단 아웃바운드를 서버로 착각하면 안 됩니다. 확장 매개변수가 포함된 경우 원본 JSON을 백업하고 대상 클라이언트에서 실제 생성된 설정을 확인하세요.

구독 디코딩 및 가져오기 관련 자주 묻는 질문

브라우저에서는 구독 주소가 열리는데 클라이언트 업데이트는 왜 실패하나요?

반환된 내용이 실제 노드 목록인지, 로그인 페이지나 API 오류 JSON인지를 먼저 확인하세요. URL에 토큰과 쿼리 매개변수가 모두 포함됐는지도 살펴보세요. 현재 네트워크에서 주소에 직접 접속할 수 없다면 이미 사용 가능한 노드가 있을 때 프록시를 통한 업데이트를 선택할 수 있습니다. 아직 가져오지 않은 노드를 업데이트에 필요한 유일한 네트워크 경로로 사용하지 마세요.

Base64 디코딩은 성공했는데 가져올 서버가 없다고 나오는 이유는 무엇인가요?

디코딩 결과의 각 줄에서 프로토콜 접두어를 확인하세요. 바깥쪽 Base64를 성공적으로 디코딩했다는 것은 인코딩을 되돌릴 수 있다는 뜻일 뿐, 내용이 클라이언트에서 지원된다는 의미는 아닙니다. 결과가 JSON이라면 공유 필드 객체인지 완전한 설정인지 구분하세요. HTML이 나온다면 계속 인코딩하지 말고 구독 요청 자체를 확인해야 합니다.

공유 링크는 가져왔는데 연결 시간 초과가 발생하면 어떻게 해야 하나요?

노드 편집 화면을 열고 원본 정보와 포트, 전송 경로, TLS, SNI를 대조하세요. 이 글의 예시에서 원격 포트는 443이고 로컬 10808은 SOCKS 수신 포트이므로 서로 바꿔 쓸 수 없습니다. 코어 로그도 확인해 도메인 확인 실패, 연결 시간 초과, TLS 핸드셰이크 오류를 구분하세요. 가져오기에 성공했다는 것은 파서가 필드를 받아들였다는 뜻일 뿐입니다.

변환 후 중국 본토 직결 규칙이 사라진 이유는 무엇인가요?

노드 공유 링크에는 일반적으로 로컬 라우팅 규칙 전체가 들어 있지 않습니다. 대상 클라이언트에서 라우팅 설정을 별도로 복원하세요. 사용자 지정 JSON을 쓴다면 routing.rules와 아웃바운드 태그가 서로 맞는지 확인하세요. domainStrategy를 설정해야 한다면 개별 규칙 안에 넣지 말고 routing 수준에 지정해야 합니다.

마지막으로 확인할 때는 한 번에 한 계층만 변경하세요. 먼저 내용 형식이 올바른지 확인하고, 다음으로 필드가 빠짐없이 있는지 살펴본 뒤 네트워크와 코어 실행 상태를 점검합니다. 이렇게 하면 구독 가져오기 실패, 링크 파싱 실패, 노드 연결 실패를 각각 구분해 해결할 수 있어 인코딩 도구와 프록시 설정을 번갈아 건드리는 일을 줄일 수 있습니다.

클라이언트 다운로드v2rayN / v2rayNG