clashsg.com › manual
Clash 설정 파일 참고서
config.yaml 전체 필드 참고서입니다: 구조 개요, 공통 필드, DNS, 노드, 정책 그룹, providers, 규칙 문법, TUN, 오버라이드까지 실행 가능한 YAML 예제로 정리했습니다. 이 페이지는 체계적으로 찾아보는 용도이며, 처음 시작하는 가이드가 아닙니다 — 처음 설치하고 구독을 가져올 때는 먼저 사용 안내서를 보고 3단계를 따라 진행하세요. 구체적인 필드가 이해되지 않을 때 이 페이지로 돌아와 장별로 찾아보면 됩니다. 클라이언트 설치 파일은 다운로드 페이지에서 받을 수 있으며, Clash Plus를 우선 추천합니다.
1. YAML 구조 개요: 설정 파일은 어떤 블록으로 구성되는가
Clash의 설정 파일은 표준 YAML 문서이며, 기본 파일명은 config.yaml입니다. YAML에는 세 가지 절대 규칙이 있으니 먼저 기억하고 넘어가세요. 첫째, 계층은 오직 들여쓰기로 표현하며 관례상 2칸 공백을 한 단계로 하고 Tab은 금지입니다. 둘째, 콜론 뒤에는 반드시 공백이 와야 합니다. port:7890은 문법 오류이고 port: 7890이어야 유효합니다. 셋째, 값에 콜론·샵·중괄호 같은 특수문자가 들어가면 인용부호로 감싸야 하며, 특히 비밀번호와 URL이 그렇습니다. 샵 # 이후 줄 끝까지는 주석이며 커널이 로드할 때 무시됩니다.
완전한 설정 파일은 위에서 아래로 대략 네 단계로 나뉩니다: 인바운드와 실행 파라미터(포트, 모드, 로그), DNS 섹션, 아웃바운드 리소스(proxies 노드 목록, proxy-groups 정책 그룹, 두 종류의 provider), 마지막으로 rules 규칙 목록입니다. 커널은 "규칙 적중 → 정책 그룹 결정 → 노드 아웃바운드" 순서로 각 연결을 처리하며, 설정 파일의 배치 순서는 이 데이터 흐름과 정확히 대응합니다. 자주 쓰는 최상위 필드는 아래 표를 참고하세요.
| 최상위 필드 | 유형 | 역할 |
|---|---|---|
mixed-port | 정수 | HTTP와 SOCKS5를 함께 처리하는 혼합 인바운드 포트, 최신 클라이언트에서 우선 사용 |
port / socks-port | 정수 | HTTP/SOCKS5를 분리한 인바운드 포트, mixed-port와 둘 중 하나만 쓰면 됨 |
allow-lan | 불리언 | 같은 네트워크의 다른 기기가 이 기기의 프록시 포트에 접속하도록 허용할지 여부 |
mode | 열거형 | rule / global / direct 세 가지 실행 모드 |
log-level | 열거형 | 로그 레벨, 문제 해결 시 debug로, 평소에는 info나 warning으로 설정 |
external-controller | 문자열 | RESTful 제어 인터페이스의 리스닝 주소, 패널과 클라이언트 UI가 이를 이용함 |
dns | 매핑 | 내장 DNS 모듈, fake-ip와 분기 해석을 모두 여기서 설정 |
proxies | 배열 | 노드 목록, 노드마다 하나의 매핑 객체 |
proxy-groups | 배열 | 정책 그룹 목록, "누가 노드를 고르고 어떻게 고르는지"를 결정 |
proxy-providers / rule-providers | 매핑 | 외부 구독 노드 모음과 외부 규칙 모음 |
rules | 배열 | 분기 규칙, 위에서 아래로 매칭하며 첫 번째로 일치하는 규칙이 적용됨 |
tun | 매핑 | 가상 네트워크 카드가 전체 트래픽을 가로채 시스템 프록시를 거치지 않는 앱까지 처리 |
아래는 바로 실행할 수 있는 최소 설정입니다. 다섯 부분이 모두 갖춰져 있고, 이후 각 장에서 이 골격을 확장해 나갑니다.
mixed-port: 7890
allow-lan: false
mode: rule
log-level: info
proxies:
- name: "노드A"
type: ss
server: example.com
port: 8388
cipher: aes-128-gcm
password: "your-password"
proxy-groups:
- name: "PROXY"
type: select
proxies:
- 노드A
- DIRECT
rules:
- DOMAIN-SUFFIX,example.com,PROXY
- GEOIP,CN,DIRECT
- MATCH,PROXY
설정 로드 실패의 첫 번째 원인은 들여쓰기입니다. 한 줄에 공백을 하나 더 넣거나 빼면 전체 파일 파싱이 중단되고, 클라이언트는 보통 "yaml: line N" 같은 오류 한 줄만 표시합니다. 설정을 고치기 전에 에디터를 "공백 문자 표시, Tab을 공백으로 변환"으로 설정해 두면 문법 문제의 90%를 피할 수 있습니다.
2. 공통 필드: 포트, 모드, 제어 인터페이스
인바운드 포트: mixed-port 하나로 셋을 대신한다
과거에는 port: 7890(HTTP)과 socks-port: 7891(SOCKS5)을 나눠 썼지만, 지금은 mixed-port: 7890을 바로 쓰는 것이 권장됩니다 — 같은 포트가 두 프로토콜을 자동으로 인식하므로 시스템 프록시와 각 앱의 프록시 설정을 모두 이 포트 하나로 지정하면 되고, 프로토콜을 구분하는 수고가 사라집니다. 7890은 커뮤니티 관례일 뿐 예약된 값은 아닙니다. 시작 로그에 "address already in use"가 뜬다면 다른 프로세스가 그 포트를 쓰고 있다는 뜻이니 사용하지 않는 포트로 바꾸면 됩니다.
allow-lan과 bind-address
allow-lan: true는 인바운드 포트를 같은 네트워크의 다른 기기에 노출합니다. 흔한 용도는 TV 박스나 게임기가 PC의 Clash를 빌려 쓰는 경우입니다. bind-address를 함께 쓰면 리스닝 주소를 제한할 수 있습니다. 기본값 "*"는 모든 네트워크 카드를 리스닝하며, 특정 내부망 IP로 바꾸면 특정 서브넷에만 개방할 수 있습니다. 켜기 전에 지금 있는 네트워크가 신뢰할 수 있는지 먼저 확인하세요 — 회사나 공용 Wi-Fi에서 allow-lan을 켜는 것은 같은 서브넷의 누구에게나 아웃바운드 통로를 빌려주는 것과 같습니다.
mode: 세 가지 실행 모드의 경계
mode: rule은 일상적인 형태로, 각 연결이 규칙 표를 한 줄씩 통과합니다. global은 규칙을 건너뛰고 모든 트래픽을 전역 정책 그룹이 정한 노드에 넘기며, "규칙 문제인지 노드 문제인지"를 임시로 확인할 때 적합합니다. direct는 모두 직접 연결하며, 프록시 로직 전체를 우회하는 것과 같습니다. 세 모드는 클라이언트 화면에서 즉시 전환할 수 있어 파일을 고칠 필요는 없지만, 설정 파일에 적힌 값이 커널 시작 시의 초기 모드를 결정합니다.
log-level과 external-controller
log-level은 적은 순서부터 silent / error / warning / info / debug입니다. "어떤 규칙이 왜 적용되지 않는지"를 조사할 때 debug로 바꾸면 각 연결이 어떤 규칙에 걸렸고 최종적으로 어디로 나갔는지 로그에 출력됩니다. 확인이 끝나면 info로 되돌리세요. debug 레벨 로그량은 장기 운영에 부담이 됩니다. external-controller: 127.0.0.1:9090은 RESTful 제어 인터페이스를 여는데, 클라이언트 패널의 노드 전환, 지연 테스트, 연결 목록이 모두 이를 통해 이뤄집니다. secret 필드는 인터페이스에 접근 암호를 걸며, 예시에서는 항상 secret: "xxxx" 같은 가짜 값을 씁니다. external-ui는 로컬 디렉터리를 지정해 웹 패널을 마운트할 수 있게 합니다. 제어 인터페이스를 0.0.0.0으로 리스닝한다면 반드시 secret도 함께 설정해야 합니다. 그러지 않으면 같은 네트워크의 누구든 프록시 상태를 바꿀 수 있습니다.
mixed-port: 7890
allow-lan: true
bind-address: "*"
mode: rule
log-level: info
ipv6: false
external-controller: 127.0.0.1:9090
secret: "xxxx"
ipv6: false는 커널이 IPv6 주소를 해석하거나 사용하지 않는다는 뜻입니다. 사용 중인 네트워크의 IPv6 연결 상태가 좋지 않다면 이를 끄면 "v6 주소는 얻었지만 연결은 안 되는" 유형의 타임아웃 일부를 피할 수 있습니다. 네트워크와 노드가 모두 v6를 지원할 때 켜면 됩니다. 이 스위치는 DNS 섹션의 해석 동작과 연동되므로 변경 후에는 핫 리로드 대신 커널을 재시작하는 것을 권장합니다.
3. DNS 설정: fake-ip, 분기 해석, 오염 방지
DNS 섹션은 "도메인이 어떻게 IP로 바뀌는지"를 결정하며 분기 정확도와 연결 성공 여부에 직접 영향을 줍니다. enable: true는 내장 DNS 모듈을 활성화하고, listen은 모듈 자체의 리스닝 주소를 지정하며 TUN 모드에서 dns-hijack과 함께 씁니다. 진짜 이해해야 할 것은 enhanced-mode의 두 값입니다.
fake-ip와 redir-host의 선택
fake-ip 모드에서는 커널이 각 도메인마다 fake-ip-range(기본값 198.18.0.1/16) 안의 가짜 주소를 먼저 돌려주고, 앱은 이 가짜 주소로 연결을 시작합니다. 커널은 "가짜 IP ↔ 도메인" 매핑을 근거로 원래 도메인을 복원해 규칙 매칭을 수행합니다 — 도메인 규칙이 100% 적중하고 로컬 해석 대기 시간을 아낄 수 있다는 장점이 있지만, 실제 IP에 의존하는 일부 프로그램(로컬 네트워크 검색, 일부 게임 연결)은 가짜 주소 때문에 방해를 받습니다. 이런 도메인은 fake-ip-filter 화이트리스트에 넣어 실제 해석 결과를 받도록 해야 합니다. redir-host는 먼저 해석하고 나서 매칭하는 방식으로 동작이 직관적이지만, "IP를 먼저 받는" 순서 때문에 도메인 규칙이 누락될 수 있습니다. 데스크톱과 모바일은 일상적으로 fake-ip를 쓰고, 호환성 문제가 많은 환경에서는 redir-host로 되돌립니다.
nameserver, fallback, fallback-filter
nameserver는 주 해석 그룹으로, 통신사에서 도달 가능하고 지연이 낮은 중국 본토 서비스를 넣는 것이 권장되며 udp, tls://(DoT), https://(DoH) 세 가지 표기를 지원합니다. fallback은 보조 그룹으로 신뢰할 수 있는 해외 DoH를 넣습니다. 두 그룹을 동시에 조회한 뒤 fallback-filter가 어느 쪽을 채택할지 결정합니다. geoip: true이고 geoip-code: CN이라는 것은 — 주 그룹의 해석 결과가 중국 본토 IP라면 채택하고, 그렇지 않으면 fallback 결과로 바꿔 오염된 응답을 피한다는 뜻입니다. mihomo 커널은 nameserver-policy를 추가로 지원해 도메인 접미사별로 특정 DNS로 보낼 수 있어 더 세밀한 제어가 가능합니다.
dns:
enable: true
listen: 0.0.0.0:1053
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
fake-ip-filter:
- "*.lan"
- "+.local"
- "+.msftconnecttest.com"
nameserver:
- https://223.5.5.5/dns-query
- 119.29.29.29
fallback:
- https://1.1.1.1/dns-query
fallback-filter:
geoip: true
geoip-code: CN
"프록시는 연결됐다고 나오는데 웹사이트가 안 열린다"는 경우, DNS는 점검 목록에서 빠지지 않는 항목입니다. fake-ip 캐시 잔존, fallback 전체 타임아웃, 시스템 DNS와 커널 DNS의 충돌이 모두 같은 증상을 만들 수 있습니다. 단계별 점검 방법은 《Clash가 연결됐는데 웹사이트가 안 열릴 때: 시스템 프록시부터 DNS까지 단계별 점검 목록》에서 확인하세요.
4. 노드 필드: proxies 프로토콜별 분석
proxies는 배열이며, 각 요소가 하나의 아웃바운드 노드를 나타냅니다. 네 필드는 모든 프로토콜에 공통입니다: name(노드 이름, 파일 전체에서 유일해야 하며 정책 그룹이 이를 통해 참조), type(프로토콜 종류), server(서버 주소, 도메인 또는 IP), port(포트). udp: true는 해당 노드가 UDP 트래픽도 전달한다는 선언으로, 음성 통화와 게임이 이에 의존합니다. 이름에 한글, 공백, 특수문자가 들어가면 인용부호로 감싸 파싱 오류를 피하세요.
Shadowsocks(ss)
필드가 가장 적은 프로토콜입니다: cipher는 암호화 방식(흔히 aes-128-gcm, chacha20-ietf-poly1305)을 지정하고, password는 사전 공유 키입니다. cipher 표기는 서버 쪽과 완전히 일치해야 하며, 틀리면 오류가 나는 게 아니라 "연결은 되지만 데이터가 전부 깨지는" 상태가 되어 지연 테스트가 항상 타임아웃됩니다.
VMess
핵심은 uuid(사용자 식별자)와 alterId(최신 배포에서는 항상 0)입니다. cipher: auto는 양쪽이 암호화 방식을 협의하게 하며, 전송 계층은 network로 선택합니다. 순수 TCP 외에 가장 흔한 것은 ws(WebSocket)로, 이때 ws-opts로 경로와 Host 헤더를 채우고 tls: true를 함께 설정해 HTTPS로 위장합니다. ws 경로, Host, TLS 이 세 가지 중 하나라도 서버와 다르면 핸드셰이크가 실패합니다.
Trojan
구조상 HTTPS처럼 보이도록 설계되었습니다: password로 인증하고, sni는 TLS 핸드셰이크에서 선언할 도메인을 지정합니다(생략 시 server 값 사용). skip-cert-verify: true는 인증서 검증을 건너뛰는데 — 서버가 자체 서명 인증서를 쓴다는 것을 명확히 알 때만 임시로 사용해야 하며, 장기간 켜두는 것은 중간자 공격 방어를 포기하는 것과 같습니다.
mihomo 확장 프로토콜
mihomo(Clash Meta) 커널은 오리지널 위에 vless(reality 전송 포함), hysteria2, tuic 등의 유형을 추가했으며, 필드 구조도 "공통 4종 세트 + 프로토콜 전용 섹션"으로 동일합니다. 구독에 이런 노드가 있다면 mihomo 커널 클라이언트(다운로드 페이지에 나열된 Clash Plus, Clash Verge Rev, FlClash 모두 해당)를 반드시 써야 하며, 오리지널 커널은 type을 인식하지 못해 설정 전체 로드를 거부합니다. 두 커널의 전체 차이 비교는 《mihomo 커널과 오리지널 Clash 커널 차이 비교》에서 확인하세요.
proxies:
- name: "SS-홍콩"
type: ss
server: hk.example.com
port: 8388
cipher: aes-128-gcm
password: "your-password"
udp: true
- name: "VMess-일본"
type: vmess
server: jp.example.com
port: 443
uuid: 00000000-0000-0000-0000-000000000000
alterId: 0
cipher: auto
tls: true
network: ws
ws-opts:
path: /ws
headers:
Host: jp.example.com
- name: "Trojan-싱가포르"
type: trojan
server: sg.example.com
port: 443
password: "your-password"
sni: sg.example.com
udp: true
skip-cert-verify: true는 "연결이 안 되면 켜보는" 만능 스위치가 아닙니다. 인증서 검증 실패라는 한 가지 오류만 해결하며, 다른 문제 때문에 켜봤자 효과가 없을뿐더러 그 노드를 지나는 모든 트래픽을 잠재적 중간자에게 노출시킵니다.
5. 정책 그룹 필드: proxy-groups 다섯 가지 유형
정책 그룹은 노드 위의 스케줄링 계층입니다: 규칙은 특정 노드를 직접 가리키지 않고 그룹을 가리키며, 그룹은 자신의 유형에 따라 어떤 노드를 쓸지 정합니다. 그룹 안의 구성원은 proxies 배열에 적으며, 노드 이름, 다른 그룹 이름, 또는 내장 정책 두 가지 — DIRECT(직접 연결)와 REJECT(연결 거부, 도메인 차단에 흔히 사용) — 가 될 수 있습니다. 그룹 안에 그룹을 넣는 것은 일반적인 방식으로, 예를 들어 "수동 선택" 그룹 안에 "자동 속도 측정" 그룹을 넣으면 수동과 자동을 함께 얻을 수 있습니다.
| type | 결정 방식 | 대표 사례 |
|---|---|---|
select | 완전 수동, 사용자가 화면에서 고른 노드를 그대로 사용 | 최상위 스위치 그룹 |
url-test | 주기적으로 지연을 측정해 가장 빠른 노드를 자동 선택 | 일상적인 자동 최적화 |
fallback | 목록 순서대로 첫 번째로 사용 가능한 노드를 사용, 장애 시 자동으로 다음 노드로 전환 | 주-백업 라인 장애 대비 |
load-balance | 연결을 여러 노드에 분산 | 단일 노드 속도 제한 회피 |
relay | 순서대로 체인 형태로 전달, 트래픽이 각 노드를 차례로 통과 | 다중 홉 경로, 지연이 누적되므로 주의해서 사용 |
자동 유형 그룹은 세 파라미터에 의존합니다: url은 생존 확인 주소로 보통 204를 반환하는 가벼운 엔드포인트를 씁니다. interval은 테스트 주기(초)로 300이 흔한 값이며 너무 작게 하면 대량의 탐지 트래픽이 생깁니다. tolerance(url-test 전용)는 전환 허용치(밀리초)로, 새 노드와 기존 노드의 지연 차이가 이 값을 넘어야 전환이 일어나 지연이 비슷한 두 노드가 번갈아 흔들리는 것을 막습니다. lazy: true는 그룹이 규칙에 실제로 쓰이기 전에는 테스트를 시작하지 않게 해, 노드가 많을 때 백그라운드 요청을 크게 줄여줍니다. load-balance는 strategy로 분배 방식을 고르는데, consistent-hashing은 같은 대상 사이트가 항상 같은 노드로 가게 해 로그인 상태 유지에 유리하고, round-robin은 순서대로 분배합니다.
proxy-groups:
- name: "수동 선택"
type: select
proxies:
- 자동 속도 측정
- SS-홍콩
- VMess-일본
- Trojan-싱가포르
- DIRECT
- name: "자동 속도 측정"
type: url-test
url: http://www.gstatic.com/generate_204
interval: 300
tolerance: 50
lazy: true
proxies:
- SS-홍콩
- VMess-일본
- Trojan-싱가포르
- name: "장애 전환"
type: fallback
url: http://www.gstatic.com/generate_204
interval: 300
proxies:
- SS-홍콩
- VMess-일본
흔한 오류 "proxy not found"는 거의 다 참조 일치 문제에서 나옵니다: 그룹에 적은 이름과 proxies 섹션의 name이 공백 하나, 인용부호 한 쌍, 전각/반각 문자 하나만 달라도 로드가 실패합니다. 이름을 바꿀 때는 전체 검색으로 옛 이름이 쓰인 곳을 모두 함께 고치세요.
6. providers: 구독 노드와 외부 규칙 모음
proxy-providers: 노드 소스를 외부로 분리하기
노드를 proxies에 직접 적는 것의 문제는, 구독이 한 번 갱신될 때마다 파일 전체가 서버 쪽 버전으로 덮어써져 로컬에서 한 수정이 사라진다는 점입니다. proxy-providers는 "노드 소스"를 따로 빼냅니다: type: http는 interval(초) 주기로 url이 가리키는 구독을 가져와 path에 캐시하고, type: file은 로컬 파일을 읽습니다. health-check 하위 섹션은 이 노드 묶음에 독립적인 생존 확인을 설정합니다. 정책 그룹은 use 필드로 provider를 참조하며, provider 안의 모든 노드가 자동으로 그룹에 주입되고 proxies 배열과 동시에 존재할 수 있습니다.
rule-providers: 규칙 모음의 세 가지 behavior
rule-providers는 규칙 버전의 같은 발상으로, rules 섹션을 짧게 유지하고 대량의 도메인/IP를 외부 모음이 관리하게 합니다. 핵심 필드 behavior는 세 가지 값을 가지며 모음 내용을 해석하는 방식을 정합니다: domain(순수 도메인 목록), ipcidr(순수 CIDR 목록), classical(각 줄이 완전한 Clash 규칙). format은 파일 형식(yaml 또는 text)을 선언하며, behavior와 실제 모음 내용이 맞지 않으면 규칙 전체가 조용히 무효화됩니다 — 이것이 "RULE-SET을 분명히 적었는데 적용이 안 되는" 가장 흔한 원인입니다.
proxy-providers:
main:
type: http
url: "https://example.com/sub.yaml"
path: ./providers/main.yaml
interval: 86400
health-check:
enable: true
url: http://www.gstatic.com/generate_204
interval: 600
rule-providers:
cn-domains:
type: http
behavior: domain
format: yaml
url: "https://example.com/cn-domains.yaml"
path: ./rules/cn-domains.yaml
interval: 86400
proxy-groups:
- name: "구독 노드"
type: select
use:
- main
구독 자체는 여러 배포 형태로 존재합니다 — 완전한 YAML, Base64 노드 목록, 범용 공유 링크 등이며 모두 provider에 바로 넣을 수 있는 것은 아닙니다. 각 형식의 구조 차이와 상호 변환 방법은 《Clash 구독 형식 상세 설명》에서, 클라이언트에서 구독을 가져오는 구체적인 절차는 사용 안내서에서 확인하세요. 갱신이 실패할 때는 먼저 path 캐시 파일이 생성됐는지, 타임스탬프가 바뀌었는지 확인한 다음, 로그에 있는 provider 조회의 HTTP 상태 코드를 보는 것이 무작정 재시도하는 것보다 훨씬 빠르게 문제를 찾아줍니다.
7. 규칙 문법: 위에서 아래로, 첫 번째 일치 적용
규칙 한 줄은 쉼표로 구분된 세 부분입니다: 유형,매칭값,정책이며, 정책은 노드 이름, 그룹 이름, DIRECT 또는 REJECT가 될 수 있습니다. 매칭 엔진은 위에서 아래로 훑으며 첫 번째로 일치한 규칙이 확정되고 이후 규칙은 더 보지 않습니다 — 그래서 순서가 곧 우선순위입니다: 정밀한 규칙(DOMAIN, PROCESS-NAME)을 가장 앞에, 범위가 넓은 규칙(GEOIP)을 뒤에 두고, MATCH 최종 처리는 반드시 마지막 한 줄이어야 하며 매칭값은 비워둡니다.
| 규칙 유형 | 매칭 대상 | 예시 | 비고 |
|---|---|---|---|
DOMAIN | 도메인이 완전히 일치 | DOMAIN,ad.example.com,REJECT | 하위 도메인 미포함 |
DOMAIN-SUFFIX | 도메인 접미사 | DOMAIN-SUFFIX,github.com,수동 선택 | 본 도메인과 모든 하위 도메인 포함 |
DOMAIN-KEYWORD | 도메인에 키워드 포함 | DOMAIN-KEYWORD,google,수동 선택 | 범위가 넓어 오탐이 쉬우므로 자주 쓰지 않음 |
GEOIP | 대상 IP가 속한 지역 | GEOIP,CN,DIRECT | GeoIP 데이터베이스에 의존 |
IP-CIDR / IP-CIDR6 | 대상 IP 대역 | IP-CIDR,192.168.0.0/16,DIRECT,no-resolve | v4 / v6 각각 별도 타입 |
SRC-IP-CIDR | 발신 IP 대역 | SRC-IP-CIDR,192.168.1.50/32,DIRECT | allow-lan 환경에서 기기별로 트래픽 분기 |
DST-PORT | 대상 포트 | DST-PORT,22,DIRECT | 포트 기준으로 대략적인 트래픽 분류 |
PROCESS-NAME | 요청을 보낸 프로세스 이름 | PROCESS-NAME,Telegram.exe,수동 선택 | 데스크톱에서 사용 가능, 앱 단위로 분기 |
RULE-SET | rule-provider 참조 | RULE-SET,cn-domains,DIRECT | 이름은 provider 키 이름과 일치해야 함 |
MATCH | 조건 없는 최종 처리 | MATCH,수동 선택 | 반드시 마지막 한 줄에만 사용 |
no-resolve는 IP 계열 규칙의 선택적 네 번째 항목으로, "대상이 아직 도메인이고 해석되지 않았다면 이 규칙을 건너뛰고 이걸 매칭하려고 별도의 DNS 해석을 발생시키지 말라"는 의미입니다. 내부망 대역, 예약 주소 대역 규칙에는 일괄적으로 no-resolve를 붙이면 의미 없는 해석 요청을 대량으로 피할 수 있습니다. mihomo 커널은 GEOSITE 유형을 추가로 제공해 사이트 카테고리별로 관리되는 도메인 데이터베이스를 바로 참조할 수 있으며(예: GEOSITE,category-ads-all,REJECT), 세밀함이 직접 작성한 규칙과 RULE-SET 사이에 있습니다.
rules:
- PROCESS-NAME,Telegram.exe,수동 선택
- DOMAIN,ad.example.com,REJECT
- DOMAIN-SUFFIX,github.com,수동 선택
- RULE-SET,cn-domains,DIRECT
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
- GEOIP,CN,DIRECT
- MATCH,수동 선택
특정 사이트가 어떤 규칙에 걸렸는지 확인하려면: log-level을 잠시 debug로 바꾸고 대상 사이트에 한 번 접속해 보세요. 로그에 연결마다 걸린 규칙과 아웃바운드 노드가 출력됩니다. 규칙 표를 보고 추측하는 것보다 훨씬 확실합니다. 낯선 용어(GeoIP, CIDR, 정책 그룹)는 언제든 용어집에서 찾아보세요.
8. TUN 모드: 가상 네트워크 카드가 전체 트래픽을 처리
시스템 프록시는 "프록시 설정을 존중하는" 앱에만 적용되며, 커맨드라인 도구, 게임 클라이언트, 일부 데스크톱 소프트웨어는 이를 무시하고 직접 패킷을 보냅니다. TUN 모드의 해법은 가상 네트워크 카드를 하나 만들어 기기 전체의 아웃바운드 트래픽을 네트워크 계층에서 가로채 커널에 넘기는 것입니다 — 앱은 이를 인지하지 못하고, 규칙은 평소처럼 적용됩니다. 대가는 더 높은 시스템 권한과 DNS에 대한 추가적인 인터셉트가 필요하다는 점입니다.
tun:
enable: true
stack: system
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
필드를 하나씩 살펴보면: stack은 프로토콜 스택 구현을 고르는데, system은 OS 네이티브 스택을 써서 처리량이 좋고, gvisor는 사용자 공간 스택으로 호환성이 필요한 상황에서 대체용, mixed는 둘을 섞은 방식입니다. auto-route는 라우팅 테이블에 자동으로 써서 기본 경로를 가상 네트워크 카드로 향하게 하며, 끄면 경로를 직접 설정해야 하므로 보통 true로 둡니다. auto-detect-interface는 실제 물리 출구 네트워크 카드를 자동으로 식별해 커널 자신의 아웃바운드 트래픽까지 가상 네트워크 카드에 잡혀 루프가 생기는 것을 막습니다 — TUN을 켠 뒤 완전히 인터넷이 끊긴다면 열 번 중 아홉은 이 부분이 문제입니다. dns-hijack은 임의 주소의 53번 포트로 가는 조회를 내장 DNS 모듈로 가로채, TUN 상태에서도 fake-ip 체계가 그대로 성립하도록 보장합니다.
| 플랫폼 | 구현 방식 | 권한 요점 |
|---|---|---|
| Windows | wintun 가상 네트워크 카드 드라이버 | 클라이언트를 관리자 권한으로 실행하거나 서비스 구성 요소에 권한을 부여해야 함 |
| macOS | 시스템 네트워크 확장 / utun 장치 | 처음 사용할 때 시스템 설정에서 네트워크 확장을 승인해야 함 |
| Android | VpnService 인터페이스 | 클라이언트가 VPN 권한만 요청하면 되고 root는 필요 없음 |
| Linux | /dev/net/tun 장치 | root 또는 CAP_NET_ADMIN 권한 필요 |
macOS의 승인 절차가 가장 헤매기 쉬운데, 네트워크 확장 승인 입구가 깊이 숨어 있고 키체인 팝업을 잘못 처리하면 계속 다시 나타납니다. 단계별 스크린샷 설명은 《macOS에서 Clash 설치 시 권한 문제가 뜬다면? 네트워크 확장과 키체인 승인 전체 절차》를 참고하세요. 또한 mihomo 커널은 sniffer 도메인 스니핑 섹션을 제공해 TUN 상황에서 TLS 핸드셰이크로부터 대상 도메인을 복원함으로써 "IP만 있고 도메인이 없어" 규칙이 잘못 판정되는 문제를 보완하며, 고급 사용자는 필요에 따라 켜면 됩니다.
TUN과 시스템 프록시는 둘 중 하나를 꼭 골라야 하는 것이 아닙니다: 평소 웹서핑은 시스템 프록시만으로 충분하고, 커맨드라인이나 게임 트래픽까지 처리해야 할 때 TUN을 켜면 됩니다. 대부분의 클라이언트는 TUN을 원터치 스위치로 만들어 뒤에서 이번 장의 필드들을 그대로 써 넣습니다.
9. 오버라이드와 병합: 구독을 업데이트해도 수정 사항 유지하기
구독으로 생성된 config.yaml을 직접 편집하는 것은 가장 흔한 유지보수 함정입니다: 다음 구독 갱신 때 파일 전체가 서버 쪽 버전으로 덮어써져 수동으로 추가한 규칙, 고친 정책 그룹이 모두 사라집니다. 올바른 방법은 "구독 원본"과 "로컬 수정"을 분리해 클라이언트가 로드할 때 둘을 병합하도록 하는 것입니다.
YAML 앵커: 파일 내부 중복 제거
먼저 YAML 자체의 재사용 문법을 이야기하면, &name은 앵커를 정의하고 *name은 참조하며, <<: 병합 키는 매핑 전체를 펼쳐 넣습니다. 여러 정책 그룹이 같은 생존 확인 파라미터를 공유할 때 앵커로 중복 구간을 한 곳으로 모을 수 있습니다.
check-common: &check
url: http://www.gstatic.com/generate_204
interval: 300
proxy-groups:
- name: "자동 속도 측정"
type: url-test
<<: *check
tolerance: 50
proxies:
- SS-홍콩
- VMess-일본
- name: "장애 전환"
type: fallback
<<: *check
proxies:
- SS-홍콩
- VMess-일본
앵커는 같은 파일 안에서만 유효합니다. 이는 "중복" 문제를 해결하는 것이고 "덮어쓰기" 문제는 해결하지 못합니다. 파일 간 병합은 클라이언트의 오버라이드 메커니즘에 맡겨야 합니다.
클라이언트 오버라이드: 구독 위에 한 겹 더 쌓기
주류 클라이언트는 대부분 오버라이드 입구를 제공하며 발상은 동일합니다: 구독 원본은 읽기 전용으로 두고, 수정 사항은 별도의 오버라이드 계층에 적으며, 로드할 때마다 먼저 구독을 가져온 뒤 오버라이드를 얹으므로 구독을 갱신해도 수정 사항이 사라지지 않습니다. Clash Verge Rev를 예로 들면 Merge(선언적 병합, 흔히 prepend-rules / append-rules 의미로 커스텀 규칙을 구독 규칙 앞이나 뒤에 끼워 넣음)와 Script(스크립트로 설정 객체를 임의로 가공) 두 방식을 제공합니다. Clash Plus 등 다른 클라이언트도 각자의 오버라이드 편집 입구가 있으며 구체적인 경로는 사용 안내서의 해당 장을 참고하세요. 선언적 병합은 요구의 90%를 충족하면서도 잘못 작성하기 어려우므로 우선 사용하고, 스크립트 방식은 "이름으로 노드를 대량 필터링, 그룹을 동적으로 변경"처럼 복잡한 가공에 남겨두세요.
prepend-rules:
- DOMAIN-SUFFIX,internal.example.com,DIRECT
- PROCESS-NAME,ssh,DIRECT
append-rules:
- GEOIP,CN,DIRECT
장기적으로 권장하는 유지보수 구조는 3계층입니다: 구독은 노드를 담당하고(proxy-provider나 구독 링크로 도입), 규칙 모음은 rule-providers가 원격으로 관리하며, 개인적인 차이는 모두 오버라이드 계층에 씁니다. 어느 한 계층을 갱신해도 다른 두 계층에는 영향을 주지 않아, 설정이 "일회성 산출물"에서 "지속적으로 관리되는 프로젝트"로 바뀝니다. 여기까지 되면 이 페이지 앞 8장의 필드들이 각자 제자리를 찾게 됩니다.
설정을 고친 뒤 바로 리로드하지 마세요: 대부분의 클라이언트는 설정 검증 입구를 제공하고, mihomo 커널도 mihomo -t -f config.yaml 커맨드라인 문법 검사를 지원합니다. 검증을 통과한 뒤 핫 리로드를 하면 "한 줄 잘못 고쳐 온 집 인터넷이 끊기는" 상황을 피할 수 있습니다.
필드를 다 확인했다면 실제 작업으로 돌아가세요: 클라이언트 설치, 구독 가져오기, 분기 확인까지.