01 · 설정 적용 흐름과 변경 기본 원칙
클라이언트, 코어, 실행 설정
클라이언트 인터페이스에서는 구독을 가져오고 옵션을 저장하며 백그라운드 서비스를 시작합니다. 코어는 규칙을 해석하고 연결을 생성해 트래픽을 전달합니다. 인터페이스에 스위치가 있다고 해서 구독 파일에 같은 이름의 항목이 반드시 있는 것은 아닙니다. 반대로 파일에 설정을 추가해도 클라이언트가 실행 설정을 생성하는 과정에서 덮어쓸 수 있습니다. 문제를 해결할 때는 먼저 클라이언트의 코어 정보나 로그에서 실제 사용 중인 코어를 확인한 다음, 코어에 전달되는 최종 설정을 찾아보세요. 구독 편집기만 확인해서는 충분하지 않습니다.
이 사이트에서는 플랫폼별 클라이언트 다운로드 경로를 안내합니다. 클라이언트를 고를 때는 먼저 Clash Plus를 살펴본 뒤, 운영체제와 필요한 기능을 기준으로 다른 클라이언트를 비교하세요. Clash Verge Rev, Clash Meta for Android, FlClash 등은 설정 위치와 병합 방식이 서로 다릅니다. 다른 설치 경로를 찾아야 한다면 클라이언트 다운로드 페이지를 방문하세요. 이 페이지에서는 특정 클라이언트의 메뉴 경로를 모든 플랫폼에 공통되는 절차로 취급하지 않습니다. 각 설정의 지원 여부는 실제로 실행 중인 코어를 기준으로 확인해야 합니다.
복구 가능한 최소 변경 절차 만들기
변경 전에 구독 원본, 로컬 오버라이드, 현재 정상 작동하는 실행 설정을 각각 저장하고 시스템 프록시와 TUN의 기존 상태를 기록하세요. 구독 주소에는 접근 자격 증명이 포함될 수 있으므로 공개 저장소나 스크린샷, 도움 요청 게시물에 올리지 마세요. 한 번에 설정 계층 하나만 변경하는 것이 좋습니다. 먼저 파일이 로드되는지 확인하고, 다음으로 규칙이 매칭되는지 살펴본 뒤, 마지막으로 트래픽 처리 방식을 조정하세요. DNS와 라우팅, 규칙 세트를 동시에 바꾸면 연결에 실패해도 어떤 변경이 트래픽 경로에 영향을 줬는지 파악하기 어렵습니다.
아래 예제는 기본 설정 항목을 이해하기 위한 것으로, 프록시 노드가 포함된 완전한 구독이 아닙니다. 규칙 모드와 혼합 포트를 사용하며, 어떤 규칙에도 매칭되지 않은 연결은 직접 나갑니다. 기존 설정과 병합할 때는 같은 이름의 최상위 항목을 편집하고, 파일 끝에 두 번째 rules를 중복으로 추가하지 마세요. YAML에서 중복 키를 처리하는 방식은 파서에 따라 다르므로 나중에 나온 내용이 앞선 내용을 덮어쓴다고 가정할 수 없습니다.
mixed-port: 7890
allow-lan: false
mode: rule
log-level: info
rules:
- DOMAIN-SUFFIX,example.com,DIRECT
- MATCH,DIRECT
들여쓰기는 공백으로 통일하고, 목록 항목의 하이픈은 해당 필드의 계층에 맞춰 배치하세요. 콜론이나 샵이 포함된 문자열, 또는 특수한 형식으로 인식될 수 있는 문자열은 따옴표로 묶는 것이 좋습니다. 흔한 형식 오류는 설정이 복잡해서라기보다 예제를 복사하는 과정에서 들여쓰기가 사라지거나, 전체 설정을 하위 항목에 넣어서 발생합니다. 편집기에서 정상적으로 보이더라도 코어가 해석할 수 있다는 뜻은 아닙니다. 저장한 뒤 로드 결과를 확인하세요.
문법 검사와 동작 검사는 따로 진행하세요
독립 실행형 Mihomo 파일이 있다면 아래 명령으로 먼저 테스트할 수 있습니다. 명령에 사용할 파일은 현재 디렉터리에 있어야 합니다. 규칙 세트나 데이터베이스 등에서 상대 경로를 사용한다면 테스트 작업 디렉터리가 실제 실행 환경과 같은지도 확인하세요. 문법 검사를 통과했다는 것은 설정을 해석할 수 있다는 뜻일 뿐, 노드가 작동하거나 DNS에 연결되거나 시스템 라우팅이 설정되었다는 의미는 아닙니다.
mihomo -t -f ./config.yaml
새 연결 하나를 기준으로 동작을 단계별로 확인하세요. 애플리케이션이 코어로 들어오는지, 대상 도메인이 인식되는지, 어떤 규칙이 매칭되는지, 최종적으로 어떤 아웃바운드가 선택되는지 살펴보면 됩니다. 브라우저의 기존 장시간 연결은 이전 정책을 계속 사용할 수 있으므로 테스트할 때 새 요청을 보내고, 필요한 경우 애플리케이션을 종료한 뒤 다시 연결하세요. 프록시 그룹을 바꾼 뒤 기존 탭에서 계속 접속된다는 이유만으로 새 규칙이 적용되었다고 판단하지 마세요.
최소 설정도 시작되지 않는다면 규칙 문법을 살펴보기 전에 포트 충돌, 파일 권한, 경로를 확인하세요. 주소가 이미 사용 중이라는 메시지가 나타나면 7890 포트 충돌 확인 및 mixed-port 변경 방법을 참고하세요. 포트를 바꾼 뒤에는 앱의 수동 프록시 설정도 함께 변경해야 합니다. 코어는 새 포트에서 수신 중인데 브라우저가 이전 포트에 연결하는 상황을 방지할 수 있습니다.
02 · 프록시 그룹 유형과 구성 실전
규칙 대상과 실제 아웃바운드를 구분하세요
규칙은 “이 연결을 어디로 보낼지”를 정하고, 프록시 그룹은 “현재 후보 아웃바운드 중 무엇을 선택할지”를 정합니다. 규칙은 특정 노드나 프록시 그룹을 지정할 수 있습니다. 일상적인 설정에서는 규칙이 이름이 안정적인 그룹을 참조하도록 하고, 노드 추가와 삭제는 그룹 안에서 처리하는 편이 좋습니다. 구독 업데이트로 노드 이름이 바뀌어도 서비스 규칙을 하나씩 수정할 필요가 없습니다. 그룹 이름은 참조 식별자이므로 공백, 대소문자, 문자를 정확히 일치시켜야 합니다.
select는 사용자가 직접 선택하는 그룹으로, 바로 조작할 수 있는 진입점에 적합합니다. url-test는 연결 테스트 결과를 바탕으로 후보를 선택합니다. fallback은 후보가 사용 가능한 경우 목록에서 앞쪽에 있는 아웃바운드를 우선 사용합니다. load-balance는 선택한 분배 방식에 따라 여러 연결에 후보 아웃바운드를 할당합니다. 각 유형이 해결하는 문제는 다르므로 이름만 보고 “자동”이 언제나 “수동”보다 적합하다고 판단하지 마세요.
| 유형 | 사용 사례 | 주의 사항 |
|---|---|---|
select | 출구를 직접 지정 | 현재 선택 항목을 직접 관리해야 함 |
url-test | 테스트 결과가 적합한 후보를 자동 선택 | 테스트 주소가 실제 서비스 환경과 같지는 않음 |
fallback | 기본 및 대기 순서가 명확함 | 후보 순서가 선택에 영향을 줌 |
load-balance | 여러 연결에 트래픽 분배 | 단일 연결의 대역폭을 여러 배로 늘릴 수는 없음 |
진입 그룹과 자동 선택 그룹 분리
관리하기 쉬운 구성은 규칙이 “네트워크 출구”를 가리키고, 진입 그룹에서 자동 그룹, 수동 후보 또는 직접 연결을 선택하도록 하는 방식입니다. 아래 예제는 내장된 DIRECT만 참조하므로 그룹 간 참조 관계를 보여줄 뿐, 프록시 출구를 제공하지 않습니다. 실제로 사용하려면 유효한 구독이나 로컬 노드 정의를 통해 실제 후보를 추가한 다음, 후보 이름을 자동 그룹에 입력하세요. 예제를 노드 출처로 오해하지 마세요.
proxy-groups:
- name: 네트워크 출구
type: select
proxies:
- 자동 선택
- DIRECT
- name: 자동 선택
type: url-test
proxies:
- DIRECT
url: https://example.com/
interval: 300
tolerance: 50
rules:
- DOMAIN-SUFFIX,example.com,네트워크 출구
- MATCH,DIRECT
여기서 interval은 주기적인 연결 테스트 간격을 나타내며, tolerance는 테스트 결과의 작은 차이 때문에 선택이 자주 바뀌는 것을 줄이는 데 사용됩니다. 테스트 주소는 후보 아웃바운드로 접속할 수 있고 응답이 명확한 엔드포인트를 선택하세요. 예제의 도메인은 설정 항목을 이해하기 위한 것이므로 실제 설정에서는 사용 중인 네트워크 환경에 맞는 테스트 대상을 고르세요. 테스트 결과는 해당 대상까지의 경로를 측정할 뿐, 다운로드 속도나 동영상 재생 여부, 계정 관련 서비스의 안정성을 보장하지 않습니다.
로그인 세션, 결제 페이지, 출구 IP에 민감한 서비스에는 보통 수동 선택 그룹을 고정해 여러 새 연결 사이에서 출구가 바뀌지 않도록 하는 편이 좋습니다. 일관성 있는 분배 방식을 사용하더라도 관련 도메인이 모두 같은 주소를 사용한다고 보장할 수는 없습니다. 페이지가 여러 서비스에 의존할 수 있고 후보 목록도 바뀔 수 있기 때문입니다. 출구를 안정적으로 유지해야 한다면 그룹 이름만 보지 말고 실제 연결 기록을 확인하세요.
순환 참조와 후보 누락 방지
프록시 그룹은 다른 그룹을 참조할 수 있지만 순환 구조를 만들면 안 됩니다. 예를 들어 진입 그룹이 자동 그룹을 참조하고 자동 그룹이 다시 진입 그룹을 참조하면 선택이 끝나는 지점이 불명확해집니다. 한 방향으로 계층을 유지하는 것이 안전합니다. 서비스 규칙에서 진입 그룹을 참조하고, 진입 그룹에서 기능 그룹을 참조하며, 기능 그룹에서 실제 노드나 내장 아웃바운드를 참조하도록 구성하세요. 구독 제공자를 참조할 때는 use에 지정한 이름이 실제로 존재하는지, 제공자가 정상적으로 로드되었는지도 확인해야 합니다.
그룹은 표시되지만 선택할 노드가 없다면 필터 표현식이 모든 후보를 제외했는지 먼저 확인한 뒤 구독 로드 기록을 살펴보세요. 바로 필터 조건을 더 복잡한 표현식으로 바꾸지는 마세요. 노드 이름이 중복되면 표시와 참조가 모호해질 수 있으므로 구독을 병합할 때 고유한 이름 규칙을 정해두세요. 자동 그룹의 후보가 모두 실패하면 이미 확인된 후보 하나를 직접 선택해 테스트하고, 노드 연결 문제인지 테스트 대상에 접근할 수 없는 문제인지 구분하세요.
그룹을 변경한 뒤에는 새 연결을 기준으로 확인하세요. 일부 클라이언트는 이전 선택을 저장해 재시작 후 복원하므로, 이는 YAML 목록의 순서와는 별개의 동작입니다. 인터페이스에서 선택한 항목이 예상과 다르면 클라이언트의 저장된 설정과 현재 실행 상태를 모두 확인하세요. 클라이언트 조작 방법을 비교하려면 그룹 이름을 반복해서 바꾸며 저장 동작을 우회하는 대신 클라이언트 비교 페이지를 참고하세요.
03 · 규칙 세트 구독 관리와 매칭 순서
규칙 내용과 트래픽 분기 대상을 분리하세요
도메인과 IP 대역 항목이 늘어나면 주 설정 파일에 모두 넣을수록 업데이트와 검토가 어려워집니다. rule-providers는 규칙 내용의 출처를 정의하고, RULE-SET은 기본 규칙 목록에서 해당 내용을 참조해 매칭 후 적용할 정책을 지정합니다. 규칙 세트는 “대상이 무엇인지”를 관리하고 기본 설정은 “대상을 어디로 보낼지”를 정합니다. 둘을 분리하면 같은 서비스 도메인 목록을 기기별로 서로 다른 프록시 그룹에 연결할 수 있습니다.
제공자의 behavior는 콘텐츠 형식과 일치해야 합니다. domain은 도메인 목록, ipcidr은 IP 대역, classical은 기존 규칙 유형을 포함하는 항목에 사용합니다. 다운로드 주소에 접속할 수 있다고 해서 파일 형식이 올바른 것은 아닙니다. payload가 포함된 YAML을 일반 텍스트 목록으로 읽거나 전체 규칙 행을 도메인 파서에 넘기면 로드에 실패하거나 예상과 다른 결과가 나올 수 있습니다.
먼저 로컬 파일로 참조 관계를 확인하세요
아래 예제는 원격 다운로드 없이 규칙 세트를 검증할 수 있도록 로컬 파일을 사용합니다. 먼저 코어 작업 디렉터리에 rules 폴더를 만들고 local-domains.yaml을 저장하세요. 이 파일에는 규칙만 넣고 프록시 정책은 작성하지 않습니다. 예제 도메인은 매칭 테스트용입니다. 실제 서비스에서는 관리가 필요한 도메인으로 바꾸고 변경 내역을 기록하세요.
# rules/local-domains.yaml
payload:
- '+.example.com'
기본 설정에서 파일 출처를 정의하고 일반 규칙에서 참조하세요. 상대 경로는 코어 작업 디렉터리를 기준으로 해석되며, 클라이언트에서 현재 편집 중인 파일의 위치를 기준으로 하지 않을 수 있습니다. 데스크톱 클라이언트를 사용하는 경우 코어에 할당된 설정 디렉터리를 먼저 확인하세요. 파일을 다운로드 폴더에 저장했는데 실행 시 다른 디렉터리를 찾는 상황을 방지할 수 있습니다.
rule-providers:
local-domains:
type: file
behavior: domain
format: yaml
path: ./rules/local-domains.yaml
rules:
- RULE-SET,local-domains,DIRECT
- MATCH,DIRECT
HTTP 출처로 전환할 때는 실제로 접근할 수 있는 url, 캐시 path, 업데이트 interval을 설정하고 서버가 웹 미리보기나 로그인 페이지가 아닌 규칙 본문을 반환하는지 확인하세요. 캐시 경로는 고유하게 지정하고 서로 다른 두 제공자가 같은 파일에 쓰지 않도록 하세요. 파일 형식은 코어에서 지원하는 YAML, 텍스트 또는 컴파일 형식을 사용할 수 있지만, 선언과 내용이 서로 일치해야 합니다. 확장자만 바꾸는 것으로는 충분하지 않습니다.
규칙 순서가 실제 결과를 결정합니다
규칙은 일반적으로 위에서 아래 순서로 매칭되며, 먼저 매칭된 규칙이 해당 연결의 선택을 끝냅니다. 특정 도메인 예외는 광범위한 분류 규칙보다 앞에 두고, 마지막에는 MATCH로 나머지 트래픽을 처리하세요. MATCH 뒤에 규칙 세트를 추가해도 예상대로 동작하지 않습니다. 마찬가지로 범위가 너무 넓은 도메인 접미사 규칙을 앞에 두면 뒤에 있는 세부 규칙이 매칭될 기회를 얻지 못할 수 있습니다.
IP 규칙은 도메인 확인을 유발할 수 있습니다. 일부 규칙에서는 끝에 no-resolve를 사용해 대상이 여전히 도메인일 때 해당 IP 규칙을 위해 별도로 조회하지 않도록 할 수 있습니다. 이는 “전체 연결에서 DNS를 사용하지 않는다”는 뜻이 아닙니다. 도메인 규칙을 우선 적용하려면 DNS 조회가 필요한 IP 대역 규칙보다 앞에 배치하세요. 불필요한 조회를 줄이려고 이 매개변수를 무조건 추가하면 조회 결과에 의존하는 규칙이 작동하지 않을 수 있습니다.
원격 규칙 세트 업데이트에 실패하면 코어가 사용 가능한 캐시를 보유하고 있는지 확인한 다음 다운로드 경로와 접근 조건을 살펴보세요. 최초 시작과 일상적인 업데이트는 조건이 다릅니다. 평소에는 기존 캐시를 이용해 시작할 수 있지만, 최초 시작 시에는 사용할 콘텐츠가 없을 수 있습니다. 규칙 다운로드에 프록시가 필요하고 프록시 선택이 아직 다운로드되지 않은 규칙에 의존한다면 시작 단계에서 순환 의존성이 생깁니다. 기본 시작 경로는 단순하게 유지하세요.
자주 업데이트되는 규칙 출처는 변경 전 내용을 저장하고, 업데이트 후 주요 서비스 도메인이 새 분류 규칙에 포함되었는지 확인하세요. GeoIP, GeoSite와 일반 규칙 제공자는 저장 방식이 완전히 같지 않습니다. 관련 데이터베이스의 형식, 경로, 업데이트 조건은 GeoIP 및 GeoSite 데이터베이스 업데이트 안내에서 확인할 수 있습니다. 이름을 통일하겠다는 이유로 서로 다른 방식의 파일을 바꿔 사용하지 마세요.
04 · DNS 조회 경로와 설정 최적화
앱 조회, 코어 조회, 노드 주소 조회를 구분하세요
DNS 문제는 “DNS 서버를 입력했는가”보다 실제로 누가 조회를 보내는지가 중요합니다. 브라우저에서 자체 암호화 DNS를 사용할 수 있고, 운영체제가 이전 결과를 캐시할 수 있으며, 코어는 프록시 서버 도메인도 조회해야 합니다. 시스템 프록시는 프록시 설정을 따르는 앱의 요청에만 영향을 주며, 모든 DNS 조회가 자동으로 코어에 전달되는 것은 아닙니다. 설정을 조정하기 전에 앱이 시스템 DNS, 코어 DNS 또는 별도의 조회 경로를 사용하는지 확인하세요.
nameserver는 일반 DNS 상위 서버입니다. default-nameserver는 DNS 상위 서버의 도메인 조회 등 기본적인 시작 과정에 사용됩니다. proxy-server-nameserver는 프록시 서버 도메인을 조회할 서버를 별도로 지정할 수 있습니다. 이들을 나누어 설정하면 프록시 연결을 시작하기도 전에 노드 주소를 확인하려고 해당 프록시에 의존하는 상황을 피할 수 있습니다. 모든 상위 서버를 HTTPS로 바꾸는 것만으로는 이런 의존성이 자동으로 해결되지 않습니다.
먼저 기본 DNS 조회 경로부터 설정하세요
아래 예제는 코어가 루프백 주소의 비표준 포트에서 DNS 서비스를 제공하고 Fake-IP를 사용하도록 합니다. 운영체제의 DNS 설정을 자동으로 바꾸지는 않습니다. 실제로 조회를 이 수신 포트로 보내야 동작을 확인할 수 있습니다. 데스크톱 클라이언트의 TUN 가로채기, 시스템 DNS 설정, 수동 테스트는 서로 다른 진입 경로일 수 있으므로 검증할 때 현재 어떤 경로를 사용하는지 분명히 하세요.
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:
- 1.1.1.1
- 8.8.8.8
nameserver:
- https://1.1.1.1/dns-query
proxy-server-nameserver:
- https://1.1.1.1/dns-query
여기에 적힌 상위 서버 주소는 설정 예시일 뿐 모든 네트워크에서 접속할 수 있다고 보장하지 않습니다. 상위 서버를 선택할 때는 현지 접속 조건, 조회 개인정보 보호 요구사항, 서비스에 적합한 응답인지 고려하세요. ipv6: false는 이 DNS 설정의 AAAA 응답 동작을 제어하며 시스템 전체의 IPv6를 끄는 설정은 아닙니다. 네트워크에서 IPv6를 사용할 수 있다면 이 설정이 기존 연결 경로를 바꿀 수도 있으므로 명확한 문제를 확인한 뒤 조정하세요.
도메인별 DNS 조회 정책 지정
사내 도메인, 가정용 기기 이름, 특정 서비스 도메인은 지정된 DNS 서버에서만 올바른 응답을 받을 수 있습니다. 이럴 때는 nameserver-policy를 사용해 해당 도메인이 전용 상위 서버를 이용하도록 설정할 수 있습니다. 내부 도메인을 공용 DNS 서버로 무작정 보내면 응답을 받지 못할 뿐 아니라 내부 네트워크에서만 사용하는 이름이 노출될 수 있습니다. 도메인 범위를 먼저 확인하고, 지나치게 넓은 접미사 규칙이 다수의 공용 조회까지 내부 서버로 보내지 않도록 하세요.
respect-rules를 사용해 DNS 상위 서버 연결에도 트래픽 분기 규칙을 적용하려면 프록시 서버 도메인의 조회 경로도 함께 고려해야 합니다. 이 옵션은 코어가 DNS 상위 서버에 접근하는 경로를 바꾸는 것이지, 모든 DNS 응답에 올바른 분류를 자동으로 적용하는 기능은 아닙니다. 노드 주소를 확인할 독립적이고 접근 가능한 경로를 먼저 설정한 다음, 상위 서버 연결이 어떤 규칙에 매칭되는지 살펴보면 노드 조회와 노드 연결이 서로를 기다리는 순환을 피할 수 있습니다.
fallback과 fallback-filter는 단순히 “기본 DNS 서버가 고장 나면 예비 서버로 전환”하는 스위치가 아닙니다. 사용하면 도메인과 주소 범위 등의 조건에 따라 응답이 필터링됩니다. 필터링 목적이 분명하지 않다면 단일하고 안정적인 조회 경로를 유지하는 편이 좋습니다. 특정 도메인에서 실제로 문제가 확인된 경우에만 대체 경로를 추가하세요. 상위 서버가 많다고 반드시 안정성이 높아지는 것은 아니며, 오히려 문제 해결 범위가 넓어질 수 있습니다.
dig @127.0.0.1 -p 1053 example.com A
테스트할 때는 조회 시간, 반환된 주소 유형, 코어 로그를 함께 기록하세요. Fake-IP 모드에서는 예약 주소 범위에 속하는 주소가 반환되는 것이 정상일 수 있으므로, 공인 IP가 아니라는 이유만으로 조회 실패라고 판단하지 마세요. 조회 모드를 바꾼 뒤에도 앱이나 시스템 캐시에 이전 결과가 남을 수 있습니다. 새 요청을 보내고 운영체제에서 제공하는 방법으로 캐시를 갱신하세요. DNS 상위 서버를 계속 추가할 필요는 없습니다.
도메인은 조회되지만 웹페이지가 열리지 않는다면 연결에 적용된 규칙과 아웃바운드를 확인하세요. 브라우저에서만 동작이 다르다면 브라우저 자체 DNS와 프록시 확장 프로그램을 살펴보세요. 관련 증상은 연결은 됐지만 웹페이지에 접속할 수 없을 때 확인할 항목을 따라 점검할 수 있습니다. DNS 최적화의 목표는 경로를 명확히 하고 결과를 검증할 수 있게 하는 것이지, 설정 항목을 최대한 많이 넣는 것이 아닙니다.
05 · TUN 트래픽 처리와 Fake-IP 매핑
각 기능의 역할 구분
TUN은 가상 네트워크 인터페이스를 만들어 운영체제가 라우팅 조건에 맞는 IP 트래픽을 코어로 보내도록 합니다. Fake-IP는 DNS 단계에서 제어된 가상 주소를 반환하고, 코어에서 이 주소와 원래 도메인의 매핑을 저장합니다. TUN은 “트래픽이 어떻게 코어에 들어오는지”를 처리하고, Fake-IP는 “이 트래픽이 원래 어떤 도메인에 접근했는지”를 파악하는 데 도움을 줍니다. 둘은 함께 자주 사용되지만 같은 기능은 아니며, 하나를 켠다고 다른 기능이 반드시 대체되는 것도 아닙니다.
시스템 프록시는 앱이 프록시 설정을 따르는지에 따라 작동하므로 이를 따르지 않는 프로그램에는 적용되지 않을 수 있습니다. TUN은 라우팅을 통해 더 많은 트래픽을 처리하지만 권한, 가상 네트워크 인터페이스, 시스템 DNS, 다른 VPN과의 충돌도 고려해야 합니다. 트래픽 처리 범위가 넓어진다고 모든 프로토콜을 원격에서 자동으로 지원하는 것은 아닙니다. 최종 사용 가능 여부는 아웃바운드 노드의 프로토콜 지원에도 달려 있습니다. 특히 UDP는 앱부터 코어, 원격 서버까지 전체 경로에서 지원해야 합니다.
클라이언트 권한 절차에 따라 활성화하세요
데스크톱에서는 먼저 클라이언트가 제공하는 서비스 설치나 권한 부여 절차를 진행한 뒤 TUN을 켜세요. Windows에서는 백그라운드 서비스나 관리자 권한이 필요한 경우가 많고, macOS에서는 클라이언트 구현에 따라 시스템 권한을 부여해야 합니다. Linux는 서비스 권한, 네트워크 관리, 라우팅 설정에 따라 달라집니다. Android는 보통 시스템 VPN 서비스 권한을 사용하며, 설정 항목이 직접 노출되는지는 클라이언트마다 다릅니다. iOS의 트래픽 처리는 앱과 시스템 확장 기능이 관리하므로 데스크톱의 네트워크 인터페이스 설정을 그대로 적용하지 마세요.
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
이 예제는 앞 장에서 코어 DNS를 활성화했고 클라이언트가 해당 TUN 설정을 허용한다고 가정합니다. auto-route는 필요한 경로를 추가하고, auto-detect-interface는 출구 인터페이스를 찾습니다. 여러 네트워크 인터페이스, 컨테이너, 원격 데스크톱, 기업 네트워크 환경에서는 자동 감지가 실제 네트워크 구성과 맞지 않을 수 있습니다. stack 선택은 플랫폼 지원과 앱 동작을 고려해야 하며, 모든 기기에 같은 스택을 권장할 수는 없습니다.
dns-hijack 예제는 기존 DNS 포트를 대상으로 합니다. 그렇다고 브라우저의 DoH나 다른 암호화 DNS를 해독하거나 대체한다고 볼 수는 없습니다. 일부 앱은 고정 IP에 직접 연결하거나 자체 DNS 서비스를 사용하므로 연결 기록을 확인해야 합니다. 앱이 코어 연결 목록에 전혀 나타나지 않는다면 도메인 규칙을 계속 바꾸기보다 라우팅과 트래픽 처리 진입 경로를 먼저 점검하세요.
Fake-IP 필터는 꼭 필요한 예외만 추가하세요
실제 주소를 반환해야 하는 앱은 Fake-IP를 받으면 제대로 작동하지 않을 수 있습니다. 예를 들어 일부 로컬 네트워크 기기 검색이나 기기 연결, 특정 인증 절차가 이에 해당합니다. 이런 경우 fake-ip-filter에 명확한 도메인 예외를 추가해 실제 DNS 결과를 반환하도록 할 수 있습니다. 추가하기 전에 현재 fake-ip-filter-mode의 의미를 확인하세요. 필터 모드에 따라 같은 목록의 의미가 반대가 될 수 있으므로 다른 사람이 공유한 긴 목록을 그대로 복사해서는 안 됩니다.
필터 범위가 지나치게 넓으면 코어가 매핑을 통해 도메인을 복원할 기회가 줄어들어 규칙 매칭 조건이 달라질 수 있습니다. 문제가 생기면 도메인 하나부터 확인하세요. 조회가 코어에 도달하는지, 어떤 주소 유형이 반환되는지, 연결이 실제 주소에 의존하는지 살펴보면 됩니다. 기기 검색은 브로드캐스트나 멀티캐스트에 의존할 수도 있으므로 도메인 필터만 추가해서 모든 로컬 네트워크 접속 문제를 해결할 수는 없습니다.
다른 VPN과 함께 사용할 때는 기본 라우트를 어느 쪽이 담당하는지, DNS를 누가 처리하는지, 중복으로 트래픽을 가로채는지 확인하세요. 두 가상 네트워크 인터페이스가 비슷한 라우트를 동시에 선언하면 요청이 우회하거나 루프에 빠지거나 일부 대상에만 접근할 수 있습니다. 한쪽의 트래픽 처리를 끈 뒤 다시 테스트하면 충돌 원인을 구분하는 데 도움이 됩니다. 네트워크 구성을 모르는 상태에서 라우팅 옵션을 더 엄격하게 바꾸지는 마세요.
되돌릴 때는 먼저 TUN을 끄고 시스템 프록시와 DNS가 예상한 상태로 복구되었는지 확인하세요. Fake-IP와 실제 DNS 모드를 전환한 뒤에는 관련 캐시를 갱신하고 연결을 새로 만들어야 합니다. 클라이언트를 종료했는데도 네트워크 문제가 계속되면 백그라운드 서비스가 실행 중인지, 시스템에 수동 프록시 설정이 남아 있는지 확인하세요. 일반적인 문제는 도움말 센터에서 추가로 확인할 수 있습니다. 장애가 발생하기 직전에 변경한 네트워크 계층도 기록하세요.
06 · 도메인 스니핑과 인식 범위
스니핑으로 연결 정보 보완
연결이 코어에 들어올 때 대상 IP만 포함되어 있으면 도메인 규칙에 필요한 정보가 부족할 수 있습니다. 도메인 스니핑은 HTTP 요청의 호스트 정보나 TLS 핸드셰이크의 서버 이름처럼 프로토콜 핸드셰이크에서 호스트 이름을 추출해 이후 처리에 활용합니다. 임의의 HTTPS 본문을 복호화하거나 모든 IP를 고유한 도메인으로 되돌리는 기능은 아닙니다. 하나의 주소에서 여러 웹사이트를 제공한다면 주소만으로 서비스 이름을 알아낼 수 없습니다.
스니핑과 Fake-IP는 모두 도메인 정보를 유지하는 데 도움을 주지만 정보의 출처가 다릅니다. Fake-IP는 코어가 처리하는 DNS 매핑에 의존하고, 스니핑은 연결 초기에 관찰할 수 있는 프로토콜 정보에 의존합니다. 앱이 코어 DNS를 우회하는 경우 스니핑이 일부 정보를 보완할 수 있지만, 핸드셰이크에서 사용할 수 있는 도메인이 드러나지 않거나 해당 프로토콜이 지원되지 않으면 도메인이 자동으로 만들어지지는 않습니다.
프로토콜과 포트 범위를 먼저 제한하세요
아래 예제는 HTTP와 TLS에 대한 기본 스니핑 설정을 보여주며 원래 연결 대상도 유지합니다. 처음에는 좁은 포트 범위로 효과를 살펴본 뒤 실제 앱에 맞춰 범위를 넓히는 편이 문제를 찾기 쉽습니다. 예제의 포트 범위는 설정 조건일 뿐, 해당 포트의 모든 트래픽이 반드시 지정된 프로토콜을 사용한다는 뜻은 아닙니다.
sniffer:
enable: true
force-dns-mapping: true
parse-pure-ip: true
override-destination: false
sniff:
HTTP:
ports:
- 80
- 8080-8880
override-destination: false
TLS:
ports:
- 443
- 8443
parse-pure-ip를 사용하면 IP를 대상으로 하는 연결도 처리할 수 있고, force-dns-mapping은 DNS 매핑과 관련된 동작을 합니다. 이런 기능이 실제로 필요한지는 원래 연결 정보를 기준으로 판단하세요. override-destination은 인식한 결과로 연결 대상을 바꿀 수 있는지를 결정하며, 도메인 정보만 보완하는 옵션은 아닙니다. 사용 전에 “규칙에서 도메인을 인식하려는 것”과 “최종 연결 대상을 바꾸려는 것”을 구분하세요.
원래 주소를 유지하면 옵션을 켜기 전후의 동작을 비교하기 쉽습니다. 특정 주소, 사설 DNS, 전용 회선 진입점을 사용하는 서비스에서는 목적지를 바꾸면 추가 DNS 조회가 발생하고 요청이 원래 서버와 다른 곳으로 갈 수 있습니다. 목적지 변경이 필요하다면 앱 하나와 도메인 하나로 먼저 검증한 뒤 범위를 넓히세요. 모든 연결 실패에 적용할 일반적인 해결책으로 사용해서는 안 됩니다.
스니핑에서 제외할 범위와 인식할 수 없는 경우
스니핑에 적합하지 않은 서비스는 코어에서 지원하는 도메인 또는 주소 제외 항목으로 예외를 설정할 수 있습니다. 재현 가능한 호환성 문제를 기준으로 예외를 추가하고, 출처를 알 수 없는 제외 목록을 그대로 복사하지 마세요. 제외하기 전후의 대상 주소, 인식된 도메인, 매칭 규칙을 기록해야 문제가 인식 과정에서 생겼는지 이후 정책 선택에서 생겼는지 알 수 있습니다.
QUIC은 일반 TLS와 전송 방식이 다르므로 해당 정보를 추출하려면 지원되는 파싱 기능을 활성화해야 합니다. 기능이 지원되더라도 암호화 핸드셰이크의 모든 정보를 볼 수 있는 것은 아닙니다. ECH 등의 기능을 사용하는 연결은 사용 가능한 대상 이름을 노출하지 않을 수 있습니다. 사설 프로토콜, IP를 직접 사용하는 앱, 호스트 정보가 없는 연결도 도메인 규칙에 적합한 정보를 스니핑하지 못할 수 있습니다.
로그에 도메인을 표시하려고 특정 프로토콜을 무작정 차단하지 마세요. UDP를 차단하면 일부 앱이 다른 전송 방식으로 전환될 수 있지만 서비스가 바로 중단될 수도 있습니다. 호환성 테스트를 해야 한다면 테스트 조건을 명확히 기록하고 완료 후 원래 설정으로 되돌리세요. 정상적인 설정은 연결 목록을 보기 좋게 만드는 것이 아니라 앱의 요구사항을 기준으로 설계해야 합니다.
연결 기록으로 변경 전후를 비교하세요
검증하려면 먼저 스니핑을 끈 상태에서 대상 요청을 새로 만들어 대상 유형, 규칙, 아웃바운드를 기록하세요. 다음으로 스니핑을 켜고 같은 서비스에 새 연결을 만드세요. 도메인은 표시되지만 트래픽 분기가 바뀌지 않았다면 앞선 IP 규칙이 이미 매칭되었거나 도메인 규칙의 범위에 해당 대상이 포함되지 않을 수 있습니다. 켠 뒤 오히려 실패한다면 대상이 바뀌었는지, 추가 DNS 조회가 성공했는지 먼저 비교하세요.
테스트 로그의 저장 범위를 제한하세요. 도메인, 요청 경로, 노드 이름, 컨트롤 인터페이스 정보는 개인이나 조직의 네트워크 활동을 드러낼 수 있으므로 도움을 요청할 때 필요한 항목만 남기고 민감 정보를 가리세요. “모든 노드가 시간 초과됨”과 같은 기본 장애에서는 스니핑이 첫 번째 확인 대상이 아닙니다. 먼저 구독, 시스템 시간, 프로토콜 호환성 점검 순서에 따라 아웃바운드 연결이 정상적으로 만들어지는지 확인한 다음 도메인 인식 설정을 살펴보세요.
07 · 로컬 오버라이드와 여러 구독 병합
업데이트되는 설정과 기기별 설정을 분리하세요
구독에서는 노드, 그룹, 제공자가 관리하는 규칙을 유지하고, 로컬 설정에서는 기기 포트, TUN, 로컬 네트워크 접근 제한, 개인별 트래픽 분기 예외를 관리하는 것이 적합합니다. 구독 본문을 직접 수정하면 다음 업데이트에서 변경 사항이 사라지는 경우가 많습니다. 클라이언트의 오버라이드, 병합 또는 확장 설정 기능을 사용하면 구독을 계속 업데이트하면서 기기별 차이도 별도로 유지할 수 있습니다.
클라이언트마다 “오버라이드”의 의미는 다릅니다. 일부는 객체를 병합하고, 일부는 항목 전체를 교체하며, 스크립트 처리를 제공하거나 마지막 단계에서 인터페이스 설정을 강제로 적용하기도 합니다. 특히 rules, proxy-groups 같은 배열은 항목이 항상 하나씩 추가된다고 가정할 수 없습니다. 설정 전에 처리 순서를 파악하고 변경 후 최종 실행 설정을 확인하세요. 오버라이드 편집기만으로는 최종 결과를 알 수 없습니다.
프록시 제공자로 여러 출처 구성하기
여러 구독의 전체 파일을 그대로 이어 붙일 필요는 없습니다. 형식이 적합한 노드 출처라면 proxy-providers를 사용해 각각 관리하고, 프록시 그룹에서 use로 참조할 수 있습니다. 아래 예제는 구조를 먼저 검증하기 위한 파일 기반 출처입니다. 코어 작업 디렉터리에 실제 노드 파일을 준비해야 합니다. 파일을 만들기 전에는 이 예제를 바로 실행할 수 있는 완전한 설정으로 취급하지 마세요.
proxy-providers:
personal-nodes:
type: file
path: ./providers/personal.yaml
work-nodes:
type: file
path: ./providers/work.yaml
proxy-groups:
- name: 개인 회선
type: select
use:
- personal-nodes
- name: 업무 회선
type: select
use:
- work-nodes
제공자 파일에는 코어가 요구하는 형식의 proxies 목록이 있어야 합니다. 규칙이 전부 포함된 클라이언트 설정을 임의로 저장하는 방식은 적합하지 않습니다. 인코딩된 공유 링크 모음, 전체 Clash 설정, 프록시 제공자 파일은 서로 다른 형식이므로 가져오기 전에 클라이언트나 출처가 해당 형식의 변환을 지원하는지 확인하세요. 비공개 구독을 출처가 불분명한 온라인 변환 서비스에 넘기지 마세요. 구독 링크와 노드 자격 증명이 통제할 수 없는 곳으로 전달되면 접근 권한도 노출될 수 있습니다.
출처에서 HTTP 제공자를 지원한다면 각 출처에 별도의 캐시 경로와 업데이트 간격을 설정할 수 있습니다. 개인 회선과 업무 회선을 분리하면 프록시 그룹의 경계가 분명해지고 한 출처만 비활성화해 테스트하기도 쉽습니다. 다만 각 출처의 사용 권한을 확인하세요. 기술적으로 병합할 수 있다고 해서 다른 기기나 사용자에게 접근 권한을 넘겨도 되는 것은 아닙니다.
이름, 추가 위치, 우선순위 관리
병합 전에 이름 규칙부터 정하세요. 제공자 이름은 고유하게, 프록시 그룹 이름은 안정적으로 유지하고, 출처가 다른 노드끼리 이름이 겹치지 않도록 하세요. 참조는 이름을 기준으로 하므로 인터페이스에 같은 이름으로 표시된다고 해서 출처를 자동으로 구분할 수는 없습니다. 접두사를 붙이거나 이름을 바꿔야 한다면 클라이언트나 코어에서 공식 지원하는 방법을 우선 사용하고, 변경된 노드 이름에도 필터 조건이 매칭되는지 테스트하세요.
로컬 규칙은 보통 앞에서 처리할 예외와 마지막에 적용할 기본 선택으로 나뉩니다. 우선 처리해야 하는 내부 도메인은 광범위한 규칙보다 앞에 두고, 마지막의 MATCH는 나머지를 처리하는 용도로만 사용하세요. 일부 병합 방식은 로컬 규칙을 구독 뒤에 추가합니다. 구독에 이미 MATCH가 있으면 추가된 규칙은 실행되지 않습니다. 병합 방식을 조정하거나 규칙 순서를 명시적으로 다시 구성하세요. 비슷한 규칙을 파일 끝에 계속 추가해서는 해결되지 않습니다.
구독 업데이트 후에도 다시 검증하세요
업데이트가 끝나면 세 가지를 확인하세요. 출처가 정상적으로 로드되었는지, 그룹 참조가 여전히 존재하는지, 앞에 두어야 할 규칙이 예상한 위치에 있는지 점검합니다. 구독에 새 설정 항목이 추가되면 기존 오버라이드가 이를 통째로 덮어쓸 수 있습니다. 로컬에 저장된 그룹 선택이 이미 삭제된 노드를 참조할 수도 있습니다. 문제가 생기면 먼저 개인 오버라이드를 끄고 원래 구독이 작동하는지 확인한 뒤 하나씩 다시 적용하면 충돌 지점을 더 빠르게 찾을 수 있습니다.
클라이언트에서 최종 설정을 표시하기 어렵다면 최소한 로드 로그, 노드 목록, 주요 연결의 규칙 기록을 보관하세요. 이전 스냅샷으로 복구할 때는 노드 자격 증명이 만료되었을 수 있다는 점도 고려해야 합니다. 설정을 로드할 수 있다고 해서 이전 노드가 여전히 작동하는 것은 아닙니다. 일상적인 작업은 빠른 시작 가이드의 가져오기 및 연결 절차를 따르세요. 이 장에서는 매번 파일을 직접 편집하도록 요구하는 것이 아니라 업데이트 뒤 병합 결과를 다시 확인해야 하는 이유를 설명합니다.
08 · 외부 컨트롤러와 유지 관리 절차
컨트롤 인터페이스는 프록시 포트가 아닙니다
external-controller는 패널에서 상태를 확인하고 프록시 정책을 바꾸거나 관리 작업을 실행할 수 있도록 코어의 관리 인터페이스를 제공합니다. HTTP, SOCKS 요청을 받는 혼합 프록시 포트나 DNS 수신 포트와는 다릅니다. 패널 연결 주소에 프록시 포트를 입력해도 관리 기능이 자동으로 생기지 않습니다. 컨트롤 포트를 네트워크 프록시로 설정해도 트래픽이 올바르게 전달되지 않습니다.
컨트롤 인터페이스는 네트워크 동작에 영향을 줄 수 있으므로 기본적으로 루프백 주소에 바인딩해 로컬에서만 접근할 수 있도록 설정하세요. 다른 기기에서 관리해야 한다면 수신 주소, 인증, 전송 보호, 방화벽을 검토하기 전에 접근 경계를 먼저 설계해야 합니다. 휴대폰에서 패널을 열기 위해 모든 네트워크 인터페이스에 컨트롤 인터페이스를 노출하고 추측하기 쉬운 예제 비밀번호에 의존해서는 안 됩니다. 컨트롤 인터페이스가 노출되면 상태를 보는 것뿐 아니라 실행 중인 선택을 바꾸는 등 더 큰 영향을 줄 수 있습니다.
로컬 패널 및 인증 설정
아래 예제는 루프백 수신과 로컬 패널 디렉터리를 설정합니다. your-password는 설명을 위한 예시이므로 실제로 활성화하기 전에 직접 생성한 강력한 비밀 키로 바꾸세요. 실제 값을 공개된 질문이나 게시물에 올리지 마세요. external-ui는 준비된 정적 패널 파일 디렉터리를 가리킵니다. 패널 파일이 없다면 이 항목만으로 사용할 수 있는 페이지가 자동 생성되지 않습니다.
external-controller: 127.0.0.1:9090
secret: "your-password"
external-ui: ./ui
클라이언트에 패널과 컨트롤 설정이 내장되어 있다면 클라이언트의 관리 기능을 우선 사용하세요. 로컬 오버라이드와 인터페이스 설정이 서로 충돌하는 상황을 피할 수 있습니다. 관리 인터페이스를 직접 테스트할 때는 신뢰할 수 있는 로컬 터미널에서 요청을 보내면 됩니다. 아래 명령은 비밀 키를 입력받아 변수에 넣으므로 실제 값을 명령 기록에 직접 남기지 않습니다. 사용 후에는 현재 터미널의 변수를 삭제합니다.
read -r -s -p "컨트롤 인터페이스 비밀 키: " MIHOMO_SECRET
printf '\n'
curl --fail --silent --show-error \
-H "Authorization: Bearer $MIHOMO_SECRET" \
http://127.0.0.1:9090/configs
unset MIHOMO_SECRET
이 명령은 Bash 환경용입니다. 다른 터미널에서는 해당 환경에서 제공하는 안전한 입력 방법을 사용하세요. 입력에 성공하면 현재 터미널에서 컨트롤 인터페이스까지 연결할 수 있다는 뜻일 뿐, 브라우저 패널도 같은 조건으로 사용할 수 있다는 의미는 아닙니다. 브라우저는 페이지 출처, 혼합 콘텐츠, 교차 출처 정책, 네트워크 주소의 영향을 받습니다. 인터페이스 연결과 페이지 접속 문제는 따로 점검하세요.
원격 접속 전에 주소가 가리키는 대상을 확인하세요
패널 페이지의 127.0.0.1은 코어를 실행하는 원격 서버가 아니라 브라우저를 연 기기를 가리킵니다. 다른 컴퓨터에서 패널에 접속하면서 루프백 주소를 입력하면 브라우저는 자기 기기에 연결하려고 합니다. 원격 관리는 제어된 암호화 터널이나 인증 및 접근 제한이 적용된 리버스 프록시를 사용하는 편이 안전합니다. 이때도 코어 컨트롤 인터페이스는 로컬 수신 상태로 유지하세요.
리버스 프록시를 사용하는 경우 일반 HTTP 요청과 WebSocket 연결을 모두 확인하세요. 연결 목록이나 로그가 지속적인 통신에 의존할 수 있습니다. 페이지는 열리지만 상태가 갱신되지 않는다면 프록시가 업그레이드 헤더를 전달하지 않거나, 인증이 일치하지 않거나, 브라우저가 연결을 차단했을 수 있습니다. 교차 출처 허용 범위는 실제로 필요한 페이지 출처로 제한하세요. 오류를 없애려고 제한을 무조건 넓히지 마세요.
패널 정적 파일도 유지 관리 대상입니다. 업데이트 출처를 확인하고 업그레이드 전에 현재 작동하는 파일과 설정을 저장하세요. 업그레이드 후에는 로그인, 프록시 정책 전환, 로그 연결을 테스트해야 합니다. 컨트롤 인터페이스는 작동하는데 새 패널에 문제가 생겼다면 전체 코어 설정을 바로 바꾸지 말고 패널 파일부터 이전 버전으로 되돌리세요. 클라이언트 내장 패널은 클라이언트의 업데이트 방식에 따라 관리해 수동 교체로 경로가 충돌하지 않도록 하세요.
변경 사항을 검증 가능한 기록으로 남기세요
설정을 마친 뒤 간단한 기록을 남기세요. 어떤 항목을 바꿨는지, 무엇이 달라질 것으로 예상했는지, 어떤 새 연결로 검증했는지, 실패하면 어떤 파일을 되돌릴지 적어두면 됩니다. 프록시 그룹은 최종 아웃바운드, 규칙 세트는 매칭 순서, DNS는 조회 경로, TUN은 진입 경로와 라우팅, 패널은 인증과 접근 범위를 검증하세요. 출처를 모르는 설정 스크린샷을 많이 저장하는 것보다 이런 기록이 장기적인 유지 관리에 더 도움이 됩니다.
문제가 발생하면 같은 순서로 점검하세요. 먼저 설정이 로드되었는지, 다음으로 트래픽이 들어오는지 확인하고, 이후 DNS 조회, 규칙, 아웃바운드를 살펴보세요. 패널에 접속할 수 없다고 바로 노드 문제라고 판단하지 말고, 웹페이지가 열리지 않는다고 컨트롤 인터페이스부터 바꾸지도 마세요. 증상별 해결 방법은 도움말 센터에서 확인할 수 있습니다. 클라이언트를 바꾸려면 다운로드 페이지에서 플랫폼별 설치 경로를 확인하세요. 각 계층의 역할을 명확히 하고 모든 변경 사항을 설명하고 검증하고 되돌릴 수 있도록 유지하는 것이 중요합니다.