먼저 구조부터: 진입점, DNS, 노드, 정책 그룹, 규칙
Clash 설정 파일을 열었다고 해서 첫 줄부터 끝까지 추측하며 읽을 필요는 없습니다. 먼저 최상위 항목을 확인하세요. mixed-port는 애플리케이션이 연결할 포트를 정하고, dns는 내장 도메인 이름 해석을 관리하며, proxies에는 노드가 저장됩니다. proxy-groups는 선택할 출구를 구성하고, rules는 각 연결을 어디서 처리할지 정합니다. 이 다섯 부분을 이해하면 ‘파일을 불러올 수 있음’과 ‘연결이 예상대로 전달됨’이 서로 다른 문제라는 점을 알 수 있습니다.
일반적인 참조 흐름은 규칙이 정책 그룹을 선택하고, 정책 그룹이 다시 노드를 선택하는 방식입니다. 규칙 대상이 DIRECT라면 원격 프록시 노드를 거치지 않고 목적지에 직접 연결합니다. 최상위 항목은 대체로 배치 순서가 실행 순서를 결정하지 않지만, rules 목록의 순서는 매칭 결과를 바로 바꿉니다.
| 설정 항목 | 역할 | 우선 확인할 사항 |
|---|---|---|
mixed-port | HTTP 및 SOCKS5 프록시 연결 수신 | 포트 사용 여부, 애플리케이션에 입력한 주소 |
dns | 내장 DNS와 향상된 모드 | 기능 활성화 여부, 요청이 코어에 전달되는지 |
proxies | 원격 노드 연결 정보 | 프로토콜, 주소, 포트, 인증 정보 |
proxy-groups | 출구 선택 및 테스트 | 이름 참조, 현재 선택 항목 |
rules | 조건에 따라 연결 분배 | 매칭 순서, 마지막 기본 정책 |
YAML 작성법: 들여쓰기를 먼저, 항목 의미는 그다음에 확인
YAML은 들여쓰기로 계층을 표현합니다. 공백 두 칸을 일관되게 사용하고 Tab은 피하세요. 같은 수준의 항목은 왼쪽을 맞추고, 목록 항목은 하이픈 뒤에 공백을 넣어 시작합니다. 파일 확장자는 .yaml 또는 .yml을 사용할 수 있지만, 확장자만 바꾼다고 문법 오류가 해결되지는 않습니다.
proxy-groups:
- name: "출구 선택"
type: select
proxies:
- DIRECT
이 설정에는 서로 다른 두 위치에서 쓰이는 개념이 있습니다. 최상위 proxy-groups는 정책 그룹 목록이고, 그룹 안의 proxies는 선택할 항목의 이름 목록이지 노드 전체 설정이 아닙니다. name, type, 그룹 내부의 proxies는 같은 객체에 속하므로 들여쓰기 수준도 같아야 합니다.
편집기에서 특히 확인할 네 가지
- 콜론 뒤 공백:
mode: rule처럼 작성하고 키와 값을 붙여 쓰지 마세요. - 불리언 값:
allow-lan: false처럼 불리언 값을 사용하세요.false를 따옴표로 감쌀 필요는 없습니다. - 특수 문자가 포함된 문자열: 노드 이름, 비밀번호,
#가 포함된 값은 주석 등의 문법으로 잘못 해석되지 않도록 따옴표로 감싸는 것이 좋습니다. - 중복 키: 파일 끝에 최상위
dns나rules를 두 번째로 추가하지 마세요. 파서에 따라 로드가 거부되거나 앞에 있는 값이 덮어써질 수 있습니다.
문법 오류 메시지에 표시된 줄이 실제 문제 위치와 다를 때도 있습니다. 예를 들어 목록 들여쓰기가 공백 두 칸 부족하면 다음 항목에서 오류가 발생한 것처럼 보일 수 있습니다. 오류가 난 줄부터 확인한 뒤, 위쪽의 가장 가까운 항목 묶음과 목록 구조를 살펴보세요.
최상위 설정: mixed-port, allow-lan, mode
mixed-port: 7890
allow-lan: false
mode: rule
log-level: info
ipv6: false
mixed-port: 7890은 하나의 수신 포트로 HTTP와 SOCKS5 프록시 연결을 모두 받을 수 있다는 뜻입니다. 로컬에서만 사용할 경우 애플리케이션에 주소 127.0.0.1과 포트 7890을 입력하면 됩니다. 포트 번호는 고정값이 아닙니다. 로그에 address already in use가 표시되면 다른 클라이언트나 프로그램이 포트를 사용 중인지 먼저 확인하세요.
allow-lan: false는 LAN 기기가 프록시 진입점을 통해 연결하지 못하도록 제한합니다. 네트워크 공유가 필요하다면 이 항목뿐 아니라 수신 주소, 시스템 방화벽, 현재 네트워크의 신뢰성도 확인해야 합니다. 로컬 연결 문제를 해결하려고 모든 인바운드 제한을 해제하지 마세요.
세 가지 모드와 rules의 관계
rule: 규칙 목록에 따라 연결 출구를 결정합니다. 분할 라우팅 설정을 확인할 때 적합합니다.global: 전역 정책으로 출구를 선택하며, 일반 규칙 목록을 하나씩 적용해 분배하지 않습니다.direct: 연결을 직접 전달합니다. 이 모드에서는 프록시 규칙을 수정해도 기대한 변화가 나타나지 않을 수 있습니다.
log-level: info는 연결과 오류를 확인할 때 적합합니다. 문제를 진단할 때는 잠시 debug로 바꾸고, 끝나면 로그가 지나치게 쌓이지 않도록 원래 수준으로 되돌리세요. ipv6: false는 이 시작용 설정에서 선택한 값일 뿐, 모든 네트워크에서 IPv6를 꺼야 한다는 뜻은 아닙니다. IPv6가 필요하다면 DNS 응답, 시스템 라우팅, 노드 지원 여부를 함께 확인하세요.
dns 항목: DNS 활성화와 향상된 모드 선택
dns는 중첩된 객체입니다. 먼저 내장 DNS를 사용할지 정한 다음 enhanced-mode를 설정하세요. 아래는 필드 간 관계를 쉽게 살펴보도록 일반 IP 주소를 업스트림으로 사용하는 예입니다. 모든 네트워크 환경에 권장되는 설정은 아닙니다.
dns:
enable: true
ipv6: false
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
nameserver:
- 223.5.5.5
- 119.29.29.29
nameserver는 업스트림 DNS 서버 목록입니다. 여기처럼 일반 IP 주소를 업스트림으로 지정하면 보통 기존 DNS 전송 방식을 사용합니다. DoH, DoT 또는 더 세밀한 분기 DNS가 필요하다면 코어 지원 여부와 업스트림 연결 가능성을 확인하세요. 최상위 ipv6와 dns.ipv6는 완전히 같은 스위치가 아닙니다. 후자는 주로 내장 DNS가 AAAA 조회를 처리하는 방식에 영향을 줍니다.
fake-ip는 처리 대상 도메인에 합성 주소를 반환합니다. 코어는 주소와 도메인의 대응 관계를 저장한 뒤, 연결에 해당하는 도메인을 기준으로 트래픽을 처리합니다. 198.18.0.1/16은 벤치마크 용도로 예약된 주소 대역입니다. 노드의 공인 IP 주소가 아니며 노드의 server 항목에 입력해서도 안 됩니다.
dns를 설정했는데도 시스템 DNS가 바뀌지 않는 이유
enable: true는 내장 DNS 기능을 활성화할 뿐, 시스템의 모든 DNS 요청이 내장 DNS로 전달된다는 뜻은 아닙니다. 프록시 프로토콜로 도메인을 전달하는 경우, 시스템이 직접 도메인을 해석하는 경우, TUN과 DNS 하이재킹으로 연결하는 경우는 서로 다른 경로입니다. 먼저 애플리케이션이 어떤 경로를 사용하는지 확인한 다음, 클라이언트에서 해당 DNS 처리 기능이 설정되어 있는지 살펴보세요.
LAN 이름, 게임 또는 기기 검색에 문제가 있다면 필요에 따라 fake-ip-filter를 설정해 특정 도메인이 합성 주소를 사용하지 않도록 할 수 있습니다. 출처를 알 수 없는 필터 목록을 그대로 복사하지 마세요. 필터 적용 후 실제 DNS 결과와 이후 라우팅도 확인해야 합니다.
proxies와 proxy-groups: 노드 설정과 출구 이름 구분하기
최상위 proxies에는 노드 객체를 저장합니다. 각 객체에는 참조에 사용할 name이 있어야 하며, 나머지 필수 항목은 프로토콜에 따라 달라집니다. 예를 들어 Shadowsocks 노드에는 일반적으로 type, server, port, cipher, password가 필요합니다. 다른 프로토콜은 UUID, TLS, 전송 계층 등의 설정이 추가될 수 있습니다. 한 프로토콜의 필드 목록을 다른 프로토콜에 그대로 적용하면 안 됩니다.
노드 정보는 실제 서비스 설정이나 신뢰할 수 있는 구독에서 가져와야 합니다. 이 글에서는 실제 서버나 인증 정보를 제공하지 않습니다. 뒤의 전체 예제에서 proxies: []는 노드 목록이 비어 있음을 나타냅니다. 이렇게 하면 연결할 수 없는 노드를 설정이 완성된 것처럼 오해하지 않고 YAML, 수신 포트, 규칙 참조를 먼저 확인할 수 있습니다.
proxies: []
proxy-groups:
- name: "출구 선택"
type: select
proxies:
- DIRECT
select는 수동 선택 그룹입니다. 그룹 이름인 ‘출구 선택’은 규칙에서 대상으로 참조할 수 있으며, 현재 그룹에는 내장 항목인 DIRECT만 있습니다. 실제 노드를 추가하려면 최상위 노드 목록에 전체 노드 객체를 먼저 입력하고, 해당 노드의 name을 그룹 목록에 그대로 추가해야 합니다. 공백, 대소문자, 기호까지 모두 일치해야 합니다. 노드 이름만 추가한다고 노드가 자동으로 만들어지는 것은 아닙니다.
자동 속도 테스트 그룹에는 무엇이 더 필요할까요?
url-test 등의 그룹 유형에는 속도 테스트 주소와 검사 간격 같은 설정도 필요합니다. 테스트 결과는 특정 요청의 상태만 보여 줄 뿐, 모든 사이트에 접속할 수 있다거나 실제 다운로드 속도가 그와 같다는 뜻은 아닙니다. 설정 구조를 처음 살펴볼 때는 select로 각 출구를 확인한 다음 자동 선택 기능을 추가하는 편이 좋습니다.
rules 항목: 위에서부터 매칭하고 MATCH는 마지막에 배치
규칙 모드에서는 코어가 목록 순서대로 조건을 확인하고, 처음 일치하는 항목의 대상을 사용합니다. 대상은 정책 그룹이나 노드 이름일 수도 있고, DIRECT, REJECT 같은 내장 정책일 수도 있습니다. 관리하기 쉽도록 모든 노드 이름을 규칙에 직접 나열하기보다 정책 그룹을 대상으로 지정하는 것이 일반적입니다.
rules:
- DOMAIN,example.com,DIRECT
- DOMAIN-SUFFIX,example.org,출구 선택
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- MATCH,출구 선택
DOMAIN은 도메인을 정확히 일치시킵니다. 여기서는example.com만 매칭되며 모든 하위 도메인은 포함되지 않습니다.DOMAIN-SUFFIX는 도메인 접미사를 기준으로 매칭합니다. 여기서는example.org와 그 하위 도메인까지 포함할 수 있습니다.IP-CIDR은 목적지 IPv4 주소 대역을 기준으로 매칭합니다.192.168.0.0/16은 흔히 쓰이는 사설 네트워크 대역 중 하나일 뿐, 모든 LAN 대역을 포함하지는 않습니다.no-resolve는 이 IP 규칙을 위해 도메인 조회를 새로 실행하지 않는다는 뜻입니다. 대상 IP를 이미 알고 있다면 그대로 매칭할 수 있습니다.MATCH는 앞선 규칙에 매칭되지 않은 연결을 처리하는 기본 항목이며, 보통 목록의 마지막에 둡니다.
예약된 예시 도메인으로 문법을 설명할 뿐, 실제 서비스별 트래픽 분배는 설정하지 않았습니다. MATCH,출구 선택을 첫 번째 줄로 옮기면 뒤의 규칙은 매칭될 기회가 없습니다. 파일에서 항목이 배치된 순서가 규칙 우선순위를 결정한다고 오해하기도 합니다. 실제로 중요한 것은 rules 내부의 항목 순서입니다.
GEOIP 또는 RULE-SET을 사용하면 관련 데이터베이스나 규칙 제공자도 필요합니다. 로그에 리소스 로드 실패가 표시되면 먼저 리소스 문제를 해결하세요. 규칙에 참조된 데이터가 아예 로드되지 않았는데 규칙 문구만 계속 바꾸지 마세요.
최소 동작 설정: 직접 연결부터 확인한 뒤 실제 노드 추가
아래는 로컬에서 직접 연결을 확인하기 위한 완성된 설정으로, 이 글에서 다룬 주요 계층을 포함합니다. 프록시 수신 포트를 열고 규칙과 정책 그룹을 통해 요청을 직접 연결하지만 원격 프록시 노드는 포함하지 않아 원격 프록시 서비스 테스트에는 사용할 수 없습니다. 앞서 본 Fake-IP 예제와 달리 여기서는 redir-host를 사용해 첫 테스트에서 합성 주소 매핑에 의존하지 않도록 했습니다.
mixed-port: 7890
allow-lan: false
mode: rule
log-level: info
ipv6: false
dns:
enable: true
ipv6: false
enhanced-mode: redir-host
nameserver:
- 223.5.5.5
- 119.29.29.29
proxies: []
proxy-groups:
- name: "출구 선택"
type: select
proxies:
- DIRECT
rules:
- DOMAIN,example.com,DIRECT
- IP-CIDR,127.0.0.0/8,DIRECT,no-resolve
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- MATCH,출구 선택
저장 및 확인 절차
- 현재 사용 중인 설정을 별도의 백업 파일로 저장한 뒤 위 내용을 UTF-8 인코딩의
config.yaml로 저장하세요. 편집기가 파일명 끝에.txt를 자동으로 붙이지 않았는지도 확인하세요. - mihomo 명령줄을 사용하는 경우
mihomo -t -f config.yaml을 실행해 설정을 검사할 수 있습니다. 그래픽 클라이언트에서는 자체 설정 검사 또는 가져오기 기능을 사용하세요. 메뉴 이름은 현재 버전에 따라 다를 수 있습니다. - 검사를 통과하면 설정을 불러오고 포트 충돌, 지원하지 않는 필드, 존재하지 않는 정책 등의 오류가 로그에 없는지 확인하세요. 그래픽 클라이언트는 원본 설정에 포트, DNS, TUN 등의 설정을 덧붙일 수 있으므로 실제 실행 설정도 살펴봐야 합니다.
- 시스템 프록시 활성화 여부에 의존하지 않도록 프록시를 명시해 요청을 한 번 보냅니다. 테스트 사이트 접속 가능 여부는 현재 네트워크의 직접 연결 상태에도 영향을 받습니다.
curl -I --proxy http://127.0.0.1:7890 https://example.com
Windows PowerShell에서 curl이 다른 명령으로 해석되면 curl.exe를 사용하세요. 테스트하는 동안 클라이언트의 연결 기록도 함께 확인합니다. 대상은 example.com, 매칭 규칙은 도메인 정확히 일치 항목, 출구는 DIRECT여야 합니다. HTTP 응답만 확인하고 연결 기록을 살펴보지 않으면 요청이 설정한 경로를 따랐는지 알 수 없습니다.
직접 연결을 확인한 뒤 실제 구독이나 서비스 설정에서 노드를 가져와 ‘출구 선택’에 노드 이름을 추가하고 클라이언트에서 직접 선택하세요. 한 번에 한 종류만 변경합니다. 노드, 정책 그룹, 분할 라우팅 규칙 순서로 추가하면 문제가 생겼을 때 가장 최근에 수정한 부분부터 확인할 수 있습니다.
설정 로드 실패와 규칙 미적용: 오류가 발생한 계층부터 확인
| 증상 | 우선 확인할 항목 | 해결 방법 |
|---|---|---|
| YAML 파싱 오류 | 들여쓰기, Tab, 콜론, 따옴표 | 오류가 난 줄과 바로 위 목록 구조 확인 |
| 정책 또는 노드를 찾을 수 없음 | 규칙 대상과 그룹 내 이름 | 해당 name과 철자까지 정확히 비교 |
| 7890 포트에서 수신할 수 없음 | 다른 클라이언트 또는 백그라운드 코어 | 중복 프로세스를 종료하거나 포트를 바꾸고 애플리케이션 설정도 함께 변경 |
| 규칙을 바꿔도 효과가 없음 | 현재 모드, 활성 설정, 덮어쓰기 설정 | rule 모드로 전환하고 실행 설정을 확인한 뒤 새 연결 생성 |
| 구독 업데이트 후 수정 사항이 사라짐 | 수정한 파일이 구독에서 생성된 파일인지 확인 | 클라이언트가 지원하는 덮어쓰기 또는 병합 기능 사용 |
규칙이나 출구를 변경해도 기존 연결은 연결 생성 당시의 경로를 계속 사용할 수 있습니다. 설정을 확인할 때는 새 요청을 보내고, 필요하면 대상 애플리케이션의 기존 연결을 종료한 다음 새로운 규칙 매칭 기록을 살펴보세요. 기존에 열린 연결 하나가 이전 출구를 계속 사용한다고 해서 설정이 로드되지 않았다고 판단하지 마세요.
구독을 관리할 때는 원본 내용과 실제 실행 결과를 구분해야 합니다. 클라이언트가 구독, 전역 설정, 덮어쓰기 규칙을 합쳐 최종 설정을 만들 수 있습니다. 구독 파일을 직접 수정하면 다음 업데이트 때 변경 내용이 사라질 수 있습니다. 포트나 라우팅 규칙을 계속 유지하려면 클라이언트 문서에서 지원하는 덮어쓰기 기능을 사용하고, 업데이트 후 최종 설정을 확인하세요.
아직 클라이언트가 없다면 클라이언트 다운로드 페이지에서 운영체제에 맞는 앱을 선택하세요. 설정 가져오기, 시스템 프록시 활성화, 첫 연결 방법은 설정 가이드에서 확인할 수 있습니다. 로그나 설정을 공유해 도움을 요청하기 전에 구독 링크, 비밀번호, UUID 등 접속 정보를 삭제하세요.