2026-08-27 · 프로토콜 해설 · 약 10분

ss://·vmess://·vless://·trojan:// 공유 링크 형식과 구독 URL 차이

ss://, vmess://, vless://, trojan:// 링크의 구조와 인코딩을 살펴보고 단일 노드 링크와 구독 URL의 가져오기·업데이트 방식 차이를 설명합니다. 예시는 모두 가상 값입니다.

핵심 내용

단일 노드 공유 링크에는 연결 매개변수가 저장되고, 구독 URL은 업데이트할 수 있는 노드 목록을 가리킵니다. 서비스와 구독을 이미 보유하고 가져오기 형식을 확인하려는 사용자를 위한 안내입니다. 먼저 링크 종류를 구분한 뒤 인코딩, 주소, 포트, TLS 항목을 확인하고, 가져오기 성공·연결 성공·규칙 적용 여부를 각각 살펴봅니다. 도메인, 비밀번호, UUID, token은 모두 예시용 가상 값이며 실제 연결에는 사용할 수 없습니다.

[URI] 매개변수 링크와 구독 URL 구분하기

Shadowrocket의 단일 노드 항목과 구독 그룹은 서로 다른 데이터입니다. ss://, vmess://, vless://, trojan://로 시작하는 공유 링크에는 보통 노드 하나의 연결 매개변수가 들어 있습니다. 반면 https://로 시작하는 구독 URL은 클라이언트가 서버에 요청해 응답 내용을 읽고 노드 목록을 생성해야 합니다. 링크 길이만으로 종류를 판단할 수는 없습니다.

4종
이 글에서 다루는 URI scheme: ss / vmess / vless / trojan
8388
이 글에서 사용하는 Shadowsocks 예시 포트이며 필수값은 아닙니다
443
이 글에서 사용하는 TLS 예시 포트이며 실제 값은 기존 서비스 매개변수에 따라 다릅니다

공유 링크는 매개변수의 스냅샷입니다. 가져온 뒤 원격 서버의 주소나 비밀번호가 바뀌어도 별도 항목에 저장된 값은 자동으로 변경되지 않습니다. 구독 URL은 목록을 가져올 수 있는 경로를 유지하므로 업데이트를 실행하면 최신 목록을 받을 수 있습니다. 다만 목록이 실시간으로 푸시되는 것은 아니며, 내용 변경 여부는 서버 응답과 업데이트 성공 여부에 달려 있습니다.

[인코딩] Base64, 퍼센트 인코딩, 구분자

Base64는 인코딩이지 암호화가 아닙니다. 공유 링크를 얻은 사람은 보통 그 안의 비밀번호나 UUID를 복원할 수 있습니다. 구독 URL의 token도 인증 정보처럼 안전하게 보관해야 합니다. 전체 링크, QR 코드, 디코딩 결과를 낯선 웹사이트에 입력하지 마세요. 문제를 확인할 때는 해당 필드의 존재 여부만 기록하고 민감한 값은 가리세요.

기호 또는 인코딩일반적인 용도확인 방법
://scheme과 뒤따르는 내용을 구분합니다반각 기호를 그대로 유지하고 공백이나 줄바꿈을 넣지 않습니다.
@인증 정보와 호스트 부분을 구분합니다비밀번호에 들어 있는 문자 그대로의 @는 보통 %40으로 표기해야 합니다.
?와 &쿼리 매개변수를 시작하고 구분합니다원본 링크를 복사하세요. 웹페이지 소스의 &를 매개변수 구분자로 착각하지 않도록 주의합니다.
#fragment를 시작하며, 보통 메모에 사용합니다메모의 공백은 %20으로 인코딩할 수 있으며 서버 인증에는 사용되지 않습니다.
Base64인증 정보, JSON 또는 구독 본문을 감쌉니다표준과 URL-safe 알파벳을 구분하고 URI 전체를 무작정 디코딩하지 않습니다.

표준 Base64에는 +, /, 끝부분의 =가 들어갈 수 있습니다. URL-safe 형식은 -와 _를 사용할 수 있으며, 일부 구현에서는 끝의 패딩을 생략합니다. 퍼센트 인코딩은 별도의 문법을 처리합니다. 예를 들어 %2F는 슬래시를 뜻합니다. 두 인코딩은 서로 바꿔 쓸 수 없으며, 모든 +를 공백으로 바꿔서도 안 됩니다.

[Check]

해당 형식에서 인코딩된 부분을 찾아 한 번만 디코딩하세요. %2F를 다시 인코딩해 %252F로 만들거나 링크 전체의 구분자를 인코딩하면 파싱 결과가 달라집니다.

[Shadowsocks] ss://의 인증 정보와 서버 항목

일반적인 SIP002 형식에서는 암호화 방식과 비밀번호를 userinfo에 인코딩하고, 서버 주소와 포트는 읽을 수 있는 형태로 둡니다. 아래 예시의 Base64 내용은 aes-128-gcm:test이며, test는 설명용 비밀번호입니다. 포트 8388은 예시일 뿐 Shadowsocks의 필수 포트가 아닙니다.

ss://[email protected]:8388#Demo%20SS
  1. scheme: ss는 Shadowsocks를 지정합니다. 가져온 뒤 다른 프로토콜로 바꾸면 안 됩니다.
  2. userinfo: 디코딩하면 암호화 방식 aes-128-gcm과 비밀번호 test가 나오며, 두 값은 콜론으로 구분됩니다.
  3. 호스트와 포트: example.com:8388은 연결 대상입니다. 실제 사용할 때는 기존에 보유한 매개변수와 일치해야 합니다.
  4. 메모: Demo%20SS를 디코딩하면 Demo SS가 됩니다. 항목을 식별할 때만 사용합니다.

구형 공유 형식은 호스트와 포트를 포함한 전체 내용을 Base64로 인코딩하기도 합니다. 따라서 모든 ss:// 링크에 읽을 수 있는 @example.com이 포함되는 것은 아닙니다. plugin 매개변수가 있는 링크는 플러그인과 옵션도 확인해야 합니다. Shadowsocks 링크임을 알아냈더라도 추가 전송 매개변수가 완전하다고 단정할 수는 없습니다. IPv6 주소를 문자 그대로 표기할 때는 호스트 부분을 대괄호로 감싸 포트 구분용 콜론과 혼동하지 않도록 하는 경우가 많습니다.

[VMess] vmess://에서 흔히 쓰이는 Base64 JSON

일반적인 vmess:// 공유 형식은 scheme 뒤에 Base64로 인코딩된 JSON을 둡니다. 아래는 디코딩한 예시이며, 그대로 붙여넣어 가져올 수 있는 완전한 URI가 아닙니다. 필드 값에는 가상 도메인과 설명용 UUID를 사용했습니다. 각 필드의 역할을 확인하는 것이 목적입니다.

{
  "v": "2",
  "ps": "Demo VMess",
  "add": "example.com",
  "port": "443",
  "id": "00000000-0000-4000-8000-000000000001",
  "aid": "0",
  "scy": "auto",
  "net": "ws",
  "type": "none",
  "host": "example.com",
  "path": "/demo",
  "tls": "tls",
  "sni": "example.com"
}

JSON의 v는 공유 형식의 필드이지 Shadowrocket 앱 버전이 아닙니다. ps는 메모이지 비밀번호가 아닙니다. 내보내기 방식에 따라 필드 구성이 다를 수 있으므로 이 예시를 모든 VMess 링크의 표준 구조로 간주해서는 안 됩니다. 가져온 뒤 프로토콜은 맞지만 경로가 누락됐다면 UUID만 확인하지 말고 노드 편집 화면에서 전송 매개변수를 확인하세요.

[VLESS / Trojan] 읽을 수 있는 URI의 인증 정보와 TLS

VLESS와 Trojan의 일반적인 공유 형식은 읽을 수 있는 URI 구조를 사용하지만, @ 앞의 인증 정보는 서로 다릅니다. VLESS는 보통 UUID, Trojan은 보통 비밀번호를 사용합니다. VLESS 자체는 TLS와 동등한 전송 암호화를 제공하지 않습니다. 이 예시는 security=tls로 TLS를 지정하므로 프로토콜 이름만 보고 연결 보안 설정을 판단해서는 안 됩니다.

vless://[email protected]:443?encryption=none&security=tls&type=ws&host=example.com&path=%2Fdemo&sni=example.com#Demo%20VLESS

trojan://demo%[email protected]:443?security=tls&type=tcp&sni=example.com#Demo%20Trojan

두 부분으로 나누어 확인: 인증 필드와 전송 필드

인증 정보와 연결 대상
  • VLESS UUID: 이 예시에는 전체 형식의 설명용 UUID를 사용했습니다.
  • Trojan 비밀번호: demo%40pass를 디코딩하면 demo@pass가 됩니다.
  • 두 예시 모두 example.com:443에 연결하며, 포트는 고정값이 아닙니다.
TLS와 전송 방식
  • sni는 TLS 핸드셰이크에 사용할 서버 이름입니다.
  • type=ws 예시에서는 Host와 /demo 경로도 확인해야 합니다.
  • type=tcp에 WebSocket 경로 설정을 그대로 적용해서는 안 됩니다.

연결 주소, TLS SNI, WebSocket Host는 서로 다른 역할을 할 수 있습니다. 같은 값을 사용해야 하는지는 기존 매개변수에 따라 확인해야 하며, 도메인이 보인다고 모두 같은 값으로 바꾸면 안 됩니다.

VLESS 예시의 encryption=none은 이 예시에서 TLS를 사용하지 않는다는 뜻이 아닙니다. security=tls와는 서로 다른 계층의 설정입니다. Trojan 예시의 비밀번호에는 특수 문자가 들어 있어 @를 퍼센트 인코딩했습니다. 링크를 보기 좋게 만들려고 인코딩을 지우지 마세요. SNI나 인증서 이름이 맞지 않는 문제를 인증서 검증을 끄는 방법으로 숨겨서도 안 됩니다.

쿼리 매개변수의 이름과 확장 지원 여부는 공유 형식에 따라 달라질 수 있습니다. 기존 링크에 추가 필드가 있다면 원래 값을 유지하고, 가져온 뒤 Shadowrocket 노드 편집 화면에서 해당 설정을 하나씩 확인하세요. 항목 이름이 보인다는 사실만으로 모든 매개변수가 적용됐다고 볼 수는 없습니다.

[구독] 단일 노드 가져오기와 구독 업데이트는 별도로 처리

아래 구독 주소는 URL 구조만 보여 주며 실제로 사용할 수 있는 서비스 주소가 아닙니다. 여기의 token=xxxx는 명백한 가상 값이며, 실제 주소의 token은 공개하지 마세요. 일반 웹페이지 URL도 HTTPS로 시작할 수 있습니다. 응답 내용이 구독 파싱 형식에 맞아야 노드 목록을 생성할 수 있습니다.

https://example.com/sub?token=xxxx
  1. 기존 단일 노드 링크: URI 한 개를 빠짐없이 복사해 앱의 링크 가져오기 기능으로 처리합니다. 가져온 뒤 Home에서 해당 노드의 편집 화면을 열어 유형, 주소, 포트, 전송 매개변수를 확인하세요.
  2. 기존 구독 URL: Home → Add Server로 이동해 Subscribe를 선택하고, 보유한 구독 URL을 입력해 저장합니다. 그런 다음 구독 그룹과 노드 목록을 확인하세요.
  3. 기존 서비스 매개변수가 변경된 경우: 구독 그룹은 업데이트하세요. 별도로 가져온 항목은 새 링크를 다시 가져오거나 새 매개변수에 맞게 직접 수정해야 합니다.
  4. 업데이트 전에 직접 수정한 항목이 있는 경우: 유지할 매개변수를 먼저 저장하세요. 구독 업데이트로 서버가 관리하는 노드가 다시 생성될 수 있으므로, 직접 바꾼 이름이나 필드 값이 계속 유지된다고 가정하지 마세요.

구독 응답은 공유 링크 여러 개의 묶음일 수도 있고, 전체 텍스트를 Base64로 인코딩한 내용일 수도 있습니다. 구독 응답 인코딩과 단일 노드 내부 인코딩은 서로 독립된 두 단계입니다. 바깥쪽을 디코딩한 뒤에도 안에 있는 vmess://가 자체 Base64 JSON을 포함할 수 있습니다. 구독 본문을 하나의 비밀번호 필드로 취급하지 말고, 디코딩된 링크 여러 개를 다시 이어 붙여 하나의 URI로 만들지도 마세요.

정리: 원격 매개변수가 바뀌면 먼저 항목의 출처를 확인하세요

Subscribe 그룹에 속한 항목은 먼저 업데이트해 반환된 목록을 확인하세요. 독립 노드라면 새 공유 링크를 사용해야 합니다. 연결을 반복해서 껐다 켜도 독립 URI의 최신 매개변수가 다시 가져와지지는 않습니다.

[라우팅] 가져온 뒤 연결 상태와 규칙 확인하기

링크 가져오기는 어떤 연결 매개변수를 저장했는지를 결정할 뿐, 모든 요청의 라우팅 방식을 정하지는 않습니다. Home에서는 노드와 연결 상태를 확인하고, Config에서는 구성을 관리하며, Settings에서는 앱 설정을 관리합니다. 문제를 확인할 때는 먼저 Home에서 선택된 노드를 살펴본 뒤 Global Routing을 확인하세요. 항목이 목록에 있다는 이유만으로 요청이 반드시 그 노드를 거친다고 단정하면 안 됩니다.

Global Routing → Config

권장

기존 규칙에 따라 연결을 사용하려면 Config를 선택하고 현재 적용 중인 구성을 확인하세요. 규칙은 보통 순서대로 매칭되며, 최종 경로는 일치한 정책에 따라 결정됩니다.

적합한 경우: 구성이 이미 있고 일상적인 규칙 분기를 확인하려는 경우

Global Routing → Proxy

프록시 경로를 임시로 확인할 때 사용합니다. Config에서 직접 연결 규칙에 일치한 결과를 노드 문제로 오해하지 않도록 할 수 있습니다. 테스트가 끝나면 원래 사용 방식으로 되돌리세요.

적합한 경우: 규칙의 영향을 분리하고 선택된 노드의 연결 상태를 확인하려는 경우

Global Routing → Direct

직접 연결 경로를 사용하므로 가져온 프록시 노드가 작동하는지 확인하는 용도로는 사용할 수 없습니다. 직접 연결로 웹페이지를 열 수 있는 것과 해당 노드의 인증이 성공하는 것은 별개의 문제입니다.

적합한 경우: 로컬 네트워크에서 직접 접속되는 상태를 비교하려는 경우

Global Routing의 Scene은 설정된 장면을 바탕으로 확인해야 하며 Proxy나 Config와 동일한 의미로 볼 수 없습니다. 아래는 규칙 순서를 이해하기 위한 [Rule] 일부이며, 완전한 구성 파일이 아니므로 기존 파일을 그대로 덮어쓰면 안 됩니다. 도메인과 IP 대역은 모두 예시입니다.

[Rule]
DOMAIN-SUFFIX,example.com,PROXY
IP-CIDR,192.0.2.0/24,DIRECT,no-resolve
GEOIP,CN,DIRECT
FINAL,PROXY

Settings → On Demand에서는 조건에 따라 연결을 시작하는 동작을 관리합니다. 노드 인증을 대신하거나 잘못된 URI를 수정해 주지는 않습니다. 가져온 결과만 확인하려는 경우에는 먼저 연결이 성립했는지, 올바른 노드가 선택됐는지 확인한 뒤 자동 연결 조건을 살펴보세요. 여러 변수를 동시에 바꾸지 않는 것이 좋습니다.

[문제 해결] 공유 링크 파싱과 업데이트 관련 자주 묻는 질문

링크를 복사했는데 노드가 가져와지지 않는 이유는 무엇인가요?

먼저 링크가 완전한 scheme으로 시작하는지 확인한 다음, 복사한 내용에 설명 문구, 따옴표, 공백 또는 메신저가 삽입한 줄바꿈이 포함됐는지 살펴보세요. 완전한 URI 하나만 복사해야 합니다. 출처에서 받은 것이 HTTPS 구독 URL이라면 단일 노드의 비밀번호처럼 붙여넣지 말고 Subscribe로 처리하세요.

노드는 표시되는데 연결되지 않는 이유는 무엇인가요?

Home에서 선택된 노드의 주소, 포트, 인증 정보를 확인한 다음 TLS SNI, WebSocket Host, 경로를 살펴보세요. 이어서 Global Routing도 확인해야 합니다. Direct 모드의 접속 결과로는 프록시 노드를 검증할 수 없습니다. 매개변수가 기존 서비스 정보와 일치한다면 프로토콜 유형을 무작정 바꾸지 말고 서버 상태를 확인하세요.

구독을 업데이트한 뒤 목록이 비었습니다. 기존 링크는 계속 사용할 수 있나요?

먼저 기존 구독 URL을 보관하고 token과 쿼리 매개변수가 온전한지 확인하세요. 응답이 노드 데이터인지, 로그인 페이지나 오류 페이지 또는 빈 응답인지도 살펴봐야 합니다. 이전 노드의 연결 가능 여부는 서버가 기존 매개변수를 계속 허용하는지에 달려 있습니다. 목록이 비었다는 사실만으로 연결할 수 없다고 판단할 수는 없습니다.

구독에서 노드 하나를 공유하면 상대방도 자동으로 업데이트되나요?

대부분 그렇지 않습니다. 노드 하나를 공유하면 현재 매개변수의 스냅샷만 전달되며 원래 구독의 업데이트 관계는 포함되지 않습니다. 원격 목록의 변경 사항을 가져오려면 해당 구독 URL을 저장하고 업데이트해야 합니다. 공유하기 전에 인증 정보를 공개해도 되는지 확인하세요.

링크에서 # 뒤의 이름을 바꾸면 연결에 영향을 주나요?

이 글에서 다루는 URI 형식에서 fragment는 메모로 사용되므로 이름을 바꿔도 서버 주소, 비밀번호, UUID는 변경되지 않습니다. 변경 후 가져오기가 되지 않는다면 앞쪽 매개변수를 잘못 지우지 않았는지, 메모의 특수 문자를 인코딩하지 않은 구분자로 입력하지 않았는지 확인하세요.

마지막으로 링크 종류 → 인코딩 상태 → 인증 필드 → 전송 및 TLS → 현재 라우팅 모드 순서로 확인하세요. 한 번에 한 항목만 변경하고 원래 값을 기록해 두세요. 그러면 파싱 실패, 서버 거부, TLS 검증 실패, 규칙에 따른 프록시 미사용을 구분할 수 있어, 반복해서 다시 가져오는 것으로 실제 문제를 가리는 일을 피할 수 있습니다.

App Store에서 정품 확인