구독 링크 형식 정리: Base64 구독, Xray JSON, 공유 링크 차이와 변환

Base64 구독, Xray JSON, vmess://·vless:// 공유 링크의 형식 차이와 클라이언트별 지원 여부, 형식 간 변환 방법을 안내합니다.

핵심 내용

구독 URL은 데이터를 가져오는 주소이고, Base64는 텍스트 인코딩 방식이며, 공유 링크는 보통 단일 노드 정보를 담습니다. Xray JSON은 실행에 필요한 커널 설정입니다. 링크가 열리지만 가져오기에 실패하거나 JSON을 구독으로 추가할 수 없는 경우를 위해, 형식 식별부터 가져오기 메뉴 선택, 오프라인 디코딩, 필드 확인까지 살펴봅니다. 바로 변환할 수 있는 항목과 설정을 보완해야 하는 항목도 구분합니다.

1. 구독 주소, 응답 본문, 노드 설정 구분하기

클립보드에 복사한 내용이 반드시 노드인 것은 아닙니다. https://로 시작하는 구독 주소는 리소스를 가리킵니다. 클라이언트가 이 주소에 요청을 보내야 실제 본문을 가져올 수 있습니다. 본문은 줄마다 공유 링크가 나열된 형식일 수도 있고, 해당 줄들을 Base64로 인코딩한 결과일 수도 있으며, 다른 형식의 설정 문서일 수도 있습니다. 주소의 확장자만으로 형식을 판단할 수는 없습니다.

네 가지 데이터 형식 구별하기
데이터일반적인 형태용도
구독 URLhttps://로 시작하며 액세스 토큰이 포함될 수 있음원격 노드 목록을 가져오고 업데이트하는 주소이며, 노드 프로토콜을 직접 나타내지는 않음
Base64 구독 본문출력 가능한 문자가 길게 이어지며 끝에 =가 붙을 수 있음대개 여러 공유 링크를 담고 있으며, 내용을 확인하려면 디코딩해야 함
단일 노드 공유 링크vmess://, vless://, trojan:// 또는 ss://서버, 인증 정보, 일부 전송 매개변수를 설명함
Xray JSON최상위 필드로 inbounds, outbounds, routing이 자주 사용됨커널의 수신 연결, 아웃바운드 및 트래픽 처리 규칙을 정의함

Base64는 암호화 기능을 제공하지 않습니다. 본문을 입수한 사람은 보통 노드 주소와 인증 정보를 복원할 수 있으며, 구독 URL의 토큰도 같은 수준의 액세스 권한을 가질 수 있습니다. 문제 해결을 위해 전체 구독 주소, QR 코드 또는 노드 내보내기 내용을 공개 게시판에 올리지 마세요. 스크린샷을 공유할 때는 경로, 쿼리 매개변수, 노드 인증 정보를 모두 가리세요.

2. Base64 구독과 VMess의 인코딩 단계

기존 구독 형식에서는 여러 공유 링크를 줄바꿈으로 연결한 뒤, 전체 UTF-8 텍스트를 Base64로 인코딩하는 경우가 많습니다. 한 번 디코딩하면 노드가 한 줄씩 표시되어야 합니다. 줄 끝에는 LF나 CRLF가 사용될 수 있습니다. 가져오기 기능은 대개 빈 줄을 무시하지만, 모든 버전이 불필요한 공백이나 바이트 순서 표시를 처리한다고 장담할 수는 없습니다.

  1. 바깥 단계: 구독 본문 전체가 Base64로 인코딩되어 있으며, 디코딩하면 여러 줄의 URI가 나옵니다.
  2. 노드 단계: 흔히 쓰이는 vmess:// 형식은 뒷부분도 Base64로 인코딩되어 있으며, 디코딩하면 노드 설명 JSON이 나옵니다.
  3. 필드 단계: VLESS 등의 URI에서 이름, 경로, 쿼리 매개변수는 퍼센트 인코딩될 수 있습니다. 예를 들어 %20은 공백을 뜻합니다.

따라서 VMess 노드에는 Base64 디코딩이 두 번 필요할 수 있지만, 각 단계에서 다루는 데이터는 서로 다릅니다. 긴 문자열이라는 이유만으로 ‘읽을 수 있는 문자가 나올 때까지’ 반복해서 디코딩하지 마세요. vless://가 보이면 본문은 보통 URI로 파싱해야 하며, 뒷부분 전체를 다시 Base64로 취급해서는 안 됩니다.

일반적인 VMess 공유 JSON에는 v, ps, add, port, id, net, tls 등의 필드가 있습니다. 이 중 v의 흔한 값인 "2"는 이 공유 형식의 버전을 나타내며, 클라이언트나 커널 버전이 아닙니다. 또한 Xray에서 바로 실행할 수 있는 기본 설정도 아닙니다.

3. 공유 링크에서 복원할 수 있는 필드

아래 예시는 예약된 도메인과 전부 0인 UUID를 사용한 VLESS URI입니다. 구조 설명용이므로 실제 연결에는 사용할 수 없습니다. 포트 443은 원격 서버의 예시 포트이며, 클라이언트의 로컬 수신 포트와는 다릅니다.

vless://[email protected]:443?encryption=none&security=tls&type=tcp&sni=node.example.invalid#TLS%20example
VLESS URI와 Xray 설정 필드 대응 관계
URI 항목설정 위치확인할 점
호스트 및 포트settings.vnext[].address、port포트는 숫자 값으로 변환하고 이름이나 메모는 포함하지 마세요.
사용자 정보의 UUIDsettings.vnext[].users[].id서버 설정과 일치해야 함
encryption=noneusers[].encryption전송 계층에 TLS가 없다는 뜻은 아님
security=tlsstreamSettings.securityTLS, REALITY 등 전송 보안 방식과 구분해야 함
snitlsSettings.serverNameTLS 서비스 이름으로 사용되므로 임의로 바꾸면 안 됨
# 뒤의 문자열클라이언트에 표시되는 노드 이름일반적으로 인증이나 네트워크 연결에는 사용되지 않음

복잡한 전송 설정을 변환할 때는 flow, alpn, 전송 경로, HTTP Host 및 관련 보안 매개변수도 확인해야 합니다. 공유 형식과 클라이언트 버전에 따라 매개변수 이름 규칙이 다를 수 있습니다. 주소, 포트, UUID가 같다고 해서 두 설정이 동일하다고 볼 수는 없습니다.

변환 시 확인 사항: 가져온 뒤 전송 매개변수 점검

원본 링크와 노드 편집 화면의 항목을 하나씩 비교하세요. 먼저 전송 유형, 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 통신이 모두 가능하다는 뜻은 아닙니다.

변환의 범위: 노드 추출과 실행 설정 보존

공유 링크를 Xray JSON으로 변환
  • 주소, 포트, 인증 정보, 전송 매개변수를 파싱합니다.
  • 로컬 인바운드와 수신 포트를 추가합니다.
  • 필요에 따라 DNS, 로그, 라우팅을 설정합니다.
Xray JSON을 공유 링크로 변환
  • URI로 표현할 수 있는 프록시 아웃바운드를 선택합니다.
  • 사용 중인 공유 형식이 모든 전송 필드를 담을 수 있는지 확인합니다.
  • 인바운드, 라우팅, DNS 설정은 별도로 백업합니다.

단일 노드 URI에는 일반적으로 전체 실행 설정을 담을 수 없습니다. 여러 아웃바운드, 체인 연결, 라우팅 규칙이 노드와 함께 자동으로 옮겨진다고 가정해서는 안 됩니다.

5. v2rayN, v2rayNG, v2flyNG 가져오기 방법

형식을 파싱할 수 있는지와 사용 중인 커널이 해당 프로토콜을 실행할 수 있는지는 별개의 조건입니다. v2rayN은 데스크톱 클라이언트이고, v2rayNG는 Xray 커널을, v2flyNG는 v2fly 커널을 사용합니다. 가져오기 전에 클라이언트의 메뉴, 커널 종류, 필요한 전송 기능을 모두 확인하세요. 한 클라이언트에서 저장할 수 있는 설정이 다른 클라이언트에서도 실행된다고 단정하면 안 됩니다.

구독 주소: 노드 목록을 계속 관리할 때

권장

v2rayN의 ‘구독 그룹’ → ‘구독 그룹 설정’에서 주소를 추가한 뒤, ‘구독 모두 업데이트(프록시 사용 안 함)’ 또는 프록시를 사용하는 해당 업데이트 메뉴를 실행하세요. 버전에 따라 메뉴 이름이 조금 다를 수 있으므로 실제 화면을 기준으로 확인하세요.

추천 상황: 노드가 바뀌며 이후에도 구독을 업데이트해야 할 때

공유 링크: 단일 노드를 가져올 때

v2rayN에서는 ‘서버’ → ‘클립보드에서 일괄 URL 가져오기’를 사용할 수 있으며, 흔히 Ctrl+V 단축키도 지원합니다. v2rayNG의 추가 메뉴에는 ‘클립보드에서 가져오기’가 있습니다. v2flyNG에서는 공유 링크 가져오기 메뉴를 사용하고, 커널이 해당 프로토콜과 전송 방식을 지원하는지 확인하세요.

추천 상황: 임시 테스트, 단일 노드 이전, 매개변수 개별 확인

Xray JSON: 전체 실행 설정을 유지할 때

구독 주소 입력란이 아니라 클라이언트의 사용자 지정 설정 가져오기 메뉴를 사용하세요. v2rayNG에서는 사용자 지정 설정 가져오기 기능을 사용할 수 있고, v2rayN에서는 사용자 지정 설정 서버 메뉴를 이용해야 합니다. v2flyNG에는 v2fly 커널과 호환되는 설정이 필요하며, Xray 전용 필드를 그대로 적용할 수 없습니다.

추천 상황: 고정 인바운드, DNS 또는 복잡한 라우팅이 필요하고 설정을 직접 관리할 수 있을 때

구독 내용을 디코딩한 뒤 수동으로 가져오면 대개 노드의 현재 상태만 저장되며, 원래 구독의 업데이트 연결은 유지되지 않습니다. 사용자 지정 JSON도 인터페이스에서 관리하는 일반 노드와 다릅니다. 시스템 프록시가 사용하는 포트는 실제 인바운드 설정과 일치해야 합니다. 위 예시는 SOCKS 10808만 수신하므로 HTTP 10809도 사용할 수 있다고 가정해서는 안 됩니다.

6. 오프라인 디코딩 및 재인코딩 방법

인코딩 형식만 확인하려면 구독 내용을 온라인 변환 서비스에 제출하지 말고, 로컬의 빈 페이지에서 브라우저 개발자 도구 콘솔을 사용할 수 있습니다. 아래 방법은 브라우저 내장 API만 사용하며 네트워크 요청을 보내지 않습니다. 먼저 고정된 텍스트로 TextEncoder와 TextDecoder가 작동하는지 확인한 다음, 신뢰할 수 있는 로컬 환경에서 이미 가져온 본문을 처리하세요. 익숙하지 않은 웹페이지의 콘솔에는 실제 구독 내용을 붙여 넣지 마세요.

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
  1. 먼저 형식을 확인하세요: 본문이 이미 줄마다 URI로 되어 있다면 바깥쪽 디코딩은 필요하지 않습니다. JSON 객체로 시작한다면 먼저 필드 구조를 확인하세요.
  2. 한 번만 디코딩하세요: Base64 형식이 맞는 본문에 디코딩 함수를 사용하고, 결과가 오류 페이지가 아니라 노드 목록인지 확인하세요.
  3. 노드 원문을 유지하세요: URI 전체에 퍼센트 디코딩을 반복 적용하지 마세요. 경로에 포함된 예약 문자의 의미가 달라질 수 있습니다.
  4. 줄 단위로 정리하세요: 내용이 없는 줄만 제거하고 각 공유 링크 내부의 문자는 그대로 유지하세요. 재인코딩할 때는 각 노드를 줄바꿈으로 연결합니다.
  5. 가져오기를 확인하세요: 전체 목록을 처리하기 전에 노드 하나로 테스트하세요. 인코딩 오류에 해당하는 경우에만 재인코딩으로 문제를 해결할 수 있습니다.

위 함수는 인코딩과 디코딩만 수행합니다. VMess를 VLESS로 변환하거나 Xray JSON을 구독으로 자동 변환하지는 않습니다. 프로토콜 변환에는 서버에서 해당 연결 방식을 제공하는지가 중요하며, 문자열 접두사만 바꿔서는 처리할 수 없습니다. 마찬가지로 Xray JSON을 Base64로 감싸도 일반적인 ‘줄마다 노드 URI가 나열된’ 구독 형식이 되는 것은 아닙니다.

7. 가져오기 실패 및 변환 후 필드 누락 해결

구독 주소는 열리는데 클라이언트에 노드가 표시되지 않는 이유는 무엇인가요?

상태 코드만 보지 말고 실제 응답 본문을 확인하세요. 로그인 양식, 액세스 제한 안내, HTML 페이지가 표시된다면 먼저 구독 액세스 권한을 해결해야 합니다. 본문이 Xray JSON이라면 사용자 지정 설정 메뉴로 가져오고, 구독 입력란에 반복해서 추가하지 마세요.

디코딩했는데도 vmess://가 보입니다. 디코딩에 실패한 건가요?

대개 바깥쪽 구독 형식이 정상적으로 디코딩되었다는 뜻입니다. VMess 링크 전체를 클라이언트로 가져오세요. 필드를 확인해야 할 때만 링크 뒷부분의 노드 설명을 따로 디코딩하고, 결과로 나온 공유 JSON을 전체 커널 설정으로 취급하지 마세요.

노드를 가져왔는데도 연결되지 않는 이유는 무엇인가요?

노드 편집 화면에서 원격 포트, UUID, 전송 유형, TLS 서비스 이름, flow를 확인한 다음 커널 로그를 살펴보세요. 가져오기에 성공했다는 것은 파서가 데이터를 받아들였다는 뜻일 뿐, 원격 서버에 연결할 수 있거나 인증이 유효하거나 애플리케이션이 로컬 프록시를 사용한다는 뜻은 아닙니다.

변환 후 분할 라우팅 규칙과 DNS 설정이 사라진 이유는 무엇인가요?

단일 노드 공유 링크에는 보통 프록시 아웃바운드 매개변수만 포함됩니다. 원본 JSON 백업에서 routing, dns, 필요한 인바운드를 각각 옮기세요. 노드 이름에 실행 규칙을 덧붙여도 클라이언트가 전체 설정을 복원하지는 않습니다.

프록시를 통한 구독 업데이트도 시간 초과가 발생합니다. 형식을 먼저 바꿔야 하나요?

먼저 요청이 실제로 완료되었는지 확인하세요. 사용 가능한 노드가 있다면 v2rayN의 ‘구독 그룹’에서 프록시를 통한 업데이트 메뉴를 시도할 수 있습니다. 연결 가능한 노드가 없다면 로컬 네트워크와 구독 주소의 액세스 권한부터 확인하세요. 본문 파싱 전에 요청 시간이 초과된 경우이므로 Base64 형식을 바꿔도 해결되지 않습니다.

최종 점검은 세 단계로 나눠 진행하세요. 구독을 정상적으로 가져왔는지, 노드 매개변수가 빠짐없이 파싱되었는지, 트래픽이 예상한 아웃바운드로 전달되는지 확인합니다. 형식을 바꾸기 전에는 원본을 백업하세요. 사용자 지정 JSON은 특히 수신 주소와 포트가 바뀌지 않았는지 확인한 뒤 애플리케이션의 프록시 설정도 점검해야 합니다.

v2rayN 다운로드