Rule 모드의 심장, rules가 하는 일
Clash 계열 클라이언트에서 Rule 모드를 켜 두면, 앱·브라우저가 내보내는 각 연결은 config.yaml(또는 구독이 합쳐진 최종 프로필) 안의 rules: 목록을 위에서 아래로 훑으며 처음 맞는 한 줄의 정책으로 보내집니다. 그래서 같은 구독 URL을 쓰더라도 규칙만 잘 짜면 국내 쇼핑몰·은행·회사 VPN은 직접 연결(DIRECT)로 두고, 해외 SaaS만 선택한 프록시 그룹으로 넘길 수 있습니다. 이 글에서는 검색과 튜토리얼에서 가장 많이 등장하는 도메인 계열(DOMAIN·DOMAIN-SUFFIX·DOMAIN-KEYWORD), GEOIP, 그리고 목록을 외부 파일이나 원격 주소로 쪼개 두는 RULE-SET에 초점을 맞추되, 규칙 순서·DNS와 엮이는 주의점까지 한 번에 정리합니다.
Mihomo(구 Clash Meta)를 쓰는 GUI라도, 최종적으로는 같은 YAML 구조를 편집하는 경우가 많습니다. 구독 제공자가 넣어 둔 rules 맨 아래에 사용자 규칙을 덧붙이는 방식이면 코어 업데이트에 덜 흔들립니다.
전제: 규칙이 가리키는 오른쪽 끝 문자열은 proxy-groups에 정의된 정책 그룹 이름이거나 DIRECT, REJECT 같은 기본 키워드여야 합니다. 오타가 나면 코어가 기동 거부 로그를 남깁니다.
첫 일치 우선: 순서가 곧 설계다
Clash는 SQL이 아니라 라인 기반 방화벽 리스트에 가깝습니다. 한 연결에 대해 맞는 규칙을 찾으면 그 즉시 멈추고, 그 줄의 대상으로 트래픽을 붙입니다. 그래서 더 구체적인 예외는 항상 위에 두고, GEOIP처럼 넓게 덮는 규칙은 중간~하단에, 마지막에는 실패하지 않도록 MATCH를 두는 패턴이 반복됩니다.
실수하기 쉬운 배치는 이 두 가지입니다. 첫째, 넓은 DOMAIN-KEYWORD나 거대한 RULE-SET을 너무 위에 올려 둬서 의도한 DIRECT 예외가 영원히 도달하지 못하는 경우. 둘째, GEOIP,CN,DIRECT 아래에 다시 글로벌 프록시로 보내야 할 도메인 규칙을 둔 경우인데, 이미 IP가 중국으로 판정된 뒤라면 도메인 규칙과 순서가 꼬일 수 있으니 DNS 모드와 no-resolve 옵션을 함께 생각해야 합니다.
도메인 계열: DOMAIN, DOMAIN-SUFFIX, DOMAIN-KEYWORD
DOMAIN은 질의 이름과 완전 일치할 때만 적용됩니다. CDN이 여러 호스트 이름을 붙이는 서비스에서는 한 줄로 끝내기 어렵기 때문에, 보통은 더 유연한 DOMAIN-SUFFIX를 많이 씁니다.
DOMAIN-SUFFIX는 규칙에 적은 접미사로 끝나는 모든 호스트에 매칭됩니다. 예를 들어 DOMAIN-SUFFIX,example.com,Proxy는 www.example.com과 a.b.example.com 모두에 걸립니다. 실무에서는 .example.com처럼 앞에 점을 두는 관습이 있기도 하지만, 코어·템플릿에 따라 생략된 형태로 저장돼 있을 수 있으니 구독 원문을 그대로 따르는 것이 안전합니다.
DOMAIN-KEYWORD는 호스트 이름 어디에든 부분 문자열이 포함되면 매칭됩니다. 작성은 빠르지만 범위가 넓어져 오탐이 나기 쉬워, 가능하면 SUFFIX나 RULE-SET으로 바꾸는 편이 안정적입니다. 잠깐 디버깅할 때만 쓰고 장기 보관하지 않는 것도 한 방법입니다.
# Examples (policy name must exist in proxy-groups)
DOMAIN,cdn.example.org,DIRECT
DOMAIN-SUFFIX,stripe.com,Proxy
DOMAIN-KEYWORD,office,DIRECT
GEOIP: 국가 코드로 기본 경로 정하기
GEOIP 규칙은 대상 IP가 지리 정보 데이터베이스상 어느 국가에 속하는지 보고 분기합니다. 한국 사용자에게 흔한 패턴은 해외 트래픽만 프록시로 보내고 GEOIP,KR,DIRECT로 국내를 직접 붙이거나, 반대로 중국 내용 CDN을 DIRECT로 두려고 GEOIP,CN,DIRECT를 넣는 식입니다. 실제 코드는 대문자 두 글자 ISO 국가 코드를 따릅니다.
여기서 중요한 옵션이 no-resolve입니다. GEOIP,US,Proxy,no-resolve처럼 붙이면 도메인 이름이 아직 IP로 확정되지 않은 단계에서는 이 줄을 건너뜁니다. DNS와 IP 규칙이 뒤섞여 예상과 다른 노드로 새는 현상을 줄이려고, 구독 템플릿이 광범위하게 no-resolve를 붙여 두기도 합니다. 반대로 no-resolve 없이 GEOIP를 너무 앞에 두면, 이름 해석 타이밍에 따라 의도와 다른 줄이 먼저 소비될 수 있으니 로그로 한 번 검증하는 것이 좋습니다.
데이터베이스: GeoIP 바이너리나 데이터 경로는 배포판마다 다릅니다. GUI의 “설정 디렉터리”에서 geoip 관련 파일이 있는지, 최근 빌드가 자동 다운로드하는지 확인하세요.
RULE-SET: 큰 목록을 모듈로 나누기
수천 줄의 DOMAIN-SUFFIX를 매번 붙여 넣기엔 유지 보수가 괴롭습니다. 그래서 Clash는 외부 목록을 provider로 등록하고, 규칙 한 줄로 참조하는 RULE-SET 패턴을 제공합니다. 흐름은 (1) rule-providers: 절에 이름·타입·behavior·원격 URL 또는 로컬 path·갱신 interval을 선언하고, (2) rules:에 RULE-SET,이름,정책을 적는 두 단계입니다.
behavior는 목록이 도메인인지 IP 대역인지에 맞춰 domain, ipcidr, classical(혼합·레거시) 등으로 둡니다. 잘못 고르면 매칭이 조용히 실패하거나 성능만 나빠질 수 있으니, 규칙 세트 제작자의 문서를 따르는 것이 좋습니다. interval은 초 단위 주기로 원격 파일을 다시 받습니다. 사적이거나 자주 바꾸는 목록은 로컬 path로 두고 버전 관리하는 편이 낫습니다.
rule-providers:
my-domains:
type: http
behavior: domain
url: https://example.com/rules/domains.txt
path: ./ruleset/my-domains.yaml
interval: 86400
rules:
- RULE-SET,my-domains,Proxy
YAML은 배열 형태(- RULE-SET,...)로 쓰거나, 구독에서 흔한 것처럼 줄 단위 문자열로 이어 붙일 수 있습니다. 코어가 둘 다 받아들이면 되는 형태인지 활성 프로필 전체를 저장하기 전에 문법 검사를 한 번 돌리세요.
함께 쓰는 규칙: IP-CIDR, DST-PORT 등
도메인만으로 부족할 때는 IP-CIDR와 IP-CIDR6로 대역을 직접 지정합니다. 192.168.0.0/16,DIRECT처럼 사설망을 앞쪽에 두면 LAN 트래픽이 실수로 해외 노드로 나가는 일을 막을 수 있습니다. DST-PORT는 원격 포트 번호로 게임·메일·특정 프로토콜만 골라내고 싶을 때 유용합니다만, 과하면 읽기 어려워지므로 RULE-SET으로 포트 목록을 모듈화하는 경우가 많습니다.
고급 빌드에서는 프로세스 이름이나 소스 IP 같은 조건도 제공되기도 합니다. 지원 여부는 코어 버전·프로 파일 전처리기에 달려 있으니, GUI가 보여 주는 템플릿 주석을 확인하세요.
DNS·fake-ip와 규칙의 상호작용
Rule 모드에서 헷갈리는 증상 중 하나가 “브라우저에는 한 IP인데 Clash 로그에는 다른 IP가 찍힌다”는 패턴입니다. fake-ip 모드는 응답을 빠르게 돌려주는 대신, 일부 규칙이 실제 주소를 보기 전에 매칭이 끝나 버릴 수 있습니다. 그래서 GEOIP·IP 규칙을 촘촘히 쓸수록 dns 섹션의 설정(enhanced-mode, nameserver, fallback)을 함께 튜닝해야 합니다.
실무 팁으로는, 문제가 되는 호스트 몇 개를 골라 로그 레벨을 올리고 어떤 규칙에 걸렸는지 확인한 다음, 그 줄을 위로 옮기거나 no-resolve 유무를 바꿔 가며 검증하는 것이 가장 빠릅니다. 원인을 모른 채 RULE-SET만 무작정 추가하면 오히려 충돌이 늘어납니다.
유지 보수 패턴과 보안 습관
인터넷에 공개된 RULE-SET URL은 편하지만, 출처와 무결성을 반드시 확인해야 합니다. 프로젝트 이슈나 포럼에서 링크만 복사해 오면 악의적인 도메인을 DIRECT/REJECT로 바꾼 목록이 섞였을 수 있습니다. 가능하면 신뢰하는 프로젝트의 릴리스 자산이나 자신이 통제하는 저장소만 쓰세요.
규칙을 바꾼 뒤에는 GUI에서 프로필 다시 로드를 잊지 마세요. 일부 클라이언트는 파일 감시로 자동 재시작하지만, 안 되는 빌드도 있어 수동 적용이 필요합니다. Git으로 프로필을 관리한다면, rules 블록만 분기해 팀원과 공유하기도 좋습니다.
짧게 보는 FAQ
Q. MATCH를 빼도 되나요?
A. 이론상 나머지 전부를 다른 규칙이 흡수할 수 있으면 가능하지만, 실수 시 규칙 미스매치로 연결이 실패할 수 있습니다. 거의 모든 템플릿이 마지막에 MATCH,Proxy 비슷한 한 줄을 둡니다.
Q. 같은 사이트인데 모바일만 우회가 안 돼요.
A. 앱이 자체 DNS나 QUIC로 빠져나가면 도메인 규칙이 비껴갈 수 있습니다. TUN 모드·앱별 설정·해당 도메인을 RULE-SET에 추가하는지 동시에 봐야 합니다.
Q. REJECT와 BLOCK 차이는?
A. 배포판에 따라 별칭이 있을 수 있으나, 일반적으로 REJECT는 즉시 거절 또는 드롭에 가깝고, 추가 필터가 붙은 빌드는 광고 전용 키워드를 따로 둡니다. 코어 문서의 정의를 따르세요.
복잡해 보여도 Clash 규칙을 쓰는 이유
긴 VPN 하나로 전부 터널링하는 방식은 설정은 단순해 보여도, 국내 서비스까지 해외 회선으로 돌아가 지연·결제 검증 오류·캡차 폭증 같은 부작용이 생기기 쉽습니다. 반대로 브라우저 확장 프로그램만 쓰면 터미널·IDE·게임 런처는 그대로 드러나는 경우가 많고, 앱마다 다른 우회 모듈을 깔아야 하는 번거로움이 있습니다. Clash류는 한 번의 YAML 규칙 표로 OS 전체 또는 TUN 범위까지 통일할 수 있고, DOMAIN·GEOIP·RULE-SET을 조합하면 “업무 트래픽은 직결, 연구용 패키지 레지스트리만 프록시”처럼 정밀한 시나리오도 표현합니다.
또 다른 장점은 구독 업체가 바뀌어도 규칙 골격은 그대로 가져갈 수 있다는 점입니다. 노드 목록만 갈아 끼우고, 회사 VPN·스트리밍 예외·악성광고 차단 목록은 자신이 관리한 RULE-SET으로 고정해 두면 재현성이 좋아집니다. 아래 다운로드 페이지에서 사용 중인 OS에 맞는 클라이언트를 고른 뒤, 이 글의 순서대로 프로필에 한 블록씩 규칙을 얹어 보시면 “왜 이 사이트만 안 되지?” 같은 상황을 훨씬 빨리 해소할 수 있습니다.