Clash 개발 도구 라우팅 고급 설정: rule-providers와 YAML 실전 구성
git clone이 실패하거나 npm install과 Docker 이미지 다운로드가 자주 멈춘다면 노드보다 라우팅 규칙을 먼저 확인해야 합니다. 이 글에서는 개발 서비스별 규칙을 분리하고 유지보수 가능한 YAML과 rule-providers 구조로 운영하는 방법을 소개합니다.
개발 도구 트래픽을 별도 경로로 분리하는 이유
git clone이 중간에 멈추거나 npm install이 특정 패키지에서 오래 대기하고, Docker 이미지 다운로드가 반복해서 재시도된다면 먼저 노드의 속도부터 바꾸기보다 라우팅 결과를 확인해야 합니다. 개발 도구는 브라우저와 달리 하나의 프로그램이 여러 도메인과 포트에 동시에 접속합니다. Git 클라이언트는 저장소 주소뿐 아니라 인증, 서브모듈, 릴리스 파일을 각각 다른 호스트에서 요청할 수 있고, npm·PyPI·Go 모듈·Rust crate 같은 패키지 관리자는 인덱스와 실제 압축 파일을 별도로 조회합니다. Docker 역시 레지스트리 주소, 인증 엔드포인트, 이미지 레이어 저장소가 나뉘는 구조가 일반적입니다.
이때 전체 프록시 모드를 사용하면 문제는 줄어들 수 있지만, 사내 Git 서버나 로컬 레지스트리까지 외부 노드로 보내게 됩니다. 반대로 규칙이 너무 좁으면 첫 번째 메타데이터 요청만 프록시되고 실제 파일 다운로드는 DIRECT로 빠져 설치가 실패할 수 있습니다. 따라서 개발 환경에서는 “개발 서비스 도메인은 전용 프록시 그룹으로 보내고, 사설망과 로컬 주소는 직결하며, 나머지는 기존 기본 규칙을 따르게 하는” 구조가 관리하기 쉽습니다.
- 개발 서비스 그룹: Git, 패키지 저장소, 컨테이너 레지스트리처럼 안정적인 해외 연결이 필요한 요청을 전용 정책 그룹으로 전달합니다.
- 사설망 예외: 사내 Git, VPN 대역, 로컬 Docker 레지스트리는 프록시로 보내지 않고
DIRECT로 유지합니다. - 기본 출구: 목록에 없는 요청은 기존 프록시 그룹이나
MATCH정책으로 넘겨 규칙 추가가 전체 인터넷 사용에 영향을 주지 않게 합니다.
노드 변경 전에 매칭 결과를 먼저 확인하세요
같은 노드에서도 Git은 성공하고 Docker만 실패할 수 있습니다. 두 프로그램이 접속하는 도메인, DNS 해석 결과, TLS 연결 방식이 다르기 때문입니다. 클라이언트의 연결 로그에서 실제 목적지 호스트와 선택된策略 그룹을 먼저 확인하면 불필요한 노드 교체를 줄일 수 있습니다.
rule-providers의 구조와 YAML 필수 항목
rule-providers는 긴 규칙 목록을 기본 YAML의 rules 항목에서 분리하는 기능입니다. 기본 설정에 수백 줄의 DOMAIN-SUFFIX를 직접 넣는 대신, 별도 파일을 읽어 하나의 규칙 집합으로 관리할 수 있습니다. mihomo에서는 원격 HTTP 제공자, 로컬 파일 제공자, 인라인 제공자를 사용할 수 있으며, 여러 클라이언트에서 같은 목록을 재사용할 때 원격 제공자가 특히 편리합니다.
원격 제공자는 보통 type, behavior, format, url, path, interval을 사용합니다. behavior는 파일의 내용이 어떤 형식인지 알려주는 값으로, 도메인 목록이면 domain, IP 대역이면 ipcidr, 완전한 Clash 규칙 줄이면 classical을 선택합니다. 이 값을 잘못 지정하면 파일을 내려받았더라도 규칙이 매칭되지 않습니다.
rule-providers:
dev-git:
type: http
behavior: domain
format: yaml
url: "https://rules.example.dev/clash/dev-git.yaml"
path: ./providers/dev-git.yaml
interval: 86400
dev-packages:
type: http
behavior: domain
format: yaml
url: "https://rules.example.dev/clash/dev-packages.yaml"
path: ./providers/dev-packages.yaml
interval: 86400
dev-containers:
type: http
behavior: domain
format: yaml
url: "https://rules.example.dev/clash/dev-containers.yaml"
path: ./providers/dev-containers.yaml
interval: 86400
path는 클라이언트가 다운로드한 파일을 저장할 위치입니다. Windows에서는 상대 경로가 클라이언트의 작업 디렉터리를 기준으로 해석될 수 있으므로, 설정 파일과 제공자 디렉터리를 함께 관리하는 편이 안전합니다. portable 클라이언트라면 설정 파일 옆에 providers 폴더를 만들고, GUI 클라이언트라면 프로필 저장 위치에 해당 폴더를 생성하세요. interval: 86400은 24시간마다 갱신한다는 뜻이며, 자주 바뀌지 않는 개발 서비스 목록에 적합합니다.
format과 behavior를 혼동하지 않기
format: yaml은 파일 포맷을 의미하고, behavior: domain은 내부 항목의 의미를 지정합니다. YAML 파일 안에 payload 배열이 있어도 실제 항목이 완전한 규칙 줄이면 classical이 필요합니다. 제공자 파일의 첫 줄과 샘플 항목을 확인한 뒤 값을 정하세요.
서비스별 제공자 파일을 나누는 방법
하나의 거대한 개발 규칙 파일을 만드는 것보다 목적에 따라 Git, 패키지, 컨테이너, 사내망을 분리하는 편이 장애 원인을 찾기 쉽습니다. 예를 들어 Git 저장소와 패키지 다운로드가 서로 다른 프록시 그룹을 사용해야 한다면 제공자도 별도로 유지해야 합니다. 특정 서비스만 직접 연결로 되돌릴 때도 전체 목록을 수정하지 않고 해당 제공자만 교체할 수 있습니다.
도메인 목록 제공자
behavior: domain을 사용한다면 파일은 대상 도메인 목록을 담아야 합니다. 아래 도메인은 실제 서비스 주소를 그대로 복사한 값이 아니라 구조를 설명하기 위한 예시이므로, 사용하는 조직이나 서비스의 실제 호스트로 바꾸어야 합니다.
payload:
- "+.git.example.dev"
- "api.git.example.dev"
- "+.packages.example.dev"
- "+.registry.example.dev"
DOMAIN-SUFFIX에 해당하는 하위 도메인 전체를 포함하려면 +. 접두사를 사용하는 형식이 편리합니다. 정확히 한 호스트만 넣고 싶다면 api.git.example.dev처럼 작성합니다. 너무 짧은 키워드나 포괄적인 상위 도메인을 넣으면 사내 웹 서비스와 일반 웹 요청까지 같은 프록시로 묶일 수 있으므로, 실제 연결 로그에 나타난 호스트를 기준으로 항목을 추가하세요.
classical 규칙 제공자
포트나 IP 조건까지 한 파일에서 다루려면 classical 형식이 적합합니다. 이 형식에서는 한 줄마다 규칙 종류, 값, 정책 그룹을 적습니다.
payload:
- DOMAIN-SUFFIX,git.example.dev,DEV-PROXY
- DOMAIN-SUFFIX,packages.example.dev,DEV-PROXY
- DOMAIN-SUFFIX,registry.example.dev,DEV-PROXY
- DST-PORT,443,DEV-PROXY
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
다만 DST-PORT,443,DEV-PROXY처럼 넓은 포트 규칙은 모든 HTTPS 요청을 개발 프록시로 보내므로 일반적으로 권장되지 않습니다. 예시는 형식 설명용이며, 실제 구성에서는 대상 도메인을 우선 사용해야 합니다. IP 대역 규칙은 도메인 해석을 다시 유발하지 않도록 no-resolve를 붙이는 것이 안전합니다.
정책 그룹과 rules 연결 순서
rule-provider를 선언하는 것만으로는 트래픽이 이동하지 않습니다. 정책 그룹을 만든 뒤 RULE-SET 규칙으로 제공자를 연결해야 합니다. 전용 그룹에는 여러 노드를 직접 나열할 수도 있지만, 실제 운영에서는 select 그룹 안에 노드 또는 다른 자동 선택 그룹을 넣어 필요할 때 수동 전환할 수 있게 만드는 편이 좋습니다.
proxy-groups:
- name: DEV-PROXY
type: select
proxies:
- "AUTO-FAST"
- "DIRECT"
- name: AUTO-FAST
type: url-test
url: "https://www.example.com/generate_204"
interval: 300
tolerance: 80
proxies:
- "Node-A"
- "Node-B"
- "Node-C"
rules:
- RULE-SET,private-network,DIRECT
- RULE-SET,dev-git,DEV-PROXY
- RULE-SET,dev-packages,DEV-PROXY
- RULE-SET,dev-containers,DEV-PROXY
- MATCH,MAIN-PROXY
규칙은 위에서 아래로 검사하며 첫 번째로 일치한 항목에서 멈춥니다. 따라서 사설망 예외를 개발 제공자보다 위에 배치해야 사내 주소가 외부 노드로 빠지지 않습니다. 반대로 개발 제공자를 너무 아래에 두고 그 앞에 포괄적인 GEOIP나 MATCH를 두면 해당 제공자는 영원히 실행되지 않습니다.
- 먼저
RULE-SET,private-network,DIRECT처럼 로컬·사설망 예외를 배치합니다. - 그다음 정확한 Git, 패키지, 컨테이너 제공자를 서비스 목적에 맞는 정책 그룹으로 연결합니다.
- 국내 직결이나 기존 지역 규칙이 있다면 개발 서비스 규칙과 충돌하지 않는 위치인지 확인합니다.
- 마지막에는 반드시
MATCH를 두어 어떤 요청도 출구 없이 끝나지 않게 합니다.
사내 주소는 개발 규칙보다 먼저 예외 처리
사내 Git 호스트가 공인 도메인을 사용하더라도 실제로는 VPN 내부에서만 접근해야 할 수 있습니다. DOMAIN 또는 DOMAIN-SUFFIX로 해당 호스트를 DIRECT에 먼저 연결하고, 사내 DNS와 VPN이 정상적으로 동작하는지 별도로 확인하세요.
git, npm, Docker 실패를 확인하는 진단 순서
구성을 적용한 뒤에는 브라우저 접속보다 실제 개발 명령으로 확인해야 합니다. 브라우저가 열리는 것은 프록시가 살아 있다는 뜻일 뿐, CLI 프로그램이 같은 경로를 사용한다는 뜻은 아닙니다. TUN을 사용하지 않는 환경에서는 Git, Node.js, Docker가 시스템 프록시를 자동으로 따르지 않을 수 있으므로 CLI별 프록시 동작도 함께 확인해야 합니다.
- Clash 로그 레벨을
info또는 일시적으로debug로 변경하고 실패 명령을 다시 실행합니다. - 로그에서 실제 호스트명, 연결 포트, 매칭된 규칙, 선택된 정책 그룹을 확인합니다. 예상한
DEV-PROXY가 아니라DIRECT나 다른 그룹으로 표시되면 규칙 순서를 수정합니다. - 프로필 화면에서 rule-provider의 다운로드 시간과 파일 상태를 확인합니다. 제공자 URL이 404를 반환하거나 TLS 오류가 발생하면 로컬 캐시만 남을 수 있습니다.
- 명령줄에서 DNS 결과를 확인합니다. fake-ip 모드라면 대상 도메인에 대해
198.18.0.0/16대역이 반환될 수 있으며, 실제 공인 IP가 나오는 것만으로 유출을 단정해서는 안 됩니다. - 한 번에 모든 서비스를 테스트하지 말고 Git 조회, 패키지 메타데이터, 실제 파일 다운로드, 컨테이너 레이어 다운로드를 각각 실행해 어느 단계에서 실패하는지 분리합니다.
| 증상 | 우선 확인할 항목 | 가능한 조치 |
|---|---|---|
| git clone은 시작되지만 객체 수신 중 멈춤 | 실제 저장소 호스트와 대용량 파일 호스트가 같은 그룹인지 | 로그에 나타난 추가 도메인을 Git 제공자에 추가 |
| npm install이 인덱스는 읽지만 tarball에서 실패 | 패키지 메타데이터와 압축 파일의 호스트 분리 여부 | 패키지 CDN 또는 파일 호스트를 별도 항목으로 등록 |
| Docker login 성공 후 pull이 재시도됨 | 인증 서버와 레이어 저장소의 정책 그룹 | 레지스트리 관련 호스트를 하나의 제공자에 함께 포함 |
| rule-provider 갱신 후 규칙이 사라짐 | behavior, format, path와 파일 권한 | 파일 구조를 확인하고 클라이언트 권한 및 캐시 경로 수정 |
유지보수 가능한 YAML 운영 원칙
규칙 파일은 작동하는 순간보다 시간이 지난 뒤에도 이해할 수 있어야 합니다. 제공자 이름은 dev-git, dev-packages처럼 목적을 나타내고, 정책 그룹 이름도 DEV-PROXY처럼 역할을 분명히 하세요. 노드 이름을 제공자 이름에 직접 넣으면 노드를 교체할 때 규칙 파일까지 수정해야 합니다.
- 범위를 작게 유지하기—상위 도메인 하나로 모든 하위 서비스를 묶기 전에 실제 연결 로그를 확인합니다.
- 갱신 주기를 구분하기—자주 바뀌는 목록은 6시간 또는 12시간, 거의 변하지 않는 목록은 24시간 이상으로 설정합니다.
- 원격 목록에 전적으로 의존하지 않기—업데이트 실패 시 사용할 수 있도록 마지막으로 정상 동작한 로컬 캐시 파일을 보존합니다.
- 규칙 순서를 기록하기—사설망 예외, 개발 서비스, 지역 규칙, 최종 MATCH 순서를 주석이나 별도 문서로 남기면 다음 수정에서 충돌을 줄일 수 있습니다.
- 민감한 URL 보호하기—구독 주소와 인증 토큰이 포함된 rule-provider URL을 공개 저장소나 팀 채팅에 그대로 올리지 않습니다.
설정 변경은 한 번에 한 영역만 진행하는 것이 좋습니다. 먼저 제공자 파일에 호스트를 추가하고 갱신 상태를 확인한 다음, RULE-SET 연결을 적용하고, 마지막으로 정책 그룹의 노드 선택을 조정하세요. 문제가 생겼을 때 변경 지점이 하나로 좁혀지므로 복구도 빠릅니다. mihomo 기반 클라이언트라면 설정 검증 기능이나 프로필 구문 검사 기능으로 YAML 들여쓰기와 정책 그룹 이름을 먼저 확인한 뒤 적용하세요.
최종 점검 기준
개발 도구별 실제 호스트가 제공자에 포함되어 있고, 사설망 예외가 위에 있으며, behavior와 파일 형식이 일치하고, 마지막에 MATCH가 있다면 기본 구조는 완성된 것입니다. 이후에는 로그에서 매칭 결과를 확인하면서 필요한 도메인만 조금씩 추가하세요.
Clash 설정 적용하기
rule-providers와 개발 도구용 YAML을 준비했다면 사용 중인 클라이언트에서 프로필을 갱신하고, mihomo 커널 지원 여부와 TUN·시스템 프록시 설정을 확인하세요. 플랫폼별 설치와 프로필 적용 순서는 아래 안내에서 이어서 확인할 수 있습니다.
Clash 클라이언트 다운로드
규칙 분리를 적용하려면 먼저 클라이언트가 트래픽을 인계받아야 합니다. 다운로드 센터에서 사용 중인 플랫폼에 맞는 클라이언트를 선택한 뒤, 다시 가이드로 돌아와 시스템 프록시 또는 TUN 인계를 완료하세요.