먼저 어떤 구독 형식인지 확인하기
결론부터 말하면, Clash 또는 Mihomo는 일반적으로 YAML 설정을 사용하고 sing-box는 JSON 설정을 사용합니다. 깨진 문자처럼 보이는 긴 구독 내용은 대개 Base64로 인코딩된 공유 링크 모음입니다. 세 형식은 일부 정보를 공유하지만, 확장자만 바꿔서 서로 변환할 수는 없습니다.
구독 링크는 콘텐츠를 가져오는 주소일 뿐, 콘텐츠 형식 자체를 의미하지 않습니다. 서버는 https://로 시작하는 같은 주소라도 클라이언트 매개변수에 따라 Clash YAML, 범용 공유 링크 또는 sing-box JSON을 반환할 수 있습니다. 확인할 때는 URL 확장자가 아니라 응답 본문을 살펴봐야 합니다.
앞부분 몇 글자로 빠르게 식별하기
| 확인한 내용 | 가능성이 높은 형식 | 다음 단계 |
|---|---|---|
proxies:、proxy-groups: |
Clash 또는 Mihomo YAML | 호환 클라이언트에 바로 가져온 후 설정 항목 확인 |
dm1lc3M6Ly8, 연속된 영문·숫자와 등호 |
Base64 인코딩 텍스트 | 먼저 디코딩한 뒤 여러 줄의 공유 링크인지 확인 |
ss://、trojan://、vless:// |
하나 이상의 URI 공유 링크 | 변환기에 전달하여 대상 설정 생성 |
{"log":、"outbounds" |
sing-box JSON | sing-box로 검증하고 Clash에 바로 가져오지 않기 |
| 웹페이지 HTML, 로그인 안내 또는 오류 메시지 | 구독 요청 실패 | 주소, 유효 기간 및 요청 매개변수 확인 |
텍스트로 먼저 확인하고 바로 실행하지 않기
브라우저 개발자 도구의 ‘네트워크’ 패널에서 응답을 확인하거나 내용을 일반 텍스트로 저장할 수 있습니다. 명령줄에서는 curl을 사용하되 출력 파일을 지정해 긴 내용이 터미널을 가득 채우지 않도록 하세요.
curl -L --max-time 20 "https://sub.example.net/api/demo-token" -o subscription.txt
head -n 8 subscription.txt
-L은 리디렉션을 따라가며, --max-time 20은 전체 요청 시간을 20초로 제한합니다. 파일 첫 줄에 <!doctype html>이 나타난다면 구독 설정이 아니라 웹페이지를 받은 것입니다. 로그인, 주소 만료 또는 게이트웨이 차단 문제를 먼저 해결해야 합니다.
YAML, Base64와 sing-box JSON의 구조 차이
형식 변환의 핵심은 문법이 아니라 모델에 있습니다. 노드 주소, 포트와 인증 정보는 비교적 쉽게 매핑할 수 있지만, 정책 그룹, 규칙 세트, DNS 동작, TUN 라우팅과 스크립트 확장은 특정 코어에만 존재할 수 있습니다. 변환기는 구조를 바꿀 수는 있어도 각 규칙의 실제 의도를 자동으로 이해하지는 못합니다.
Clash와 Mihomo YAML
YAML 설정에는 보통 노드, 정책 그룹과 분할 라우팅 규칙이 함께 들어갑니다. Mihomo는 Clash 설정 생태계를 계승한 오픈 소스 프록시 코어로, 다양한 프로토콜과 확장 필드를 지원합니다. 최소 예시는 다음과 같습니다.
mixed-port: 7890
mode: rule
allow-lan: false
proxies:
- name: HK-01
type: ss
server: edge.example.net
port: 8388
cipher: aes-128-gcm
password: demo-pass
proxy-groups:
- name: PROXY
type: select
proxies:
- HK-01
- DIRECT
rules:
- DOMAIN-SUFFIX,example.org,PROXY
- MATCH,PROXY
mixed-port: 7890은 HTTP와 SOCKS 요청이 7890 포트를 함께 사용한다는 뜻입니다. proxy-groups는 클라이언트에서 선택할 수 있는 정책을 정의하고, rules는 위에서 아래 순서로 트래픽에 매칭됩니다. 노드 목록만 있고 정책 그룹과 규칙이 없을 때 일부 클라이언트는 자동으로 보완하지만, 다른 클라이언트는 설정을 사용할 수 없다고 표시할 수 있습니다.
Base64 공유 링크 모음
Base64는 프록시 프로토콜도, 완전한 설정 형식도 아닙니다. 바이트를 전송하기 쉬운 텍스트로 인코딩하는 방식일 뿐입니다. 일반적인 구독은 여러 줄의 ss://, trojan://, vmess:// 또는 vless:// 링크를 이어 붙인 뒤 전체를 한 번 Base64로 인코딩합니다.
ss://[email protected]:8388#HK-01
trojan://[email protected]:443?security=tls#SG-01
이 형식에는 보통 노드 매개변수와 표시 이름만 들어 있으며 Clash의 전체 규칙은 포함되지 않습니다. YAML로 변환할 때 변환 도구가 템플릿에 따라 proxy-groups, rules와 DNS 설정을 추가하는 경우가 많으므로, 같은 노드라도 템플릿에 따라 최종 동작이 완전히 달라질 수 있습니다.
sing-box JSON
sing-box는 JSON으로 인바운드, 아웃바운드, 라우팅과 DNS를 표현합니다. sing-box 1.12 설정 구조를 예로 들면 노드는 일반적으로 outbounds 배열에 들어가며, 선택기도 하나의 아웃바운드 객체입니다.
{
"log": {
"level": "info"
},
"outbounds": [
{
"type": "shadowsocks",
"tag": "hk-01",
"server": "edge.example.net",
"server_port": 8388,
"method": "aes-128-gcm",
"password": "demo-pass"
},
{
"type": "selector",
"tag": "proxy",
"outbounds": [
"hk-01"
]
}
],
"route": {
"rules": [
{
"action": "route",
"domain_suffix": [
"example.org"
],
"outbound": "proxy"
}
],
"final": "proxy"
}
}
Clash의 proxy-groups는 sing-box의 selector 및 urltest와 대략적으로 매핑할 수 있지만 필드 이름과 실행 모델은 다릅니다. Clash의 MATCH는 일반적으로 sing-box 라우팅의 최종 아웃바운드에 해당하며, 같은 이름의 규칙으로 단순 복사하는 개념이 아닙니다.
먼저 Base64를 디코딩한 뒤 변환 대상 결정하기
긴 문자열이라고 해서 곧바로 변환기에 전달하지 마세요. 로컬에서 먼저 디코딩하고 앞부분 몇 줄을 확인하면 콘텐츠가 완전한지 검증할 수 있으며, 오류 페이지나 압축 데이터 또는 이중 인코딩된 내용을 노드 구독으로 잘못 판단하는 것도 막을 수 있습니다.
Windows PowerShell에서 디코딩
$raw = (Get-Content .\subscription.txt -Raw).Trim()
$bytes = [Convert]::FromBase64String($raw)
[Text.Encoding]::UTF8.GetString($bytes) |
Set-Content .\decoded.txt -Encoding utf8
Get-Content .\decoded.txt -TotalCount 8
FromBase64String에서 형식 오류가 발생하면 텍스트에 공백, HTML 태그 또는 URL 안전형 문자가 섞였는지 먼저 확인하세요. URL 안전형 Base64는 더하기 기호와 슬래시 대신 하이픈과 밑줄을 사용하고 끝의 등호를 생략할 수 있으므로, 해당 변형을 지원하는 도구로 처리해야 합니다.
Linux와 macOS에서 디코딩
# GNU/Linux
base64 -d subscription.txt > decoded.txt
# macOS
base64 -D subscription.txt > decoded.txt
sed -n '1,8p' decoded.txt
디코딩 결과가 여전히 하나의 Base64 문자열이라면 이중 인코딩일 수 있지만, VMess 링크 내부의 JSON 인코딩일 수도 있습니다. 먼저 접두사를 확인하세요. 구독 전체가 이중 인코딩된 경우 계속 디코딩할 수 있지만, vmess:// 뒤의 내용은 개별 노드이므로 일반 Base64 명령에 줄 전체의 접두사까지 함께 전달하면 안 됩니다.
오픈 소스 변환 도구로 Clash YAML 생성하기
출처가 URI 목록 또는 Base64 구독이고 대상 클라이언트가 Mihomo라면 Clash 출력을 지원하는 오픈 소스 구독 변환기를 사용할 수 있습니다. 일반적인 구현은 출처 주소, 대상 형식과 규칙 템플릿을 받아 YAML을 반환하는 /sub 인터페이스를 제공합니다.
변환 전 확인할 세 가지 매개변수
- 대상 형식: Clash 또는 Mihomo, Clash Meta 출력이라고 명확히 표시된 형식을 선택하세요. 구버전 Clash 대상은 최신 프로토콜 필드를 제거할 수 있습니다.
- 출처 주소: 주소 자체에
?,&또는 등호가 포함되어 있다면 특히 URL 인코딩이 필요합니다. - 규칙 템플릿: 노드 변환과 규칙 생성은 별개의 작업입니다. 첫 테스트에서는 간단한 템플릿을 사용하고, 노드 연결을 확인한 뒤 원격 규칙 세트를 추가하는 편이 좋습니다.
로컬 변환 서비스가 127.0.0.1:25500에서 수신한다고 가정하면, 출처 주소를 인코딩한 뒤 다음 형식으로 Clash 출력을 요청할 수 있습니다.
curl "http://127.0.0.1:25500/sub?target=clash&url=https%3A%2F%2Fsub.example.net%2Fapi%2Fdemo-token" \
-o converted.yaml
프로젝트와 브랜치마다 지원하는 target 이름이 다릅니다. 일부 버전은 clash를 지원하고, 일부 확장 버전은 Mihomo 또는 sing-box 대상도 제공합니다. 현재 빌드의 대상 목록을 확인하고 인터페이스 이름만 보고 추측하지 마세요. 도구가 sing-box 출력을 지원하지 않는다면 해당 어댑터를 갖춘 구현을 사용해야 하며, YAML의 확장자를 .json으로 바꾸는 방식은 올바르지 않습니다.
가져오기 전 문법 검사하기
Mihomo는 명령줄에서 설정을 검사할 수 있습니다. 실행 파일 이름이 mihomo이고 설정 파일이 현재 디렉터리의 converted.yaml이라고 가정하면 다음과 같습니다.
mihomo -t -f ./converted.yaml
테스트 통과는 설정을 해석할 수 있다는 뜻일 뿐, 모든 노드에 연결된다는 의미는 아닙니다. 이어서 클라이언트를 실행하고 ‘구독’ 또는 ‘설정’ 화면에서 파일을 불러온 다음, ‘프록시’ 화면에서 정책 그룹에 노드가 표시되는지 확인하세요. 마지막으로 ‘설정’ → ‘시스템 프록시’를 열어 HTTP와 SOCKS 포트가 설정과 일치하는지 확인합니다. 예를 들어 모두 혼합 포트 7890을 가리켜야 합니다.
로컬 자체 호스팅 변환 서비스를 안전하게 운영하는 절차
구독 주소에는 보통 접근 자격 증명이 포함됩니다. 자주 변환해야 한다면 오픈 소스 변환 프로그램을 로컬 또는 관리되는 서버에서 실행하여 출처 주소가 자신의 장치와 구독 서버 사이에서만 전달되도록 하는 것이 좋습니다. 자체 호스팅을 사용하면 버전과 규칙 템플릿을 고정하기도 쉬워 같은 구독이 날짜에 따라 서로 다른 결과를 내는 문제를 줄일 수 있습니다.
로컬 실행 시 기본 설정
- 프로젝트 릴리스에서 운영 체제와 CPU 아키텍처에 맞는 빌드를 받으세요. 예를 들면 Windows x64, Linux amd64 또는 macOS arm64입니다.
- 프로그램과 설정 파일을 별도 디렉터리에 두고, 처음 실행할 때는
127.0.0.1에서만 수신하도록 설정하세요. 공용 네트워크 인터페이스에 직접 바인딩하지 마세요. - 수신 포트가
25500인지 확인한 다음 브라우저 또는curl로 로컬 인터페이스에 접속하세요. - 규칙 템플릿을 로컬에 보관하고 변환 프로그램 버전, 템플릿 버전과 출력 시간을 기록하세요.
- 노드 하나로 먼저 테스트하여 필드 매핑이 올바른지 확인한 뒤 전체 구독을 처리하세요.
변환 서비스를 LAN 서버에서 실행해야 한다면 출처 주소를 제한하고 리버스 프록시 계층에 접근 제어를 추가하세요. 변환 인터페이스는 보통 호출자가 임의의 구독 URL을 제출할 수 있도록 되어 있습니다. 제한이 없으면 구독 내용이 노출될 뿐 아니라 서버가 다른 사용자를 대신해 내부 네트워크 주소에 요청을 보낼 수도 있습니다.
입력과 출력을 고정해 롤백을 쉽게 만들기
다음 세 파일을 보관하는 것이 좋습니다. 원본 응답 source.txt, 변환 출력 converted.yaml 또는 config.json, 버전과 매개변수를 기록한 conversion-notes.txt입니다. 예를 들어 수신 포트 25500, 대상 clash, 템플릿 파일 이름과 변환 날짜를 기록하세요. 다음에 노드 수가 비정상적으로 줄었을 때 출처, 템플릿, 도구 업그레이드 중 무엇이 원인인지 빠르게 비교할 수 있습니다.
Clash YAML을 sing-box JSON으로 매핑하는 방법
YAML을 JSON으로 바꾸는 것은 단순한 문법 변환이 아닙니다. 일반 YAML-JSON 변환 도구는 들여쓰기 구조를 중괄호 구조로 바꿀 뿐, Clash의 proxies를 sing-box의 outbounds로 변환하거나 정책 그룹과 라우팅 규칙을 이해하지 못합니다. 두 프록시 설정 모델을 모두 이해하는 변환기를 사용해야 합니다.
주요 필드 대응 관계
| Clash / Mihomo | sing-box | 변환 시 주의할 점 |
|---|---|---|
proxies[].name |
outbounds[].tag |
tag는 반드시 고유해야 하며, 이름이 중복되면 변경해야 합니다 |
server、port |
server、server_port |
포트 필드 이름이 다릅니다 |
proxy-groups의 select |
selector outbound |
구성원 이름을 해당 tag로 변경해야 합니다 |
url-test |
urltest outbound |
테스트 주소, 간격과 허용 오차를 다시 확인해야 합니다 |
rules |
route.rules |
규칙 유형과 최종 아웃바운드를 기계적으로 복사할 수 없습니다 |
dns |
dns와 라우팅 연동 |
리졸버 태그, 분할 조건과 캐시 동작이 다릅니다 |
tun |
inbounds의 tun |
인터페이스 주소, 자동 라우팅과 엄격한 라우팅을 다시 설정해야 합니다 |
프로토콜 필드도 다를 수 있습니다. 예를 들어 TLS 서버 이름, ALPN, Reality 매개변수, WebSocket 경로와 요청 헤더는 두 설정에서 중첩되는 위치가 다릅니다. 변환 후 노드는 표시되지만 핸드셰이크가 실패한다면 로컬 포트를 반복해서 바꾸기보다 먼저 이 필드들을 대조하세요.
규칙을 완전히 매핑할 수 없을 때의 처리 순서
- 노드 하나만 먼저 변환하고 최종 라우팅을 해당 노드로 지정하여 프로토콜 매개변수를 검증합니다.
- 수동 선택기를 하나 추가하고 노드 tag와 선택기 구성원이 일치하는지 확인합니다.
- LAN 및 자주 사용하는 직접 연결 규칙을 추가하여 로컬 장치의 접근에 문제가 없는지 확인합니다.
- 그다음 도메인, IP와 규칙 세트를 가져와 로그에서 실제로 어떤 규칙이 매칭되는지 관찰합니다.
- 마지막으로 TUN과 복잡한 DNS 분할을 활성화하여 여러 변수를 동시에 점검하지 않도록 합니다.
변환 후 반드시 확인할 열 가지 필드
변환이 끝났다고 현재 사용 중인 설정을 바로 덮어쓰지 마세요. 먼저 다른 파일로 저장한 후 항목별로 점검하세요. 다음 항목은 ‘파일을 가져올 수 있는가’보다 중요합니다.
- 노드 수: 출처에 노드가 36개라면 출력에도 3개만 남아서는 안 됩니다. 수가 줄었다면 대상 형식이나 변환기에서 특정 프로토콜을 필터링했는지 확인하세요.
- 노드 이름: 이름은 고유해야 합니다. 이름이 중복되면 정책 그룹이 그중 하나만 참조할 수 있습니다.
- 서버와 포트:
server가 구독 서버 주소로 잘못 기록되지 않았는지 확인하고 443, 8443, 8388 등의 실제 포트를 대조하세요. - 인증 정보: 비밀번호, UUID, 키와 대소문자를 확인하고 URL 디코딩 과정에서 더하기 기호가 공백으로 잘못 처리되지 않았는지 살펴보세요.
- TLS 매개변수: 서버 이름, 인증서 검증 건너뛰기 여부, ALPN과 Reality 공개 키 등의 필드를 대조하세요.
- 전송 매개변수: WebSocket 경로의 첫 슬래시를 유지해야 하며, gRPC service name과 HTTP Host를 서로 바꿔 사용할 수 없습니다.
- 정책 그룹 구성원: 수동 선택, 자동 속도 측정과 장애 조치 그룹에는 유효한 노드가 반드시 있어야 하며 그룹 이름만 남아서는 안 됩니다.
- 규칙 순서: 규칙은 순서대로 매칭됩니다. LAN 직접 연결 규칙은 일반적으로 최종 기본 규칙보다 앞에 배치해야 합니다.
- DNS 동작: 수신 주소, 업스트림 서버, 프록시 DNS와 직접 연결 DNS의 역할을 확인하여 DNS 순환이 발생하지 않도록 하세요.
- 로컬 포트: 설정을 7891로 변경했다면 Windows 11의 ‘설정’ → ‘네트워크 및 인터넷’ → ‘프록시’에서도 함께 변경해야 합니다. 기존 7890이 자동으로 따라 바뀌지는 않습니다.
가장 짧은 경로로 결과 검증하기
먼저 TUN을 끄고 시스템 프록시와 수동 노드 하나만 활성화하세요. 외부 IP 확인 페이지에 접속한 다음 명령줄에서 혼합 포트를 통해 HTTPS 주소를 요청합니다.
curl -x http://127.0.0.1:7890 --connect-timeout 8 https://example.com/
정상적으로 응답하면 규칙 모드, 자동 속도 측정과 TUN을 차례로 테스트하세요. 자동 속도 측정에 80ms가 표시되어도 측정 대상까지 왕복이 빠르다는 뜻일 뿐, 모든 웹사이트에 안정적으로 접속된다는 의미는 아닙니다. 실제 검증에서는 DNS, TLS 핸드셰이크와 다운로드 과정도 살펴봐야 합니다.
자주 묻는 질문
YAML 확장자를 JSON으로 바꾸면 sing-box가 읽을 수 있나요?
읽을 수 없습니다. 확장자를 바꿔도 내부 데이터 모델은 달라지지 않습니다. 일반 도구로 YAML 문법을 JSON으로 바꾸더라도 내부에는 여전히 Clash의 proxies, proxy-groups와 rules가 남아 있으며, sing-box가 이를 아웃바운드와 라우팅으로 자동 해석하지는 않습니다.
Base64를 디코딩했는데 노드만 있고 규칙은 없는 이유는 무엇인가요?
범용 URI 구독은 주로 노드 매개변수를 전달하며, 일반적으로 Clash 정책 그룹과 분할 라우팅 규칙은 포함하지 않습니다. YAML을 생성할 때 규칙 템플릿을 선택하거나 변환 결과에서 정책 그룹과 규칙을 직접 관리해야 합니다.
변환된 구독도 자동으로 업데이트되나요?
가져오는 방식에 따라 다릅니다. 로컬에서 내보낸 정적 파일은 자동으로 업데이트되지 않지만, 클라이언트가 변환 인터페이스 주소를 저장한 경우 업데이트 간격에 따라 다시 요청할 수 있습니다. 원본 주소를 보관하고 변환 서비스가 장기간 사용 가능한지 확인하세요.
Mihomo 설정을 구버전 Clash에서 직접 사용할 수 있나요?
기본 필드는 호환될 수 있지만 Mihomo 확장 프로토콜, 규칙 세트, DNS와 TUN 필드는 구형 코어에서 인식하지 못할 수 있습니다. 대상 클라이언트가 구형 코어를 사용한다면 해당 출력 형식을 선택하고, 그 코어에서 제공하는 설정 검사 명령으로 검증하세요.
변환 후 지연 시간이 모두 시간 초과로 표시되면 무엇부터 확인해야 하나요?
먼저 속도 측정 주소에 접근할 수 있는지 확인한 다음 정책 그룹에 실제로 노드가 포함되어 있는지 확인하세요. 수동 연결도 실패한다면 서버, 포트, TLS 서버 이름과 전송 경로를 비교하고, 수동 연결이 정상이라면 속도 측정 URL, 간격 또는 동시성 설정을 점검하세요.
형식 선택 가이드
대상이 Mihomo 클라이언트라면 서버에서 직접 제공하는 Clash 또는 Mihomo YAML을 우선 사용하세요. sing-box가 대상이라면 현재 sing-box 설정 구조에 맞게 생성된 JSON을 우선 받아야 합니다. 출처에서 대상 형식을 제공하지 않을 때만 변환 계층을 추가하세요.
Base64 URI 구독은 범용 노드 소스로 적합하지만 완전한 분할 라우팅을 담당하지는 않습니다. 장기간 사용할 때는 노드 변환과 규칙 템플릿을 분리해 관리하세요. 노드는 구독에 따라 업데이트하고 규칙은 직접 선택한 설정으로 관리하면, 문제가 생겼을 때 노드 매개변수 변화인지 라우팅 및 DNS 설정 변화인지 명확히 판단할 수 있습니다.
마지막으로 간단한 원칙 하나만 기억하세요. 먼저 단일 노드를 검증한 뒤 정책 그룹을 추가하고, 시스템 프록시를 확인한 뒤 TUN을 활성화하며, 문법을 확인한 뒤 네트워크를 점검하세요. 형식 변환에 포함되는 변수가 적을수록 오류 원인을 더 빠르게 찾을 수 있습니다.