V2Ray 구독 형식 완벽 가이드: Base64 인코딩, 네이티브 JSON 및 공유 링크 변환

자주 쓰이는 세 가지 구독 형식인 Base64 통합 구독, 네이티브 JSON 설정, 개별 공유 링크의 구조와 지원 클라이언트를 정리하고, 필드 의미와 호환 범위, 변환 방법을 설명해 구독 가져오기가 실패하는 원인을 찾도록 돕습니다.

이 글 한눈에 보기

구독 가져오기에 실패해 원인을 찾거나, 노드를 다른 클라이언트로 옮기거나, 설정 구조를 이해하려는 사용자에게 적합한 글입니다. 먼저 응답 내용을 확인하고, 노드 공유 정보와 전체 실행 설정을 구분한 뒤, 필드 지원 범위에 따라 변환하는 것이 핵심 순서입니다. 글을 읽고 나면 텍스트가 Base64 통합 구독인지, 네이티브 JSON인지, 아니면 VMess·VLESS·Trojan·Shadowsocks 공유 링크인지 직접 판단할 수 있습니다.

먼저 어떤 형식인지 확인하기

‘구독’은 하나의 파일 규격이 아니라 배포 방식입니다. 클라이언트가 구독 주소에 접속하면 서버는 Base64로 인코딩한 여러 줄의 공유 링크를 반환할 수도 있고, 줄 단위 텍스트나 JSON 노드 목록, 특정 클라이언트용 설정 객체를 그대로 반환할 수도 있습니다. 주소가 https://로 시작한다는 사실만으로는 전송 방식만 알 수 있으며, 응답 본문의 구조까지 판단할 수는 없습니다.

개별 공유 링크는 하나의 아웃바운드 노드를 설명하며, 대표적인 접두사는 vmess://, vless://, trojan://, ss://입니다. 일반적으로 서버 주소, 포트, 인증 정보, 전송 방식, TLS 매개변수가 포함됩니다. 통합 구독은 여러 공유 링크를 하나의 응답에 담고, 클라이언트가 업데이트할 때 다시 내려받아 해당 구독 그룹을 갱신합니다.

네이티브 JSON 설정은 범위가 더 넓습니다. inbounds, outbounds, routing, dns, log를 동시에 포함할 수 있어 원격 노드뿐 아니라 로컬 수신 포트, 라우팅 규칙, DNS 동작까지 지정합니다. 전체 JSON을 일반 구독으로 가져오면 클라이언트가 이를 받아들이지 않을 수 있습니다.

3가지
통합 구독, 네이티브 JSON, 공유 링크
4개 접두사
VMess、VLESS、Trojan、Shadowsocks
36자
하이픈이 포함된 표준 UUID 길이
10808
일반적인 로컬 SOCKS 수신 포트
확인한 내용 가능성이 높은 형식 적합한 가져오기 경로
긴 영문자·숫자 문자열이며 끝에 등호가 하나 또는 두 개 붙을 수 있음 Base64 통합 구독 구독 그룹 또는 구독 설정
중괄호로 시작하며 inbounds와 outbounds를 포함함 네이티브 JSON 설정 사용자 지정 설정 또는 코어 설정 경로
vmess://, vless:// 등의 접두사로 시작함 개별 공유 링크 클립보드 가져오기 또는 QR 코드 스캔
여러 줄로 구성되며 각 줄이 프로토콜 접두사로 시작함 전체 인코딩되지 않은 통합 목록 클라이언트의 구독 파싱 기능에 따라 다름

결론: 본문을 먼저 확인하고 URL 접미사로 형식을 추측하지 마세요

구독 주소가 .json으로 끝나더라도 Base64 텍스트를 반환할 수 있으며, 파일 확장자가 없는 API가 JSON을 반환할 수도 있습니다. 문제를 확인할 때는 실제 응답의 앞부분 수십 글자, HTTP 상태, 응답 유형을 확인한 뒤 사용할 가져오기 경로를 결정해야 합니다.

Base64 통합 구독 풀어보기

가장 흔한 기존 구독 구조는 여러 공유 링크를 줄바꿈으로 연결한 다음, 전체 텍스트를 한 번 Base64로 인코딩하는 방식입니다. Base64는 문자 인코딩일 뿐 암호화나 필드 검증을 수행하지 않습니다. 디코딩에 성공했다는 것은 문자 수준에서 복원할 수 있다는 뜻일 뿐, 모든 노드를 현재 코어가 인식한다는 의미는 아닙니다.

표준 Base64 문자표에는 대소문자, 숫자, 더하기 기호, 슬래시가 포함되며 끝부분은 등호로 패딩할 수 있습니다. 일부 서비스는 URL-safe 변형을 사용해 더하기 기호를 하이픈으로, 슬래시를 밑줄로 바꾸고 끝의 패딩을 생략합니다. 클라이언트가 표준 문자표만 허용하면 ‘구독 내용이 비어 있음’ 또는 ‘형식이 잘못됨’ 오류가 발생할 수 있습니다.

인코딩 전 통합 콘텐츠 예시:

vmess://eyJ2IjoiMiIsInBzIjoiV00tMDEiLCJhZGQiOiJleGFtcGxlLmNvbSJ9
vless://[email protected]:443?encryption=none&security=tls&type=ws&path=%2Fedge#VL-01
trojan://[email protected]:443?security=tls&sni=example.com#TR-01

처리 순서:
HTTP 응답 본문 → 앞뒤 공백 제거 → 전체 Base64 디코딩 → 줄바꿈으로 분리 → 각 프로토콜 링크 파싱

VMess 공유 링크 자체도 ‘접두사 + Base64 JSON’ 구조를 자주 사용하므로 통합 구독에는 두 단계의 인코딩이 포함될 수 있습니다. 외부 계층은 노드 목록을 묶는 용도이고, 내부 계층은 VMess 공유 형식입니다. 외부 계층을 디코딩한 뒤에는 줄 단위 링크에서 멈추고, 각 vmess:// 뒤의 내용을 개별적으로 디코딩해야 합니다. VLESS와 Trojan은 일반적으로 URI 쿼리 매개변수를 사용하므로 전체 링크를 다시 Base64로 디코딩할 필요가 없습니다.

네이티브 JSON을 노드 목록과 동일하게 볼 수 없는 이유

네이티브 V2Ray 또는 Xray JSON은 코어 실행 설정입니다. 데이터가 어떤 로컬 인바운드로 들어오고, 어떤 라우팅 규칙과 일치하며, 어느 아웃바운드 연결로 전달되는지, 도메인을 어떻게 해석할지를 정의합니다. 하나의 노드 아웃바운드는 outbounds 배열의 한 항목일 뿐이며, 전체 설정에는 direct, block 같은 여러 아웃바운드 태그가 포함될 수 있습니다.

아래 축약 예시는 구조의 계층을 보여 줍니다. 127.0.0.1:10808에서 수신하는 SOCKS 인바운드가 로컬 트래픽을 받고, proxy라는 VLESS 아웃바운드가 원격 서버의 443 포트에 연결합니다. 실제 사용 시 전송 계층, TLS 또는 REALITY 매개변수는 streamSettings에 들어갑니다.

{
  "inbounds": [
    {
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "udp": true
      }
    }
  ],
  "outbounds": [
    {
      "tag": "proxy",
      "protocol": "vless",
      "settings": {
        "vnext": [
          {
            "address": "example.com",
            "port": 443,
            "users": [
              {
                "id": "11111111-1111-4111-8111-111111111111",
                "encryption": "none"
              }
            ]
          }
        ]
      }
    }
  ]
}

공유 링크 또는 구독

추천

클라이언트가 로컬 인바운드, 로그, 기본 라우팅을 생성하고 노드는 원격 연결에 필요한 필드만 제공합니다. 이전 작업 부담이 비교적 적습니다.

적합한 용도: v2rayN, v2rayNG, v2flyNG에서 일상적인 노드 관리

네이티브 JSON

인바운드, 아웃바운드, DNS, 라우팅, 정책을 모두 제어할 수 있지만 코어마다 지원하는 필드 집합이 다를 수 있습니다.

적합한 용도: 사용자 지정 라우팅 경로 또는 정밀한 코어 동작이 필요한 경우

클라이언트 백업

노드 외에도 구독 그룹, UI 옵션, 로컬 데이터베이스 정보가 저장될 수 있어 일반적으로 같은 클라이언트에서 복원할 때 적합합니다.

적합한 용도: 동일한 클라이언트 버전 간 설정 이전

JSON에서 공유 링크를 추출할 때 address, port, id만 복사해서는 안 됩니다. streamSettings.network, security, WebSocket 경로, HTTP Host, gRPC serviceName, TLS serverName, REALITY의 publicKey·shortId·fingerprint도 확인해야 합니다. 핵심 필드 하나라도 빠지면 문법은 맞지만 핸드셰이크에 실패하는 링크가 될 수 있습니다.

반대로 변환할 때도 정보가 손실됩니다. 개별 공유 링크는 복잡한 routing.rules, DNS hosts 매핑, 여러 인바운드 포트, 로드 밸런서, 체인 프록시를 대개 완전히 담을 수 없습니다. 공유 링크를 가져오면 클라이언트가 자체 템플릿에 따라 이러한 로컬 부분을 다시 생성하며, 원본 JSON의 모든 동작을 복원하는 것은 아닙니다.

결론: 변환의 경계는 원격 아웃바운드로 설정하세요

클라이언트 간 노드만 이전해야 한다면 서버 아웃바운드에 필요한 필드만 변환하세요. DNS, 라우팅 분기, 여러 인바운드를 유지해야 한다면 네이티브 JSON을 이전하고, 대상 코어가 각 설정 구간을 지원하는지 확인해야 합니다.

VMess, VLESS 및 기타 공유 링크의 필드 차이

VMess의 일반적인 공유 형식은 JSON 객체를 인코딩한 뒤 vmess:// 뒤에 붙입니다. 대표적인 필드는 버전 v, 메모 ps, 주소 add, 포트 port, 사용자 식별자 id, 추가 ID aid, 암호화 방식 scy, 전송 네트워크 net, 위장 유형 type, Host, 경로, TLS, SNI, ALPN, fingerprint입니다. 이 형식은 클라이언트 생태계에서 오랫동안 확장되어 왔으므로 일부 신규 필드는 구버전 클라이언트에서 무시될 수 있습니다.

VLESS는 표준 URI에 가깝습니다. 사용자 정보 위치에는 UUID를 넣고, 호스트와 포트에는 서버 주소를 넣으며, 쿼리 매개변수로 전송 계층과 보안 계층을 설명하고, 해시 기호 뒤의 fragment는 노드 메모입니다. VLESS의 encryption은 일반적으로 none이며, 이는 TLS 활성화 여부가 아닙니다. TLS와 REALITY 같은 보안 방식은 security 매개변수로 지정합니다.

공유 필드 의미 일반적인 오류
address / add 원격 서버 도메인 또는 IP 복사 과정에서 프로토콜 접두사나 경로가 섞임
port 원격 수신 포트(예: 443) 로컬 10808 포트로 잘못 입력함
id VMess 또는 VLESS 사용자 UUID 문자 누락, 공백 포함 또는 잘못된 사용자 사용
type 전송 유형(예: tcp, ws, grpc) 서버의 전송 방식과 불일치
security 전송 보안 방식(예: tls, reality, none) 프로토콜 자체의 암호화 필드와 혼동함
sni / serverName TLS 핸드셰이크에 사용할 서버 이름 IP를 입력하거나 서버가 요구하는 도메인을 누락함
path WebSocket HTTP 경로 슬래시 또는 퍼센트 디코딩 단계가 잘못됨
flow VLESS flow 방식(예: xtls-rprx-vision) 일반 TLS 노드에 Vision을 잘못 설정함
pbk / sid REALITY 공개 키와 shortId 서버의 비공개 매개변수를 클라이언트 필드에 입력함
VLESS 링크 구조 예시:

vless://UUID@서버:포트
?encryption=none
&security=reality
&type=tcp
&sni=핸드셰이크 도메인
&fp=chrome
&pbk=REALITY 공개 키
&sid=shortId
&flow=xtls-rprx-vision
#노드 메모

Trojan 링크는 사용자 정보 위치에 비밀번호를 넣고, 뒤에 security, sni, type, path 등의 쿼리 매개변수를 추가할 수 있습니다. Shadowsocks 공유 링크는 주로 암호화 방식, 비밀번호, 주소, 포트를 표현하며, 확장 전송 매개변수의 호환성은 구체적인 형식에 따라 달라집니다. 변환 도구가 기본 필드만 인식하면 노드 인증 정보는 유지하더라도 플러그인이나 전송 설정을 잃을 수 있습니다.

URI의 노드 메모, 경로, Host는 퍼센트 인코딩될 수 있습니다. 예를 들어 공백은 %20, 쿼리 매개변수의 슬래시는 %2F로 표시될 수 있습니다. 올바른 처리 방법은 URI 규칙에 따라 각 구성 요소를 파싱하는 것이며, 전체 링크에 문자열 치환을 반복 적용하는 것이 아닙니다. 해시, 물음표, 연결 기호를 너무 일찍 디코딩하면 필드 경계가 바뀔 수 있습니다.

세 가지 형식을 안전하게 변환하는 절차

변환의 첫 번째 목표는 텍스트 모양을 같게 만드는 것이 아니라 연결에 필요한 필드를 보존하는 것입니다. 먼저 원본 형식을 확인하고, 프로토콜·주소·포트·인증·전송·보안 계층·메모를 최소한 기록하는 통합 노드 데이터 모델을 만드세요. 마지막으로 대상 클라이언트나 생성기가 대상 형식에 맞춰 출력하도록 합니다.

  1. 원본 콘텐츠 식별

    응답 시작 부분, 프로토콜 접두사, JSON 최상위 키를 확인합니다. 구독 URL이라면 먼저 HTTP 상태가 200인지 확인하고, 전체 Base64 디코딩이 필요한지 판단합니다.

  2. 노드 분리

    통합 구독은 LF 또는 CRLF로 줄을 나누고 빈 줄을 제거합니다. 각 링크는 프로토콜 접두사에 맞는 파서를 사용하며, VLESS 매개변수를 VMess에 적용하지 마세요.

  3. 필드 정규화

    서버, 포트, 사용자 식별자, 전송 유형, TLS 또는 REALITY 매개변수를 통일해 저장하고, WebSocket path, gRPC serviceName, SNI는 각각 별도로 보존합니다.

  4. 코어 확인

    v2rayN에서 ‘설정’ → ‘매개변수 설정’ → ‘Core 유형’을 확인해 선택한 코어가 노드에 사용된 프로토콜, REALITY 또는 XTLS Vision 필드를 지원하는지 확인합니다.

  5. 가져오기 및 테스트

    먼저 노드 하나만 가져와 코어 로그에 unknown field, failed to find an available destination, TLS handshake 등의 메시지가 나타나는지 확인한 뒤 일괄 변환하세요.

v2rayN에서는 일반적으로 구독을 구독 그룹에 추가한 뒤 모든 구독 업데이트를 실행합니다. 개별 공유 링크는 클립보드로 가져오는 편이 적합합니다. 전체 JSON을 불러와야 한다면 클라이언트가 제공하는 사용자 지정 설정 기능을 사용하고, JSON 파일의 URL을 일반 구독 주소 입력란에 넣지 마세요. 가져온 뒤에는 활성 서버를 선택하고 시스템 프록시 또는 필요한 TUN 모드를 활성화해야 합니다.

v2rayNG와 v2flyNG에서는 구독 설정이 원격 주소와 업데이트 결과를 저장하고, 클립보드 가져오기는 개별 공유 링크를 처리합니다. v2rayNG는 Xray 코어를 사용하고 v2flyNG는 v2fly 코어를 사용하므로, 일반적인 VMess·VLESS·Trojan·Shadowsocks 지원 범위와 최신 전송 필드 수용 정도가 완전히 같지 않습니다. 이전 후에는 노드 이름이 표시되는지만 보지 말고 노드 상세 정보에서 항목별로 확인해야 합니다.

결론: 노드 하나를 먼저 변환한 뒤 전체 구독을 처리하세요

단일 노드로 가져오기, 코어 시작, 실제 연결을 차례로 검증하면 필드 매핑 문제를 빠르게 발견할 수 있습니다. 수십 개 노드를 바로 변환하면 이름 중복, 일부 프로토콜 비호환, 로그 혼재로 인해 문제를 찾기 어려워집니다.

구독을 가져온 뒤 비어 있을 때의 점검 순서

가져온 뒤 목록이 비어 있다고 해서 구독에 노드가 없는 것은 아닙니다. 네트워크 요청, 응답 디코딩, 줄 단위 식별, 프로토콜 호환성, 그룹 표시 중 어느 단계에서든 문제가 발생할 수 있습니다. 효율적인 점검은 앞 단계부터 시작해 클라이언트 설정을 반복해서 삭제하지 않는 것입니다.

먼저 구독 요청이 로그인 페이지, 속도 제한 안내, HTML 오류 페이지가 아닌 실제 본문을 반환했는지 확인하세요. 페이지가 200을 반환하더라도 액세스 토큰이 만료되어 안내 문구만 출력할 수 있습니다. 응답이 <html 또는 <!doctype로 시작하면 Base64 디코딩과 프로토콜 파싱으로 노드가 생성되지 않습니다.

구독 업데이트가 시간 초과될 때는 어떻게 하나요?

먼저 기기에서 구독 도메인에 접속할 수 있는지 확인하세요. 직접 연결할 수 없다면 기존의 정상 노드에 연결한 뒤 구독 설정에서 프록시를 통한 업데이트를 활성화합니다. 시스템 시간과 구독 주소가 완전히 복사되었는지도 확인하세요.

업데이트는 성공했지만 노드 목록이 비어 있나요?

업데이트 로그에서 새로 추가된 수를 확인하고, 응답 디코딩 후 vmess://, vless:// 등의 접두사가 나타나는지 확인하세요. JSON만 보인다면 노드 배열인지, inbounds와 outbounds를 포함한 전체 코어 설정인지 구분해야 합니다.

일부 노드만 가져와졌나요?

가져오지 못한 노드를 프로토콜과 전송 유형별로 분류하고 URL-safe Base64, REALITY 매개변수, gRPC serviceName, 메모의 특수 문자를 중점적으로 확인하세요. 구형 클라이언트는 인식할 수 없는 필드나 레코드 전체를 건너뛸 수 있습니다.

노드는 있지만 코어 시작에 실패하나요?

v2rayN에서 ‘설정’ → ‘매개변수 설정’ → ‘Core 유형’을 열어 코어를 확인한 뒤, 코어 로그의 첫 번째 오류를 살펴보세요. 포트가 사용 중이면 로컬 10808 등의 수신 포트를 확인하고, 필드 오류라면 노드 편집 화면에서 전송 계층과 보안 계층을 다시 확인하세요.

업데이트 후 수동 수정 사항이 덮어써지나요?

구독 노드는 일반적으로 원격 콘텐츠가 관리하므로 다시 업데이트하면 로컬 필드가 덮어써질 수 있습니다. 수정 사항을 장기간 유지하려면 노드를 별도 그룹에 복사하거나 원본 구독에서 해당 매개변수를 수정하세요. 구독 그룹의 임시 복사본만 수정해서는 안 됩니다.

구독을 디코딩할 수 있고 공유 링크도 개별적으로 가져올 수 있지만 일괄 업데이트 후 비어 있다면, 응답 형식이 클라이언트 구독 파서의 예상과 다른 것이 흔한 원인입니다. 예를 들어 서버가 JSON 배열을 직접 반환하지만 클라이언트는 Base64로 인코딩된 여러 줄 링크만 처리할 수 있습니다. 이 경우 구독 출력 형식을 조정하거나 해당 JSON 구조를 명확히 지원하는 가져오기 방식을 선택해야 합니다.

노드는 가져와지지만 연결에 실패한다면 Base64를 더 살펴보는 것을 멈추세요. 이 경우 인코딩 단계는 이미 완료되었으므로 주소, 포트, UUID, 비밀번호, SNI, WebSocket path, gRPC serviceName, REALITY publicKey, shortId, flow에 문제가 있을 가능성이 큽니다. 코어 로그에서 처음 나타나는 핸드셰이크 오류부터 하나씩 확인하는 것이 구독을 반복 업데이트하는 것보다 효과적입니다.

형식 선택과 장기 유지 관리 팁

v2rayN, v2rayNG, v2flyNG에서 여러 노드를 일상적으로 관리한다면 구독과 공유 링크를 함께 사용하는 방식이 업데이트에 편리합니다. 클라이언트는 로컬 인바운드, 시스템 프록시, 기본 라우팅을 생성하고 구독 소스는 원격 노드만 관리합니다. 특정 노드를 수정해야 할 때는 다음 업데이트에서 덮어써지지 않도록 구독 소스에서 먼저 수정하세요.

복잡한 DNS, 도메인 또는 IP별 라우팅, 여러 인바운드 포트, 체인 아웃바운드가 필요하다면 네이티브 JSON이 더 적합합니다. 이러한 설정은 대상 코어와 지원 버전을 기록하고 Core 유형을 바꾼 뒤 필드를 다시 확인해야 합니다. Xray와 v2fly의 설정 구조에는 공통점이 많지만 REALITY, XTLS Vision, 일부 확장 기능은 필드 이름만으로 호환성을 판단할 수 없습니다.

사용 목적 권장 형식 중점 관리 항목
여러 노드 정기 업데이트 통합 구독 그룹, 업데이트 시간, 응답 형식
노드 하나를 임시로 전달 공유 링크 프로토콜 필드, URI 인코딩, 메모
라우팅 및 DNS 정밀 제어 네이티브 JSON 코어 호환성, 설정 계층, 아웃바운드 태그
클라이언트 간 이전 표준 공유 필드 노드 하나를 먼저 검증한 뒤 일괄 생성

설정을 저장할 때는 ‘노드 데이터’와 ‘클라이언트 상태’도 구분해야 합니다. 노드 데이터에는 주소, 포트, 인증, 전송 매개변수가 포함되고, 클라이언트 상태에는 현재 선택한 노드, 구독 그룹, 시스템 프록시 모드, TUN 설정, 라우팅 규칙이 포함됩니다. 공유 링크만 내보내면 후자는 함께 이동하지 않으며, 이는 내보내기 실패가 아니라 형식의 경계입니다.

선택은 다음의 간단한 규칙으로 정리할 수 있습니다. 여러 노드를 자동으로 업데이트하려면 구독을 사용하고, 노드 하나를 전달하려면 공유 링크를 사용하며, 전체 코어 실행 동작을 재현하려면 네이티브 JSON을 사용하세요. 변환할 때는 먼저 대상 형식으로 표현할 수 없는 필드를 나열한 다음, 손실을 감수할지 클라이언트가 다시 만들도록 할지 원본 설정을 보존할지 결정합니다.

클라이언트 설치 패키지로 이동 Windows, macOS, Android, Linux