V2Ray 구독 형식 총정리: Base64, 네이티브 JSON, 공유 링크 변환 방법

Base64 구독, 네이티브 JSON 설정, VMess·VLESS 공유 링크는 서로 다른 데이터 형식입니다. 외부 컨테이너와 노드 프로토콜을 먼저 확인한 뒤 디코딩·분리·가져오기를 진행하면 형식 오류와 필드 손실을 줄일 수 있습니다.

이 글의 핵심

V2Ray 구독을 가져오거나 이전하고 문제를 해결하려는 사용자를 위해 Base64 텍스트, 네이티브 JSON, 공유 링크의 구조적 차이를 설명합니다. 형식 확인부터 클라이언트 가져오기까지의 흐름과 변환 중 누락되기 쉬운 전송·TLS·라우팅·구독 업데이트 정보를 함께 다룹니다.

먼저 구독, 공유 링크, 실행 설정을 구분하기

‘구독’은 보통 주기적으로 요청할 수 있는 주소를 뜻합니다. 클라이언트가 해당 주소에 접속하면 서버가 여러 노드 데이터를 반환하고, 클라이언트는 이를 로컬 데이터베이스에 저장합니다. 구독 주소 자체는 노드가 아니라 지속적으로 갱신되는 데이터 입구에 가깝습니다. 같은 주소가 오늘은 노드 8개를 반환해도 다음 업데이트에서는 10개가 될 수 있습니다.

‘공유 링크’는 단일 노드를 나타냅니다. 일반적으로 vmess:// 또는 vless://로 시작하며, 서버 주소·포트·사용자 식별자·전송 방식·TLS 매개변수를 포함합니다. 여러 공유 링크를 한 줄씩 배치한 뒤 전체를 인코딩해 구독 응답으로 만들 수 있지만, 개별 링크 자체에는 자동 업데이트 기능이 없습니다.

‘네이티브 JSON’은 일반적으로 V2Ray 또는 Xray 코어가 읽을 수 있는 실행 설정입니다. inbounds, outbounds, routing, dns 등의 객체를 포함하며, 원격 노드뿐 아니라 로컬 수신 포트, 트래픽 진입점, 라우팅 동작까지 정의합니다. 완전한 실행 설정을 일반 구독처럼 가져오면 클라이언트가 노드 목록만 분리하지 못할 수 있습니다.

구독 응답

데이터 수량
일반적으로 여러 노드
일반적인 외부 형식
Base64 텍스트
업데이트 방식
구독 주소로 다시 요청
주요 용도
노드 일괄 관리

핵심은 노드 모음과 이후 업데이트이며, 클라이언트의 모든 설정을 저장하는 용도는 아닙니다.

단일 노드 링크

데이터 수량
링크 하나당 노드 하나
일반적인 접두사
vmess 또는 vless
업데이트 방식
링크를 다시 가져오기
주요 용도
공유 및 빠른 이전

소수의 노드를 옮길 때 적합하지만, 구독 그룹의 원격 업데이트 관계는 유지할 수 없습니다.

네이티브 JSON

최상위 객체
inbounds 및 outbounds
로컬 포트
10808, 10809 등을 포함할 수 있음
라우팅 규칙
완전하게 표현 가능
주요 용도
코어 실행 설정

가져오기 전에 클라이언트가 노드 파싱만이 아니라 전체 설정 실행을 지원하는지 확인해야 합니다.

클라이언트 로컬 데이터

노드 기록
구독 또는 수동 추가로 생성
그룹 정보
클라이언트가 관리
시스템 프록시
이 기기의 설정에 해당
라우팅 모드
구독과 별도로 관리될 수 있음

노드 이전은 로컬 포트, 라우팅 모드, 시스템 프록시 상태의 이전을 의미하지 않습니다.

결론: 변환 전에 데이터 계층을 확인하기

정기적인 업데이트가 필요하면 구독 주소를 유지하고, 단일 노드만 옮길 때는 공유 링크를 사용하세요. 로컬 인바운드, DNS, 라우팅 동작까지 복사해야 할 때만 전체 JSON 설정을 고려하면 됩니다.

Base64 구독 확인 및 디코딩 방법

기존 V2Ray 구독 응답은 여러 공유 링크를 줄바꿈으로 이어 붙인 뒤 전체 UTF-8 텍스트를 Base64로 인코딩하는 경우가 많습니다. 브라우저에서 구독 주소를 직접 열면 문자·숫자·더하기 기호·슬래시·등호로 이루어진 긴 문자열이 표시될 수 있습니다. 외부 형식을 디코딩해야 비로소 줄마다 배치된 vmess:// 또는 vless:// 링크가 나타납니다.

판단할 때 문자열이 ‘Base64처럼 보이는지’만 확인해서는 안 됩니다. 일반 텍스트, 압축 데이터, 일부 URL 안전 인코딩도 비슷한 형태를 띨 수 있습니다. 먼저 응답의 콘텐츠 유형과 앞부분의 몇 글자를 확인한 뒤 디코딩하는 것이 안전합니다. 결과는 유효한 UTF-8 텍스트여야 하며, 비어 있지 않은 각 줄에는 인식 가능한 프로토콜 접두사가 있어야 합니다. 디코딩 후에도 인코딩된 텍스트가 남는다면 무작정 반복 디코딩하지 말고 이중 인코딩 여부를 확인하세요.

응답 가져오기 컨테이너 확인 텍스트 디코딩 줄별 파싱 그룹에 저장

외부 형식을 디코딩한 일반적인 구조

vmess://인코딩된 단일 노드 데이터
vless://사용자 식별자@node-a.example:443?encryption=none&security=tls&type=ws&path=%2Fedge#A-WS
vless://사용자 식별자@node-b.example:443?encryption=none&security=reality&type=tcp&flow=xtls-rprx-vision#B-TCP

위 내용은 구조를 보여 주기 위한 예시이며 실제 접속 자격 증명을 제공하지 않습니다. 실제로 파싱할 때는 줄바꿈 문자로 나누고 Unix의 LF와 Windows의 CRLF를 모두 처리해야 합니다. 빈 줄은 무시해도 되지만 각 줄의 앞뒤 공백은 먼저 제거해야 합니다. 서버 응답이 줄바꿈 없이 끝나더라도 마지막 링크는 반드시 파싱해야 합니다.

Base64에는 표준 알파벳과 URL 안전 알파벳이 있습니다. 표준 형식은 더하기 기호와 슬래시를 사용하고, URL 안전 형식은 하이픈과 밑줄을 사용합니다. 끝의 등호 패딩이 생략될 수도 있습니다. 일반적인 클라이언트는 이러한 차이를 처리하지만, 직접 다룰 때는 먼저 알파벳을 통일하고 길이를 맞춰야 합니다. 인코딩 길이를 4로 나눈 나머지가 2이면 등호 2개, 3이면 등호 1개를 추가합니다. 나머지가 1이면 보통 텍스트가 잘린 것입니다.

VMess·VLESS 공유 링크의 필드 차이

VMess와 VLESS 공유 링크는 인코딩 방식이 다릅니다. 일반적인 VMess 링크는 vmess:// 뒤에 Base64로 인코딩된 JSON을 두며, 객체에는 add, port, id, net, path, host, tls, sni 등의 필드가 포함될 수 있습니다. 일부 구형 형식에는 v, ps, aid도 있으며, 흔한 설정 버전 값은 2이고 최신 배포 환경의 aid는 대개 0입니다.

VLESS 공유 링크는 표준 URI에 가깝습니다. 사용자 식별자는 사용자 이름 영역에, 서버 주소와 포트는 호스트 영역에 있으며, 전송 및 보안 매개변수는 쿼리 문자열에 들어갑니다. 노드 메모는 해시 뒤의 프래그먼트에 배치됩니다. 예를 들어 type=ws는 WebSocket, security=tls는 TLS를 뜻하고, path=%2Fedge는 디코딩하면 /edge가 됩니다. 매개변수 순서는 보통 의미에 영향을 주지 않지만 이름과 값은 올바르게 URL 인코딩해야 합니다.

필드 용도 VMess에서 흔한 필드 VLESS에서의 일반적인 위치 변환 시 주의할 점
서버 add URI 호스트 부분 IPv6 주소의 대괄호를 유지해야 함
포트 port URI 포트 부분 1~65535 사이의 정수여야 함
사용자 식별자 id URI 사용자 정보 부분 복사할 때 공백을 추가하지 말 것
전송 유형 net type ws, tcp, grpc를 서로 직접 혼용할 수 없음
전송 경로 path path 또는 serviceName WebSocket 경로와 gRPC 서비스 이름은 의미가 다름
보안 계층 tls security TLS와 Reality에 필요한 매개변수가 다름
서버 이름 sni sni 노드 메모로 서버 이름을 대신하지 말 것

변환은 단순히 접두사만 바꾸는 작업이 아닙니다

VMess와 VLESS는 서로 다른 프로토콜이므로 vmess://vless://로 직접 바꿀 수 없습니다. 서버 주소·포트·전송 계층이 같더라도 서버에 해당 프로토콜의 인바운드가 있어야 하며 사용자 인증 방식도 일치해야 합니다. ‘상호 변환’이란 서버가 대상 프로토콜도 지원한다는 전제에서 공통 연결 매개변수를 다른 링크 구조에 매핑하는 작업에 가깝습니다.

전송 필드는 의미에 맞게 매핑해야 합니다. 예를 들어 VMess JSON의 net=ws는 VLESS의 type=ws로 매핑할 수 있고, path=/edge는 URL 인코딩된 쿼리 매개변수로 바꿔야 합니다. 하지만 Reality에 필요한 공개 키·짧은 식별자·핑거프린트·Flow는 기존 VMess + TLS 링크에 없으므로 변환 도구가 임의로 값을 만들어 낼 수는 없습니다.

결론: 변환은 기존 매개변수만 매핑하기

대상 링크에 공개 키, 짧은 식별자, SNI 또는 gRPC 서비스 이름이 없으면 노드 제공처에서 완전한 매개변수를 받아야 합니다. 기본값으로 채우면 형식은 올바르지만 연결할 수 없는 링크가 되는 경우가 많습니다.

네이티브 JSON과 공유 링크를 서로 정리하는 방법

네이티브 JSON에서 공유 링크를 추출할 때는 먼저 outbounds에서 프로토콜이 VMess 또는 VLESS인 아웃바운드를 찾고 서버·포트·사용자 필드를 읽습니다. 이어 streamSettings도 확인해야 합니다. network는 전송 유형을, security는 TLS 또는 Reality를 결정하며, 구체적인 WebSocket·gRPC·TCP 설정은 해당 하위 객체에 있습니다.

반대로 JSON을 생성할 때 공유 링크로 복원할 수 있는 것은 원격 아웃바운드와 전송 매개변수뿐입니다. 로컬 SOCKS 포트, HTTP 포트, DNS 서버, 로그 수준, 전체 라우팅 규칙은 보통 포함되지 않습니다. 따라서 공유 링크를 JSON으로 변환한 뒤에는 클라이언트나 설정 생성기가 로컬 부분을 추가해야 합니다. 흔한 로컬 구성은 SOCKS 리스닝 127.0.0.1:10808, HTTP 리스닝 127.0.0.1:10809이지만 실제 포트는 현재 클라이언트 설정을 따르세요.

{
  "log": {
    "loglevel": "warning"
  },
  "inbounds": [
    {
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks"
    }
  ],
  "outbounds": [
    {
      "protocol": "vless",
      "settings": {
        "vnext": [
          {
            "address": "node.example",
            "port": 443,
            "users": [
              {
                "id": "예시 값은 숨김 처리됨",
                "encryption": "none"
              }
            ]
          }
        ]
      }
    }
  ]
}

이 JSON은 계층 구조를 설명하기 위한 예시일 뿐입니다. 실제 설정에는 노드와 일치하는 streamSettings가 필요하며, 직접 연결 및 차단용 아웃바운드가 추가로 필요할 수도 있습니다. 전송 설정이 빠진 구성을 그대로 가져오고 서버가 실제로 WebSocket + TLS를 사용한다면 코어는 일치하지 않는 기본 전송으로 접속을 시도합니다. 로그에는 대개 연결 종료 또는 핸드셰이크 실패가 표시됩니다.

완전한 설정에서 단일 노드 링크를 내보낼 때는 라우팅 정보를 표현할 수 없다는 문제도 생깁니다. 도메인 분기, GeoIP, GeoSite, 프로세스 규칙, DNS 조회 정책은 실행 설정에 속하며 단일 노드 URI의 필드가 아닙니다. 올바른 방법은 노드와 라우팅을 따로 옮기는 것입니다. 노드는 공유 링크로 가져오고, 라우팅 규칙은 클라이언트의 백업·가져오기 기능이나 수동 설정으로 복원하세요.

  1. JSON 최상위에 outbounds가 있는지 확인하고 대상 아웃바운드의 프로토콜 이름을 확인합니다.
  2. 서버 주소·포트·사용자 매개변수를 읽고 예시나 만료된 기록은 복사하지 않습니다.
  3. streamSettings에서 전송, 보안 계층, SNI, 경로, 서비스 이름을 추출합니다.
  4. 대상 프로토콜에 맞춰 공유 링크를 생성하고 경로·메모·쿼리 매개변수를 URL 인코딩합니다.
  5. 클라이언트로 가져온 뒤 상세 화면에서 포트·전송·TLS·SNI·사용자 식별자를 항목별로 대조합니다.
  6. 먼저 단일 노드를 테스트한 다음 구독 응답에 일괄 추가해 잘못된 매개변수가 전체 그룹으로 퍼지는 것을 막습니다.

세 클라이언트의 가져오기 범위와 구체적인 사용 방법

v2rayN은 데스크톱 클라이언트로 구독 그룹, 단일 노드 링크, 사용자 지정 설정을 관리할 수 있습니다. 7.x 계열 화면을 기준으로 구독 주소를 추가하려면 ‘구독 그룹’ → ‘구독 그룹 설정’으로 이동해 그룹을 만든 뒤 구독 주소를 입력하고 저장합니다. 이후 ‘구독 그룹’ → ‘모든 구독 업데이트’를 실행하세요. 클립보드에 여러 공유 링크가 있다면 ‘서버’ → ‘클립보드에서 여러 URL 가져오기’를 사용할 수 있습니다.

v2rayNG는 Xray 코어로 일반적인 VMess 및 VLESS 노드를 처리합니다. Android에서 구독을 추가하려면 왼쪽 위 메뉴를 열고 ‘구독 그룹 설정’으로 이동한 다음 오른쪽 위의 추가 버튼으로 주소를 저장하고 메인 화면에서 업데이트를 실행하세요. 단일 또는 여러 공유 링크는 먼저 클립보드에 복사한 뒤 오른쪽 위 ‘+’에서 ‘클립보드에서 가져오기’를 선택하면 됩니다. 세부 버전에 따라 문구는 조금 다를 수 있지만 메뉴는 구독 그룹과 추가 버튼을 중심으로 구성됩니다.

v2flyNG는 v2fly 코어를 사용하며 VMess 및 V2Ray 코어 호환 설정이 중심인 환경에 적합합니다. 구독 및 클립보드 가져오기 흐름은 Android의 일반적인 화면 구성과 비슷하지만, 인식 가능한 프로토콜 범위는 코어의 기능에 따라 달라집니다. 다른 코어에서만 구현된 보안 방식이나 전송 조합이 구독에 포함되어 있으면 링크가 파싱되어 표시되더라도 실행 시 실패할 수 있습니다.

클라이언트 주요 플랫폼 Base64 다중 노드 구독 공유 링크 전체 JSON
v2rayN 7.x 데스크톱 구독 그룹별 업데이트 가능 클립보드 일괄 가져오기 지원 사용자 지정 설정으로 사용할 수 있으나 코어 확인 필요
v2rayNG 1.10.x Android 주소를 저장하고 업데이트 가능 클립보드 및 파일 가져오기 지원 가져오기 가능 여부는 설정 구조와 Xray 코어에 따라 달라짐
v2flyNG 1.x Android 구독 그룹 관리 가능 V2Ray 호환 링크에 적합 v2fly 코어 지원 범위를 충족해야 함

가져온 후 반드시 확인할 여섯 가지 매개변수

변환 실패·빈 구독·문자 깨짐 문제 해결 방법

변환 실패는 보통 구독 응답 가져오기, 외부 형식 디코딩, 개별 노드 파싱의 세 단계에서 발생합니다. 문제를 해결할 때는 이 순서대로 확인하고 처음부터 프로토콜 매개변수를 수정하지 마세요. 구독 요청이 이미 오류 페이지를 반환했다면 이후의 Base64 디코딩과 노드 가져오기도 유효한 결과를 만들 수 없습니다.

먼저 HTTP 상태, 응답 바이트 수, 디코딩 후 비어 있지 않은 줄 수라는 세 가지 수치를 기록해 보세요. 예를 들어 상태가 정상이고 응답이 18KB이며 디코딩 후 24줄이 나왔다면 구독 가져오기와 외부 디코딩은 대체로 완료된 것입니다. 클라이언트에 노드가 20개만 표시된다면 나머지 4줄의 프로토콜 접두사나 필드 형식을 확인하세요.

구독 업데이트 후 노드가 0개로 표시되면 어떻게 하나요?

기존 그룹을 먼저 삭제하지 마세요. 통제된 환경에서 구독 주소를 확인하고 응답 유형을 점검합니다. 내용이 웹페이지 태그로 시작한다면 요청이 안내 페이지로 리디렉션된 경우가 많습니다. 주소가 완전한지 확인한 뒤 클라이언트에 다시 저장하고 업데이트하세요.

Base64 디코딩에서 길이가 올바르지 않다고 표시되면 어떻게 하나요?

먼저 줄바꿈과 앞뒤 공백을 제거한 뒤 표준 알파벳과 URL 안전 알파벳 중 어느 형식인지 확인하세요. 길이를 4로 나눈 나머지가 2이면 등호 2개, 3이면 1개를 추가하고, 1이면 원문을 다시 가져와야 합니다.

가져오기는 성공했지만 노드 이름이 모두 깨지면 어떻게 하나요?

구독 응답과 디코딩 결과를 UTF-8로 읽는지 확인하세요. 해시 뒤의 메모만 깨졌다면 URI 프래그먼트에 퍼센트 디코딩을 다시 적용하고, 전체 링크를 반복해서 디코딩하지 마세요.

VLESS 링크를 가져온 뒤 경로가 사라지면 어떻게 하나요?

원본 링크에 type=wspath=가 포함되어 있는지 확인하세요. 경로의 슬래시는 %2F로 인코딩해야 합니다. gRPC를 사용한다면 WebSocket 경로가 아니라 serviceName을 확인하세요.

같은 링크가 클라이언트마다 다르게 작동하는 이유는 무엇인가요?

먼저 클라이언트의 코어 계열과 버전을 비교한 뒤 노드 상세 정보에서 인식되지 않은 매개변수를 확인하세요. 링크 파싱 성공은 구조를 읽을 수 있다는 뜻일 뿐, 현재 코어가 해당 전송 및 보안 조합을 구현했다는 의미는 아닙니다.

로그로 필드 계층 오류 찾기

노드가 시작되지만 연결되지 않는다면 먼저 클라이언트 코어 로그를 확인하세요. DNS 조회 실패는 도메인이나 DNS 설정 문제일 가능성이 높고, 연결 시간 초과는 주소·포트·네트워크 경로 문제일 가능성이 큽니다. TLS 핸드셰이크 실패는 SNI·시스템 시간·보안 계층을 중점적으로 확인해야 합니다. 시작 단계에서 설정 필드 오류가 바로 발생하면 JSON 계층이나 현재 코어가 해당 필드를 인식하는지 확인하세요.

로컬 포트 충돌도 ‘가져오기는 올바르지만 사용할 수 없는’ 원인이 됩니다. 예를 들어 SOCKS 포트가 10808로 설정되어 있는데 다른 인스턴스가 이미 같은 포트를 사용하면 코어가 시작되지 않을 수 있습니다. v2rayN에서 ‘설정’ → ‘매개변수 설정’으로 들어가 포트를 확인하고 중복 실행 중인 인스턴스를 종료하세요. Android에서는 현재 연결을 먼저 중지한 뒤 대상 설정을 다시 시작합니다.

안전한 이전과 장기 관리 권장 사항

구독 주소로 노드 목록에 접근할 수 있으므로 민감한 설정처럼 관리해야 합니다. 클라이언트의 구독 그룹에 저장하고 스크린샷·공개 문서·대화 기록에는 전체 주소를 노출하지 마세요. 여러 기기 사이에서 옮길 때는 우선 클라이언트 자체의 설정 내보내기 기능을 사용하고, 완료 후 임시 파일을 삭제하세요.

실제 구독을 온라인 변환 페이지에서 처리하지 마세요. Base64는 인코딩일 뿐 기밀성을 제공하지 않습니다. 원문을 읽을 수 있는 서비스라면 그 안의 노드 매개변수도 확인할 수 있습니다. 구조를 점검해야 한다면 로컬에서 복사본을 만들고 사용자 식별자와 구독 쿼리 매개변수를 먼저 제거한 뒤 형식을 분석하세요.

장기적으로는 ‘노드 출처’와 ‘이 기기의 정책’을 분리해 관리해야 합니다. 구독은 노드 업데이트를 담당하고 클라이언트는 시스템 프록시·TUN·DNS·라우팅 분기를 담당합니다. 이렇게 하면 구독 목록이 바뀌어도 로컬 직접 연결 도메인, 차단 규칙, 리스닝 포트가 노드와 함께 실수로 덮어써지지 않습니다.

  1. 출처별로 독립적인 구독 그룹을 만들고, 모든 노드를 추적할 수 없는 하나의 목록에 합치지 마세요.
  2. 업데이트 전에 노드 수를 기록하고, 업데이트 후 추가·삭제·이름 변경 내역을 비교하세요.
  3. 검증을 마친 사용 가능한 노드 사본을 하나 보관해 구독이 일시적으로 비정상일 때 모든 설정을 사용할 수 없게 되는 상황을 막으세요.
  4. 변환할 때마다 VMess 노드 하나와 VLESS 노드 하나 이상을 표본 검사해 전송 계층 필드를 대조하세요.
  5. 클라이언트를 업그레이드한 뒤에는 자동 업데이트를 다시 활성화하기 전에 구독 업데이트, 노드 시작, 로컬 포트를 먼저 확인하세요.

결론: 노드 형식과 로컬 정책을 분리해 관리하기

구독은 노드 모음 업데이트만 담당하고, 공유 링크는 단일 노드 이전만 담당하며, JSON은 완전한 실행 구조를 표현합니다. 이 세 계층에 따라 데이터를 저장하면 나중에 클라이언트나 코어를 바꿀 때 호환성 문제를 더 쉽게 찾을 수 있습니다.

클라이언트 바로가기 플랫폼별 다운로드 옵션 보기