먼저 구조부터: YAML 순서와 설정 의존성은 같은 개념이 아닙니다
Clash, Clash Meta 및 후속 mihomo 커널은 일반적으로 YAML 파일로 실행 매개변수를 정의합니다. 하나의 완전한 설정에는 수신 포트, 실행 모드, DNS, 프록시 노드, 정책 그룹, 규칙 집합과 트래픽 스니핑 등이 함께 포함될 수 있습니다. YAML 매핑 자체는 작성 순서로 업무 우선순위를 표현하지 않으므로 rules를 파일 앞부분에 작성해도 포트 필드보다 규칙이 먼저 적용되지는 않습니다.
실제로 문제를 점검할 때는 의존 관계에 따라 읽는 것이 좋습니다. 먼저 기본 수신 설정과 실행 모드를 확인하고, 이어서 DNS, 노드 출처와 정책 그룹 참조를 점검한 다음, 규칙이 요청을 어떤 정책 그룹으로 보내는지 확인합니다. 이 순서는 YAML 파서가 강제하는 로드 순서가 아니라 오류를 더 쉽게 찾기 위한 점검 흐름입니다.
- 기본 필드는 클라이언트가 로컬 트래픽을 어떻게 수신하고 규칙, 전체 또는 직접 연결 모드 중 무엇을 사용할지 결정합니다.
- DNS 필드는 도메인 조회 진입점, 업스트림 서버와 Fake-IP 매핑 방식을 결정합니다.
proxies와proxy-providers는 사용할 수 있는 프록시 노드를 제공합니다.proxy-groups는 노드나 다른 정책 그룹을 묶어 선택 가능한 출구로 구성합니다.rule-providers는 원격 규칙 컬렉션을 제공하고,rules는 최종 매칭 순서를 결정합니다.
기본 필드: 포트, LAN 접근과 실행 모드
기본 섹션은 보통 파일 상단에 배치해 클라이언트가 어떤 진입점을 열고 있는지 빠르게 확인할 수 있도록 합니다. 클라이언트에 따라 일부 값이 그래픽 인터페이스에서 덮어써질 수 있으므로 파일의 값이 실행 시 최종값과 항상 같지는 않습니다. 문제를 점검할 때는 설정 파일과 클라이언트의 현재 상태 화면을 함께 확인해야 합니다.
mixed-port: 7890
allow-lan: false
bind-address: "*"
mode: rule
log-level: info
ipv6: false
external-controller: 127.0.0.1:9090
mixed-port는 HTTP와 SOCKS 프록시 연결을 모두 받아 로컬 프록시 포트 하나만 설정하는 환경에 적합합니다. 일부 설정은 port와 socks-port를 별도로 사용하기도 합니다. 같은 유형의 진입점을 충돌하는 여러 포트로 중복 개방할 필요는 없습니다. 포트를 다른 프로그램이 이미 사용 중이면 커널이 수신 대기를 시작하지 못할 수 있습니다.
allow-lan은 LAN 기기가 로컬 프록시 포트에 연결할 수 있는지 제어합니다. true로 설정했다면 시스템 방화벽과 수신 주소도 확인해야 합니다. bind-address는 수신할 네트워크 인터페이스 범위를 결정하지만, 실제 동작은 커널 버전을 기준으로 판단해야 합니다. 로컬 기기에서만 사용할 경우 LAN 접근을 끄는 편이 진입점을 관리하기 쉽습니다.
mode의 일반적인 값은 rule, global, direct입니다. 규칙 모드는 rules를 차례로 매칭하고, 전체 모드는 모든 트래픽을 전역 정책 선택에 맡기며, 직접 연결 모드는 프록시를 우회합니다. 그래픽 클라이언트의 모드 전환은 실행 중 설정을 바로 바꾸는 경우가 많아 구독 파일에 다시 기록되지 않을 수 있습니다.
| 필드 | 주요 기능 | 점검할 내용 |
|---|---|---|
mixed-port |
HTTP 및 SOCKS 프록시 연결 수신 | 포트 사용 여부와 애플리케이션이 같은 포트를 가리키는지 확인 |
allow-lan |
LAN 기기의 접속 허용 또는 차단 | 수신 주소, 방화벽과 기기가 연결된 네트워크 대역 |
mode |
규칙, 전체 또는 직접 연결 모드 선택 | 클라이언트 실행 상태가 파일 값을 덮어썼는지 확인 |
log-level |
로그 상세 수준 설정 | 문제 해결 시 DNS, 규칙과 연결 정보를 확인할 수 있는지 |
DNS 섹션: 조회 진입점, 업스트림과 Fake-IP 매핑
DNS 설정은 단순한 서버 주소 목록이 아닙니다. 내장 DNS를 활성화하면 커널은 수신 진입점, 해석 모드, 기본 DNS 서버와 실제 업스트림을 결정해야 합니다. TUN으로 트래픽을 라우팅할 때는 DNS 가로채기와 라우팅 설정에 따라 요청이 커널로 들어오는지도 달라집니다.
dns:
enable: true
listen: 0.0.0.0:1053
ipv6: false
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
fake-ip-filter:
- "*.lan"
- "localhost.ptlogin2.qq.com"
default-nameserver:
- 223.5.5.5
- 1.1.1.1
nameserver:
- https://dns.alidns.com/dns-query
- https://1.1.1.1/dns-query
default-nameserver는 주로 암호화된 DNS 업스트림 자체의 도메인을 해석하는 데 사용하며, 일반적으로 직접 연결할 수 있는 IP 주소를 입력합니다. nameserver는 일반적인 도메인 조회를 담당합니다. 일부 mihomo 설정은 프록시 서버 도메인을 전용으로 해석하는 proxy-server-nameserver를 사용하거나, nameserver-policy로 특정 도메인에 서로 다른 업스트림을 지정하기도 합니다.
enhanced-mode: fake-ip는 먼저 도메인에 가상 주소를 할당한 뒤 연결 시 도메인 정보를 복원하고 규칙을 매칭합니다. 이를 통해 애플리케이션 자체 해석으로 인한 매칭 오차를 줄일 수 있습니다. LAN 호스트 이름, 일부 기기 검색 프로토콜, 특정 게임 또는 실제 주소를 반환해야 정상 작동하는 도메인은 fake-ip-filter에 추가해야 할 수 있습니다. 필터 규칙은 실제 이상이 발생하는 항목만 대상으로 추가하고, 광범위한 도메인을 전부 제외하지 않는 것이 좋습니다.
프록시 노드와 정책 그룹: 구성원을 먼저 정의하고 출구를 연결하기
proxies에는 파일에 직접 작성한 노드가 저장됩니다. 각 노드에는 최소한 이름, 프로토콜 유형, 서버 주소, 포트와 프로토콜에 필요한 인증 매개변수가 포함되어야 합니다. 프로토콜마다 필드 차이가 크므로 한 프로토콜의 매개변수를 다른 프로토콜에 그대로 복사할 수 없습니다. 구독 변환 도구가 생성한 노드도 커널이 실제로 지원하는 필드를 기준으로 확인해야 합니다.
proxies:
- name: "노드 A"
type: socks5
server: proxy.example.com
port: 1080
username: account
password: passphrase
udp: true
proxy-groups:
- name: "노드 선택"
type: select
proxies:
- "자동 속도 테스트"
- "노드 A"
- DIRECT
- name: "자동 속도 테스트"
type: url-test
proxies:
- "노드 A"
url: https://www.gstatic.com/generate_204
interval: 300
이름은 참조 키입니다. 정책 그룹의 노드 A는 공백, 대소문자와 전각 기호를 포함해 노드 이름과 한 글자까지 일치해야 합니다. 정책 그룹은 다른 정책 그룹도 참조할 수 있으므로 먼저 “자동 속도 테스트”를 만들고 이를 “노드 선택”의 구성원으로 넣을 수 있습니다. 참조가 순환하면 커널이 유효한 출구를 찾지 못하므로 계층을 조정해야 합니다.
select는 사용자가 구성원을 직접 선택하고, url-test는 테스트 결과에 따라 지연 시간이 낮은 사용 가능한 노드를 자동 선택하며, fallback은 정해진 순서대로 사용 가능한 구성원을 선택하는 데 중점을 둡니다. load-balance는 정책에 따라 여러 구성원 사이에 연결을 분배합니다. 지연 시간 테스트 주소는 사용 가능 여부와 응답 시간 측정에만 사용되며, 모든 대상 사이트의 실제 속도를 의미하지는 않습니다.
DIRECT, REJECT 등은 내장 동작이므로 proxies에 다시 선언할 필요가 없습니다. DIRECT는 직접 연결, REJECT는 연결 거부를 의미합니다. 규칙 대상이 이러한 동작을 직접 가리킬 수도 있지만, 자주 사용하는 출구를 정책 그룹 하나로 통합하면 클라이언트에서 전환하기가 보통 더 편리합니다.
규칙 섹션: 위에서 아래로 매칭되며 첫 번째 결과가 적용됩니다
YAML 최상위 매핑과 달리 rules는 순서가 있는 목록입니다. 커널은 일반적으로 첫 번째 규칙부터 확인하고 매칭되면 이후 검사를 중단합니다. 따라서 구체적인 규칙은 포괄적인 규칙보다 앞에 두고, 기본 처리 규칙은 마지막에 배치해야 합니다. MATCH를 앞에 두면 뒤에 있는 도메인 및 IP 규칙이 작동하지 않습니다.
rules:
- DOMAIN,example.com,DIRECT
- DOMAIN-SUFFIX,example.org,노드 선택
- DOMAIN-KEYWORD,media,노드 선택
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- GEOIP,CN,DIRECT
- MATCH,노드 선택
DOMAIN은 전체 도메인을 매칭하고, DOMAIN-SUFFIX는 지정한 도메인과 하위 도메인을 매칭하며, DOMAIN-KEYWORD는 키워드로 매칭하므로 일반적으로 범위가 더 넓습니다. IP-CIDR은 대상 IP 대역에 적용됩니다. no-resolve를 추가하면 이 규칙을 매칭하기 위해 도메인을 추가로 해석하는 일을 피할 수 있지만, 연결 컨텍스트에 대상 IP가 이미 있어야 바로 판단할 수 있습니다.
GEOIP는 지리 데이터베이스를 이용해 IP를 분류합니다. mihomo는 GeoSite, 규칙 컬렉션과 더 많은 규칙 유형도 지원하지만, 사용 가능 여부는 커널 버전, 데이터베이스 파일과 설정 방식에 따라 달라집니다. 규칙 대상은 이미 존재하는 정책 그룹, 노드 이름 또는 내장 동작이어야 합니다. 로그에 정책을 찾을 수 없다는 메시지가 표시되면 먼저 규칙의 마지막 항목과 proxy-groups 이름을 확인하세요.
규칙 모드는 출구만 선택할 뿐 모든 기기의 트래픽을 자동으로 Clash로 보내지는 않습니다. 브라우저나 시스템이 먼저 시스템 프록시를 사용하거나 TUN 가상 네트워크 인터페이스가 트래픽을 라우팅해야 합니다. “규칙이 적용되지 않는다”는 문제가 발생하면 먼저 해당 연결이 클라이언트 로그에 표시되는지 확인하세요. 로그에 연결이 전혀 없다면 규칙 순서를 계속 수정하기보다 트래픽 진입점을 점검해야 합니다.
원격 컬렉션: proxy-providers와 rule-providers
노드가 많을 때는 proxy-providers를 사용해 원격 주소나 로컬 파일에서 노드 컬렉션을 불러온 다음 정책 그룹에서 use로 참조할 수 있습니다. 규칙 컬렉션은 rule-providers로 정의하고 rules에서 RULE-SET으로 호출합니다. 두 이름은 비슷하지만 제공하는 데이터 유형이 다르므로 서로 바꿔 사용할 수 없습니다.
proxy-providers:
provider-main:
type: http
url: https://sub.example.com/profile.yaml
path: ./providers/provider-main.yaml
interval: 3600
health-check:
enable: true
url: https://www.gstatic.com/generate_204
interval: 300
proxy-groups:
- name: "구독 노드"
type: select
use:
- provider-main
rule-providers:
private-network:
type: http
behavior: ipcidr
format: yaml
path: ./rules/private-network.yaml
url: https://rules.example.com/private-network.yaml
interval: 86400
rules:
- RULE-SET,private-network,DIRECT
- MATCH,구독 노드
path는 원격 콘텐츠를 다운로드한 뒤 저장할 로컬 위치입니다. 실행 환경에서 커널이 해당 디렉터리에 쓸 수 있어야 합니다. interval은 일반적으로 초 단위이며 업데이트 간격을 뜻합니다. 상태 확인 간격과 구독 업데이트 간격은 서로 독립적인 설정입니다. 상태 확인은 기존 노드를 테스트할 뿐 구독 업데이트를 대신하지 않습니다.
규칙 제공기의 behavior는 도메인 컬렉션, IP 대역 컬렉션 또는 클래식 규칙 형식 등 콘텐츠 구조와 일치해야 합니다. mihomo 버전에 따라 format, 바이너리 규칙 집합과 동작 유형 지원 여부가 다를 수 있습니다. 원격 규칙 로드에 실패하면 브라우저에서 URL이 열리는지만 확인하지 말고 로그의 다운로드 상태, 파일 형식과 파싱 오류를 확인해야 합니다.
들여쓰기, 인용 부호와 YAML 유형: 가장 흔한 파싱 경계
YAML은 들여쓰기로 계층을 표현하므로 공백을 일관되게 사용하고 탭 문자를 섞지 않는 것이 좋습니다. 같은 수준의 필드는 동일한 들여쓰기를 유지하고 목록 항목에는 하이픈을 사용합니다. 아래 두 구문은 비슷해 보이지만 두 번째 구문은 enable을 dns 바깥에 배치해 의미가 달라졌습니다.
dns:
enable: true
enhanced-mode: fake-ip
dns:
enable: true
enhanced-mode: fake-ip
콜론, 샵 기호, 앞뒤 공백이 포함되거나 불리언 값으로 오인되기 쉬운 텍스트는 인용 부호로 감싸는 것이 좋습니다. 노드 이름과 정책 그룹 이름은 일관되게 유지하면 한국어를 사용할 수 있습니다. 포트는 숫자로, 스위치 값은 true 또는 false로 작성하고 모든 값을 문자열로 감싸지는 마세요. 일부 필드는 문자열 형식도 허용하지만 유형 호환 여부는 커널 문서와 오류 로그를 기준으로 판단해야 합니다.
YAML 앵커와 참조를 사용하면 반복 설정을 줄일 수 있지만, 복잡한 구독이 클라이언트 덮어쓰기, 형식 변환 또는 재내보내기를 거치면 앵커 구조가 펼쳐질 수 있습니다. 직접 파일을 관리할 때는 신중하게 사용할 수 있지만, 구독 변환 과정을 자주 거친다면 핵심 필드를 명시적으로 작성하는 편이 문제를 찾기 쉽습니다.
필드 덮어쓰기 관계와 전체 점검 절차
실행 중 설정은 원격 구독 원문, 클라이언트 로컬 덮어쓰기, 사용자가 인터페이스에서 임시로 선택한 값과 커널 시작 매개변수 등 여러 계층에서 만들어질 수 있습니다. 최종 적용값은 클라이언트가 이러한 출처를 병합하는 방식에 따라 달라집니다. 같은 필드가 여러 번 정의되었을 때는 파일 내 위치만으로 결과를 추측하지 말고 클라이언트가 생성한 최종 설정이나 실행 상태를 확인해야 합니다.
정책 그룹의 현재 선택값은 보통 클라이언트나 커널 캐시에 저장됩니다. 구독 업데이트 후에도 그룹 이름과 구성원 관계가 유효하면 기존 선택이 유지될 수 있습니다. 노드 이름이 바뀌거나 삭제되면 클라이언트가 그룹 내 다른 구성원으로 되돌릴 수 있습니다. 규칙 업데이트만으로 노드 사용 가능성이 입증되는 것은 아니며, 노드 상태 확인에 성공했다고 해서 규칙 대상이 올바르다는 뜻도 아닙니다.
- YAML 문법 확인: 들여쓰기, 콜론, 목록 기호와 인용 부호가 올바른지 확인해 파싱 불가 문제를 먼저 배제합니다.
- 로컬 진입점 확인: mixed-port, 시스템 프록시 또는 TUN 상태를 확인하고 대상 연결이 로그에 들어오는지 살펴봅니다.
- DNS 경로 확인: 쿼리가 커널에 수신되는지, 업스트림에 접근 가능한지, Fake-IP 제외 범위가 적절한지 확인합니다.
- 노드 출처 확인: 정적 노드 또는 프록시 제공기가 정상적으로 로드되었고 서버 도메인을 해석할 수 있는지 확인합니다.
- 이름 참조 확인: 규칙 대상에서 정책 그룹까지, 다시 정책 그룹에서 노드 또는 제공기까지 추적합니다.
- 규칙 순서 확인: 구체적인 규칙은 앞에, 포괄적인 규칙은 뒤에 두고 마지막에는 명확한 기본 규칙을 남깁니다.
- 실행 중 덮어쓰기 확인: 클라이언트 인터페이스의 모드, 포트와 정책 선택이 예상한 설정을 덮어쓰지 않았는지 확인합니다.
로드되고, 트래픽을 넘겨받고, DNS를 해석하고, 경로를 선택할 수 있어야 설정이 완전한 흐름을 갖춥니다. 문제가 발생하면 “진입점 → DNS → 노드 → 정책 그룹 → 규칙 → 출구” 순서로 각 단계를 확인하는 편이 여러 필드를 한꺼번에 수정하는 것보다 원인을 찾기 쉽습니다. 한 번에 한 단계만 조정하고 로그로 결과를 검증하면 문법, 네트워크와 규칙 문제가 서로 뒤섞이는 일을 막을 수 있습니다.