1. YAML 구조와 설정 진입점

먼저 세 가지를 구분해야 합니다. 구독 링크는 설정을 가져오는 주소이고, Profile은 클라이언트가 관리하는 설정 항목이며, 코어가 실제로 읽는 것은 적용된 설정입니다. 원격 Profile은 클라이언트 설정이나 오버라이드, 스크립트를 거치는 경우가 많습니다. 따라서 구독 원본에 필드가 있어도 코어가 같은 값을 사용한다고 볼 수는 없습니다. 문제를 확인할 때는 구독 파일을 계속 수정하기보다 클라이언트의 실행 설정 미리보기를 확인한 다음 필드의 출처를 추적하는 편이 효과적입니다.

최상위 구조에서 참조 관계 살펴보기

아래는 설정 로딩 과정을 확인할 수 있는 직접 연결 기준 설정입니다. mixed-port와 모드, 비어 있는 노드 목록, 수동 정책 그룹, 기본 규칙으로 구성되어 있으며 모든 요청은 직접 연결됩니다. 원격 프록시 기능은 제공하지 않습니다. 먼저 이 설정이 정상적으로 로드되는지 확인한 뒤 서비스 제공업체가 준 노드를 하나씩 추가하세요. 구조 오류와 원격 연결 오류를 분리할 수 있어 처음부터 여러 변수를 동시에 다루는 일을 피할 수 있습니다.

mixed-port: 7890
allow-lan: false
mode: rule
log-level: info
ipv6: false

proxies: []

proxy-groups:
  - name: "출구 선택"
    type: select
    proxies:
      - DIRECT

rules:
  - MATCH,출구 선택

proxies는 원격 연결 정보를 정의하고, proxy-groups는 노드나 다른 그룹을 선택 대상으로 묶으며, rules는 요청을 어느 대상으로 보낼지 결정합니다. 규칙은 파일에서 노드가 놓인 순서가 아니라 이름을 참조합니다. 이름은 공백, 대소문자, 전각 문장부호까지 정확히 일치해야 합니다. 읽기 편하게 노드, 그룹, 규칙 순으로 작성하는 것이 좋지만, YAML 최상위 필드가 반드시 그 순서여야 한다는 뜻은 아닙니다.

들여쓰기, 목록, 문자열의 기본 규칙

YAML은 들여쓰기로 항목 간 관계를 나타냅니다. 공백 두 칸을 일관되게 사용하고 탭은 쓰지 마세요. 같은 단계의 필드는 줄을 맞춰야 합니다. 목록 항목은 하이픈과 공백으로 시작하고, 항목 안의 속성은 한 단계 더 들여씁니다. 콜론 뒤에는 보통 공백을 넣어 키와 값을 구분합니다. 노드 이름이나 비밀번호, 콜론 또는 샵이 포함된 문자열은 따옴표로 감싸는 편이 안전합니다. 특히 숫자로만 된 비밀번호는 문자열로 지정해야 파서가 숫자로 처리하지 않습니다.

따옴표 밖의 샵은 보통 주석을 시작합니다. 특수 문자가 든 비밀번호를 따옴표 없이 붙여 넣으면 뒤쪽이 주석으로 처리될 수 있습니다. 파일은 파싱되더라도 연결 인증은 실패할 수 있습니다. 불리언 값은 true와 false로, 포트는 정수로, 빈 목록은 []로 작성하세요. 화면에서 복사한 중국어 콜론은 설정에 넣지 마세요. 비슷하게 보여도 YAML의 키·값 구분자로 작동하지 않습니다.

형식작성 예확인할 점
매핑mode: rule키와 콜론 뒤의 공백
목록- MATCH,DIRECT하이픈 뒤에 공백 입력
문자열name: "출구 선택"따옴표 짝과 이름 일치 여부
불리언allow-lan: false따옴표로 감싼 문자열로 쓰지 않기

단일 파일과 여러 설정 항목

여러 Profile은 일반적으로 서로 전환해서 사용하는 항목이며 자동으로 합쳐지지 않습니다. 현재 선택된 Profile이 주된 설정 출처가 됩니다. 전역 오버라이드가 계속 적용되는지는 클라이언트의 적용 범위 설정에 따라 다릅니다. 완성된 구독 설정 두 개를 그대로 이어 붙이면 최상위 키가 중복되거나 같은 이름의 노드가 덮어써질 수 있습니다. 여러 출처를 조합하려면 프록시 컬렉션이나 클라이언트의 병합 기능을 명시적으로 사용하세요. 중복 필드의 파싱 결과에 기대서는 안 됩니다.

원격 설정을 업데이트하면 수동으로 수정한 원본이 다시 다운로드된 내용으로 바뀔 수 있습니다. 개인 규칙을 계속 유지하려면 별도 오버라이드에 넣고, 잠깐 시험할 설정은 로컬 Profile로 복사해 알아보기 쉬운 이름을 붙이세요. 항목을 가져오거나 삭제하고 전환하는 방법은 Profile 및 여러 설정 관리 방법을 참고하세요. 이후 설명은 최종 설정에 명확한 구조가 하나만 남는다는 전제로 진행합니다.

2. 포트, 모드 및 실행 필드

공통 필드는 클라이언트가 요청을 받는 위치, 프록시 모드, 로그 상세도를 결정합니다. 수정하기 전에 요청이 어디서 들어오는지 확인하세요. 브라우저가 시스템 프록시를 사용하는지, 명령줄에서 프록시를 따로 지정하는지, 아니면 TUN이 기기 전체 트래픽을 처리하는지 살펴봐야 합니다. 세 가지 진입 방식은 함께 사용할 수 있지만 같은 스위치는 아닙니다. 포트가 열려 있다는 것은 코어가 요청을 받을 준비가 됐다는 뜻일 뿐입니다. 앱에서 요청을 해당 포트로 보내지 않으면 프록시 연결은 만들어지지 않습니다.

port, socks-port, mixed-port

port는 HTTP 프록시 진입점, socks-port는 SOCKS 진입점을 제공하고, mixed-port는 한 포트에서 두 종류의 연결을 모두 받습니다. 일반적인 데스크톱 사용에는 mixed-port만으로 충분한 경우가 많습니다. 설정을 빠짐없이 채우려고 모든 진입점을 열 필요는 없습니다. 포트 번호는 고정된 값이 아니므로 변경할 수 있지만, 클라이언트의 시스템 프록시 설정과 브라우저 확장 프로그램, 명령줄 환경 변수도 함께 바꿔야 합니다.

mixed-port: 7890
allow-lan: false
bind-address: "127.0.0.1"
mode: rule
log-level: info
ipv6: false

profile:
  store-selected: true

이 예제는 로컬 기기의 요청만 받습니다. 같은 LAN의 다른 기기에서 연결해야 한다면 allow-lan, 수신 주소, 시스템 방화벽을 함께 확인하세요. 스위치만 켜면 되는 문제가 아닙니다. 모든 네트워크 인터페이스에서 수신하도록 설정하면 접근 범위가 넓어지므로 신뢰할 수 없는 네트워크에 그대로 노출해서는 안 됩니다. 임시 공유가 끝나면 로컬 수신으로 되돌리고, 라우터에 포트 포워딩이 설정되어 있는지 확인하세요. 불필요한 포워딩은 함께 해제해야 합니다.

필드기능주요 확인 방법
mixed-portHTTP와 SOCKS 혼합 진입점앱이 사용하는 프록시 포트 확인
allow-lanLAN에서 프록시 진입점에 접근 허용수신 주소와 방화벽 함께 확인
mode규칙·전역·직접 연결 모드 선택실행 화면에서 현재 모드 확인
log-level로그 상세도 조절문제 해결 중에는 debug, 완료 후 원래 설정으로 복구

모드는 트래픽을 분기할 뿐 시스템 프록시를 켜지 않음

rule은 규칙에 따라 연결 경로를 정하고, global은 일반 요청에 전역 정책을 적용하며, direct는 일반 요청을 직접 연결합니다. 여기서 전역 모드라고 해서 기기의 모든 앱이 자동으로 처리되는 것은 아닙니다. 코어에 들어오지 않은 트래픽은 제어할 수 없습니다. 평소에는 규칙 모드를 사용하세요. 특정 사이트의 문제를 확인할 때는 잠시 전역 모드로 바꿔 분기 설정이 원인인지 비교할 수 있습니다. 확인이 끝나면 규칙 모드로 되돌려 직접 연결해야 할 요청까지 원격으로 보내지 않도록 하세요.

profile.store-selected는 재시작 후에도 정책 그룹의 선택 상태를 복원하기 위한 설정입니다. YAML 전체 수정 내용을 저장하는 기능은 아닙니다. 그룹 이름이 바뀌거나 노드가 삭제되고 캐시가 초기화되면 복원 결과도 달라질 수 있습니다. 구독을 바꾼 뒤 선택 항목이 예상과 다르면 마지막으로 누른 기록만 보지 말고 정책 그룹의 현재 구성원을 확인하세요. 세 가지 모드의 사용 방법은 규칙·전역·직접 연결 모드 안내를 참고하세요.

TUN은 별도의 트래픽 진입 방식

TUN은 가상 네트워크 인터페이스와 라우팅을 통해 트래픽을 받으므로 시스템 프록시를 따르지 않는 프로그램에 적합합니다. 아래는 일반적인 구조 예시입니다. 활성화하기 전에 클라이언트에 필요한 서비스가 설치되어 있고 시스템 권한이 있는지 확인하세요. 데스크톱 클라이언트가 화면에서 관련 필드를 관리할 수 있습니다. 화면에서 TUN을 꺼 두었다면 원본 파일을 직접 수정해도 실행 상태가 바뀌지 않을 수 있습니다. 모바일은 보통 시스템 VPN 인터페이스를 사용하므로 데스크톱 서비스 설치 절차를 그대로 적용해서는 안 됩니다.

tun:
  enable: true
  stack: mixed
  auto-route: true
  auto-detect-interface: true
  dns-hijack:
    - any:53

stack은 프로토콜 스택 구현을 선택하는 항목입니다. 사용할 수 있는 값과 지원 여부는 현재 mihomo 코어를 기준으로 확인해야 하며, 스택 변경을 모든 네트워크 문제의 만능 해결책으로 여겨서는 안 됩니다. auto-route는 라우트를 만들고, auto-detect-interface는 출구 인터페이스를 자동으로 찾습니다. 여러 네트워크 어댑터나 다른 VPN, 가상 머신 네트워크가 판단에 영향을 줄 수 있습니다. DNS 하이재킹은 지정된 일반 DNS 요청을 처리할 뿐, 앱 내 암호화 DNS까지 모두 가로챈다는 뜻은 아닙니다.

3. DNS, fake-ip 및 이름 해석 경로

DNS는 도메인에서 IP 주소를 얻는 방식입니다. 프록시 설정에서는 규칙 판정과 노드 서버 주소 확인, 연결 경로에도 영향을 줍니다. 먼저 두 종류의 도메인을 구분하세요. 웹사이트에 접속할 때는 대상 도메인을 해석하고, 프록시 연결을 만들 때도 노드 서버의 도메인을 해석할 수 있습니다. 후자가 아직 연결되지 않은 프록시에 의존하면 순환 참조가 생깁니다. 모든 노드가 동시에 실패한다면 웹사이트 규칙을 바꾸기 전에 노드 서버의 도메인이 해석되는지 확인하세요.

먼저 단순하고 이해하기 쉬운 DNS 설정 구성

아래 예제는 fake-ip를 사용하고 상위 DNS와 노드 도메인용 해석기를 지정합니다. 로컬 DNS 서비스와 충돌하지 않도록 수신 포트는 설정하지 않았습니다. 시스템 요청이 코어의 DNS로 들어오는 방식은 클라이언트의 TUN 또는 DNS 통합 설정에서 확인해야 합니다. 예제의 공용 DNS 서버에 접속할 수 있는지는 현재 네트워크에 따라 다릅니다. 실제로 사용하기 전에 로컬 네트워크에서 연결 가능 여부를 시험하고 유지할지 결정하세요. DNS 서버 주소가 모든 지역에 적합한 고정 답이라고 가정해서는 안 됩니다.

dns:
  enable: true
  ipv6: false
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  fake-ip-filter:
    - "*.lan"
    - "*.local"
  default-nameserver:
    - 223.5.5.5
  proxy-server-nameserver:
    - 223.5.5.5
  nameserver:
    - https://dns.alidns.com/dns-query

default-nameserver는 DNS 상위 서버 자체의 도메인을 해석하며, 보통 부트스트랩 DNS라고 합니다. 단순한 예비 웹사이트 DNS를 뜻하는 것은 아닙니다. nameserver는 일반 쿼리에 사용하는 상위 서버입니다. proxy-server-nameserver는 프록시 서버 도메인을 해석해 프록시 연결에 필요한 해석 경로를 명확히 하는 항목입니다. 노드가 도메인을 사용하고 상위 서버가 해당 노드를 거쳐야 접속된다면, 이 단계에 순환 의존성이 있는지 먼저 확인하세요.

fake-ip는 가상 주소를 반환하며 노드 주소가 아님

fake-ip 모드에서는 먼저 앱에 가상 주소를 반환한 뒤 코어가 도메인 매핑을 저장하고 후속 연결을 처리할 수 있습니다. 198.18 대역의 주소가 보인다고 해서 웹사이트가 실제로 그 대역에 있거나 DNS 응답이 오염됐다고 볼 수는 없습니다. 중요한 것은 이후 연결이 같은 코어를 계속 거치는지, 매핑이 유효한지입니다. 앱이 코어를 우회해 가상 주소로 직접 연결하면 연결에 실패합니다. 따라서 fake-ip를 사용할 때는 트래픽이 완전히 가로채지고 있는지도 함께 확인해야 합니다.

fake-ip-filter는 실제 주소가 필요한 도메인을 가상 주소 응답에서 제외합니다. LAN 기기 검색이나 일부 게임, 특수 인증 프로그램은 별도 처리가 필요할 수 있지만 문제가 생길 때마다 모든 도메인을 제외하지는 마세요. 먼저 로그에서 정확한 도메인을 확인하고 범위를 최소화해 필터에 추가한 다음 관련 캐시를 지우고 다시 시도하세요. *.lan과 *.local은 예시일 뿐이며 실제 LAN 도메인을 확인하는 과정을 대신하지 않습니다.

필드해결하는 문제혼동하기 쉬운 점
default-nameserver상위 DNS 서버의 도메인 해석일반 요청의 유일한 출구가 아님
nameserver일반 도메인 쿼리 처리암호화 전송이 프록시 경유를 뜻하지 않음
proxy-server-nameserver노드 서버 도메인 해석아직 연결되지 않은 프록시에 의존하지 않도록 주의
nameserver-policy지정 도메인에 사용할 상위 서버 선택DNS 서버만 선택하며 트래픽 출구는 선택하지 않음

도메인 정책, 라우팅 정책, 캐시는 각각 따로 처리

내부 도메인만 사내 DNS를 사용해야 한다면 nameserver-policy로 해석기를 따로 지정할 수 있습니다. 하지만 사용할 DNS와 웹사이트 연결에 사용할 노드는 별개의 문제이며, 연결 경로는 규칙이 결정합니다. 암호화 DNS의 HTTPS 주소도 전송 방식만 나타낼 뿐, 쿼리가 프록시를 경유한다고 보장하지 않습니다. DNS가 규칙을 따르도록 하는 옵션을 켜기 전에는 노드 도메인과 상위 서버 자체의 해석 경로를 먼저 설정해 순환 의존성을 피하세요.

IPv6도 연결 경로를 단계별로 확인해야 합니다. 최상위 ipv6 설정, DNS의 AAAA 레코드 응답 여부, 노드의 목적지 주소 지원, 시스템에 사용 가능한 라우트가 있는지는 서로 관련은 있지만 같은 항목이 아닙니다. DNS 모드를 바꾼 뒤에도 운영체제, 브라우저, 앱이 이전 캐시를 사용할 수 있습니다. 관련 연결을 닫고 필요한 캐시를 지운 뒤 같은 도메인을 테스트하세요. 브라우저에 기존 연결이 열리는 것만으로 새 설정의 DNS 경로가 올바르다고 판단할 수는 없습니다.

4. 프록시 노드 필드와 프록시 컬렉션

프록시 노드는 원격 연결에 필요한 매개변수를 설명하며, 어떤 웹사이트가 해당 노드를 사용할지는 결정하지 않습니다. 일반적으로 이름, 프로토콜 유형, 서버 주소, 포트와 프로토콜에 따른 인증 및 전송 설정이 공통 필드입니다. 서비스 제공업체가 주는 URI, QR 코드, 구독에는 추가 매개변수가 포함될 수 있으므로 직접 작성할 때 주소와 비밀번호만 옮겨 적어서는 안 됩니다. 먼저 프로토콜을 확인하고 같은 프로토콜의 필드를 기준으로 대조하세요. 서로 다른 가이드의 매개변수를 한 노드 정의에 섞지 마세요.

공통 필드를 먼저 확인하고 프로토콜별 필드 살펴보기

다음은 Shadowsocks 설정 구조 예제입니다. 도메인과 비밀번호는 설명용 값이므로 실제 연결에는 사용할 수 없습니다. 서비스 제공업체의 실제 매개변수를 확인한 뒤 입력하세요. name은 로컬에서 참조하기 위한 이름이므로 알아보기 쉽게 바꿀 수 있습니다. server에는 해석 가능한 호스트 이름이나 올바른 IP 주소를 입력해야 하며 웹페이지 경로를 넣어서는 안 됩니다. port는 원격 서버의 포트이며 로컬 mixed-port와 다릅니다.

proxies:
  - name: "예시 SS"
    type: ss
    server: proxy.example.com
    port: 8388
    cipher: aes-128-gcm
    password: "your-password"
    udp: true

cipher는 서버 설정과 일치해야 합니다. 최신처럼 보이게 하려고 임의로 바꾸지 마세요. 암호화 방식에 따라 비밀번호 형식도 달라질 수 있습니다. udp: true는 노드가 해당 UDP 트래픽을 처리하도록 허용하지만, 실제 지원 여부는 프로토콜과 서버, 네트워크 경로에 따라 다릅니다. 브라우저는 되는데 게임이나 음성 통화가 실패한다면 이 필드를 반복해서 켜는 것만으로 해결되지 않습니다. 해당 트래픽이 코어로 들어오는지, 원격 서버가 UDP를 허용하는지 더 확인해야 합니다.

필드값을 확인할 곳오류 증상
name로컬에서 정의하고 이름을 고유하게 유지그룹에서 참조하지 못하거나 구분하기 어려움
type서비스 제공업체의 프로토콜 안내필드를 인식하지 못하거나 핸드셰이크 실패
server / port원격 연결 매개변수이름 해석 실패, 연결 거부 또는 시간 초과
인증 필드비밀번호, 사용자 식별자 등 프로토콜 매개변수인증 실패. 로컬 포트로 대체할 수 없음

TLS, SNI, 전송 매개변수는 서로 대체할 수 없음

TLS를 사용하는 프로토콜에서는 서버 주소와 TLS 검증 이름이 다를 수 있습니다. 예를 들어 Trojan의 sni는 TLS 이름 협상에 사용되며 일반적으로 서버 인증서 및 설정과 일치해야 합니다. 임의로 넣는 가속 도메인이 아니며 실제 연결 IP와 같지 않을 수도 있습니다. WebSocket 경로와 HTTP Host, 그 밖의 전송 매개변수는 별도 항목이므로 하나씩 맞춰야 합니다. SNI만 입력한다고 나머지 설정이 자동으로 채워지지는 않습니다.

proxies:
  - name: "예시 Trojan"
    type: trojan
    server: proxy.example.com
    port: 443
    password: "your-password"
    sni: proxy.example.com
    skip-cert-verify: false
    udp: true

인증서 오류가 나면 시스템 시간, SNI, 서버 인증서, 연결 대상을 먼저 확인하세요. 검증을 끄는 방식으로 장기간 해결하려고 하지 마세요. 중요한 신원 확인 절차를 우회하고 잘못 입력한 매개변수를 가릴 수 있습니다. 서비스 제공업체가 특수 인증서나 추가 공개 키 매개변수를 요구한다면 프로토콜 안내에 따라 설정하세요. 다른 프로토콜의 필드를 현재 노드에 그대로 넣지 마세요. 구버전 클라이언트는 YAML을 가져올 수 있더라도 새 코어의 모든 프로토콜을 지원하지 않을 수 있습니다. 필요하다면 설치 파일 페이지에서 적절한 클라이언트를 선택하세요.

proxy-providers는 노드, rule-providers는 규칙 관리

프록시 컬렉션을 사용하면 노드 출처를 별도로 관리할 수 있고, 정책 그룹은 use로 컬렉션 이름을 참조합니다. 아래는 구조를 이해하기 위한 로컬 파일 예제입니다. 상대 경로는 설정 작업 디렉터리를 기준으로 하며 다운로드 폴더를 기준으로 하지 않을 수 있습니다. 파일 안에는 포트와 규칙을 포함한 전체 설정이 아니라 proxies 목록이 있어야 합니다. HTTP 컬렉션에는 유효한 다운로드 주소, 업데이트 간격, 쓰기 가능한 캐시 경로도 필요합니다. 서비스 제공업체의 링크가 해당 컬렉션 형식과 호환되는지도 확인해야 합니다.

proxy-providers:
  로컬 노드:
    type: file
    path: ./providers/local.yaml

proxy-groups:
  - name: "구독 출구"
    type: select
    use:
      - 로컬 노드

원격 출처를 업데이트할 때는 계정 접근 정보가 포함될 수 있는 구독 주소를 안전하게 관리하세요. 설정을 공유하기 전에 전체 링크와 비밀번호를 삭제해야 합니다. 노드 이름만 가리는 것으로는 충분하지 않습니다. 컬렉션 로딩에 실패하면 경로와 형식을 먼저 확인하고, 다음으로 네트워크 다운로드를 살펴본 뒤 그룹 참조가 올바른지 확인하세요. 사용 가능한 구성원이 없으면 정책 그룹이 있어도 원하는 출구를 제공할 수 없습니다. 가져오기 성공 여부, 노드 존재 여부, 실제 연결 성공 여부를 각각 확인해야 합니다.

5. 정책 그룹 유형과 참조 관계

정책 그룹은 규칙과 노드 사이에 있으며, 설정에서 이름을 안정적으로 유지하기 좋은 계층입니다. 규칙은 계속 '프록시 출구'를 가리키고 그룹 내부의 노드는 구독 업데이트에 따라 바뀔 수 있습니다. 따라서 노드를 바꿀 때마다 규칙을 수정할 필요가 없습니다. 그룹이 새로운 프로토콜을 만드는 것은 아니며 UDP를 지원하지 않는 노드에 UDP 기능을 더하지도 않습니다. 후보 중 무엇을 선택할지, 언제 다시 선택할지를 정할 뿐입니다.

select는 수동 선택, 자동 그룹은 후보 결정

select는 수동 선택 그룹으로, 자동 그룹과 직접 연결, 고정 노드를 나란히 표시할 때 적합합니다. url-test는 후보를 주기적으로 시험하고 결과에 따라 선택하며, fallback은 설정한 순서에 따라 사용 가능한 후보를 선택하는 데 중점을 둡니다. 테스트는 지정한 주소에 대한 탐지 결과일 뿐 모든 웹사이트의 속도나 대역폭을 의미하지 않습니다. 그룹 유형을 선택하기 전에 고정된 선호를 원하는지, 테스트 결과에 따라 자동 조정되길 원하는지 먼저 결정하세요.

proxy-groups:
  - name: "프록시 출구"
    type: select
    proxies:
      - 자동 선택
      - DIRECT

  - name: "자동 선택"
    type: url-test
    use:
      - 로컬 노드
    url: https://www.gstatic.com/generate_204
    interval: 300
    tolerance: 50

rules:
  - MATCH,프록시 출구

여기서는 앞 장의 '로컬 노드' 컬렉션을 사용합니다. 이 부분만 따로 복사하려면 해당 정의부터 추가해야 합니다. interval은 초 단위로 테스트 간격을 지정하고, tolerance는 작은 차이로 인해 선택이 자주 바뀌는 것을 줄입니다. 탐지 주소는 안정적이고 실제 네트워크 환경에 적합해야 합니다. 특정 경로에서 해당 주소가 제한되면 테스트 결과가 왜곡될 수 있습니다. 예제에는 실제 탐지에 쓰이는 주소가 있지만, 배포 전에 현재 환경에서 접속 가능한지 확인하세요.

형식선택 방식적합한 사용 사례
select사용자가 구성원을 직접 선택공통 진입점, 고정된 서비스 출구
url-test탐지 결과에 따라 선택자동 조정을 허용하는 일반적인 웹 탐색
fallback순서대로 사용 가능한 구성원 선택주 회선·백업 회선 및 명확한 우선순위
load-balance정책에 따라 연결 분배세션 제약을 고려한 다중 출구 요구

부하 분산은 단일 연결의 대역폭을 합산하지 않음

load-balance는 여러 연결을 서로 다른 후보에 분배할 수 있지만, 일반적으로 하나의 다운로드 연결에 여러 노드의 대역폭을 합산하는 기능은 아닙니다. 로그인, 결제, 일부 장시간 연결 서비스처럼 출구 IP가 유지되어야 하는 작업도 있습니다. 특별한 요구가 없다면 수동 그룹이나 자동 선택 그룹을 사용하는 편이 연결 경로를 이해하기 쉽습니다. 분배 방식과 세션 제약을 이해한 뒤에 부하 분산을 고려하세요.

자동 그룹의 테스트가 성공해도 기존 연결이 새 노드로 즉시 옮겨가는 것은 아닙니다. 연결이 만들어진 뒤에는 보통 기존 출구가 유지되고 새 연결부터 변경된 그룹 선택을 따릅니다. 문제를 확인할 때는 연결 기록에서 실제 경로를 살펴본 뒤 요청을 새로 보내세요. 그룹 화면에서 현재 선택된 항목만 보고 모든 트래픽이 경로를 바꿨다고 판단해서는 안 됩니다. 코어를 재시작하면 연결을 정리할 수 있지만 기존 작업이 중단되므로 전환할 때마다 꼭 필요한 절차는 아닙니다.

안정적인 그룹 이름으로 구독 변경 분리

'프록시 출구'나 '업무용 연결'처럼 안정적인 이름의 서비스 그룹을 만들고 규칙은 이 이름을 참조하게 하세요. 그룹 내부에서 노드 컬렉션이나 자동 그룹을 연결하면 됩니다. 계층은 규칙→서비스 그룹→후보 그룹→노드 정도로 간단하게 유지하는 것이 좋습니다. 그룹끼리 순환 참조해도 이점이 없으며 설정 로딩에 실패할 수 있습니다. 예를 들어 A가 B를 포함하고 B가 다시 A를 포함한다면 한 방향으로만 연결하세요.

이름 충돌도 확인해야 합니다. 노드와 정책 그룹에 같은 이름을 쓰지 않는 편이 좋습니다. 실행 경로를 볼 때 구분하기 어려워집니다. 컬렉션 업데이트로 구성원 이름이 바뀌면 수동 선택 상태가 복원되지 않을 수 있습니다. 컬렉션 참조를 사용하면 고정된 노드 이름이 바뀌어 생기는 문제를 줄일 수 있지만 컬렉션에 유효한 구성원이 있는지는 여전히 확인해야 합니다. 정규식 필터는 간단한 표현식부터 적용하고 결과를 살펴본 뒤 범위를 좁히세요. 처음부터 조건을 지나치게 제한해 모든 후보가 걸러지지 않도록 합니다.

모바일 기기에서는 탐지 빈도도 고려해야 합니다. 여러 자동 그룹과 프록시 컬렉션에서 동시에 상태 확인을 하면 요청이 중복될 수 있습니다. 간격을 짧게 줄인다고 사용 경험이 반드시 안정되는 것은 아닙니다. 중복 테스트를 줄이고 실제 사용하는 후보만 남긴 뒤 백그라운드 동작을 비교하세요. 배터리 소모가 늘었다면 모바일 백그라운드 및 배터리 절약 문제 해결도 확인하세요. 배터리 잔량이 한 번 변한 것만으로 코어 오류라고 판단해서는 안 됩니다.

6. 규칙 순서, 문법 및 규칙 집합

규칙 모드는 위에서 아래로 순서대로 검사합니다. 일치하는 규칙을 찾으면 해당 정책으로 요청을 보내며, 뒤에 있는 '더 정확한' 규칙을 계속 찾지 않습니다. 따라서 예외 규칙은 앞에, 범위가 넓은 규칙은 뒤에 두고 마지막에 MATCH로 나머지 요청을 처리해야 합니다. 이름이 비슷한 규칙이라도 범위는 다를 수 있습니다. 특정 도메인과 그 하위 도메인, 문자열 일부를 각각 일치시키려면 서로 다른 규칙 유형을 선택해야 합니다.

도메인 규칙과 IP 주소 규칙 구분하기

DOMAIN은 정확한 도메인에 일치하고, DOMAIN-SUFFIX는 해당 도메인과 하위 도메인에 일치합니다. DOMAIN-KEYWORD는 키워드로 검색하므로 범위가 넓고 원치 않는 요청까지 일치할 수 있습니다. 특정 사이트의 경로를 지정하려면 정확한 도메인이나 접미사를 우선 사용하세요. 짧다는 이유만으로 키워드 규칙을 선택하지 마세요. 규칙에 프로토콜 접두어나 웹페이지 경로를 넣어서는 안 됩니다. 특정 URL의 페이지는 보통 도메인 규칙만으로 구분할 수 없습니다.

rules:
  - DOMAIN,internal.example.com,DIRECT
  - DOMAIN-SUFFIX,example.com,프록시 출구
  - 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
  - MATCH,프록시 출구

예제에서는 내부 사이트를 먼저 직접 연결하고, 나머지 example.com 요청은 프록시 그룹으로 보냅니다. 순서를 바꾸면 내부 사이트가 범위가 넓은 접미사 규칙에 먼저 일치합니다. IP-CIDR은 주소 대역에 사용하고, IPv6에는 해당하는 IP-CIDR6를 사용할 수 있습니다. no-resolve는 IP 규칙 판정을 위해 도메인 해석을 새로 요청하지 않도록 합니다. 전체 요청에 DNS가 필요 없다는 뜻은 아닙니다. 대상에 이미 주소가 있다면 IP 규칙으로 판정할 수 있습니다.

규칙 유형일치 대상사용 시 주의점
DOMAIN정확한 도메인범위가 명확한 예외 몇 개에 적합
DOMAIN-SUFFIX도메인 및 하위 도메인URL 경로를 넣지 않기
IP-CIDRIPv4 주소 대역DNS 해석 요청과 주소 일치 구분
RULE-SET외부 규칙 집합집합 이름과 파일 형식 확인
MATCH나머지 모든 요청보통 규칙 끝에 배치

규칙 집합의 behavior와 파일 내용이 일치해야 함

규칙 집합은 긴 도메인 목록을 별도로 관리할 때 유용합니다. domain은 도메인 목록, ipcidr은 주소 대역 목록, classical은 규칙 유형이 포함된 클래식 규칙 목록에 사용합니다. 전체 Clash 설정 파일을 규칙 집합으로 사용할 수 없으며 프록시 구독 주소를 규칙 집합 출처에 입력해서도 안 됩니다. 아래는 로컬 domain 집합 예제입니다. 주 설정은 트래픽의 목적지를 정하고 집합 파일은 일치 범위만 나열합니다.

# 주 설정의 일부
rule-providers:
  업무 도메인:
    type: file
    behavior: domain
    format: yaml
    path: ./rules/work.yaml

rules:
  - RULE-SET,업무 도메인,프록시 출구
  - MATCH,DIRECT
# ./rules/work.yaml
payload:
  - "example.com"
  - "+.example.org"

이 예제에서 example.com은 도메인을 정확하게 지정하고, +.example.org는 해당 도메인과 하위 도메인 범위를 나타냅니다. 클래식 규칙 집합에는 DOMAIN-SUFFIX,example.org처럼 유형이 포함된 항목을 쓸 수 있지만, 항목에 정책 대상을 다시 추가하지 마세요. 대상은 주 설정의 RULE-SET에서 지정합니다. HTTP 규칙 집합에는 업데이트 간격과 캐시 경로도 필요합니다. 처음 다운로드에 실패하면 사용 가능한 캐시가 있는지 확인하세요. 업데이트 실패가 모든 규칙의 중단을 뜻한다고 단정해서는 안 됩니다.

연결 기록에서 실제로 일치한 규칙 확인

규칙을 수정한 뒤 대상 요청을 새로 보내고 연결 화면에서 도메인, 일치한 규칙, 정책 경로를 확인하세요. 브라우저 페이지는 로그인, 이미지, API 등 여러 도메인에 동시에 요청할 수 있으므로 주소창의 주 도메인만 수정해서는 해결되지 않을 수 있습니다. 실제로 실패한 요청을 찾은 다음 범위가 가장 작은 규칙을 추가하세요. 범위가 넓은 키워드 규칙으로 모든 요청을 같은 출구에 보내지 마세요. 앱 내 암호화 DNS, 연결 재사용, IP 주소만으로 설정된 연결도 도메인 정보를 확인하기 어렵게 만들 수 있습니다.

프로세스 규칙은 데스크톱 앱을 분기할 때 쓸 수 있지만, 코어가 프로세스 정보를 가져올 수 있어야 합니다. 시스템별 권한과 트래픽 진입 방식에 따라 동작도 달라질 수 있으므로 사용하는 플랫폼에서 먼저 검증하세요. 프로세스 이름을 모든 플랫폼에 통용되는 식별자로 간주하지 마세요. GEOIP나 지리 정보 분류 규칙은 관련 데이터 파일과 업데이트 상태에도 영향을 받습니다. 먼저 명확한 도메인 규칙 몇 개로 분기 경로가 정상인지 확인한 뒤 범위가 큰 규칙 집합을 추가하면 문제를 더 쉽게 찾을 수 있습니다.

7. 오버라이드, 병합 및 구독 업데이트

오버라이드는 원격 구독과 개인 설정을 분리하기 위한 기능이지, 거의 같은 내용을 담은 대형 파일을 하나 더 관리하기 위한 기능이 아닙니다. 일반적인 사용 사례로는 로컬 포트 고정, 내부 사이트 예외 추가, 안정적인 정책 그룹 생성, DNS 설정 변경이 있습니다. 클라이언트마다 오버라이드 형식과 실행 순서가 다르므로 화면에서 제공하는 기능이 필드 대체, 재귀 병합, 규칙 앞에 추가, 스크립트 처리 중 무엇인지 먼저 확인하세요. 한 클라이언트의 제어용 키를 mihomo 기본 필드로 착각해서는 안 됩니다.

수정할 출처와 적용할 설정 범위부터 확인

일반적으로 원격 콘텐츠를 가져온 뒤 클라이언트 변환이나 확장을 적용하고, 개인 오버라이드를 실행한 다음 코어에 전달하는 흐름으로 이해할 수 있습니다. 전역 설정이나 실행 중 수정이 더해질 수도 있으므로 실제 적용 설정은 클라이언트에서 확인해야 합니다. 특정 구독 한 개에만 필요한 예외는 해당 Profile에 연결하고 모든 설정에 필요한 로컬 항목만 전역 범위로 설정하세요. 범위를 지나치게 넓히면 다른 구독에서 존재하지 않는 그룹을 참조할 수 있습니다.

오버라이드를 추가하기 전에 원본 설정을 복사하고 현재 모드, 그룹 선택, 재현 가능한 테스트 대상을 기록하세요. 그다음 DNS 고정처럼 한 종류의 필드만 수정합니다. 노드와 규칙을 동시에 바꾸지 마세요. 로딩에 성공하면 원본과 최종 설정을 비교해 값이 예상대로 바뀌었는지, 기존 목록이 남았는지, 대상 그룹이 삭제되지 않았는지 확인하세요. '저장 성공'만 보고 변경 사항을 한꺼번에 적용하는 것보다 결과를 확인한 뒤 다음 작업을 진행하는 편이 안전합니다.

스칼라 덮어쓰기와 목록 병합은 다름

mode 같은 스칼라는 나중에 지정한 값이 앞선 값을 덮어쓰는 경우가 많습니다. dns 같은 매핑은 재귀 병합되거나 전체 교체될 수 있고, rules 같은 목록은 통째로 바뀌기 쉽습니다. 클라이언트 두 곳에서 모두 '병합'이라고 부르는 기능이라도 동작이 같다고 볼 수 없습니다. 아래는 의미상 변경 전후를 비교한 예제로 모든 클라이언트에서 그대로 사용할 수 있는 오버라이드 문법은 아닙니다.

구독 원본 규칙

rules:
  - DOMAIN-SUFFIX,example.org,프록시 출구
  - MATCH,프록시 출구

원하는 최종 규칙

rules:
  - DOMAIN,intranet.example.com,DIRECT
  - DOMAIN-SUFFIX,example.org,프록시 출구
  - MATCH,프록시 출구

여기서는 예외 규칙 하나를 앞에 추가하면서 기존 규칙을 보존하려고 합니다. 클라이언트가 목록 교체만 지원한다면 완성된 결과 전체를 명시적으로 작성해야 합니다. 규칙을 앞에 추가하는 기능이 있다면 그 기능을 사용하는 것이 적절합니다. 파일 끝에 rules 키를 하나 더 쓴다고 규칙이 자동으로 앞에 추가되지는 않습니다. YAML 앵커를 이용해 파일 간 목록을 연결하려고 하지 마세요. 앵커는 주로 같은 문서 안에서 참조할 때 쓰며 클라이언트의 병합 기능을 대신하지 않습니다.

수정 대상확인할 동작확인 결과
포트, 모드클라이언트 화면에서 다시 관리하는지최종 값과 실행 상태가 일치
DNS 매핑재귀 병합인지 전체 교체인지필수 DNS 서버 필드가 남아 있음
규칙 목록앞에 추가, 뒤에 추가, 전체 교체 중 어떤 방식인지예외는 앞에, 기본 규칙은 뒤에
정책 그룹 목록이름 기준으로 병합하는지 새로 만드는지참조 대상이 유효하고 구성원이 빠지지 않음

동일한 그룹 이름과 동적 노드를 함께 고려

구독의 그룹 이름은 바뀔 수 있습니다. 개인 규칙이 서비스 제공업체의 그룹 이름을 오랫동안 참조하면 업데이트 뒤 대상을 찾지 못할 수 있습니다. 이름이 안정적인 서비스 그룹을 직접 만들고 프록시 컬렉션을 참조하도록 설정하거나, 클라이언트가 명시적으로 지원하는 스크립트에서 조건에 따라 구성원을 만들 수 있습니다. 스크립트는 노드 목록이 비어 있는 상황과 이름 충돌을 처리해야 합니다. 매번 같은 노드가 내려온다고 가정해서는 안 되며 후보를 찾지 못했을 때 확인하지 않은 출구를 조용히 선택해서도 안 됩니다.

개인 오버라이드에는 서비스 제공업체의 인증 정보를 되도록 중복 저장하지 마세요. 구독 비밀번호가 바뀌어도 두 곳을 수정할 필요가 없습니다. 수동 노드와 구독 노드를 함께 사용해야 한다면 이름을 다르게 지정하고 출처를 표시하세요. 병합에 실패하면 개인 확장을 먼저 비활성화해 원래 구독이 로드되는지 확인한 뒤 하나씩 다시 활성화하세요. 원본 구독이 이미 손상됐다면 먼저 출처 문제를 해결해야 합니다. 최상위 구조에 관한 자세한 설명은 config.yaml 단계별 설명을 참고하세요.

8. 설정 검증, 문제 확인 및 복구

검증은 세 단계로 나뉩니다. 파일 파싱, 코어의 설정 수락, 요청의 예상대로 동작 여부입니다. YAML 문법이 올바른 것은 첫 단계만 통과했다는 뜻입니다. 지원되지 않는 필드, 없는 그룹 이름, 잘못된 규칙 집합 형식이 있으면 코어가 설정을 거부할 수 있습니다. 코어가 시작됐더라도 모든 원격 서버에 연결할 수 있다는 보장은 없습니다. 이 세 단계를 순서대로 확인하면 시작 오류와 네트워크 오류를 구분할 수 있고 클라이언트를 무의미하게 재설치하는 일도 줄어듭니다.

정적 검사 후 실행 경로 테스트

mihomo 명령줄 코어가 설치되어 있다면 설정 파일이 있는 디렉터리에서 테스트 명령을 실행할 수 있습니다. Windows에서는 해당 운영체제의 실행 파일 이름을 사용하고, 다른 시스템에서는 실제 설치 경로에 맞춰 실행하세요. 아래 예제는 현재 디렉터리에 실행 파일과 config.yaml이 있다고 가정합니다. 이 명령은 설정을 검사하지만 서비스 계정이 유효한지, 모든 원격 리소스를 다운로드할 수 있는지, 각 업무 규칙이 예상대로 작동하는지는 확인하지 않습니다. 데스크톱 클라이언트 사용자는 화면에서 제공하는 설정 검사 기능을 이용할 수도 있습니다.

# Linux / macOS: 테스트 디렉터리에서 실행
./mihomo -t -d . -f ./config.yaml

# Windows PowerShell: 테스트 디렉터리에서 실행
.\mihomo.exe -t -d . -f .\config.yaml

상대 경로 문제는 작업 디렉터리를 명확하게 지정해 해결하는 것이 우선입니다. -d .은 현재 디렉터리를 설정 작업 디렉터리로 지정합니다. 규칙 집합과 프록시 컬렉션에서 참조하는 파일도 해당 위치에 있어야 합니다. 테스트를 통과시키려고 실행 중인 클라이언트의 데이터 디렉터리를 임의로 옮기지 마세요. 별도 테스트를 할 때 필요한 파일을 전용 디렉터리에 복사하면 경로를 쉽게 확인할 수 있고 주 설정이나 캐시에 영향을 주지 않습니다.

증상우선 확인할 항목다음 단계
줄 번호 표시 또는 파싱 실패들여쓰기, 따옴표, 콜론 및 중복 키오류가 난 줄과 직전 부분 확인
프록시 또는 그룹을 찾을 수 없음이름과 컬렉션 참조최종 설정에 실제 정의가 있는지 확인
포트에서 수신할 수 없음포트 충돌, 주소 및 권한충돌 프로그램을 종료하거나 진입 포트를 함께 변경
연결 시간 초과 또는 핸드셰이크 실패DNS, 원격 주소, 프로토콜 매개변수이름 해석과 연결을 나눠 테스트
일부 웹사이트만 실패일치한 규칙, 실제 출구 및 관련 도메인직접 연결 경로와 프록시 경로 비교

재현 가능한 요청 하나를 기준으로 로그 확인

상세 로그가 필요하면 log-level을 잠시 debug로 설정하고 관련 없는 앱을 닫은 다음 대상 하나에 접속하세요. 먼저 요청이 코어에 들어오는지 확인한 뒤 일치한 규칙과 정책 경로를 살펴보고 마지막으로 연결 단계의 오류를 확인합니다. 요청 기록이 전혀 없다면 시스템 프록시, 앱의 프록시 설정, TUN 처리 문제가 원인일 수 있습니다. 원격 노드를 먼저 수정해서는 안 됩니다. 올바른 정책 경로가 확인되면 DNS, 인증, TLS를 점검하세요.

오류 로그를 모두 같은 문제로 취급하지 마세요. 규칙 집합의 백그라운드 업데이트가 실패해도 기존 캐시로 웹페이지가 정상적으로 열릴 수 있습니다. 테스트 주소 하나의 실패가 모든 요청의 실패를 의미하지도 않습니다. 로그를 공유할 때 오류 전후의 맥락과 시간 순서를 남기되 구독 링크, 인증 정보, 공개하고 싶지 않은 도메인은 삭제하세요. '시간 초과'라는 한 줄만으로는 DNS, 연결, 핸드셰이크 중 어느 단계에서 실패했는지 판단하기 어렵습니다.

감이 아니라 비교 테스트로 수정 결과 확인

HTTP 프록시를 명시적으로 지정해 포트 진입점을 테스트할 수 있습니다. 아래 명령은 요청이 로컬 mixed-port를 통해 전송되는지만 확인합니다. 시스템 전체가 프록시를 사용한다는 뜻도 아니며 UDP를 자동으로 테스트하지도 않습니다. 명령을 실행하기 전에 코어가 해당 포트에서 수신 중인지 확인하세요. 연결이 거부되면 구독을 바꾸기보다 로컬 서비스와 포트를 먼저 살펴보세요. 테스트 대상은 현재 네트워크에서 결과를 예상할 수 있는 사이트를 선택해야 합니다.

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

그다음 직접 연결해야 하는 대상과 프록시를 사용해야 하는 대상을 각각 방문하고 연결 화면에서 결과를 확인하세요. 규칙을 바꿨다면 새 연결을 만들어야 하고, DNS를 수정했다면 이전 캐시를 고려해야 합니다. 정책 그룹을 전환한 뒤에는 실제 연결 경로를 확인하세요. 매번 '무엇을 바꿨는지, 무엇을 테스트했는지, 어떤 결과가 나왔는지' 기록하고 효과를 설명할 수 있는 변경만 유지하세요. 문제가 계속된다면 노드 시간 초과 문제 해결 순서로 범위를 좁히거나 도움말 센터에서 관련 증상을 찾아보세요.

설정 복구와 이후 관리

복구할 때는 먼저 새로 추가한 오버라이드를 비활성화하고 검증된 Profile로 전환하세요. 그래도 문제가 남으면 시스템 프록시와 TUN에 서로 맞지 않는 진입 설정이 남아 있는지 확인합니다. 비교 자료를 잃지 않도록 모든 설정, 캐시, 로그를 한꺼번에 삭제하지 마세요. 클라이언트는 먼저 Clash Plus를 검토한 뒤 시스템과 기능 요구에 맞춰 다른 제품을 비교할 수 있습니다. 설치 경로는 모두 클라이언트 다운로드 페이지에서 확인하세요. 구버전 클라이언트에서 필드를 지원하지 않는다면 들여쓰기를 계속 바꾸기보다 코어 지원 여부를 먼저 확인하세요.

설정이 안정되면 디버그 로그를 평소 수준으로 되돌리고 효과가 없는 테스트 항목을 제거한 뒤 간단한 변경 기록을 남기세요. 백업에는 개인 오버라이드와 필요한 로컬 컬렉션 파일도 포함해야 합니다. 구독 링크만 보관해서는 개인 규칙 전체를 복원할 수 없습니다. 이후 업데이트할 때마다 고정된 사용 사례 몇 가지를 확인하면 규칙 순서, 그룹 구성원, DNS 경로가 바뀌었는지 빠르게 알아낼 수 있습니다. 연결 절차를 다시 처음부터 확인하려면 빠른 시작 가이드를 참고하고, 이 페이지는 필드 확인용으로 활용하세요.