Clash YAML 설정 파일 구조 분석: mixed-port부터 rules까지
mixed-port, dns, proxies, proxy-groups, rule-providers, rules의 각 항목을 순서대로 살펴보고 자주 발생하는 들여쓰기 오류도 예시로 확인합니다.
1. 설정 파일 구조: 클라이언트 설정과 코어 설정 구분하기
Clash Verge Rev에서 사용하는 mihomo 코어는 연결, DNS, 규칙 매칭을 담당합니다. YAML은 설정을 작성하는 형식이지 프록시 프로토콜이 아닙니다. YAML 파서가 파일을 읽을 수 있다는 것은 문법이 올바르다는 뜻일 뿐입니다. 노드 유형이 지원되는지, 정책 그룹 이름이 실제로 존재하는지는 코어에서 별도로 확인해야 합니다.
구독 설정을 살펴볼 때는 ‘접속 포트 → DNS → 노드 → 정책 그룹 → 규칙 집합 → 매칭 규칙’ 순서로 보면 편리합니다. 실제로 설정이 파일 위에서 아래로 순차 실행되는 것은 아닙니다. 예를 들어 rules는 앞에서 정의한 정책 그룹을 참조하고, 정책 그룹은 다시 노드를 참조합니다. 이런 이름들이 설정 항목 간 연결 고리입니다.
mixed-port,mode같은 최상위 항목은 로컬 접속 포트와 작동 방식을 정합니다.dns는 매핑 구조이며, 안에 활성화 여부와 해석 모드, 업스트림 서버가 들어갑니다.proxies,proxy-groups,rules는 목록이며 각 항목 앞에 하이픈을 붙입니다.rule-providers는 이름별로 구성된 매핑으로, 외부 규칙 집합을 선언합니다.
2. mixed-port: 앱이 연결할 로컬 접속 포트 지정
mixed-port는 하나의 포트에서 HTTP와 SOCKS 프록시 연결을 모두 받습니다. 아래에서는 7897을 예시로 사용하지만 모든 설치 환경에서 이 값을 쓰는 것은 아닙니다. 클라이언트에 현재 표시된 수신 포트를 기준으로 설정하세요.
mixed-port: 7897
allow-lan: false
mode: rule
log-level: info
ipv6: false
| 항목 | 예시 값의 의미 | 확인할 사항 |
|---|---|---|
mixed-port: 7897 | 로컬 혼합 프록시 포트는 7897 | 프록시를 수동 설정하는 앱에도 이 포트를 입력해야 합니다 |
allow-lan: false | LAN 기기의 접속을 허용하지 않음 | 이 기기에서만 사용할 때는 보통 비활성화합니다 |
mode: rule | 규칙에 따라 트래픽 출구 선택 | 전역 모드에서는 rules로 분기 결과를 확인할 수 없습니다 |
log-level: info | 일반 실행 정보 기록 | 문제 해결 중에는 debug로 잠시 변경하고, 끝나면 되돌립니다 |
ipv6: false | 코어의 IPv6 지원 비활성화 | 운영체제의 IPv6까지 끄는 것은 아닙니다 |
HTTP 프록시를 수동으로 설정할 때 호스트에는 127.0.0.1, 포트에는 7897을 입력하세요. 클라이언트 포트를 7898로 변경했다면 수동 설정도 같은 값으로 바꿔야 합니다. 클라이언트가 시스템 프록시를 관리하는 경우에는 앱 설정 후 시스템에 적용된 실제 값도 확인하세요.
혼합 포트는 DNS 포트도 코어 제어 인터페이스도 아닙니다. 브라우저 프록시 설정에 external-controller 주소를 입력하지 마세요. LAN에 프록시를 공유하려면 수신 주소, 방화벽, 접근 인증도 확인해야 합니다. allow-lan을 true로 바꾸는 것만으로 설정이 완료되는 것은 아닙니다.
3. dns: 해석 모드, 업스트림 서버, 트래픽 가로채기
dns는 코어 자체의 DNS 모듈을 제어합니다. 이를 활성화해도 운영체제의 모든 DNS 요청이 자동으로 클라이언트를 통과하는 것은 아닙니다. 시스템 DNS, 앱 내 보안 DNS, TUN의 DNS 하이재킹 설정이 실제 요청 경로에 영향을 줄 수 있습니다. 먼저 요청이 어디로 전달되는지 확인한 다음 업스트림 주소를 조정하세요.
dns:
enable: true
listen: 127.0.0.1:1053
ipv6: false
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
nameserver:
- https://1.1.1.1/dns-query
- https://1.0.0.1/dns-query
fake-ip는 매핑 주소를 반환합니다
fake-ip는 도메인에 매핑용 주소를 할당하고, 코어는 이후 연결 처리를 위해 도메인과 해당 주소의 대응 관계를 보관합니다. 198.18로 시작하는 결과가 보여도 곧바로 DNS 오염이라고 판단할 필요는 없습니다. 예시 주소 대역은 테스트용으로 예약된 범위이며 원격 웹사이트의 실제 공인 IP가 아닙니다.
1053 포트를 열어도 시스템 DNS가 자동으로 바뀌지는 않습니다
listen: 127.0.0.1:1053은 로컬 DNS 서비스가 1053 포트에서 요청을 받는다는 뜻입니다. 일반적인 시스템 DNS 설정에는 서버 IP만 입력할 수 있고 사용자 지정 포트 항목이 없는 경우가 많으므로, 127.0.0.1만 입력한다고 1053 포트에 접속하는 것은 아닙니다. TUN 모드에서는 클라이언트가 생성한 tun 및 dns-hijack 설정을 함께 확인해 DNS 요청이 어떻게 가로채지는지 파악하세요.
nameserver는 코어가 DNS 해석에 사용할 업스트림 서버를 지정합니다. 예시에는 실제 DoH 주소 두 개가 사용되며, 연결 가능 여부는 사용 중인 네트워크에 따라 달라집니다.- 도메인 형식의 암호화 DNS 주소를 사용할 때는 업스트림 서버 도메인을 처음 해석할 수 있도록
default-nameserver설정이 필요할 수 있습니다. - 일부 기기나 앱이 fake-ip와 호환되지 않는다면 도메인별로
fake-ip-filter를 확인하세요. 처음부터 모든 DNS 기능을 끄지는 마세요.
구독에 완성된 DNS 설정이 포함되어 있다면 이 짧은 설정으로 그대로 덮어쓰지 않는 것이 좋습니다. 원본에는 노드 도메인 해석, 중국 본토와 해외 트래픽의 해석 정책, 특정 도메인 처리 규칙이 더 들어 있을 수 있습니다. 문제를 확인할 때는 한 번에 한 항목만 바꾸고, 변경 전후 로그를 보관해야 원인을 파악할 수 있습니다.
4. proxies와 proxy-groups: 노드 설정 및 출구 선택
proxies는 개별 노드의 연결 정보를 정의하고, proxy-groups는 노드를 수동 선택이나 속도 측정 선택 등의 정책으로 묶습니다. 노드 이름은 설명용 문구가 아니라 다른 설정에서 참조하는 식별자입니다. 공백, 대소문자, 문자까지 정확히 일치해야 합니다.
아래는 Shadowsocks 노드의 설정 항목 구조만 보여 주는 예시입니다. 192.0.2.10은 문서용 예시 주소이고 example-only-not-a-secret은 설명을 위한 비밀번호이므로 실제 프록시 연결에는 사용할 수 없습니다. 실제 서버 주소, 포트, 암호화 방식, 비밀번호는 서비스 제공업체가 안내한 값이어야 하며 임의로 추측해서는 안 됩니다.
proxies:
- name: "예시 노드"
type: ss
server: 192.0.2.10
port: 443
cipher: aes-128-gcm
password: "example-only-not-a-secret"
udp: true
proxy-groups:
- name: "수동 선택"
type: select
proxies:
- "예시 노드"
- DIRECT
select와 url-test는 서로 다른 방식입니다
select는 구성원 중 하나를 직접 선택하는 방식입니다. url-test는 설정된 탐색 URL과 간격에 따라 후보 구성원을 테스트합니다. 측정 결과는 해당 탐색 대상에 연결했을 때의 성능을 주로 보여 줍니다. 다운로드 속도와 같다고 볼 수 없으며, 모든 웹사이트에서 같은 출구가 최선이라는 보장도 없습니다.
DIRECT는 내장된 직접 연결 출구이므로 proxies에 별도 노드를 만들 필요가 없습니다. 노드의 udp: true는 해당 UDP 기능을 사용할 수 있도록 허용할 뿐입니다. 실제 사용에는 서버 지원 여부와 프로토콜 기능, 로컬 트래픽 처리 방식이 모두 맞아야 합니다.
5. rule-providers: 규칙을 별도 파일로 분리하기
rule-providers는 규칙 집합의 소스, 형식, 동작을 선언하지만 선언만으로 규칙이 적용되지는 않습니다. rules에서 RULE-SET으로 규칙 집합 이름을 참조하고, 일치했을 때 사용할 출구도 지정해야 합니다.
사용할 수 있는지 불확실한 예시 URL을 규칙 소스로 오해하지 않도록 아래에서는 로컬 파일을 사용합니다. 먼저 코어가 허용하는 설정 디렉터리에 rules/local-direct.yaml을 준비한 뒤 주 설정을 불러오세요. 상대 경로는 브라우저나 문서 위치가 아니라 코어의 작업 디렉터리와 경로 제한을 기준으로 해석됩니다.
rule-providers:
local-direct:
type: file
behavior: domain
format: yaml
path: ./rules/local-direct.yaml
이 규칙 파일의 전체 내용은 다음과 같이 작성할 수 있습니다.
payload:
- "example.com"
- "+.example.org"
example.com은 단일 도메인 예시이고 +.example.org는 해당 도메인과 하위 도메인을 나타냅니다. 두 도메인 모두 문서용 예시일 뿐 실제 서비스에 필요한 트래픽 분기 목록을 뜻하지 않습니다.
behavior: domain: 규칙 내용은 도메인 매칭 항목입니다.DOMAIN-SUFFIX,...처럼 완전한 규칙을 적지 마세요.behavior: ipcidr: 규칙 내용은192.0.2.0/24와 같은 IP 대역입니다.behavior: classical:DOMAIN-SUFFIX같은 클래식 규칙 표현식을 사용할 수 있습니다. 규칙 집합 항목에는 보통 출구 이름을 붙이지 않고, 참조하는 쪽에서 출구를 지정합니다.
type: http로 설정하려면 실제로 접속 가능한 url과 캐시 경로를 지정해야 합니다. 예를 들어 interval: 86400은 86400초, 즉 24시간마다 업데이트한다는 뜻입니다. 다운로드 실패, 파일 형식 불일치, 규칙 미참조는 서로 다른 문제이므로 로그, 파일 내용, 주 설정을 각각 확인해야 합니다.
6. rules: 순서대로 매칭하고 마지막에 기본 출구 지정하기
규칙 모드에서 rules는 목록 순서대로 확인하며, 일반적으로 처음 일치한 규칙이 출구를 결정합니다. 예외 규칙은 앞에, 범위가 넓은 규칙은 뒤에 두고 MATCH는 마지막에 배치하세요. 모든 규칙을 확인한 뒤 가장 적합한 규칙을 고르는 방식이 아닙니다.
rules:
- DOMAIN,example.com,DIRECT
- DOMAIN-SUFFIX,example.net,수동 선택
- RULE-SET,local-direct,DIRECT
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- MATCH,수동 선택
이 부분은 앞에서 정의한 수동 선택 정책 그룹과 local-direct 규칙 집합을 참조하므로 단독으로 완전한 설정을 구성하지는 않습니다. DOMAIN은 지정한 도메인과 일치하고 DOMAIN-SUFFIX는 해당 도메인과 하위 도메인에 일치합니다. 이름이 비슷하다는 이유만으로 두 규칙을 서로 바꾸지 마세요.
no-resolve는 모든 DNS를 끄는 설정이 아닙니다
IP 유형 규칙은 도메인 요청과 일치시키기 위해 DNS 해석을 유발할 수 있습니다. 예시의 no-resolve는 이 규칙을 위해 도메인 해석을 새로 요청하지 말라는 뜻입니다. 요청 자체가 IP이거나 이미 사용할 수 있는 해석 결과가 있다면 매칭될 수 있습니다. DNS 모듈을 끄는 설정이 아니며 다른 단계에서 요청이 해석되지 않는다는 보장도 없습니다.
MATCH를 앞에 두면 뒤의 규칙은 적용되지 않습니다
첫 번째 규칙이 MATCH,DIRECT라면 뒤에 있는 도메인 프록시 규칙은 매칭될 기회가 없습니다. ‘규칙을 작성했는데 적용되지 않는’ 문제를 확인할 때는 클라이언트의 ‘연결’ 페이지에서 새 연결에 적용된 규칙과 출구를 먼저 확인한 다음, 앞쪽에 더 넓은 범위를 포괄하는 규칙이 있는지 살펴보세요. 수정 후에는 새 연결로 검증해야 합니다. 이미 연결된 장시간 연결은 규칙을 바꿔도 자동으로 다른 연결로 전환되지 않습니다.
7. YAML 들여쓰기 오류: 파싱 성공과 실행 성공을 따로 확인하기
각 단계는 공백 두 칸으로 들여쓰고 Tab은 사용하지 않는 것이 좋습니다. YAML은 들여쓰기로 계층을 구분하며, 콜론 뒤에는 보통 공백을 넣고 목록 항목 앞에는 하이픈과 공백을 사용합니다. 설정 오류에 표시되는 줄 번호는 파서가 문제를 발견한 위치일 수 있으며, 실제 원인은 바로 앞 줄에 있을 수도 있습니다.
오류 1: 항목이 상위 단계에 잘못 배치됨
아래의 enable은 dns 아래에 들어가 있지 않습니다. YAML 문법상 유효할 수는 있지만 코어가 기대하는 설정 구조와는 다릅니다.
# 오류: enable이 최상위 항목이 됨
dns:
enable: true
# 올바른 예
dns:
enable: true
오류 2: 목록 항목과 상위 항목의 계층이 맞지 않음
# 오류: DIRECT와 proxies가 같은 단계에 있음
proxy-groups:
- name: "수동 선택"
type: select
proxies:
DIRECT
# 올바른 예
proxy-groups:
- name: "수동 선택"
type: select
proxies:
- DIRECT
오류 3: 특수 문자와 중복 키로 값이 바뀜
: 또는 공백 뒤에 #이 포함된 비밀번호나 이름은 따옴표로 감싸는 것이 좋습니다. 예를 들어 name: "회선: A #1"처럼 쓰면 전체 문자열을 값으로 유지할 수 있습니다. 같은 단계에 dns:나 rules:를 두 번 적고 자동으로 합쳐지길 기대하지 마세요. 파서에서 오류가 발생하거나 한 항목만 남을 수 있으며, 어느 쪽도 오버라이드 방법으로 적절하지 않습니다.
‘정책 그룹을 찾을 수 없음’, ‘규칙 집합이 없음’은 대개 들여쓰기 오류가 아니라 참조 오류입니다. 노드 이름, 정책 그룹 이름, 규칙 집합 이름이 정확히 일치하는지 확인하세요. 오류가 표시된 줄만 보면서 공백을 반복해서 늘리거나 줄이지 마세요.
8. 설정 적용 확인: 접속, DNS, 출구, 규칙 순으로 검증
위의 모든 조각을 그대로 이어 붙여 실제 운영 설정으로 사용하지 마세요. 각 조각은 설정 구조를 설명하기 위한 것입니다. 노드에는 문서용 주소가 들어 있고 규칙 집합은 먼저 로컬 파일을 만들어야 합니다. 실제 설정은 현재 사용할 수 있는 구독을 바탕으로 한 번에 하나의 항목만 변경하세요.
- 기준 상태를 기록합니다. 현재 설정을 백업하고 혼합 포트, 작동 모드, 선택한 정책 그룹 구성원을 기록하세요. ‘프로필’ 페이지에서 방금 편집한 항목이 활성화되어 있는지도 확인합니다.
- 설정 로드를 확인합니다. 수정한 뒤 ‘로그’ 페이지에서 파싱 오류와 이름 참조 오류를 먼저 해결하세요. 설정이 정상적으로 로드되지 않았다면 접속 결과로 새 규칙을 판단하지 마세요.
- 접속 포트를 확인합니다. 실제 수신 포트가 예상한
7897또는 변경한 값인지 확인하세요. 앱이 시스템 프록시 설정을 따르지 않는다면 수동 프록시 설정이나 TUN 처리 방식이 필요한지 살펴보세요. - DNS 해석을 확인합니다. DNS 시간 초과, 노드 도메인 해석 실패, 대상 도메인 해석 실패를 구분하세요. fake-ip를 사용할 때 매핑 주소가 보인다는 사실만으로 실패라고 판단할 수는 없습니다.
- 출구를 확인합니다. ‘프록시’ 페이지에서 정책 그룹이 실제로 선택한 구성원을 확인한 다음, ‘연결’ 페이지에서 새 요청에 매칭된 규칙과 출구 경로를 살펴보세요.
- 설정 유지 여부를 확인합니다. 구독을 한 번 업데이트하거나 설정을 다시 불러와 사용자 설정이 남아 있는지 확인하세요. 덮어써졌다면 적절한 오버라이드 위치로 옮기세요.
항목 간 관계를 더 자세히 알아보려면 고급 설정을 참고하세요. 혼합 포트, 정책 그룹, TUN의 의미가 익숙하지 않다면 먼저 용어 가이드를 확인하세요. 전체 YAML을 한꺼번에 교체하는 것보다 요청이 클라이언트에 들어오는지 확인한 뒤 DNS와 규칙을 검증하는 편이 문제를 찾기 쉽습니다.