Clash 고급 설정 가이드
정책 그룹, 규칙셋, DNS, 네트워크 트래픽 처리까지. 주제별로 필드를 확인하고 연결 경로에 따라 결과를 검증하세요.
최초 설치, 구독 가져오기, 프록시 모드 선택은 먼저 빠른 시작 가이드를 완료하세요. 이 페이지는 이미 인터넷에 연결할 수 있는 사용자를 대상으로 설정 간 의존성, 자주 마주치는 제약과 복구 방법을 설명합니다. 가이드에서 첫 연결을 설정했다면, 이 문서에서는 설정이 작동하는 원리와 변경 후 적용 여부를 확인하는 방법을 살펴봅니다.
예제는 mihomo 필드를 기준으로 합니다. 별도 안내가 없는 한 코드는 독립적으로 사용할 수 있는 완성된 설정이 아니라 기존 파일의 해당 계층에 병합할 설정 조각입니다. GUI 클라이언트마다 메뉴 이름과 오버라이드 방식이 다를 수 있으므로 실제로 로드된 설정과 코어 로그를 기준으로 확인하세요.
클라이언트 선택은 먼저 다운로드 페이지에서 확인하세요. Windows, macOS, Android, iOS에서는 Clash Plus를 우선 비교하고, Linux에서는 Clash Verge Rev와 FlClash를 비교할 수 있습니다. 클라이언트 UI에서 설정할 수 있다고 해서 현재 코어가 모든 필드를 지원하는 것은 아닙니다.
정책 그룹 종류와 활용
정책 그룹은 규칙과 실제 아웃바운드 사이의 중간 계층입니다. 규칙마다 노드 이름을 직접 지정하는 대신 안정적인 그룹 이름을 참조하고, 그룹 안에서 수동 선택, 자동 선택 또는 장애 조치 방식을 정할 수 있습니다. 이렇게 하면 구독을 업데이트해 노드 이름이 바뀌더라도 그룹 이름과 프로바이더 참조만 유지하면 라우팅 규칙을 다시 작성할 필요가 없습니다. 설계에 앞서 세 가지 객체를 구분하세요. 노드는 원격 연결을 담당하고, 프로바이더는 노드를 모으며, 정책 그룹은 출구를 선택합니다. 이름은 자유롭게 정할 수 있지만 참조할 때는 공백과 대소문자까지 정확히 일치해야 합니다.
수동 선택과 자동 전환 중 먼저 정하기
select는 출구를 고정해야 하는 서비스에 적합합니다. 사용자가 프록시 페이지에서 그룹 구성원을 선택하면 코어는 선택된 대상으로 트래픽을 보냅니다. url-test는 테스트 주소에 주기적으로 요청을 보내 사용 가능한 구성원 중 응답이 빠른 출구를 선택합니다. tolerance는 작은 차이로 전환이 반복되는 현상을 줄이는 값이지 노드 품질 점수가 아닙니다. fallback은 구성원 순서대로 사용 가능한 출구를 찾아 주 경로와 백업 경로를 구성할 때 적합합니다. load-balance는 여러 연결에 출구를 분산합니다. 단일 연결의 대역폭을 합치거나 요청마다 같은 출구를 보장하지는 않습니다.
로그인, 결제 또는 세션 안정성이 필요한 서비스는 탐지 속도만 좇기보다 수동 선택 그룹을 사용하는 편이 좋습니다. 자동 그룹이 전환되어도 이미 연결된 세션은 보통 즉시 이동하지 않고, 새 연결부터 새 선택 결과를 사용합니다. 따라서 브라우저에서 같은 페이지의 리소스가 잠시 서로 다른 출구를 사용할 수 있습니다. 이런 상황을 확인할 때는 먼저 노드를 하나로 고정하고 기존 연결을 닫은 뒤 페이지를 다시 열어 보세요. 그다음 서비스 자체가 출구 변경을 제한하는지 확인합니다. 웹페이지 로딩 실패를 곧바로 규칙 문법 탓으로 돌리지는 마세요.
일상적인 선택과 자동 후보를 두 계층으로 분리하기
아래 예제는 proxy-providers에 primary라는 프로바이더가 이미 있다고 가정합니다. 자세한 가져오기 방법은 오버라이드 장을 참고하세요. 자동 그룹은 프로바이더의 구성원을 불러오고, 상위 수동 그룹에서는 자동 선택 결과와 직접 연결 중 하나를 고를 수 있습니다. 테스트 URL은 연결 상태를 확인하는 대상이지 구독 주소가 아닙니다. 접속 성공 여부는 출구, DNS, 대상 서비스의 정책에 따라 달라질 수 있습니다. interval의 단위는 초입니다. 너무 짧게 설정하면 특히 백그라운드 실행에 제약이 있는 모바일 기기에서 탐색 요청이 늘어납니다.
# 설정 예제: 기존 primary 노드 프로바이더 사용
proxy-groups:
- name: 자동 후보
type: url-test
use:
- primary
url: https://www.gstatic.com/generate_204
interval: 300
tolerance: 50
lazy: true
- name: 기본 출구
type: select
proxies:
- 자동 후보
- DIRECT
rules:
- MATCH,기본 출구
그룹을 서로 중첩해 참조할 수는 있지만 순환 구조를 만들어서는 안 됩니다. 예를 들어 기본 출구가 자동 후보를 포함하고 자동 후보가 다시 기본 출구를 참조하면 최종 출구를 결정할 수 없습니다. 확인할 때는 규칙의 대상부터 시작해 실제 노드 또는 DIRECT에 도달할 때까지 참조를 따라가세요. 클라이언트에 그룹이 비어 있다고 표시되면 먼저 프로바이더가 정상적으로 로드됐는지 확인하고, 필터 조건이 모든 노드를 제외했는지 살펴보세요. 구성원 누락을 감추려고 중첩 계층을 늘리지는 마세요. 일부 클라이언트는 이전 선택을 기억하지만 이름이 바뀌면 기본 구성원으로 돌아갈 수 있으므로 구독 업데이트 후 중요한 업무 그룹을 다시 확인하세요.
테스트 결과와 실제 접속을 따로 확인하기
프록시 페이지의 테스트 결과는 특정 출구가 지정된 테스트 대상에 접속했을 때의 상태만 보여 줍니다. 실제 앱은 다른 도메인, 포트 또는 UDP를 사용할 수 있으므로 모든 서비스가 정상이라고 판단할 수는 없습니다. 정책 그룹을 검증하려면 연결 페이지에서 일치한 규칙, 최종 아웃바운드, 대상 호스트를 함께 확인하세요. 자동 그룹은 정상인데 동영상이나 게임에 문제가 있다면 구성원을 고정한 뒤 프로토콜 지원과 서비스 지역 제한을 확인하세요. UI에서 조작하는 방법은 프록시 선택 가이드를 참고하세요. 출구를 장기간 고정해야 하는 그룹은 여러 단계의 자동 알고리즘보다 명확한 수동 선택 경로를 하나 유지하는 편이 관리하기 쉽습니다.
규칙셋 구독 관리
규칙을 rule-providers에 넣으면 규칙 내용과 라우팅 결정을 분리해 관리할 수 있습니다. 프로바이더는 도메인, 주소 또는 클래식 규칙 목록을 다운로드하거나 읽고, rules에서 RULE-SET으로 일치 후 사용할 출구를 지정합니다. 규칙셋 자체가 프록시와 직접 연결 중 하나를 결정하지는 않습니다. 같은 목록을 여러 설정에서 서로 다른 정책 그룹에 연결할 수 있습니다. 관리할 때는 파일 형식이 올바르게 파싱되는지, 업데이트가 안정적인지, 전체 규칙 목록에서 우선순위에 맞는 위치에 있는지 확인하세요. 구독 방식은 반복 편집을 줄여 주지만 규칙 충돌까지 자동으로 해결하지는 않습니다.
behavior와 format은 파일 내용에 맞아야 합니다
behavior: domain은 도메인 규칙 목록, ipcidr은 주소 대역 목록, classical은 규칙 유형이 포함된 클래식 규칙 목록을 뜻합니다. format은 파일 인코딩 형식을 나타내며, 일반적으로 YAML 또는 일반 텍스트를 사용합니다. YAML을 선택하면 보통 payload 계층이 필요합니다. 파일명이 .yaml로 끝난다고 해서 내용이 요구사항에 맞는 것은 아니며 노드와 정책 그룹이 포함된 전체 구독을 규칙 프로바이더에 넣어서도 안 됩니다. 로드 오류가 발생하면 확장자만 바꾸지 말고 실제 파일을 열어 첫 줄, 들여쓰기, 항목 내용을 확인하세요.
먼저 로컬 규칙셋으로 검증 가능한 최소 사례를 만들어 보세요. 아래 두 예제는 각각 기본 설정 파일과 별도의 규칙 파일에 들어갑니다. 경로는 코어 설정 디렉터리를 기준으로 해석되며, GUI 클라이언트에서 실제 디렉터리는 설정 관리 화면이나 실행 로그로 확인해야 합니다. 규칙셋에는 직접 연결할 문서 사이트 도메인만 적고, 전체 규칙에는 LAN 우회와 마지막 기본 규칙을 유지합니다. 예제에서 사용하는 기본 출구는 앞 장의 정책 그룹입니다. 해당 그룹이 없으면 먼저 추가해야 하며, 이 코드를 완성된 구독으로 단독 가져오면 안 됩니다.
# 기본 설정 조각
rule-providers:
local-domains:
type: file
behavior: domain
format: yaml
path: ./rules/local-domains.yaml
rules:
- IP-CIDR,127.0.0.0/8,DIRECT,no-resolve
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- RULE-SET,local-domains,DIRECT
- MATCH,기본 출구
# 별도 파일: rules/local-domains.yaml
payload:
- '+.example.com'
- '+.example.org'
원격 업데이트를 사용하더라도 복구 가능한 로컬 경로 유지하기
원격 프로바이더에는 type: http를 사용하고 url, path, interval을 설정합니다. 주소는 내용 형식을 확인할 수 있는 규칙 소스여야 합니다. 캐시 경로를 다른 프로바이더와 공유하면 다운로드 결과가 서로 덮어써질 수 있습니다. 최초 실행 시 규칙셋을 내려받는 데 프록시가 필요한데 프록시를 설정하는 데 아직 로드되지 않은 규칙이 필요하다면 시작 과정에 의존성 문제가 생길 수 있습니다. 초기 연결에 필요한 도메인에 명확한 접근 경로를 마련하고 기본 로컬 규칙을 보관하세요. 업데이트 실패 후 캐시를 계속 사용하는지는 로그와 파일 상태로 확인해야 하며 클라이언트의 업데이트 버튼 메시지만으로 판단하면 안 됩니다.
구독 주기는 규칙 품질을 보장하지 않습니다. 출처가 불분명하고 분류 기준도 모호한 목록을 자주 가져오면 로그인 API와 정적 리소스가 서로 다른 출구를 사용할 수 있습니다. 새 규칙셋을 추가하기 전에 어떤 서비스 범위를 처리하려는지 정하고 대표 도메인이 목록에 포함됐는지 확인하세요. 용량이 큰 클래식 규칙셋은 로딩 시간과 기기 리소스를 고려하세요. 라우터에서는 저장 공간과 쓰기 횟수도 확인해야 합니다. 원격 콘텐츠를 업데이트한 뒤에는 새 연결로 검증하세요. 계속 유지된 기존 연결로 새 규칙의 적용 여부를 판단하지 마세요.
규칙 순서가 충돌 시 결과를 결정합니다
규칙은 순서대로 검사하며 일치 항목이 있으면 보통 다음 규칙으로 넘어가지 않습니다. 구체적인 도메인 예외를 넓은 범위의 목록보다 앞에 두고, 기본 규칙인 MATCH는 마지막에 배치하세요. 주소 규칙에 no-resolve가 있으면 해당 규칙을 위해 도메인을 주소로 능동적으로 변환하지 않습니다. 현재 연결 정보가 도메인뿐이라면 이 주소 규칙에 일치하지 않을 수 있습니다. 도메인 규칙, 지리 데이터 규칙, 주소 규칙은 업무 목적에 따라 조합해야 하며 많을수록 완전해지는 것은 아닙니다. 중국 본토 사이트를 직접 연결하는 방법은 라우팅 규칙 실전 가이드를 참고하세요.
DNS 설정 최적화
DNS 설정은 해석 서버 주소만 입력하는 작업이 아닙니다. 한 번의 연결에는 프록시 노드의 도메인 해석, 서비스 도메인 해석, DNS 업스트림의 초기 해석이 포함될 수 있으며 각 요청의 출구가 같다고 보장할 수 없습니다. 먼저 앱이 조회를 어디에 전달하는지 확인하고, 코어가 업스트림에 어떻게 연결하는지 파악한 다음 반환된 주소가 이후 라우팅에 적합한지 살펴보세요. 브라우저의 보안 DNS, 시스템의 암호화 DNS, 앱 자체 DNS는 클라이언트의 DNS 진입점을 우회할 수 있습니다. nameserver만 변경해도 모든 앱의 조회가 코어를 거친다고 증명할 수는 없습니다.
초기 해석, 노드 해석, 서비스 도메인 해석 구분하기
default-nameserver는 주로 DNS 업스트림의 도메인 이름을 해석하는 데 사용하므로 직접 초기 연결이 가능한 주소 형식이어야 합니다. nameserver는 일반 서비스 조회를 위한 업스트림입니다. proxy-server-nameserver를 별도로 지정하면 프록시 노드 도메인을 독립적으로 해석해 노드 연결이 아직 성립하지 않은 프록시 경로에 의존하는 상황을 피할 수 있습니다. nameserver-policy는 지정한 도메인에 특정 해석기를 할당하므로 내부 도메인, 특정 네트워크 서비스 또는 명확한 해석 경계에 적합합니다. 각 필드는 서로 다른 단계를 처리하므로 같은 주소 목록을 모든 항목에 그대로 복사해서는 안 됩니다.
아래는 서비스 연결의 도메인 매핑 방식으로 Fake-IP를 사용하는 병합용 DNS 설정 조각입니다. 기재된 해석 주소는 예시이며 모든 네트워크에서 연결을 보장하지 않으므로 사용 전에 현재 네트워크에서 테스트하세요. 수신 주소를 루프백에 바인딩하면 로컬 요청만 허용됩니다. 라우터에서 LAN 기기에 서비스를 제공하려면 수신 인터페이스, 방화벽, 접근 범위를 별도로 설계해야 합니다. 데스크톱 예제의 수신 주소를 모든 인터페이스로 바꾸는 것만으로 배포가 완료되는 것은 아닙니다.
# 설정 조각: 프록시 및 규칙 정의 제외
dns:
enable: true
listen: 127.0.0.1:1053
ipv6: false
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
default-nameserver:
- 223.5.5.5
- 1.1.1.1
proxy-server-nameserver:
- 223.5.5.5
nameserver:
- https://dns.alidns.com/dns-query
- https://cloudflare-dns.com/dns-query
fake-ip-filter:
- '*.lan'
- '*.local'
서버를 늘리기보다 해석 목적에 맞게 조정하기
내부 도메인은 보통 로컬 게이트웨이나 조직에서 제공하는 해석기로 보내야 합니다. 공용 해석기가 해당 레코드를 알지 못할 수 있습니다. 실제 내부 도메인을 확인한 뒤 nameserver-policy로 내부 DNS에 전달하고 적절한 Fake-IP 예외도 설정하세요. 여기에는 서로 별개인 두 가지 결정이 있습니다. 매핑 주소를 반환할지, 실제 결과를 어느 업스트림에서 가져올지입니다. 도메인을 필터 목록에 추가하면 향상 모드의 처리 방식만 달라지며 올바른 내부 해석기로 자동 전달되지는 않습니다.
fallback과 fallback-filter는 여러 업스트림의 결과를 필터링하고 비교하는 기능으로 단순한 기본·보조 서버 순서와는 다릅니다. 명확한 필터링 목적이 없다면 여러 주소를 쌓기보다 설명하기 쉬운 소수의 업스트림을 관리하는 편이 문제를 해결하기 쉽습니다. respect-rules를 사용하면 DNS 업스트림 연결에도 라우팅 규칙을 적용할 수 있지만, 노드 도메인 해석 경로를 따로 고려하고 적절한 proxy-server-nameserver를 설정해야 합니다. 그렇지 않으면 “업스트림을 해석하려면 프록시에 연결해야 하고, 프록시에 연결하려면 먼저 해석해야 하는” 순환 의존성이 생길 수 있습니다.
해석 결과와 조회 출구를 각각 검증하기
로컬 수신 주소에서 nslookup example.com 127.0.0.1을 실행할 수 있지만, 이 명령은 기본 DNS 포트를 조회하므로 위 예제에서 사용한 1053 포트를 직접 테스트하지 못합니다. 포트를 지정할 수 있는 도구에서는 dig @127.0.0.1 -p 1053 example.com을 실행하세요. 매핑 주소를 받았다는 사실은 해당 조회가 Fake-IP 처리에 들어갔다는 뜻일 뿐, 모든 조회가 같은 경로를 거친다는 뜻은 아닙니다. 앱의 실제 동작을 판단하려면 브라우저의 DNS 설정, TUN의 DNS 하이재킹, 로그에 기록된 업스트림 연결도 확인해야 합니다.
DNS를 변경한 뒤에는 시스템, 브라우저, 코어의 여러 계층에 이전 캐시가 남아 있을 수 있습니다. 먼저 새 연결을 만들고 필요한 경우 캐시를 지우세요. 클라이언트를 다시 시작해도 브라우저 캐시까지 초기화되지 않을 수 있습니다. 웹사이트 도메인은 해석되지만 연결에 실패한다면 매핑이 여전히 유효한지, 대상 정책 그룹이 사용 가능한지, IPv6가 다른 경로를 만드는지 확인하세요. 검사 방법과 설정 조합은 DNS 누수 검사 및 설정 가이드를 참고하세요. 진단할 때는 특정 앱과 조회 경로를 설명하고 단일 검사 사이트 결과만으로 전체 상황을 판단하지 마세요.
TUN과 Fake-IP
시스템 프록시는 시스템 프록시 설정을 따르는 앱에 주로 영향을 줍니다. TUN은 가상 네트워크 인터페이스와 라우팅을 통해 IP 트래픽을 처리합니다. 트래픽을 처리하는 범위가 다르므로 시스템 프록시를 켰다고 모든 앱이 처리 대상이 되는 것은 아닙니다. Fake-IP는 DNS 도메인 매핑 방식이지 TUN의 다른 이름이 아닙니다. 매핑된 IP 패킷을 받은 코어가 원래 도메인을 복원해 도메인 라우팅 규칙을 적용할 수 있어 두 기능을 함께 사용하는 경우가 많습니다. 하지만 TUN은 다른 DNS 모드와 함께 사용할 수 있고 Fake-IP도 적절한 비TUN 환경에서 사용할 수 있습니다.
활성화 전에 권한과 현재 네트워크 환경 확인하기
데스크톱 클라이언트에서는 설정에서 서비스 모드나 관련 시스템 권한을 확인한 뒤 TUN을 켜세요. Windows에서는 보통 가상 네트워크 인터페이스와 라우팅을 관리할 서비스 권한이 필요하고, macOS에서는 시스템 승인이, Linux에서는 해당 네트워크 관리 권한이 필요합니다. 구체적인 조작 방법은 클라이언트 구현에 따라 다릅니다. Android와 iOS는 일반적으로 시스템 VPN 기능으로 트래픽을 처리하므로 같은 기기의 다른 VPN과 동시에 실행하지 못할 수 있습니다. 사내 네트워크, 보안 소프트웨어, 기존 터널도 라우팅에 영향을 줄 수 있으니 먼저 현재 상태를 기록하세요. 영향을 파악할 수 없는 상황에서 라우트를 무리하게 추가하지 마세요.
아래 코드는 네트워크 트래픽 처리 설정 조각입니다. auto-route는 코어가 필요한 경로를 만들도록 하고, auto-detect-interface는 출구 인터페이스를 찾도록 돕습니다. 여러 네트워크 인터페이스, 브리지 또는 기존 VPN을 사용하는 환경에서는 실제로 검증해야 합니다. dns-hijack는 일치하는 DNS 트래픽을 가로채는 기능이지 암호화된 DNS를 모두 자동으로 찾아내는 기능은 아닙니다. 앱이 HTTPS로 자체 해석기에 접속하면 여기에서 53 포트를 지정해도 일반 DNS 조회처럼 코어에 전달되지 않습니다.
# 설정 조각: 활성화된 dns 설정 필요
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
- tcp://any:53
dns:
enable: true
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
stack과 매핑 주소의 범위 이해하기
stack은 TUN 패킷이 어떤 프로토콜 스택 경로로 들어갈지 결정합니다. system, gvisor, mixed의 지원 여부와 동작은 코어와 플랫폼에 따라 달라지므로 옵션 이름만 보고 성능이 더 높다고 판단하면 안 됩니다. 클라이언트의 기본값을 우선 유지하고 재현 가능한 호환성 문제가 있을 때만 별도로 바꿔 비교하세요. 같은 앱, 출구, 네트워크로 테스트하면서 TCP, UDP, LAN 연결이 달라지는지 확인합니다. 스택, DNS, 규칙을 동시에 바꾸면 원인을 파악하기 어려워집니다.
Fake-IP는 매핑용 주소를 반환하므로 해당 주소를 웹사이트의 실제 서버 주소처럼 사용해 위치를 판단하면 안 됩니다. 이후 앱 연결이 매핑 정보를 보유한 코어를 다시 거치지 않으면 일반 네트워크에서는 이 주소를 실제 목적지로 사용할 수 없습니다. 클라이언트를 종료했거나 매핑 정보가 삭제됐거나 앱이 이전 캐시를 계속 사용하면 “설정을 바꾸자마자 인터넷이 끊기는” 문제가 생길 수 있습니다. 이때는 매핑 대역 전체를 직접 연결 규칙에 넣기보다 앱의 기존 연결을 종료하고 다시 해석한 다음 캐시 삭제가 필요한지 판단하세요.
LAN 예외와 장애 복구
프린터, 네트워크 저장 장치, 화면 미러링, LAN 기기 검색은 서로 다른 프로토콜을 사용하므로 도메인 필터만으로는 충분하지 않을 수 있습니다. 서비스가 내부 도메인과 고정 주소 중 무엇을 쓰는지 확인한 다음 대역 라우팅, DNS 해석, 멀티캐스트 검색을 점검하세요. 실제 주소가 필요한 도메인은 fake-ip-filter에 추가하고 확인된 내부 네트워크 대역은 직접 연결로 설정한 뒤 TUN 라우팅이 로컬 인터페이스 접근을 허용하는지 확인하세요. 업무 도메인 분류 전체를 예외 처리하지 마세요. 예외 범위가 너무 넓으면 도메인 규칙에 필요한 매칭 정보가 사라집니다.
활성화 후 인터넷이 완전히 끊기면 권한, 가상 네트워크 인터페이스, 기본 경로, DNS 업스트림, 노드 연결 순으로 확인하세요. 먼저 TUN을 끄고 시스템 프록시만 유지합니다. 시스템 프록시가 복구되면 문제는 트래픽 처리 계층에 있을 가능성이 높습니다. 둘 다 실패하면 구독, 정책 그룹, 기본 네트워크를 확인하세요. 오류 로그를 기록한 뒤 설정을 한 번에 하나씩 되돌리고, 필요하면 활성화 전에 저장해 둔 설정으로 복구하세요. 플랫폼별 전체 절차는 TUN 모드 설정 가이드를, 일반적인 문제는 문제 해결에서 확인하세요.
도메인 스니핑
도메인 스니핑은 연결에 도메인 정보가 없을 때 지원되는 프로토콜의 특징에서 호스트명을 찾아내는 기능입니다. HTTP 요청의 Host, TLS 핸드셰이크에서 확인할 수 있는 서버 이름, 일부 QUIC 핸드셰이크 정보가 대표적인 출처입니다. 암호 해독 기능이 아니며 코어가 HTTPS 콘텐츠 전체를 읽게 해 주거나 모든 연결의 도메인을 알아내는 기능도 아닙니다. 연결 대상이 IP 주소로 전달되거나 DNS 조회가 현재 코어를 거치지 않을 때 도메인 규칙이 적용되도록 보완하는 기능으로 이해하세요.
정말 도메인 정보가 없는지 먼저 확인하기
연결 페이지에 올바른 도메인이 표시되고 예상한 규칙이 적용됐다면 스니핑의 효과가 없을 수도 있습니다. 먼저 재현 가능한 사례를 찾아 주소만 표시되는지, 주소 규칙을 타는지, 기본 규칙으로 빠지는지 확인하세요. 활성화 전후에 같은 서비스의 새 연결을 비교해 올바른 호스트명이 다시 표시되는지 살펴봅니다. 모든 라우팅 문제를 스니핑으로 해결하려고 해서는 안 됩니다. 규칙 순서 오류, 비어 있는 정책 그룹, 접근할 수 없는 출구, DNS 업스트림 오류는 각각 해당 계층에서 처리해야 합니다.
아래 설정은 HTTP, TLS, QUIC 식별을 활성화합니다. 포트 배열에 문자열로 적힌 범위는 설정 문법이지 네트워크 스캔 작업이 아닙니다. parse-pure-ip를 사용하면 순수 IP 대상에서도 스니핑을 시도하고, force-dns-mapping은 DNS 매핑과 관련된 환경에서 스니핑 처리를 강화합니다. 적용 전에 현재 mihomo 코어가 해당 필드를 지원하는지 확인하세요. 시작 로그에 알 수 없는 설정이나 지원되지 않는 프로토콜이 표시되면 옵션을 더 추가하기 전에 클라이언트가 실제로 사용하는 코어를 확인해야 합니다.
# 설정 조각
sniffer:
enable: true
force-dns-mapping: true
parse-pure-ip: true
override-destination: false
sniff:
HTTP:
ports:
- 80
- 8080-8880
TLS:
ports:
- 443
- 8443
QUIC:
ports:
- 443
도메인 매칭과 대상 주소 변경은 별개의 기능
override-destination은 스니핑 결과로 원래 대상을 바꿀지 결정합니다. 처음 테스트할 때는 비활성화한 채 보완된 도메인이 규칙 매칭에 어떤 영향을 주는지 확인하세요. 스니핑된 도메인으로 대상을 다시 지정해야 하는 업무가 있을 때만 활성화를 검토합니다. 앱이 특정 주소에 연결하는 이유는 자체 로드밸런싱, 특수한 해석 방식, 고정 서버 요구사항일 수 있습니다. 무턱대고 대상을 바꾸면 앱이 원래 선택한 경로가 달라집니다. 스니핑된 이름이 맞더라도 재해석 후 호환된다는 보장은 없습니다.
하나의 IP 주소에서 여러 도메인을 제공할 수 있으므로 연결 로그의 주소만으로 서비스 이름을 판단할 수는 없습니다. 반대로 핸드셰이크에 포함된 이름은 사용자가 보는 웹사이트가 아니라 게이트웨이, 공유 진입점 또는 중간 서비스일 수 있습니다. 검증할 때는 원래 대상, 스니핑한 이름, 일치 규칙, 최종 출구를 함께 기록하세요. 이미 생성된 장기 연결에서는 스니핑 설정을 바꿔도 최초 핸드셰이크 정보를 다시 가져올 수 없습니다. 비교 가능한 결과를 얻으려면 연결을 끊고 새로 만들어야 합니다.
프로토콜 제한 및 호환성 확인
암호화된 클라이언트 헬로 같은 방식을 사용하는 연결은 원래 보이던 서버 이름이 숨겨질 수 있습니다. 비표준 프로토콜, 특수 핸드셰이크, 너무 일찍 실패한 연결에서도 충분한 정보를 얻지 못할 수 있습니다. QUIC은 UDP를 사용하므로 접속 성공 여부는 출구의 UDP 지원과 네트워크 경로에도 좌우됩니다. QUIC 접속 실패를 모두 스니핑 문제로 돌리면 안 됩니다. 테스트할 때 앱에서 TCP 경로로 잠시 전환해 도메인 인식이 달라지는지 비교할 수는 있지만, 이를 근거로 모든 앱에서 QUIC을 비활성화해야 한다고 단정하지 마세요.
활성화한 뒤 특정 서비스에만 문제가 생기면 먼저 대상 변경을 끄고 프로토콜과 포트 범위를 좁히세요. 특정 도메인이 원인이라고 확인되면 코어가 지원하는 skip-domain 설정으로 해당 도메인을 제외한 뒤 제외 방식이 예상대로 동작하는지 검증하세요. 키워드 하나만 보고 범위가 지나치게 넓은 와일드카드를 추가하면 안 됩니다. 새로 인식된 도메인이 더 앞에 있는 규칙에 일치해 문제가 생긴 것은 아닌지도 확인하세요. 스니핑 후 라우팅 결과가 달라졌다면 기존 IP 규칙 대신 도메인 규칙이 적용된 것일 수 있습니다. 스니핑이 실패했다고 단정하기보다 규칙 설계를 조정하세요.
도메인, 주소, 규칙 사이의 용어 차이를 확인하려면 개념 빠른 참조를 참고하세요. 일상적인 관리에서 스니핑은 목적이 명확할 때 보완 기능으로 사용해야 하며, 인터넷 문제가 생길 때마다 우선 켜는 만능 스위치가 아닙니다. 더 많은 식별 옵션을 활성화하는 것보다 연결 하나가 규칙에 일치한 이유를 설명할 수 있는 것이 중요합니다.
로컬 오버라이드와 여러 구독 병합
원격 구독은 노드나 전체 설정을 전달하고, 로컬 오버라이드는 기기별 포트, DNS, 규칙 예외, 정책 구성을 유지합니다. 다운로드한 구독 파일을 직접 수정하면 다음 업데이트에서 변경 내용이 사라지는 경우가 많습니다. 먼저 클라이언트가 YAML 병합, 설정 확장, 스크립트 처리, 별도 로컬 설정 중 어떤 오버라이드 방식을 지원하는지 확인하세요. 병합 순서는 방식마다 다를 수 있고, 이름이 같은 필드도 항상 깊은 병합을 하는 것은 아닙니다. 한 클라이언트의 조작 방법을 다른 클라이언트에 그대로 적용하지 마세요.
최종적으로 로드된 파일부터 확인하기
설정 페이지에서 현재 구독을 선택한 다음 확장 또는 오버라이드 메뉴로 이동하세요. 메뉴 이름은 실제 클라이언트 UI를 기준으로 확인해야 합니다. 저장 후 다시 로드하고 실행 설정, 설정 미리보기 또는 코어 로그에서 최종 결과를 확인하세요. 원본 파일에 mixed-port: 7890이 있어도 클라이언트 전역 설정이 다시 덮어썼다면 실제 실행 포트는 7890이 아닐 수 있습니다. 원격 원본, 로컬 오버라이드, 최종 설정을 각각 따로 보관하세요. 편집기 내용만 보고 설정이 적용됐다고 판단하면 안 됩니다. 클라이언트에 코어 설정 검사 기능이 있으면 먼저 검사를 통과한 뒤 다시 로드하세요.
여러 구독을 사용할 때는 전체 YAML 두 개를 직접 이어 붙이기보다 노드 소스를 여러 proxy-providers로 구성한 뒤 정책 그룹에서 참조하는 편이 좋습니다. 전체 구독에는 dns, rules, 같은 이름의 정책 그룹이 함께 들어 있을 수 있어 텍스트를 단순히 합치면 최상위 키가 중복되거나 참조가 충돌합니다. 아래는 로컬 노드 프로바이더 예제입니다. 두 파일 각각에는 유효한 proxies 배열이 있어야 하며 규칙과 설정이 모두 포함된 전체 설정을 넣으면 안 됩니다. 파일은 코어가 실제로 접근할 수 있는 설정 디렉터리에 두세요.
# 기본 설정 조각: 로컬 노드 파일 두 개 사용
proxy-providers:
primary:
type: file
path: ./providers/primary.yaml
backup:
type: file
path: ./providers/backup.yaml
proxy-groups:
- name: 여러 구독 출구
type: select
use:
- primary
- backup
proxies:
- DIRECT
rules:
- MATCH,여러 구독 출구
배열 병합은 결과를 가장 쉽게 바꿉니다
스칼라 필드에는 일반적으로 최종값 하나만 있지만 규칙, 노드, 정책 그룹은 배열입니다. 오버라이드 도구는 배열 전체를 교체하거나 끝에 추가할 수 있으며 두 동작은 rules에 완전히 다른 결과를 만듭니다. 로컬 예외가 기존 MATCH 뒤에 추가되면 예상대로 일치하지 않습니다. 저장한 뒤 최종 규칙 목록을 펼쳐 예외가 기본 규칙 앞에 있는지 확인하세요. 정책 그룹 배열도 기존 참조가 유지되는지 점검해야 합니다. 새 그룹이 나타났는지만 확인하고 기존 그룹이 통째로 교체된 것을 놓치면 안 됩니다.
서로 다른 소스의 노드 이름이 중복될 수 있습니다. 이름이 같아도 같은 서버라는 뜻은 아니며, 선택 기록과 규칙 참조가 모호해질 수 있습니다. 클라이언트에서 이름 변경이나 프로바이더 이름 관리를 지원한다면 변환 규칙을 일관되게 유지하고 어느 단계에 적용되는지 기록하세요. 임시 상태에 따라 이름에 접두사를 자주 붙이면 업데이트 후 수동 선택이 작동하지 않을 수 있습니다. 필터 표현식도 먼저 일부 노드에 적용해 테스트하세요. 모든 노드가 일치하거나 전부 제외되면 그룹이 설계와 다르게 동작할 수 있습니다.
구독 형식과 원격 프로바이더의 범위
HTTP 원격 프로바이더는 코어가 파싱할 수 있는 노드 목록을 반환해야 합니다. 일반 Base64 링크 목록, 단일 프로토콜 링크, 전체 Clash YAML은 서로 다른 입력 형식이므로 URL만 proxy-providers에 넣는다고 자동 변환되지 않습니다. 형식 확인과 변환 절차는 구독 형식 비교 가이드를 참고하세요. 구독 링크에 접근 인증 정보가 들어 있을 수 있으므로 로그, 스크린샷, 설정을 공유하기 전에 해당 내용을 삭제하세요. 처리 방식을 확인할 수 없는 온라인 변환 서비스에 실제 링크를 입력하지 마세요.
관리할 때는 정상 작동이 확인된 최종 설정과 해당 오버라이드 원본을 보관하세요. 업데이트할 때마다 프로바이더 구성원 수와 주요 그룹의 구성원 유무를 먼저 확인한 다음 중요 규칙과 DNS 필드를 점검합니다. 실패하면 최근 추가한 오버라이드를 먼저 비활성화해 원래 구독을 복구하세요. 모든 소스를 한꺼번에 삭제하지 마세요. 특히 스크립트 오버라이드에서는 예외 처리에 유의해야 합니다. 입력 구조가 바뀌면 스크립트가 명시적으로 오류를 내거나 원래 결과를 유지해야 하며, 노드가 누락된 설정을 조용히 반환하면 안 됩니다. 포트와 규칙 예외 몇 가지만 필요한 사용자는 복잡한 스크립트보다 단순한 YAML 오버라이드를 확인하기 쉽습니다.
외부 대시보드
외부 컨트롤 인터페이스로 실행 상태를 확인하고 정책 그룹을 전환하며 연결과 설정을 관리할 수 있습니다. 컨트롤 패널은 이 인터페이스에 접속하는 웹 프런트엔드입니다. 앱이 사용하는 프록시 포트와는 별개의 서비스이므로 브라우저에서 패널에 접속된다고 브라우저 트래픽이 프록시를 사용한다는 뜻은 아닙니다. 프록시 포트에 연결할 수 있어도 컨트롤 인터페이스가 정상이라는 뜻은 아닙니다. 설정 전에 패널이 로컬 기기, LAN 기기, 서버 중 어디에서 실행되는지 정하고 인터페이스가 수신할 주소를 결정하세요. 일반적인 데스크톱 사용에서는 로컬 루프백에 바인딩하는 편이 접근 범위를 관리하기 쉽습니다.
인터페이스 주소와 정적 파일 디렉터리 구분하기
external-controller는 컨트롤 인터페이스의 수신 주소를 지정하고 external-ui는 대시보드의 정적 파일 디렉터리를 가리킵니다. 디렉터리에는 실제 진입 파일과 관련 리소스가 있어야 하며 빈 폴더만 만든다고 사용할 수 있는 대시보드가 생기지는 않습니다. 출처를 확인한 정적 대시보드 파일을 코어 작업 디렉터리에 넣고 상대 경로를 설정할 수 있습니다. 클라이언트에 대시보드가 이미 내장되어 있다면 위치가 다른 프런트엔드 파일 두 세트를 따로 관리하기보다 제공되는 관리 메뉴를 우선 사용하세요. 상대 경로는 실제 실행 디렉터리를 기준으로 해석됩니다.
# 설정 조각: ui 디렉터리에 대시보드 정적 파일이 있어야 함
external-controller: 127.0.0.1:9090
external-ui: ./ui
secret: "your-controller-secret"
예시 키는 필드를 설명하기 위한 값일 뿐입니다. 실제로 사용할 때는 충분히 길고 고유하며 공개되지 않은 값을 직접 설정하세요. 공개 게시물, 스크린샷, 저장소에 키를 올리지 말고 대시보드 공유를 위해 페이지 링크에 키를 삽입하지도 마세요. 컨트롤 인터페이스는 실행 상태를 변경할 수 있으므로 읽기 전용 정보 페이지처럼 배포해서는 안 됩니다. 클라이언트가 secret을 자동 관리한다면 해당 인증 방식을 사용해 연결하세요. 클라이언트가 생성한 값을 덮어쓰면 내장 UI가 연결되지 않을 수 있습니다.
로컬에서 검증한 뒤 LAN 연결 고려하기
먼저 같은 기기에서 포트가 수신 중인지 확인하고 설정된 정적 대시보드 경로에 접속한 뒤 인터페이스 주소와 키를 입력하세요. 페이지는 열리지만 연결에 실패한다면 정적 리소스와 API의 경로가 서로 다르다는 뜻이므로 주소, 인증, 브라우저 오류를 확인해야 합니다. 아래 명령은 인증을 포함해 로컬에서 조회하는 방법을 보여 줍니다. 예시 키는 로컬 설정의 값과 일치해야 합니다. 테스트가 끝난 뒤 실제 키가 포함된 명령을 외부에 공유하지 마세요.
curl --header "Authorization: Bearer your-controller-secret" \
http://127.0.0.1:9090/configs
대시보드를 다른 기기에서 열면 127.0.0.1은 코어 실행 호스트가 아니라 브라우저가 실행되는 기기를 가리킵니다. 코어 호스트에서 실제로 접근 가능한 주소를 입력하고 수신 주소와 방화벽 범위를 명확히 설정하세요. allow-lan은 프록시 서비스의 LAN 접근을 제어하며 컨트롤 인터페이스 공개 여부를 결정하는 전체 스위치가 아닙니다. 컨트롤 인터페이스의 수신 주소는 별도로 점검해야 합니다. 프록시는 로컬 전용으로 설정했더라도 인터페이스를 잘못 바인딩하면 관리 기능이 노출될 수 있습니다.
브라우저 보안 제한과 원격 배포
HTTPS 대시보드에서 HTTP 인터페이스에 접속하면 혼합 콘텐츠 제한이 적용될 수 있습니다. 서로 다른 출처의 페이지에서는 교차 출처 제한도 발생할 수 있습니다. 브라우저 보호 기능을 끄고 오류를 우회하기보다 실제 배포 환경에 맞춰 동일 출처 접근이나 안전한 리버스 프록시를 사용하세요. 컨트롤 인터페이스의 교차 출처 설정을 조정해야 한다면 확인된 대시보드 출처만 허용하고 모든 출처를 기본값처럼 공개하지 마세요. 페이지에 연결 실패가 표시되면 브라우저 개발자 도구에서 네트워크 연결 실패, 인증 오류, 보안 정책 차단을 구분할 수 있습니다.
컨트롤 인터페이스를 인터넷에 직접 공개하는 것은 권장하지 않습니다. 원격 관리가 꼭 필요하다면 접근 제어가 있는 사설 네트워크나 인증된 보안 진입점을 사용하고 출처 제한, 암호화 전송, 복구 경로를 준비하세요. 키 인증만으로 네트워크 경계를 대체할 수는 없습니다. 원격에서 규칙이나 정책 그룹을 수정하기 전에 변경으로 인해 현재 관리 연결이 끊기지 않는지 확인하세요. 특히 서버에서는 설정을 다시 불러온 뒤에도 접근할 수 있도록 로컬이나 다른 유지 관리 경로를 남겨 두어야 합니다.
외부 대시보드는 규칙과 연결을 자세히 살펴봐야 하는 사용자에게 적합하며 기본 연결을 완료하는 데 필수는 아닙니다. 구독을 가져오고 출구를 선택하는 정도라면 클라이언트 내장 UI를 먼저 사용하세요. 각 영역의 역할은 클라이언트 UI 영역별 안내를 참고하세요. 문제를 해결할 때는 코어 자체가 정상적으로 실행되는지 확인한 다음 대시보드 리소스, 인터페이스 접근, 브라우저 제한을 점검하세요. 프런트엔드 연결 오류를 노드 문제로 잘못 판단하지 않도록 주의해야 합니다.
포트 설정과 구성 검증
포트는 앱이 코어 서비스에 연결하는 진입점이지 원격 프록시 노드의 서버 포트가 아닙니다. mixed-port는 HTTP와 SOCKS 프록시 연결을 모두 받으며 port와 socks-port는 각각 해당 서비스를 제공합니다. 컨트롤 인터페이스, DNS 수신 주소, 프록시 진입점은 용도가 다르므로 모두 로컬 주소를 사용한다고 서로 바꿔 쓸 수는 없습니다. 흔한 실수로 9090을 브라우저 프록시 설정에 입력하거나 7890을 DNS 포트로 사용하는 경우가 있습니다. 숫자를 바꿔 가며 시험하기보다 먼저 프로토콜을 확인하고 주소와 포트를 맞추세요.
필드와 서비스의 대응 관계 확인하기
| 설정 필드 | 주요 용도 | 검증 항목 |
|---|---|---|
mixed-port | HTTP·SOCKS 프록시 진입점 | 앱 프로토콜, 수신 주소, 포트 사용 여부 |
external-controller | 코어 컨트롤 API | 인증, 접근 범위, 브라우저 제한 |
dns.listen | DNS 조회 진입점 | UDP 또는 TCP, 실제 조회 포트 |
allow-lan | 프록시의 LAN 접근 설정 | 바인딩 주소, 방화벽, 접근 권한 |
로컬에서 사용할 때는 먼저 allow-lan: false를 유지하고 앱이 루프백 주소로 연결되도록 하세요. LAN 기기에 프록시를 제공해야 한다면 수신 주소, 기기 접근 권한, 방화벽 규칙을 명확히 설정합니다. 프록시 공유와 컨트롤 인터페이스 공유는 별도로 설계해야 합니다. 라우터와 데스크톱 운영체제는 로컬 방화벽 동작도 다릅니다. 설정 버튼이 켜졌는지만 확인하지 말고 실제 프록시를 사용할 기기에서 연결을 시도해 기기 간 접근 경로를 검증하세요.
# 설정 조각: 로컬 프록시 진입점
mixed-port: 7890
allow-lan: false
bind-address: 127.0.0.1
mode: rule
log-level: info
한 번에 하나씩 변경하고 검증하기
변경 전에 정상 작동하는 설정을 저장하고 현재 네트워크, 정책 그룹 선택, 클라이언트 실행 모드를 기록하세요. 클라이언트에서 최종 실행 설정을 내보낼 수 있다면 함께 저장해야 합니다. 구독 원본에 클라이언트가 추가한 설정이 포함되지 않을 수 있습니다. 변경 후 문법과 참조를 먼저 검사하고 다시 로드하세요. 기본 코어에서는 해당 작업 디렉터리에서 mihomo -t -f config.yaml을 실행해 설정을 검사할 수 있습니다. 이 명령은 인터넷 연결 테스트를 대신하지 않으며 원격 규칙 소스, 노드, DNS 업스트림의 연결을 보장하지도 않습니다.
설정이 로드됐는지 확인한 다음 실제로 포트가 수신 중인지 살펴보세요. Windows에서는 Get-NetTCPConnection -LocalPort 7890으로 로컬 TCP 수신 상태를 확인할 수 있습니다. Linux에서는 ss -lntp, macOS에서는 lsof -nP -iTCP:7890 -sTCP:LISTEN을 사용하세요. 일부 명령은 적절한 권한이나 시스템 도구가 필요합니다. 다른 클라이언트가 포트를 사용 중이라면 충돌 프로세스를 종료하거나 새 포트를 선택하고 시스템 프록시와 앱 설정도 함께 변경하세요. YAML만 수정한 뒤 기존 포트에 계속 연결해서는 안 됩니다.
명시적 프록시 테스트로 시스템 프록시의 영향을 일시적으로 제외할 수 있습니다. 아래 명령은 HTTP 프록시 진입점을 지정해 예시 도메인에 요청합니다. 성공하더라도 해당 요청이 이 진입점을 통해 처리됐다는 뜻일 뿐, TUN, 모든 규칙, UDP가 정상이라는 뜻은 아닙니다. SOCKS를 테스트할 때는 원격 도메인 해석을 사용하는 형식을 지정하면 로컬 해석과 프록시 경로 해석의 차이를 구분하는 데 도움이 됩니다. 테스트 대상은 현재 확인하려는 적법한 서비스 주소로 바꾸고 비공개 접근 정보가 로그에 남지 않도록 하세요.
curl --proxy http://127.0.0.1:7890 --head https://example.com
curl --proxy socks5h://127.0.0.1:7890 --head https://example.com
연결 경로의 어느 계층에서 문제가 생겼는지 찾기
진입 연결이 거부되면 프로세스, 수신 주소, 포트를 우선 확인하세요. 코어에 들어오지만 도메인이 올바르지 않으면 DNS, 앱의 해석 방식, 스니핑을 확인합니다. 도메인은 맞지만 출구가 잘못되면 규칙 순서와 그룹 선택을 점검하세요. 출구도 맞는데 연결되지 않으면 노드 프로토콜, 대상 서비스, 네트워크 경로를 살펴봅니다. 로그 상세도를 일시적으로 높이면 상황을 파악하는 데 도움이 되지만 문제 해결 후에는 적절한 수준으로 되돌려 연결 정보가 과도하게 기록되지 않도록 하세요. 로그를 공유하기 전에 구독 주소, 인증 정보, 사적인 도메인을 삭제하세요.
구성 검증을 위해 고정된 테스트 사례를 준비하는 것이 좋습니다. 직접 연결되어야 하는 사이트 하나, 프록시를 사용해야 하는 서비스 하나, LAN 대상 하나, 실제로 필요한 UDP 앱 하나를 정하세요. 한 번에 한 종류의 필드만 변경하고 새 연결 결과를 확인한 뒤 다음 항목으로 넘어갑니다. 부팅 후에만 문제가 생긴다면 서비스 시작과 설정 로드 순서를 확인하고 부팅 시 자동 실행 가이드를 참고하세요. 특정 앱에서만 문제가 발생한다면 사용 팁을 확인하세요. 안정적인 설정은 필드가 가장 많은 설정이 아니라 각 필드의 목적이 명확하고 예외마다 재현 가능한 검증 방법이 있는 설정입니다.