1. YAML 구조 개요
Clash의 모든 동작은 YAML 형식의 설정 파일 하나로 제어됩니다. 클라이언트 화면의 모든 스위치, 모든 정책 그룹, 모든 분기 규칙은 결국 이 파일 안의 특정 필드에 대응합니다. 전체 구조를 이해하는 것은 이후의 모든 수정 작업의 전제 조건입니다. 어떤 필드가 어느 섹션에 속하는지 알아야, 수정이 무엇에 영향을 미치는지, 구독 업데이트 시 덮어써지는지 여부를 알 수 있습니다.
완전한 설정 파일은 최상위 레벨에서 몇 개의 고정된 이름을 가진 섹션으로 구성되며, 커널은 이름으로 이를 인식하므로 순서는 파싱에 영향을 주지 않습니다. 자주 쓰이는 섹션은 다음과 같습니다.
- 공통 필드: 최상위에 흩어져 있는 스칼라 설정으로,
mixed-port,mode,log-level등이 있으며 포트, 프록시 모드, 실행 파라미터를 제어합니다; dns: 도메인 해석 동작을 정의하며, 내장 DNS 활성화 여부, Fake-IP 모드, 상위 서버 목록을 포함합니다;proxies: 프록시 노드 배열로, 각 항목은 출구 서버 하나의 프로토콜, 주소, 인증 정보를 기술합니다;proxy-groups: 정책 그룹 배열로, 노드를 선택 가능하고 자동 속도 측정이 가능한 그룹으로 구성합니다;rules: 분기 규칙 배열로, 각 연결이 어느 정책 그룹을 거칠지 또는 직접 연결할지를 결정합니다;proxy-providers/rule-providers: 외부 주소나 로컬 파일에서 노드와 규칙 세트를 가져와 유지 관리를 분리할 수 있게 합니다;tun: 가상 네트워크 어댑터 모드로, 시스템 전체 트래픽을 인수할 때 사용합니다.
실행 가능한 최소 설정은 세 부분만 있으면 됩니다: 인바운드 포트 하나, 노드 최소 1개(또는 DIRECT를 직접 사용), 기본 규칙 하나. 아래 골격은 그대로 config.yaml로 저장해 검증할 수 있습니다:
mixed-port: 7897
mode: rule
log-level: info
proxies: []
proxy-groups: []
rules:
- MATCH,DIRECT
YAML에는 몇 가지 엄격한 작성 규칙이 있으며, 설정 파싱 실패의 대부분 원인이 여기서 발생합니다. 첫째, 계층 구조는 오직 들여쓰기로 표현되며 같은 레벨의 들여쓰기 폭은 반드시 일치해야 합니다. 관례적으로 공백 2칸을 사용합니다. 둘째, 콜론 뒤에는 반드시 공백이 하나 있어야 하며, mode:rule은 잘못된 표기입니다. 셋째, 필드명은 대소문자를 구분하므로 Mode는 mode로 인식되지 않습니다. 넷째, 문자열은 일반적으로 인용부호가 필요 없지만 콜론, 샵(#), 별표(*) 등 특수문자가 포함된 경우에는 반드시 인용부호로 감싸야 합니다. 예를 들어 비밀번호 "p@ss:word#1"처럼요.
Tab 들여쓰기 금지
YAML 규격은 탭 문자 들여쓰기를 허용하지 않으며, 커널은 found a tab character that violates indentation 오류를 내며 로드를 거부합니다. 메모장, vim 등의 편집기로 설정을 수정하기 전에 편집기가 Tab 키를 공백으로 매핑하도록 설정되어 있는지 먼저 확인하세요. 웹페이지에서 복사한 조각도 줄 앞머리에 탭 문자가 섞여 들어갔는지 확인해야 합니다.
설정 파일의 저장 위치와 구독 업데이트 시 어느 섹션이 전체 교체되는지는 사이트 내 글 《Clash 설정 파일(Profile) 구조 분석》을 참고하세요. 본 페이지의 8장에서도 로컬 변경 사항이 업데이트 후에도 유지되는 병합 방안을 제공합니다.
2. 공통 필드: 포트, 모드와 실행 제어
공통 필드는 설정 최상위에 바로 작성되며, 커널이 어떤 방식으로 동작할지를 제어합니다. 수는 많지 않지만 거의 매번 문제 해결 시 가장 먼저 확인해야 하는 부분입니다. 포트 충돌, 모드 선택 오류, LAN 기기 연결 불가 등의 원인이 대부분 여기에 있습니다.
2.1 인바운드 포트
커널은 여러 종류의 인바운드 리스닝을 동시에 열 수 있습니다. port는 순수 HTTP 프록시 포트이고, socks-port는 순수 SOCKS5 포트입니다. mixed-port는 같은 포트에서 HTTP와 SOCKS5 요청을 동시에 식별하며, 현재 대부분의 클라이언트가 기본값으로 채택하고 있습니다. 시스템 프록시와 서드파티 소프트웨어가 같은 포트를 가리키기만 하면 되므로 설정이 가장 간단합니다. 세 가지는 동시에 존재할 수 있지만 리스닝 포트 번호는 중복되지 않아야 하며, 시스템의 다른 프로그램이 사용 중인 포트와도 충돌하면 안 됩니다. 시작 시 bind: address already in use 오류가 나면 포트가 이미 사용 중이라는 뜻이므로 사용하지 않는 포트 번호로 바꾸면 됩니다.
2.2 LAN 접근
allow-lan은 인바운드 포트가 로컬 머신 외부의 연결을 허용할지 결정합니다. true로 설정하면 같은 LAN 내의 스마트폰, TV 셋톱박스가 프록시 서버를 이 기기의 내부 IP로 지정해 동일한 출구와 규칙을 공유할 수 있습니다. bind-address와 함께 사용하면 특정 네트워크 어댑터에서만 리스닝하도록 제한할 수 있습니다. 활성화하기 전에 현재 네트워크 환경을 주의해야 합니다. 회사나 공용 Wi-Fi에서 LAN 리스닝을 열면 같은 네트워크 대역의 모든 기기가 이 프록시 포트를 사용할 수 있게 됩니다.
2.3 프록시 모드 mode
mode는 세 가지 값을 받습니다: rule(규칙 섹션을 하나씩 매칭해 분기), global(모든 트래픽을 전역 출구로), direct(모든 트래픽 직접 연결). 평소에는 rule로 고정해두어야 하며, 나머지 두 모드는 상시 사용하는 옵션이 아니라 진단용 도구입니다. 언제 임시로 전환하고 전환 후 어떻게 확인하는지는 사이트 내 글 《Clash 세 가지 프록시 모드, 어떻게 선택할까》에서 전체 절차를 설명합니다.
2.4 자주 쓰는 공통 필드 요약
| 필드 | 유형 / 값 | 설명 |
|---|---|---|
| mixed-port | 1-65535 | HTTP와 SOCKS5 혼합 인바운드 포트, 유일한 인바운드로 사용하는 것을 권장 |
| allow-lan | true / false | LAN 기기가 로컬 프록시 포트에 접속하도록 허용할지 여부 |
| bind-address | IP / "*" | 리스닝 주소, allow-lan과 함께 네트워크 어댑터를 제한 |
| mode | rule / global / direct | 프록시 모드, 평소에는 rule 유지 |
| log-level | silent / error / warning / info / debug | 로그 레벨, 문제 해결 시 임시로 debug로 조정 |
| ipv6 | true / false | IPv6 트래픽 처리 여부, 네트워크 환경이 지원하지 않으면 꺼서 해석 잡음을 줄일 수 있음 |
| external-controller | IP:포트 | RESTful 제어 인터페이스 주소, 클라이언트 패널이 이를 통해 커널 상태를 읽고 씀 |
| secret | 문자열 | 제어 인터페이스 접근 토큰, LAN을 개방할 때는 반드시 설정 |
external-controller는 따로 설명할 필요가 있습니다. 이는 HTTP 인터페이스를 개방하며, 클라이언트 GUI가 바로 이 인터페이스를 통해 노드를 전환하고 지연 시간과 트래픽 데이터를 읽습니다. 기본값 127.0.0.1:9090은 로컬 머신에만 개방됩니다. 만약 0.0.0.0:9090으로 바꿔 LAN 패널이 접근하도록 한다면 반드시 secret도 함께 설정해야 합니다. 그렇지 않으면 같은 네트워크 대역의 기기가 커널을 직접 조작할 수 있습니다.
2.5 TUN 섹션 요약
시스템 프록시는 프록시 설정을 준수하는 애플리케이션에만 적용되며, 커맨드라인 도구, 게임, 일부 클라이언트 소프트웨어는 이를 우회합니다. tun 섹션은 가상 네트워크 어댑터를 생성해 네트워크 계층에서 모든 트래픽을 인수함으로써 "프록시를 설정했지만 특정 프로그램이 이를 거치지 않는" 문제를 해결합니다:
tun:
enable: true
stack: system
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
stack은 프로토콜 스택 구현 방식(system / gvisor / mixed)을 지정하며, 호환성 문제가 있을 때 몇 가지 값을 바꿔가며 비교할 수 있습니다. auto-route는 시스템 라우팅 테이블을 자동으로 기록합니다. dns-hijack은 53번 포트로 향하는 평문 DNS 쿼리를 내장 DNS로 가로채며, 다음 장의 설정과 함께 사용하면 해석 우회를 막을 수 있습니다. TUN을 활성화하려면 관리자 또는 root 권한이 필요하며, 각 클라이언트는 해당 시스템 서비스 설치를 안내합니다.
3. DNS 섹션: 해석 동작과 Fake-IP
프록시 환경에서 DNS는 가장 쉽게 간과되는 부분입니다. 도메인 해석이 여전히 로컬 통신사의 평문 53번 포트를 통해 이루어진다면, 트래픽 자체는 프록시를 거치더라도 어떤 도메인에 접속했는지는 로컬 링크에 그대로 노출됩니다. 일부 도메인은 오염된 주소로 해석되어 연결 실패를 일으키기도 합니다. dns 섹션의 역할은 커널이 해석 과정을 넘겨받아 "누가 해석하는지, 어떻게 해석하는지, 해석 결과를 어떻게 쓰는지"를 통합적으로 결정하는 것입니다.
3.1 기본 스위치와 리스닝
dns:
enable: true
listen: 0.0.0.0:1053
ipv6: false
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
enable: true는 내장 DNS 모듈을 활성화합니다. listen은 이를 일반 DNS 서버로도 동작하게 하여 외부에 해석 서비스를 제공하며, 주로 TUN의 dns-hijack이나 라우터 환경에서 함께 사용됩니다. enhanced-mode는 이 섹션의 핵심 선택 항목으로, 해석 결과의 표현 방식을 결정합니다.
3.2 Fake-IP와 Redir-Host
fake-ip 모드에서는 커널이 실제 해석이 끝나기를 기다리지 않고, fake-ip-range 예약 대역(기본값 198.18.0.1/16)에서 즉시 가상 주소를 하나 할당해 애플리케이션에 반환하며 동시에 "이 가상 주소가 어느 도메인에 해당하는지"를 기억합니다. 애플리케이션이 그 가상 주소로 연결을 시도하면 커널은 IP가 아닌 도메인 기준으로 규칙을 매칭해 전달합니다. 이 방식의 장점은 한 번의 해석 왕복을 줄여 첫 패킷 지연을 크게 낮추고, 규칙 매칭이 항상 도메인 기반이라 정확도가 높다는 점입니다. redir-host는 실제 해석 결과를 반환하여 전통적인 DNS와 더 비슷하게 동작하며, 호환성은 좋지만 속도와 매칭 정확도는 다소 떨어집니다. 두 모드의 메커니즘 차이, 그리고 LAN 서비스나 게임 온라인 매칭처럼 Fake-IP를 피해야 하는 상황은 사이트 내 글 《Clash Fake-IP 모드 작동 원리》에서 자세히 다룹니다.
Fake-IP를 사용할 때 실제 IP를 반드시 받아야 하는 일부 쿼리는 fake-ip-filter로 제외해야 합니다. 대표적으로 LAN 호스트명, 시스템 인터넷 연결 감지 도메인, NTP 서비스가 있습니다:
fake-ip-filter:
- "*.lan"
- "+.local"
- "+.msftconnecttest.com"
- "+.pool.ntp.org"
여기서 *는 한 단계 하위 도메인을 매칭하고, +는 여러 단계의 하위 도메인과 도메인 자체를 포함해 매칭합니다.
3.3 상위 서버의 3단계 구조
default-nameserver:
- 223.5.5.5
- 119.29.29.29
nameserver:
- https://dns.alidns.com/dns-query
- https://doh.pub/dns-query
fallback:
- https://1.1.1.1/dns-query
fallback-filter:
geoip: true
geoip-code: CN
세 그룹의 서버는 역할이 다르므로 혼동하면 안 됩니다. default-nameserver는 순수 IP만 입력할 수 있으며, 뒤의 두 그룹인 암호화 DNS 서버 자체의 도메인을 해석하는 데만 사용되어 "닭이 먼저냐 달걀이 먼저냐"는 문제를 해결합니다. nameserver는 주력 해석 그룹으로, DoH(https:// 접두사)나 DoT(tls:// 접두사) 같은 암호화 프로토콜 사용을 권장합니다. fallback은 보조 그룹으로 fallback-filter와 연동됩니다. 주력 그룹의 해석 결과가 필터 조건에 걸리면(예: geoip-code: CN 이외의 결과) 보조 그룹의 응답으로 바꾸어 오염에 대응합니다. 이 이중 쿼리 메커니즘이 필요하지 않다면 nameserver 그룹만 남겨도 됩니다.
DNS 누출 자가 진단
시스템 프록시 모드에서는 애플리케이션의 DNS 쿼리가 반드시 커널을 거치는 것은 아닙니다. TUN 모드가 dns-hijack과 함께 사용되거나, 애플리케이션이 프록시 포트를 통해 직접 연결을 시작할 때만 해석이 완전히 인수됩니다. 누출 감지 도구에서 출구가 통신사 DNS로 표시된다면 TUN이 활성화되어 있는지, dns 섹션의 enable이 true인지 먼저 확인하세요. 더 많은 확인 방법은 자주 묻는 질문 페이지의 문제 해결 분류를 참고하세요.
4. 프록시 노드 필드(proxies)
proxies는 배열이며, 각 항목이 출구 노드 하나를 완전히 기술합니다. 구독 설정에서 이 섹션은 서비스 제공자가 생성하므로 보통 직접 작성할 필요가 없습니다. 다만 노드를 자체 구축하거나, 구독에 개인 출구를 추가하거나, "특정 노드가 왜 연결되지 않는지" 대조 확인할 때는 각 필드의 의미를 이해해야 합니다.
4.1 모든 프로토콜에 공통되는 필드
어떤 프로토콜이든 네 가지 필드는 필수입니다: name(노드명, 정책 그룹이 이를 통해 참조하며 같은 설정 내에서 중복될 수 없음), type(프로토콜 유형), server(서버 도메인 또는 IP), port(서비스 포트). 그 외 udp: true는 해당 노드가 UDP 포워딩을 지원함을 선언하며, 음성 통화, 게임 등 UDP에 의존하는 애플리케이션에 필요합니다.
4.2 세 가지 대표적인 프로토콜 예시
proxies:
- name: "HK-01"
type: ss
server: hk01.example.com
port: 8388
cipher: aes-256-gcm
password: "your-password"
udp: true
- name: "JP-01"
type: vmess
server: jp01.example.com
port: 443
uuid: 0f7b7c4e-3a52-4e70-9d2b-1c8a5f6e0d43
alterId: 0
cipher: auto
tls: true
network: ws
ws-opts:
path: /ws
headers:
Host: jp01.example.com
- name: "US-01"
type: trojan
server: us01.example.com
port: 443
password: "your-password"
sni: us01.example.com
udp: true
Shadowsocks(ss)의 핵심 필드는 암호화 방식인 cipher와 password이며, 양쪽이 완전히 일치해야 합니다. VMess는 uuid를 신원 인증 정보로 사용하며, alterId는 현재 프로토콜에서 0으로 고정됩니다. network는 전송 계층(ws, grpc, http 등)을 선언하며, 어떤 전송 계층을 선택하든 그에 맞는 *-opts 하위 섹션이 필요합니다. 예시의 ws-opts는 WebSocket의 경로와 Host 헤더를 지정합니다. Trojan은 원래 TLS 위에서 동작하며, sni는 핸드셰이크 시 선언하는 서버 이름을 지정합니다. 서버 인증서와 일치하지 않으면 곧바로 연결에 실패합니다.
mihomo 커널은 이 세 가지 외에도 vless, hysteria2, tuic, wireguard 등의 프로토콜을 지원하며, 필드 구조는 동일한 패턴을 따릅니다: 공통 4개 필드에 프로토콜 고유 필드를 추가하는 방식입니다. 새로운 프로토콜 노드를 받으면 먼저 type 표기가 커널 지원 목록과 일치하는지 확인한 뒤, 프로토콜이 요구하는 인증 필드를 하나씩 채우면 됩니다.
skip-cert-verify 신중히 사용
TLS 계열 노드(vmess+tls, trojan, vless 등)는 skip-cert-verify: true로 인증서 검증을 건너뛸 수 있습니다. 이는 인증서 문제를 진단할 때의 임시 조치로만 사용해야 하며, 장기간 켜두면 서버 신원 검증을 포기하는 것과 같아 중간자가 노드 서버로 위장할 수 있습니다. 서비스 제공자가 명확히 요구하지 않는다면 실제 사용 설정에서는 기본값인 검증 활성화 상태를 유지하세요.
5. 정책 그룹 필드(proxy-groups)
proxies가 원재료라면 proxy-groups는 원재료를 "결정 가능한 단위"로 조직하는 계층입니다. 규칙 섹션의 출구는 거의 언제나 단일 노드가 아니라 정책 그룹을 가리킵니다. 이렇게 하면 노드를 바꿀 때 그룹 안에서만 전환하면 되고 규칙은 손댈 필요가 없습니다. 클라이언트 메인 화면의 그룹 선택 목록이 바로 이 섹션을 시각화한 것입니다.
5.1 네 가지 그룹 유형
| 유형 | 동작 | 대표적인 용도 |
|---|---|---|
| select | 수동 선택, 사용자가 마지막에 선택한 항목 유지 | 최상위 메인 스위치 그룹, 용도별 업무 그룹 |
| url-test | 주기적으로 지연 시간을 측정해 가장 빠른 노드를 자동 선택 | 노드를 수동으로 고르고 싶지 않을 때 쓰는 "자동" 그룹 |
| fallback | 목록 순서대로 첫 번째 사용 가능한 노드를 선택, 실패 시 자동으로 다음 순서로 넘어감 | 주-보조 구조: 우선 고정된 메인 노드를 사용하고 장애 시 대체 |
| load-balance | 정책에 따라 연결을 여러 노드에 분산 | 다중 노드로 동시 연결을 분산해 단일 지점 부담을 낮춤 |
5.2 전체 예시와 파라미터 설명
proxy-groups:
- name: "노드 선택"
type: select
proxies:
- 자동 테스트
- HK-01
- JP-01
- US-01
- DIRECT
- name: "자동 테스트"
type: url-test
url: http://www.gstatic.com/generate_204
interval: 300
tolerance: 50
lazy: true
proxies:
- HK-01
- JP-01
- US-01
자동 유형 그룹의 세 가지 파라미터는 체감에 직접 영향을 줍니다. url은 속도 측정 대상이며, 관례적으로 204 상태 코드를 반환하는 경량 주소를 사용해 "이 노드를 통해 이 주소에 접근"하는 전체 왕복을 측정합니다. interval은 측정 간격(초)으로, 너무 짧으면 많은 탐지 트래픽이 발생합니다. tolerance는 전환 허용치(밀리초)로, 새로운 최속 노드가 현재 노드보다 이 차이만큼 더 빨라야 전환이 일어나며, 지연 시간이 비슷한 두 노드 사이에서 왔다 갔다 하는 것을 막아줍니다. lazy: true는 그룹이 사용되지 않을 때 속도 측정을 일시 정지시켜 백그라운드 부담을 줄입니다.
그룹은 다른 그룹을 참조할 수 있습니다. 예시의 「노드 선택」은 「자동 테스트」를 첫 번째 선택 항목으로 두어 "상위는 수동, 하위는 자동"인 2단계 구조를 형성합니다. 구독 설정에 흔히 보이는 「홍콩」, 「일본」 같은 지역 그룹을 다시 하나의 총괄 그룹으로 모으는 것도 같은 방식의 중첩입니다. 예약된 두 이름은 어떤 그룹에도 바로 나타날 수 있습니다: DIRECT는 직접 연결, REJECT는 연결 거부(광고 차단 규칙의 출구로 자주 사용)를 뜻합니다. 그룹과 노드는 같은 네임스페이스를 공유하므로 그룹명은 노드명과 중복될 수 없고, 순환 참조를 구성해서도 안 됩니다. A 그룹이 B 그룹을 포함하고 B 그룹이 다시 A 그룹을 포함하면 로드에 실패합니다.
6. 규칙 문법(rules)
rules 섹션은 각 연결의 방향을 결정하며, 전체 설정에서 직접 관리할 가치가 가장 큰 부분입니다. 각 규칙은 쉼표로 구분된 한 줄의 텍스트로, 기본 형태는 「유형,매칭값,출구」이며 출구에는 정책 그룹명, 노드명 또는 DIRECT / REJECT를 씁니다.
6.1 매칭 순서: 위에서 아래로, 첫 매칭에서 멈춤
커널은 새로운 연결마다 첫 번째 규칙부터 하나씩 시도하며, 매칭되면 그 규칙의 출구를 채택하고 이후 규칙은 더 이상 관여하지 않습니다. 이 메커니즘에서 규칙 배치의 모든 원칙이 도출됩니다: 정밀한 규칙을 앞에, 넓은 범위의 규칙을 뒤에, 기본 규칙을 맨 마지막에 둡니다. GEOIP,CN,DIRECT 규칙이 특정 도메인을 위한 프록시 규칙보다 앞에 놓여 있고 그 도메인이 마침 중국 본토 IP로 해석된다면, 뒤에 있는 도메인 규칙은 영원히 작동하지 않습니다. "규칙을 분명히 작성했는데 적용되지 않는" 문제의 대부분은 순서 문제입니다.
6.2 자주 쓰는 규칙 유형
| 유형 | 매칭 대상 | 예시 |
|---|---|---|
| DOMAIN | 도메인 완전 일치 | DOMAIN,dl.example.com,DIRECT |
| DOMAIN-SUFFIX | 도메인 자체와 모든 하위 도메인 | DOMAIN-SUFFIX,openai.com,노드 선택 |
| DOMAIN-KEYWORD | 도메인에 키워드 포함 | DOMAIN-KEYWORD,github,노드 선택 |
| IP-CIDR | 목적지 IPv4가 해당 대역에 속함 | IP-CIDR,192.168.0.0/16,DIRECT,no-resolve |
| IP-CIDR6 | 목적지 IPv6가 해당 대역에 속함 | IP-CIDR6,fd00::/8,DIRECT,no-resolve |
| GEOIP | 목적지 IP의 지리 데이터베이스 소속 국가 | GEOIP,CN,DIRECT |
| PROCESS-NAME | 연결을 시작한 프로세스 이름(데스크톱) | PROCESS-NAME,steam.exe,DIRECT |
| DST-PORT | 목적지 포트 | DST-PORT,22,DIRECT |
| RULE-SET | rule-providers 규칙 세트 참조 | RULE-SET,telegram,노드 선택 |
| MATCH | 무조건 매칭, 반드시 마지막 규칙이어야 함 | MATCH,노드 선택 |
DOMAIN-SUFFIX,example.com은 example.com과 a.b.example.com을 모두 매칭하며, 한 사이트를 포괄하는 데 가장 흔히 쓰이는 유형입니다. DOMAIN-KEYWORD는 범위가 가장 넓어 잘못 걸릴 위험이 있으므로 키워드가 충분히 고유하다고 확신할 때만 사용하세요. IP 계열 규칙 끝의 no-resolve 파라미터는 "현재 연결의 목적지가 도메인이지 IP가 아니라면 이 규칙을 건너뛰고, 매칭을 위해 해석을 시도하지 말라"는 의미입니다. 내부망 대역 규칙에 이를 추가하면 모든 도메인 연결이 먼저 해석되어 매칭이 느려지는 것을 막을 수 있습니다.
6.3 그대로 적용할 수 있는 배치 예시
rules:
- PROCESS-NAME,steam.exe,DIRECT
- DOMAIN,dl.example.com,DIRECT
- DOMAIN-SUFFIX,openai.com,노드 선택
- DOMAIN-KEYWORD,github,노드 선택
- IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- GEOIP,CN,DIRECT
- MATCH,노드 선택
이 배치는 권장하는 계층 구조를 보여줍니다: 프로세스와 정확한 도메인 규칙을 가장 먼저, 업무 도메인 규칙을 그다음, 내부망 대역과 지역 기반 직접 연결을 뒤쪽에, MATCH로 마무리합니다. MATCH 뒤에 오는 규칙은 모두 죽은 코드입니다. 커널이 오류를 내지는 않지만 절대 실행되지 않으므로, 설정을 검토할 때 이를 "규칙 섹션 종료 표시"로 여기면 됩니다. 사용자 정의 규칙을 작성한 뒤 매칭 여부를 확인하는 방법은 9장의 로그 방법을 참고하세요.
7. 외부 리소스: proxy-providers와 rule-providers
노드가 여러 구독에서 오고 규칙 항목이 수백, 수천 개에 달할 때 모든 내용을 하나의 YAML에 쌓아두면 금방 관리할 수 없게 됩니다. Provider 메커니즘은 노드 목록과 규칙 세트를 독립된 파일로 분리해 커널이 주기적으로 자동 업데이트하도록 하고, 메인 설정은 참조 관계만 유지하도록 해줍니다.
7.1 proxy-providers: 노드 소스와 헬스 체크
proxy-providers:
main-sub:
type: http
url: "https://example.com/subscribe/token"
path: ./providers/main-sub.yaml
interval: 86400
health-check:
enable: true
url: http://www.gstatic.com/generate_204
interval: 600
proxy-groups:
- name: "구독 노드"
type: select
use:
- main-sub
type: http은 원격 주소에서 가져온다는 뜻이고, path는 로컬 캐시 경로입니다(가져오기 실패 시 캐시를 그대로 사용해 오프라인에서도 시작 가능). interval은 자동 업데이트 주기(초)입니다. health-check는 커널이 주기적으로 해당 소스의 모든 노드 가용성을 테스트하도록 하며, 실패한 노드는 자동 유형 그룹에서 건너뛰어집니다. 정책 그룹은 use 필드로 provider 이름을 참조하며, proxies 필드와 함께 사용할 수 있습니다. 하나의 그룹이 직접 작성한 노드와 구독 전체 소스를 동시에 포함할 수 있습니다.
7.2 rule-providers: 규칙 세트의 세 가지 behavior
rule-providers:
telegram-ip:
type: http
behavior: ipcidr
format: yaml
url: "https://example.com/rules/telegram.yaml"
path: ./rules/telegram-ip.yaml
interval: 86400
rules:
- RULE-SET,telegram-ip,노드 선택
behavior는 규칙 세트 파일의 내용 형태를 선언하며 세 값은 혼용할 수 없습니다: domain은 파일 내 항목이 모두 도메인이라는 뜻이고, ipcidr은 모두 대역 항목이라는 뜻입니다. 이 두 형태는 커널이 효율적인 인덱스를 구축하므로 수만 건의 대형 목록에 적합합니다. classical은 파일 내에 유형 접두사가 붙은 완전한 규칙 행이 있다는 뜻으로 유연하지만 매칭 비용이 더 큽니다. format은 yaml과 text를 지원하며 파일의 실제 형식과 일치해야 합니다. 메인 설정에서는 RULE-SET,규칙세트명,출구 형태로 참조하며, 이 줄이 규칙 섹션 내에서 위치하는 순서 역시 6장의 순서 원칙을 따릅니다.
업데이트 주기 선택
interval을 너무 짧게 설정할 필요는 없습니다. 노드 구독은 하루 한 번(86400)이면 대체로 충분하고, 규칙 세트는 변경이 더 느리므로 며칠에 한 번도 괜찮습니다. 주기가 너무 짧으면 트래픽 낭비 외에도 소스 서버가 불안정할 때 가져오기 실패 로그가 빈번히 발생해 문제 진단을 방해합니다.
8. 오버라이드와 병합: 구독 업데이트 후에도 변경 사항 유지하기
구독으로 생성된 설정 파일을 직접 편집하는 데는 근본적인 문제가 있습니다. 구독 업데이트는 전체 교체 방식이므로 수동으로 추가한 노드, 변경한 규칙이 다음 업데이트 시 모두 사라집니다. 해결 방법은 하나뿐입니다. "서비스 제공자가 제공하는 내용"과 "로컬에서사용자 정의한 내용"을 분리해서 저장하고, 클라이언트가 로드할 때 병합하도록 하는 것입니다. 각 클라이언트마다 이 메커니즘을 제공하지만 이름은 다르고 원리는 동일합니다.
8.1 클라이언트의 오버라이드 메커니즘
다운로드 센터에서 첫 번째로 추천하는 Clash Plus는 구독 원문을 건드리지 않고도 규칙과 노드를 추가할 수 있는 설정 오버라이드 항목을 제공합니다. Clash Verge Rev는 「병합(Merge)」과 「스크립트(Script)」 두 종류의 확장 설정을 제공합니다. Merge는 선언적 YAML로 추가와 교체를 기술하고, Script는 JavaScript 함수로 로드 시점에 설정 객체를 재작성해 조건 로직을 처리할 수 있습니다. FlClash도 마찬가지로 오버라이드 설정을 지원합니다. 어떤 클라이언트를 쓰든 원칙은 같습니다: 구독 파일 자체는 항상 읽기 전용으로 유지하고, 모든 사용자 정의는 오버라이드 계층에 작성합니다.
8.2 Merge 방식 오버라이드 예시
prepend-rules:
- DOMAIN-SUFFIX,internal.example.com,DIRECT
- PROCESS-NAME,steam.exe,DIRECT
append-rules:
- DOMAIN-KEYWORD,tracker,REJECT
append-proxies:
- name: "자체 구축-HK"
type: ss
server: my.example.com
port: 8388
cipher: aes-256-gcm
password: "your-password"
prepend-*는 해당 섹션 맨 앞에 항목을 삽입하고, append-*는 맨 뒤에 추가합니다. 방향 선택은 규칙 매칭 순서와 연관지어야 합니다. 우선 매칭되기를 원하는 사용자 정의 규칙은 prepend-rules를 쓰고, 기본값 성격의 차단 규칙은 append-rules를 쓰되 이것이 구독 원문의 MATCH 뒤에 놓인다는 점을 주의해야 합니다. 구독 끝에 이미 MATCH가 있다면 추가한 규칙은 실제로 도달할 수 없으므로, 이 경우에는 prepend를 쓰거나 rules 섹션 전체를 교체하는 방식을 써야 합니다. mixed-port, dns 같은 스칼라나 매핑 필드는 오버라이드 계층에 같은 이름의 필드를 쓰면 전체가 교체됩니다.
8.3 수동 관리 시나리오
Linux 서버처럼 mihomo 커널을 직접 실행하고 GUI 클라이언트가 없는 환경에서는 별도의 병합 계층이 없으므로, 구독을 기준 파일로 내려받은 뒤 스크립트나 수동 작업으로 사용자 정의 섹션을 이어붙여 최종 설정을 만들고, 구독을 업데이트할 때는 기준 부분만 교체하는 방식을 권장합니다. 디렉터리 구성과 systemd 상시 구동 방안은 사이트 내 글 《Clash의 Linux 배포 두 가지 경로》를 참고하세요.
설정 변경 전 백업부터
어떤 방식으로 수정하든 손대기 전에 현재 정상 작동하는 설정 파일을 복사해 설정 디렉터리 밖에 보관하세요. 병합 로직에 오류가 생겼을 때 백업으로 되돌리는 것이 가장 빠른 복구 수단입니다. 로그를 한 줄씩 대조하며 오류를 찾는 것보다 훨씬 시간을 절약할 수 있습니다. 여러 설정 전환과 백업의 구체적인 방법은 Profile 관리 가이드를 참고하세요.
9. 검증 및 문제 해결
설정을 수정한 뒤 바로 리로드해버리지 말고, 먼저 문법을 검증하고 그다음 동작을 관찰하면 문제 진단 시간을 최소로 줄일 수 있습니다. 이 장에서는 고정된 검증 순서를 제시합니다.
9.1 로드 전: 문법 검증
mihomo 커널은 자체 설정 테스트 파라미터를 제공하며, 서비스를 시작하지 않고 파싱만 수행해 몇 초 내에 결과를 알려줍니다:
mihomo -t -f config.yaml
configuration file test is successful이 출력되면 문법이 통과된 것입니다. 그렇지 않으면 오류가 발생한 필드 경로와 줄 번호를 출력합니다. 데스크톱 클라이언트도 설정을 가져오거나 저장할 때 동일한 검증을 수행하며 오류 세부 정보를 팝업으로 보여줍니다. 오류 문구는 커널과 동일하므로 아래 표를 그대로 대조해 확인할 수 있습니다.
9.2 자주 발생하는 오류 대조표
| 오류 키워드 | 원인 | 대처 |
|---|---|---|
| found a tab character | 줄 앞머리에 탭 문자가 섞임 | Tab을 모두 공백으로 바꾸고 2칸 들여쓰기로 통일 |
| did not find expected key | 들여쓰기 계층이 어긋나 필드가 잘못된 상위 항목에 걸림 | 오류 줄과 주변 컨텍스트의 들여쓰기 폭이 일치하는지 대조 |
| proxy not found / group not found | 규칙이나 그룹이 존재하지 않는 이름을 참조함 | 이름 표기와 전각/반각 공백을 확인하고, 참조 대상이 실제로 존재하는지 확인 |
| bind: address already in use | 인바운드 또는 제어 포트가 다른 프로그램에 점유됨 | 포트를 바꾸거나 점유 중인 프로세스를 찾아 종료 |
| duplicate proxy name | 노드나 그룹의 이름이 중복됨 | 둘 중 하나의 이름을 변경, 그룹과 노드가 네임스페이스를 공유한다는 점 주의 |
| unsupported proxy type | type 표기 오류 또는 커널이 해당 프로토콜을 지원하지 않음 | 프로토콜명 표기를 대조하고 mihomo 커널을 사용하고 있는지 확인 |
9.3 로드 후: 실제 동작 관찰
문법이 통과했다고 해서 분기가 예상대로 작동한다는 뜻은 아닙니다. log-level을 임시로 debug로 바꾸고 리로드하면 클라이언트 로그 패널에 연결 기록이 한 줄씩 출력됩니다. 형식은 example.com:443 --> 노드 선택 (match DOMAIN-SUFFIX/example.com)와 비슷하며, 각 연결이 어떤 규칙에 매칭되었고 어느 출구를 거쳤는지 바로 표시해줍니다. 이는 사용자 정의 규칙을 검증하는 가장 신뢰할 수 있는 방법으로, 웹페이지를 계속 새로고침하며 짐작하는 것보다 훨씬 효율적입니다. 확인이 끝나면 로그 레벨을 다시 info로 되돌리는 것을 잊지 마세요. debug 레벨의 로그량은 매우 많습니다.
커맨드라인 환경에서 커널이 살아 있는지 확인해야 할 때는 제어 인터페이스에 직접 접근할 수 있습니다:
curl -s http://127.0.0.1:9090/version -H "Authorization: Bearer 여기에 secret 입력"
정상적인 JSON 응답이 있으면 커널이 실행 중이고 제어 인터페이스에 접근 가능하다는 뜻입니다. 응답이 없으면 커널이 시작되지 않았거나 external-controller 주소가 예상과 다르다는 뜻입니다. 클라이언트가 실행하자마자 바로 꺼져 로그조차 볼 시간이 없는 경우에는 《Clash 클라이언트 실행 시 크래시 문제 해결 매뉴얼》에서 제시하는 각 플랫폼별 로그 위치와 확인 순서에 따라 하나씩 처리하세요.
9.4 다음 단계
여기까지 읽었는데도 아직 정상 작동하는 기본 환경이 없다면, 먼저 빠른 시작으로 돌아가 메인 흐름에 따라 첫 연결을 완료한 뒤, 구체적인 필요가 생기면 다시 돌아와 해당 장을 찾아보시기를 권합니다. 클라이언트 본체는 다운로드 센터에서 플랫폼별로 받을 수 있으며, 전체 플랫폼에서 Clash Plus를 첫 번째로 추천합니다. 사용 중 자주 발생하는 의문점 — 자동 시작, 구독 실패, 노드 타임아웃 등 — 은 자주 묻는 질문 페이지에 정리되어 있으며 이 페이지와 상호 보완적입니다.