먼저 구독 URL, URL 요청 결과, 개별 노드 공유 링크를 구분한 뒤 VLESS over TCP + TLS 예제로 필드가 어떻게 대응되는지 살펴봅니다. 구독 업데이트 후 노드가 표시되지 않거나, 클립보드에서 JSON을 가져오지 못하거나, 노드는 가져왔지만 연결에 실패하는 경우에 유용합니다. 본문의 주소, UUID, 포트는 형식을 설명하기 위한 예시이며 실제 접속 가능한 서버 정보가 아닙니다.
세 가지 형식: URL, 노드 목록, 전체 설정
‘V2Ray 구독’은 하나의 파일 형식을 가리키지 않습니다. 일반적으로 제공받는 구독 URL은 HTTPS 주소이며, 클라이언트가 이 주소에 접속해야 노드 목록을 가져올 수 있습니다. 응답 본문은 줄마다 공유 링크가 나열된 텍스트일 수도 있고, 이 목록을 Base64로 인코딩한 문자열일 수도 있습니다. URL은 목록을 가져오고 업데이트하는 데 쓰이며, 본문은 노드 정보를 담습니다. 둘은 서로 대체할 수 없습니다.
| 형식 | 일반적인 구조 | 가져오기 경로 | 포함되는 정보 |
|---|---|---|---|
| Base64 구독 | 디코딩하면 여러 줄의 공유 링크가 나옴 | 구독 그룹에 등록한 URL | 주로 노드 연결 매개변수 |
| VLESS 공유 링크 | vless://UUID@호스트:포트?매개변수#이름 | 클립보드에서 가져오기 | 일반적으로 노드 하나를 설명 |
| 네이티브 JSON | inbounds, outbounds 등의 키 포함 | 사용자 지정 설정 메뉴 | 인바운드, DNS, 라우팅, 여러 아웃바운드 포함 가능 |
Base64는 인코딩이지 암호화가 아닙니다. 디코딩할 수 있는 사람은 서버 주소와 인증 정보도 볼 수 있습니다. 구독 URL, 디코딩한 노드 목록, 전체 설정을 공개 게시판에 올리지 마세요. 구독 URL에 포함된 토큰으로 다른 사람이 계속 업데이트를 가져갈 수도 있으므로, 비밀번호처럼 보이지 않는다는 이유로 공개해서는 안 됩니다.
형식 판별: 디코딩한 결과의 첫 단계 확인
여러 줄의 프로토콜 링크가 보이면 노드 목록으로, 인바운드와 아웃바운드가 포함된 객체가 보이면 전체 설정으로 처리하세요. 파일 확장자나 텍스트 길이만으로 형식을 판단하지 마세요.
v2rayN·v2rayNG: 올바른 가져오기 메뉴 선택
v2rayN은 데스크톱 클라이언트이고, v2rayNG는 Xray 코어를 사용하는 Android 클라이언트입니다. 두 클라이언트의 일반적인 구독 기능은 노드 목록을 대상으로 합니다. 지원되는 프로토콜과 매개변수는 클라이언트 및 코어 버전에 따라 달라질 수 있습니다. ‘JSON 지원’을 구독 업데이트 메뉴에서 임의의 JSON을 바로 받을 수 있다는 뜻으로 이해하면 안 됩니다.
구독 URL
권장제공업체에서 받은 구독 URL을 구독 그룹에 저장하세요. 이후에도 같은 주소에서 업데이트를 가져오므로 노드가 바뀌는 서비스에 적합합니다.
추천 용도: 주기적으로 업데이트할 노드 목록
개별 공유 링크
전체 vless:// 또는 vmess:// 링크를 복사한 다음 클립보드에서 가져오세요. 한 번 가져온다고 해서 업데이트 가능한 구독이 만들어지는 것은 아닙니다.
추천 용도: 단일 노드 테스트 및 매개변수 확인
사용자 지정 JSON
클라이언트의 사용자 지정 설정 기능을 사용하고, 설정이 선택한 코어와 호환되는지 확인하세요. 전체 설정은 DNS와 라우팅을 제어할 수 있으므로 서버 주소만 확인해서는 안 됩니다.
추천 용도: 전체 라우팅이나 특수 아웃바운드 설정을 유지해야 할 때
구독 그룹 만들기
v2rayN 메인 화면에서 「구독 그룹」 → 「구독 그룹 설정」으로 이동해 그룹을 추가하고 구독 URL을 입력하세요. 여기에 입력하는 것은 URL이며, Base64 문자열 전체를 붙여 넣는 곳이 아닙니다.
노드 업데이트
「구독 그룹」 메뉴로 돌아가 「전체 구독 업데이트(프록시 사용 안 함)」를 선택하세요. 기존 프록시를 통해서만 URL에 접속할 수 있다면 「프록시를 통해 업데이트」에 해당하는 메뉴를 시도하세요. 메뉴 이름과 문장 부호는 버전에 따라 조금 다를 수 있습니다.
개별 링크 테스트
v2rayN에서는 「서버」 → 「클립보드에서 URL 일괄 가져오기」를 선택하세요. v2rayNG에서는 메인 화면의 「+」 → 「클립보드에서 가져오기」를 선택합니다. 프로토콜 링크만 복사하고 따옴표나 설명 문구는 포함하지 마세요.
Android 구독
v2rayNG 메인 화면 오른쪽 위 메뉴에서 「구독 그룹 설정」으로 이동한 뒤 「+」를 눌러 URL을 추가하고 저장하세요. 메인 화면으로 돌아와 메뉴에서 「구독 업데이트」를 실행합니다. 버전에 따라 메뉴 이름이 다르면 구독 그룹 및 업데이트 기능을 기준으로 찾으세요.
v2flyNG는 v2fly 코어를 사용하므로 Xray용 확장 매개변수를 모두 그대로 적용해서는 안 됩니다. 특히 REALITY나 특정 흐름 제어 기능은 코어가 지원하는지 먼저 확인해야 합니다. 이 글의 필드 변환 예시는 Xray 기준이며, 다른 코어와의 호환성을 보장하지 않습니다.
Base64 디코딩과 재인코딩: 바깥쪽 포장만 변환
일반적인 Base64 구독은 각 노드 링크를 한 줄씩 입력한 뒤, 전체 UTF-8 텍스트를 인코딩해 만듭니다. 따라서 올바르게 디코딩한 결과는 보통 JSON이 아니라 링크 목록입니다. 일부 제공업체는 링크 목록을 평문으로 바로 반환하므로 이때는 다시 디코딩할 필요가 없습니다.
Mac에서는 먼저 Base64 구독 본문을 복사한 다음 터미널에서 아래 명령을 실행하면 됩니다. 이 명령은 클립보드 내용을 읽어 현재 터미널에 출력하며, 구독 URL에 접속하지는 않습니다. 출력에 인증 정보가 포함되므로 터미널 화면을 공유하지 않도록 주의하세요.
pbpaste | base64 -D
반대로 변환할 때는 공유 링크를 로컬 텍스트 파일에 한 줄씩 저장한 뒤 파일을 인코딩하세요. 아래 명령은 현재 디렉터리에 nodes.txt가 이미 있다고 가정합니다. 생성되는 것은 정적 텍스트 파일이며, 클라이언트에서 업데이트할 수 있는 구독 URL이 자동으로 만들어지는 것은 아닙니다.
base64 -i nodes.txt -o subscription.txt
- 디코딩에 실패하면 잘못 복사한 따옴표, 코드 펜스, 웹페이지 안내 문구가 포함되지 않았는지 먼저 확인하세요. HTTP 오류 페이지도 구독 본문이 아닙니다.
- 표준 Base64와 URL 안전 Base64는 사용하는 문자 집합이 다릅니다. URL 안전 형식에서는
-,_를 사용하고 끝의 패딩을 생략할 수 있습니다. 모든 내용을 표준 Base64라고 가정하고 처리하지 마세요. vmess://의 일반적인 공유 형식에는 JSON을 인코딩한 부분이 한 겹 더 들어 있습니다. 전체 구독을 디코딩한 뒤 이 부분이 보이는 것은 정상이며, 모든 줄을 다시 통째로 디코딩해야 한다는 뜻은 아닙니다.vless://는 보통 URI 필드와 쿼리 매개변수를 직접 사용합니다. VMess의 내부 JSON 구조를 VLESS 링크를 해석하는 데 그대로 적용하지 마세요.
vless:// 링크를 JSON으로 변환: 필드별 대응
아래에서는 TCP + TLS를 사용해 최소한의 필드 변환을 설명합니다. 서버 도메인은 문서용 예시 도메인이고 UUID도 형식 예시이므로 실제 연결에 사용할 수 없습니다. 실제로 사용하려면 서비스 제공업체가 제공한 주소, 포트, UUID, TLS 매개변수가 서로 일치해야 합니다. 도메인만 바꾼다고 작동하는 것은 아닙니다.
vless://[email protected]:443?encryption=none&security=tls&type=tcp&sni=node.example.com#Example-TLS
이 숫자는 설정 구조를 설명하기 위한 것으로, 속도 측정 결과나 모든 클라이언트의 기본값이 아닙니다. 원격 포트와 로컬 수신 포트는 연결의 양쪽 끝에 해당하므로 같은 값일 필요가 없습니다. 아래는 필드 설명을 위한 Xray 설정이며, 수신 주소는 로컬 루프백 주소로 제한되어 있습니다.
{
"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.com",
"port": 443,
"users": [
{
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"encryption": "none"
}
]
}
]
},
"streamSettings": {
"network": "tcp",
"security": "tls",
"tlsSettings": {
"serverName": "node.example.com"
}
}
}
]
}
| 링크 필드 | JSON 위치 | 주의 사항 |
|---|---|---|
| UUID | settings.vnext[0].users[0].id | 인증 정보이므로 임의로 변경하지 마세요 |
| 호스트와 포트 | settings.vnext[0].address 및 port | JSON의 포트 값은 숫자로 입력 |
encryption=none | users[0].encryption | VLESS 필드이며 TLS를 끄는 설정이 아님 |
type=tcp | streamSettings.network | 전송 방식이며 서버와 일치해야 함 |
security=tls | streamSettings.security | 여기서는 TLS 전송 보안을 선택 |
sni | tlsSettings.serverName | 연결 주소와 다를 수 있음 |
#Example-TLS | 클라이언트에서 표시할 노드 이름 | 프로토콜 핸드셰이크에 사용되지 않음 |
WebSocket, gRPC, REALITY 또는 Vision을 사용하는 경우에는 경로, 서비스 이름, 공개 키, 짧은 ID, 지문, flow 등의 해당 필드도 매핑해야 합니다. TCP 예시에 flow=xtls-rprx-vision을 임의로 추가했다고 변환이 끝나는 것은 아닙니다. 전송 방식, 서버 설정, 코어 지원 여부를 함께 확인하세요.
JSON을 공유 링크로 변환: 빠지는 정보
역변환하려면 먼저 대상 아웃바운드를 찾고 프로토콜, 서버, 사용자, 전송 설정을 확인해야 합니다. 위 JSON에는 VLESS 아웃바운드가 하나뿐이므로 해당 링크로 변환할 수 있습니다. 설정에 서버나 사용자가 여러 개 있으면 각각 링크를 만들어야 하며, URI 하나로 모든 객체를 나타낼 수는 없습니다.
- 대상이
protocol: "vless"인지 확인하고vnext에서 주소, 포트, 사용자 UUID를 확인하세요. - 전송 네트워크와 보안 유형을 각각
type및security에 입력한 다음, 프로토콜에 필요한 쿼리 매개변수를 채우세요. - 쿼리 매개변수 값과 이름에는 퍼센트 인코딩을 적용하세요. 예를 들어 경로
/edge?x=1은%2Fedge%3Fx%3D1로 써야 물음표가 잘못 해석되는 것을 막을 수 있습니다. - 서버 주소가 IPv6라면 URI에서 주소를 대괄호로 감싸야 합니다. 콜론을 기준으로 주소 전체를 나누지 마세요.
- 대상 클라이언트에서 다시 가져온 다음 노드 편집 화면의 항목을 하나씩 확인하고 실제 연결을 테스트하세요.
결론: 노드 변환과 설정 이전은 다릅니다
DNS, 라우팅, 여러 아웃바운드 간 선택 관계 또는 로컬 인바운드를 유지해야 한다면 원본 JSON을 보관하세요. 공유 링크로는 링크 형식에 표현할 수 있는 노드 매개변수만 옮길 수 있습니다.
링크를 성공적으로 가져와도 클라이언트는 자체 시스템 프록시, TUN, DNS, 라우팅 설정을 계속 사용합니다. 원본 JSON의 ‘중국 본토는 직접 연결, 그 외에는 프록시 사용’ 규칙은 VLESS 노드 하나만으로 이전되지 않습니다. 시스템 프록시는 어떤 앱의 요청을 클라이언트에 전달할지 정하고, 라우팅 규칙은 전달받은 요청이 어떤 아웃바운드로 나갈지 정합니다. 서로 다른 단계의 설정입니다.
가져오기 실패와 연결 실패: 단계별 점검
먼저 문제가 발생한 단계를 확인하세요. 구독 요청 실패, 본문 파싱 실패, 또는 노드가 목록에 표시되지만 연결 실패 중 어느 경우인지 살펴봅니다. 노드가 표시된다는 것은 적어도 일부 형식 파싱을 통과했다는 뜻일 뿐, UUID와 TLS 매개변수 또는 원격 서버가 정상이라는 의미는 아닙니다.
구독 업데이트는 성공했는데 노드가 없는 이유는 무엇인가요?
현재 선택한 구독 그룹과 목록 필터를 확인하고, 업데이트 로그에 유효한 노드가 0개라고 표시되는지 살펴보세요. 응답 본문이 로그인 페이지, 만료 안내 또는 전체 JSON이라면 먼저 제공업체에 해당 클라이언트에서 사용할 수 있는 구독 형식을 확인하세요. 같은 내용을 반복해서 인코딩하지 마세요.
JSON을 붙여 넣었는데 유효한 설정이 없다고 표시되는 이유는 무엇인가요?
일반적인 클립보드 노드 가져오기 메뉴는 공유 링크를 파싱합니다. 전체 JSON은 사용자 지정 설정 기능으로 가져오세요. 쉼표, 큰따옴표, 최상위 구조도 확인해야 합니다. JSON에는 주석이나 마지막 항목 뒤의 불필요한 쉼표를 넣을 수 없습니다. 문법이 올바르더라도 설정이 선택한 코어와 호환되는지 확인하세요.
링크는 가져와지는데 TLS 핸드셰이크 오류가 발생하나요?
먼저 원격 포트, security, SNI, 시스템 시간을 확인한 다음 서버가 요구하는 전송 유형과 대조하세요. 인증서 검증을 끄는 방식은 일반적인 해결책으로 사용하지 마세요. 주소를 해석할 수 있는지와 인증서 이름이 일치하는지는 별개의 확인 항목입니다.
구독 URL이 시간 초과되면 먼저 TUN을 켜야 하나요?
먼저 TUN을 변경할 필요는 없습니다. 사용할 수 있는 노드가 이미 있다면 클라이언트의 프록시를 통한 업데이트 옵션을 시도해 보세요. 사용 가능한 노드가 없다면 현재 네트워크에서 구독 URL에 접속할 수 있는지 확인하세요. 로그에 로컬 포트 사용 중 오류가 표시되면 중복 실행 중인 클라이언트를 종료하거나 수신 포트를 변경하세요.
변환한 노드는 연결되는데 앱은 왜 연결되지 않나요?
앱이 시스템 프록시를 사용하는지, 실제 프록시 포트가 클라이언트 설정과 일치하는지 확인하세요. 명령줄 도구는 시스템 프록시 설정을 읽지 않을 수 있으므로 브라우저 테스트만으로 모든 앱의 연결을 판단할 수는 없습니다. TUN을 켜기 전 권한, 라우팅, DNS를 확인하세요. 여러 설정을 한꺼번에 바꾸면 문제 원인을 찾기 어려워집니다.