Clash 사용자 정의 규칙 설정법: DOMAIN-SUFFIX·IP-CIDR·GEOIP와 규칙 우선순위

Clash 규칙 유형별 문법과 용도를 정리하고, 위에서부터 첫 번째로 일치하는 규칙이 적용되는 방식과 rule-providers 및 MATCH의 배치 방법을 설명합니다.

규칙 형식: 유형, 매칭 대상, 출구 정책

Clash 사용자 정의 규칙은 YAML 설정의 rules: 목록에 작성합니다. 클라이언트가 규칙 모드로 실행되면 코어가 이 목록에 따라 연결에 사용할 출구를 결정합니다. 이 글은 Clash 공통 규칙 문법을 기준으로 설명하며, 규칙 세트 로딩은 mihomo에서 지원하는 설정을 기준으로 합니다. 그래픽 클라이언트는 규칙을 편집하는 인터페이스를 제공하고, 실제 규칙 실행은 현재 활성화된 코어가 담당합니다.

mode: rule
rules:
  - DOMAIN,example.com,DIRECT
  - DOMAIN-SUFFIX,example.org,프록시 선택
  - IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
  - MATCH,프록시 선택

기존 설정에 추가할 내용이며, 구독 설정 전체가 아닙니다. 예시의 프록시 선택은 기존 proxy-groups에 있는 정책 그룹 이름이어야 합니다. 설정에 이미 등록된 노드 이름으로 바꿔도 됩니다. 이름은 공백과 대소문자까지 정확히 일치해야 합니다. 존재하지 않는 정책을 지정하면 설정 로딩에 실패할 수 있습니다.

  • DOMAIN: 규칙 유형으로, 두 번째 필드를 어떤 방식으로 해석할지 정합니다.
  • example.com: 매칭 대상입니다. 여기서는 프로토콜, 경로, 포트가 없는 전체 도메인 이름을 지정합니다.
  • DIRECT: 내장 직접 연결 정책으로, 로컬 네트워크를 통해 대상에 직접 연결합니다.
  • REJECT: 내장 연결 차단 정책으로, 규칙에 일치하는 연결을 차단합니다.
  • no-resolve: 일부 IP 규칙에서 지원하는 추가 매개변수이며, 출구 이름이 아닙니다.

DOMAIN-SUFFIX: 도메인 접미사와 정확한 도메인 매칭의 차이

호스트 이름 하나만 지정할 때는 DOMAIN을, 도메인과 모든 하위 도메인을 지정할 때는 DOMAIN-SUFFIX를 사용합니다. 접미사 매칭은 도메인 레이블 경계를 기준으로 하며, 임의의 문자열을 검색하는 방식이 아닙니다.

규칙 예시매칭되는 항목매칭되지 않는 항목
DOMAIN,example.com,DIRECTexample.comwww.example.com
DOMAIN-SUFFIX,example.com,DIRECTexample.com、api.example.comnotexample.com
DOMAIN-KEYWORD,example,DIRECT도메인에 example이 포함된 호스트해당 문자열이 포함되지 않은 도메인

예외 규칙을 접미사 규칙보다 먼저 배치

example.com 전체는 직접 연결하고 api.example.com만 프록시로 보내려는 경우를 가정해 보겠습니다. 정확한 도메인 규칙을 먼저 쓰고, 그다음 더 넓은 범위를 다루는 접미사 규칙을 작성합니다.

rules:
  - DOMAIN,api.example.com,프록시 선택
  - DOMAIN-SUFFIX,example.com,DIRECT
  - MATCH,프록시 선택

앞의 두 줄 순서를 바꾸면 API 도메인이 접미사 규칙에 먼저 걸려 직접 연결됩니다. 코어는 뒤에 더 구체적인 규칙이 있더라도 다시 선택하지 않습니다. DOMAIN-KEYWORD는 범위가 더 넓어 관련 없는 도메인까지 함께 매칭하기 쉽습니다. 정확한 도메인이나 접미사로 표현할 수 있다면 범위가 분명한 규칙을 우선 사용하세요.

도메인 규칙은 웹페이지 경로를 매칭하지 않습니다

https://example.com/video를 DOMAIN에 넣지 마세요. 매칭 대상은 전체 URL이 아니라 호스트 이름입니다. 같은 도메인의 /video와 /docs는 위 도메인 규칙으로 구분할 수 없습니다. HTTPS에서는 코어가 이 규칙만으로 암호화된 웹페이지 경로를 읽을 수도 없습니다.

IP-CIDR와 GEOIP: 주소 범위, 데이터베이스, no-resolve

IP-CIDR은 대상 IPv4 대역에 적용하고, IP-CIDR6는 IPv6에 사용합니다. 슬래시 뒤 숫자는 포트가 아니라 프리픽스 길이를 나타냅니다. IPv4 주소 하나는 /32, IPv6 주소 하나는 /128로 지정할 수 있습니다.

rules:
  - IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
  - IP-CIDR,10.0.0.0/8,DIRECT,no-resolve
  - IP-CIDR,172.16.0.0/12,DIRECT,no-resolve
  - IP-CIDR6,fc00::/7,DIRECT,no-resolve
  - GEOIP,CN,DIRECT
  - MATCH,프록시 선택

앞의 세 규칙은 일반적인 IPv4 사설 주소 대역을 포함하고, 네 번째 규칙은 IPv6 고유 로컬 주소 대역을 포함합니다. 이는 코어 내부의 트래픽 분기 규칙이며, 모든 LAN 연결이 코어를 거친다는 뜻은 아닙니다. 시스템 프록시의 우회 목록이나 TUN 라우팅 제외 설정에 따라 해당 연결이 클라이언트를 우회할 수 있습니다.

GEOIP는 웹사이트의 국가를 판별하는 기능이 아닙니다

GEOIP,CN,DIRECT는 코어가 사용하는 IP 지리 데이터로 대상 주소를 매칭합니다. 도메인 접미사, 회사 등록 국가, 사용자 계정의 지역을 확인하는 기능은 아닙니다. CDN 주소 변경, DNS 응답 차이, 지리 데이터베이스 버전에 따라 매칭 결과가 달라질 수 있습니다. 특정 서비스를 항상 같은 방식으로 처리하려면 명확한 도메인 규칙을 GEOIP보다 앞에 배치하세요.

no-resolve는 현재 규칙에 의한 DNS 조회만 제한합니다

연결에 도메인 정보만 있고 사용할 수 있는 실제 대상 IP가 아직 없으면, IP 규칙의 판정을 위해 DNS 조회가 발생할 수 있습니다. no-resolve를 추가하면 해당 규칙이 매칭을 위해 도메인을 먼저 조회하지 않습니다. 연결에 사용할 수 있는 IP가 이미 있다면 주소 매칭은 계속 수행할 수 있습니다.

  • 사설 네트워크 대역 규칙에 no-resolve를 추가하면 사설 주소 여부를 확인하기 위한 불필요한 DNS 조회를 줄일 수 있습니다.
  • GEOIP에 이 매개변수를 추가하면 도메인만 있고 사용할 수 있는 IP가 없는 연결은 해당 규칙을 건너뛰고 다음 규칙으로 넘어갈 수 있습니다.
  • 앞선 규칙에서 이미 DNS 조회가 발생했다면 뒤에 있는 no-resolve가 조회 결과를 취소하지는 않습니다.

규칙 적용 순서: 위에서부터 검사하고 첫 매칭에서 종료

규칙 목록은 자동으로 ‘정확한 규칙 우선’ 정렬을 하지 않으며, 규칙 유형에 따라 DOMAIN을 GEOIP보다 앞에 배치하지도 않습니다. 일반적인 트래픽 분기에서는 첫 규칙부터 확인하고, 일치하지 않으면 다음 규칙으로 넘어갑니다. 규칙이 일치하면 해당 정책으로 연결을 보내고 더 적합한 규칙을 찾지 않습니다.

  1. 명확한 예외를 맨 앞에 둡니다. 예를 들어 특정 API는 프록시로 보내고, 특정 테스트 도메인은 차단해야 하는 경우입니다.
  2. 그다음 도메인 및 서비스 규칙 세트를 배치합니다. IP의 지역을 기준으로 처리하기 전에 확정된 서비스 정책을 먼저 적용합니다.
  3. 이어서 사설 네트워크 대역 및 지역 IP 규칙을 배치합니다. 두 규칙의 순서는 도메인 정책이 주소 정책보다 우선해도 되는지에 따라 달라집니다.
  4. MATCH는 맨 마지막에 둡니다. 앞선 규칙에 일치하지 않은 모든 연결에 명확한 출구를 지정합니다.

위 순서는 흔히 쓰이는 구성 방식일 뿐, 코어가 강제하는 규칙은 아닙니다. 모든 사설 네트워크 대상에 반드시 직접 연결해야 한다면, 해당 규칙을 덮어쓸 수 있는 서비스 규칙보다 앞에 배치하세요. 순서가 적절한지 판단하려면 먼저 어떤 정책이 업무상 우선인지 정해야 합니다.

rules:
  - DOMAIN,blocked.example.com,REJECT
  - DOMAIN,api.example.com,프록시 선택
  - DOMAIN-SUFFIX,example.com,DIRECT
  - IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
  - GEOIP,CN,DIRECT
  - MATCH,프록시 선택

이 목록에서는 blocked.example.com이 차단되고, api.example.com은 프록시 선택으로 전달되며, www.example.com은 직접 연결됩니다. API가 뒤에 있는 GEOIP 조건에 해당하는 주소로 해석되더라도 도메인 규칙이 이미 일치했으므로 해당 규칙은 더 이상 확인하지 않습니다.

MATCH 뒤의 일반 규칙은 실행되지 않습니다

MATCH,프록시 선택에는 매칭 대상 필드가 없으므로 이 줄까지 도달한 모든 연결에 적용됩니다. 목록 중간에 배치하면 뒤에 있는 일반 규칙은 효력이 없어집니다. MATCH,*,프록시 선택처럼 작성하지 마세요. 출구는 두 번째 필드에 지정합니다.

규칙에 일치한 뒤 연결이 실패하더라도 코어는 보통 이전으로 돌아가 다음 규칙을 시도하지 않습니다. 노드 장애 전환이 필요하면 rules에 같은 도메인을 여러 번 써서 각기 다른 출구로 보내지 말고, 정책 그룹에 적절한 선택 방식을 설정하세요.

rule-providers: 규칙 세트를 선언하고 RULE-SET으로 참조하기

rule-providers는 규칙 세트의 출처를 선언하고, RULE-SET은 해당 규칙 세트를 매칭 목록에 연결합니다. 선언만으로 트래픽 분기에 자동 적용되지는 않습니다. 아래는 mihomo의 로컬 파일 규칙 세트 예시이며, 규칙 파일은 클래식 규칙 형식으로 작성합니다.

rule-providers:
  office-services:
    type: file
    behavior: classical
    format: yaml
    path: ./rules/office-services.yaml

rules:
  - DOMAIN,api.example.com,프록시 선택
  - RULE-SET,office-services,DIRECT
  - GEOIP,CN,DIRECT
  - MATCH,프록시 선택

아래 내용을 코어 작업 디렉터리의 rules/office-services.yaml에 저장하세요. 상대 경로의 기준은 클라이언트가 코어를 실행할 때 사용하는 작업 디렉터리입니다. 다운로드 폴더가 기준이 아닐 수 있으며, 클라이언트에서 코어가 접근할 수 있는 위치에 파일을 두어야 합니다.

payload:
  - DOMAIN-SUFFIX,example.org
  - DOMAIN,intranet.example.com
  - IP-CIDR,10.20.0.0/16

여기서 payload 항목에는 DIRECT나 정책 그룹 이름을 쓰지 않습니다. 출구는 참조하는 RULE-SET,office-services,DIRECT에서 한 번에 지정합니다. 일반 설정의 rules와 규칙 세트 파일의 payload는 구조가 다르므로 서로 바꿔 쓸 수 없습니다.

behavior콘텐츠 형식사용 범위
classicalDOMAIN-SUFFIX,example.org와 같은 유형 포함 항목도메인 조건과 IP 조건을 함께 구성할 때 적합
domain도메인 매칭 전용 항목DOMAIN-SUFFIX, 접두사가 붙은 클래식 규칙을 붙여 넣지 마세요
ipcidr10.20.0.0/16과 같은 주소 대역도메인이나 출구 정책을 섞어 넣지 마세요

RULE-SET의 우선순위는 rules 목록에서의 위치로 정해집니다. MATCH 뒤에 두면 적용되지 않고, 정확한 예외보다 앞에 두면 예외 연결까지 먼저 매칭할 수 있습니다. 최상위 rule-providers가 rules 앞이나 뒤에 있는지는 매칭 우선순위에 영향을 주지 않습니다.

원격 HTTP 규칙 세트를 사용하는 경우 interval: 86400은 해당 provider의 업데이트 주기가 86400초, 즉 24시간이라는 뜻입니다. 구독 설정이나 프록시 노드 목록의 업데이트 주기와는 별개의 설정입니다. 이 글에서는 로컬 파일 예시를 사용하므로 HTTP 업데이트 매개변수는 설정하지 않습니다.

클라이언트에 적용하기: 덮어쓰기, 다시 불러오기, 연결 확인

구독 파일을 직접 수정하면 다음 구독 업데이트 때 원래 내용으로 되돌아갈 수 있습니다. 사용자 정의 규칙을 계속 유지하려면 클라이언트의 덮어쓰기, 설정 병합 또는 스크립트 기능을 우선 사용하고, 최종 생성된 rules의 순서를 확인하세요. 클라이언트마다 배열을 통째로 바꾸거나 앞뒤에 삽입하는 등 처리 방식이 다를 수 있으므로 편집창의 내용만으로 최종 결과를 판단하면 안 됩니다.

편집한 내용뿐 아니라 최종 적용된 설정을 확인하세요

  1. 현재 클라이언트와 코어 버전을 기록해 두세요. 클라이언트의 「설정」 또는 「정보」 페이지에서 mihomo와 다른 코어 중 무엇이 실행 중인지 확인하세요. 새 문법을 구형 코어에 바로 적용하는 일을 방지할 수 있습니다.
  2. 「설정」 페이지에서 현재 구독을 선택한 다음 해당 설정의 편집 또는 덮어쓰기 메뉴로 이동하세요. 메뉴 이름은 클라이언트 버전에 따라 다를 수 있습니다. 저장한 뒤 설정을 다시 불러오거나 적용해야 합니다.
  3. 최종 적용된 설정에 최상위 rules:가 하나만 있는지 확인하고, 새로 추가한 예외 규칙이 구독에서 생성된 MATCH보다 앞에 있는지도 확인하세요.
  4. 「규칙 / Rule」 모드로 전환한 다음 「연결 / Connections」에서 대상 연결의 세부 정보를 열어 매칭된 규칙, 규칙 내용, 정책 체인을 확인하세요.

새 연결을 만들어 규칙 적용 여부를 확인하세요

기존 TCP 연결은 보통 연결을 시작할 때 선택된 출구를 계속 사용합니다. 규칙을 수정한 뒤에는 관련된 기존 연결을 닫거나 앱을 종료한 후 요청을 다시 보내세요. 브라우저가 연결을 재사용하면 결과를 잘못 판단할 수 있습니다. 다음 명령은 최종 설정에서 실제로 mixed-port: 7890을 수신하고, 수신 주소에서 로컬 접근을 허용하는 경우에만 사용할 수 있습니다.

curl.exe -I --proxy http://127.0.0.1:7890 https://example.com/

Windows에서는 curl.exe를 사용하면 curl 프로그램을 명확히 실행할 수 있습니다. 여기서는 HTTP 프록시를 직접 지정하므로 브라우저가 시스템 프록시를 사용하는지에 영향을 받지 않습니다. 7890은 테스트용 포트일 뿐이며 모든 클라이언트의 기본 포트는 아닙니다. 명령을 실행한 뒤 연결 페이지에서 example.com을 찾아 매칭된 규칙과 정책 체인을 확인하세요. 페이지가 열리는지만으로 트래픽 분기가 올바른지 판단할 수 없습니다.

자주 발생하는 오류와 해결 방법

  • 설정 파싱 실패: 들여쓰기에 공백을 사용했는지, 목록 항목에 - 가 붙었는지, 쉼표를 전각 문자로 잘못 입력하지 않았는지 확인하세요. 같은 최상위 키를 중복해서 추가하지 마세요.
  • 정책을 찾을 수 없음: 규칙의 세 번째 필드가 실제 정책 그룹 이름과 정확히 일치하는지 확인하세요. 특히 구독 업데이트 후 정책 그룹 이름이 바뀌지 않았는지 살펴보세요.
  • 규칙 세트 로딩 실패: provider 이름, 파일 경로, behavior, 파일 내용을 확인하고 payload의 들여쓰기가 올바른지 살펴보세요.
  • 계속 MATCH에 일치함: 연결 세부 정보에 도메인 정보가 있는지, 대상이 다른 호스트 이름으로 바뀌었는지, 규칙이 최종 설정에 실제로 포함되었는지 확인하세요.
  • 연결 페이지에 기록이 없음: 먼저 앱이 프록시를 사용하거나 TUN에 의해 트래픽을 전달하는지 확인하세요. 코어에 들어오지 않은 트래픽은 규칙 순서를 바꿔도 해결되지 않습니다.

설정 필드를 확인하려면 프로토콜 레퍼런스를 참고하세요. 정책 그룹, 시스템 프록시, TUN의 차이가 헷갈린다면 먼저 용어 설명을 읽어 보세요. 규칙을 관리할 때는 예외를 명확히 하고, 출구가 유효한지 확인하며, MATCH를 항상 마지막 대체 규칙으로 두는 것이 중요합니다.

Clash 다운로드운영체제에 맞는 설치 파일 선택