config.yaml / reference

Clash 전체 설정 가이드

항목의 의미부터 섹션 간 참조 관계와 최종 적용 설정까지, 궁금한 부분을 찾아 확인하세요.

이 페이지는 설정을 수정하거나 구독 내용을 확인하고 트래픽 분기 문제를 해결하려는 사용자를 위해 mihomo 커널에서 자주 쓰이는 항목을 중심으로 안내합니다. 클라이언트에 따라 포트, DNS, TUN 설정을 자체적으로 관리하거나 화면의 옵션이 파일 내용을 덮어쓸 수 있습니다. 예제를 참고할 때는 커널의 지원 범위와 클라이언트가 생성한 실행 설정을 함께 확인하세요. 처음 사용한다면 먼저 빠른 시작 가이드에 따라 설정을 가져오고 활성화한 다음 연결을 확인한 뒤, 이 페이지에서 필요한 항목을 찾아보세요. 설치는 클라이언트 다운로드에서 확인할 수 있으며, 일반적인 그래픽 인터페이스를 찾는다면 Clash Plus도 살펴보세요.

1. YAML 구조와 설정 간 참조

설정 파일은 먼저 YAML 문서이며, 그다음에야 Clash가 이해하는 네트워크 설정입니다. 파서가 계층 구조와 목록, 데이터 유형을 올바르게 읽어야 커널이 항목을 검사할 수 있습니다. 편집기에서 파일이 열린다고 해서 구조가 올바른 것은 아닙니다. 주석에는 한글을 써도 대체로 문제가 없지만, 키와 값을 구분하는 콜론, 따옴표, 목록 앞의 하이픈은 반각 문자를 사용해야 합니다. 파일은 UTF-8로 저장하고 편집기에서 공백 문자를 표시해, 겉보기에는 정렬된 것처럼 보여도 실제로는 탭이 섞여 있는 상황을 피하세요.

최상위 항목, 맵과 목록

같은 계층의 키는 같은 열에 맞춰야 합니다. dns는 맵이며 하위 항목은 들여쓰기해서 씁니다. proxies, proxy-groups, rules는 보통 목록이며 각 항목 앞에 하이픈을 붙입니다. 아래 설정은 로컬에서 구조를 검증할 때 출발점으로 사용할 수 있습니다. 루프백 주소에서만 수신하고, 정책 그룹에는 직접 연결 옵션만 두며, 모든 트래픽을 최종적으로 직접 연결합니다. 참조 관계를 설명하기 위한 예제일 뿐, 연결 가능한 원격 프록시는 포함하지 않습니다.

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

dns:
  enable: false

proxies: []

proxy-groups:
  - name: Proxy
    type: select
    proxies:
      - DIRECT

rules:
  - MATCH,Proxy

여기서 Proxy는 예약 키워드가 아니라 정책 그룹 이름입니다. 마지막 규칙에서 이 이름을 참조하므로 대소문자, 공백, 문장 부호까지 완전히 일치해야 합니다. DIRECT는 대상에 직접 연결하는 내장 정책입니다. 설정을 읽을 때는 참조를 거꾸로 따라가 보세요. 규칙이 어떤 그룹을 가리키는지, 그룹에 어떤 노드가 포함되는지, 그 노드가 실제로 정의되어 있는지 확인해야 합니다. 어느 한 곳이라도 빠지면 로드 오류가 발생하거나 예상과 다른 경로로 연결될 수 있습니다.

들여쓰기뿐 아니라 데이터 유형도 확인하세요

가독성을 위해 공백 두 칸을 통일해 사용하는 것이 좋지만, YAML의 핵심은 같은 계층의 들여쓰기를 일관되게 맞추는 것입니다. 모든 위치에서 반드시 두 칸만 써야 하는 것은 아닙니다. 포트는 정수로, 스위치는 true 또는 false로, 이름과 비밀번호는 문자열로 작성합니다. 비밀번호에 콜론, 샵 또는 특수 문자가 포함되면 따옴표로 묶으세요. 큰따옴표 안의 백슬래시는 이스케이프 문자로 처리되므로 주의해야 합니다. 일반 문자를 그대로 보존하려면 작은따옴표가 적합하며, 문자열에 작은따옴표가 포함된 경우에는 작은따옴표를 두 번 써서 나타냅니다.

주석은 YAML 문법상 유효한 위치의 샵부터 시작합니다. 비밀번호 일부가 주석으로 잘못 해석되지 않도록 주의하세요. 같은 맵에 dns 또는 rules를 중복 정의하지 마세요. 일부 파서가 중복 키를 허용하더라도 나중 값만 남을 수 있습니다. 빈 목록 []과 빈 맵 {}은 서로 다릅니다. 전자는 항목이 없음을, 후자는 키와 값이 없음을 뜻합니다. 필요한 구조는 각 항목의 정의를 따르세요.

원본 설정과 실행 설정 구분하기

그래픽 클라이언트는 구독, 전역 설정, 덮어쓰기 조각을 합쳐 실행 설정을 만드는 경우가 많습니다. 따라서 구독 파일에 있는 mixed-port가 현재 수신 포트와 다를 수 있고, 다운로드 캐시 파일을 편집해도 변경 내용이 유지되지 않을 수 있습니다. 수정 전에 세 위치를 구분하세요. 구독 원문, 클라이언트에 저장된 사용자 설정, 커널이 실제로 읽는 파일입니다. 파일 경로는 클라이언트마다 다르므로 다른 클라이언트의 경로를 추측하지 말고 설정 상세 정보, 실행 정보 또는 로그에서 확인하세요.

유지보수할 때는 한 번에 한 가지 주제만 수정하는 것이 좋습니다. 먼저 수신 설정을 바꾸고, 다음에 DNS를 처리한 뒤, 마지막으로 규칙을 변경하세요. 항목별로 수정할 때마다 검증하면 오류 원인을 제한된 변경 사항에서 찾기 쉽습니다. 파일의 각 부분을 어떤 순서로 읽어야 하는지 더 알고 싶다면 config.yaml 항목별 분석을 참고하세요. 이 페이지의 다음 장에서는 각 항목의 범위를 따로 살펴보므로 모든 기능을 정해진 순서대로 한꺼번에 활성화할 필요는 없습니다.

2. 포트, 모드와 접근 범위

공통 설정 항목은 클라이언트가 어디에서 연결을 수신할지, 연결을 어떻게 처리할지, 어떤 기기에서 해당 진입점을 사용할 수 있을지를 결정합니다. 문제를 해결할 때는 ‘앱이 요청을 커널로 전달하는가’와 ‘커널이 출구를 어떻게 선택하는가’를 나눠서 살펴보세요. 규칙 모드를 켜도 커널에 들어온 요청만 처리되며, 모든 앱이 자동으로 프록시를 사용하는 것은 아닙니다. 시스템 프록시, 앱 자체 프록시, TUN은 서로 다른 연결 방식이므로 mode 항목만으로 서로 대체할 수 없습니다.

포트 항목별 역할

항목기능확인할 점
mixed-port하나의 포트에서 HTTP와 SOCKS 프록시 연결을 모두 수신앱에서 해당 프로토콜을 지정해야 함
portHTTP 프록시 수신 포트원격 노드 포트가 아님
socks-portSOCKS 프록시 수신 포트UDP 사용 가능 여부는 연결 경로에도 좌우됨
allow-lanLAN에서 들어오는 연결 허용 여부바인딩 주소와 방화벽도 함께 확인
external-controller관리 API의 수신 주소앱의 인터넷 연결에 사용하는 프록시 진입점이 아님

일반적인 데스크톱 사용이라면 mixed-port 하나만 설정하는 것이 명확합니다. ‘완전한 설정’을 위해 모든 수신 포트를 동시에 열 필요는 없습니다. 서로 다른 진입점이라도 같은 주소에서 동일한 포트를 사용할 수 없습니다. 다른 프로세스가 해당 포트를 사용 중이면 커널이 수신을 시작하지 못할 수 있습니다. 포트를 변경한 뒤에는 시스템 프록시, 브라우저 확장 프로그램, 터미널 환경 변수, 앱 내부 설정도 함께 바꾸세요. 그렇지 않으면 앱이 이전 주소에 계속 연결해 노드가 작동하지 않는 것처럼 보일 수 있습니다.

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

세 가지 모드는 출구 선택 방식을 바꿉니다

rule은 규칙 목록을 위에서 아래로 확인해 대상 출구를 결정합니다. global은 전역 정책에서 선택한 대상을 사용해 연결된 트래픽을 처리합니다. direct는 연결된 트래픽을 직접 연결합니다. 전역 모드가 시스템 전체를 자동으로 프록시 처리한다는 뜻은 아니며, 직접 연결 모드에서도 앱이 로컬 커널을 거치지 않는 것은 아닙니다. 클라이언트가 모드 설정을 자체적으로 저장할 수 있으므로 전환 후에는 최종 설정이나 관리 화면에서 실제 적용 값을 확인하세요. 구체적인 사용 사례는 규칙·전역·직접 연결 모드의 차이에서 살펴볼 수 있습니다.

log-level의 일반적인 값은 debug, info, warning, error, silent입니다. 평소에는 정보 수준을 사용하고, 문제를 재현할 때만 잠시 더 자세한 로그를 켠 뒤 다시 원래대로 돌리는 것이 좋습니다. 상세 로그에는 접속 도메인과 연결 정보가 포함될 수 있습니다. 화면이나 로그를 공유하기 전에 구독 주소, 인증 정보와 공개하고 싶지 않은 대상 정보를 삭제하세요.

LAN 접근은 별도로 설정해야 합니다

휴대폰이나 다른 컴퓨터에서 이 기기의 프록시를 사용하려면 allow-lan을 참으로 바꾸는 것만으로 충분하지 않을 수 있습니다. 수신 주소가 LAN 인터페이스를 포함하는지, 시스템 방화벽에서 인바운드 연결을 허용하는지, 접속 기기에 프록시 호스트의 LAN 주소를 입력했는지 확인하세요. 모바일 기기에 해당 기기 자신의 127.0.0.1을 입력하면 컴퓨터가 아니라 모바일 기기 자신에 접속합니다. 공용 네트워크나 공유 네트워크에서는 수신 포트를 신중하게 개방하고, 필요한 경우 인증을 설정하고 접속 가능한 출처를 제한하세요.

관리 인터페이스와 프록시 진입점은 따로 관리해야 합니다. 컨트롤러는 상태를 읽고 일부 실행 설정을 변경할 수 있으므로 인터넷에 직접 노출해서는 안 됩니다. 원격 관리가 꼭 필요하다면 인증, 접근 제어, 보호된 전송 경로를 함께 설계하세요. 예제에서는 로컬 기기에서만 사용할 수 있도록 루프백 주소에 바인딩합니다. 컨트롤러 포트를 브라우저 프록시 설정에 입력하지 마세요. 관리 화면이 열린다고 해서 프록시 수신이나 원격 연결까지 정상이라는 뜻은 아닙니다.

최상위 ipv6와 DNS 아래의 같은 이름을 가진 항목도 구분해야 합니다. 전자는 커널의 IPv6 사용 방식에 관여하고, 후자는 내장 DNS가 AAAA 응답을 처리하는 방식을 제어하므로 같은 스위치가 아닙니다. 네트워크에서 IPv6를 실제로 사용한다면 무조건 비활성화하는 것을 일반적인 최적화로 여기지 마세요. 먼저 문제가 이름 확인, 연결, 라우팅 중 어느 단계에서 발생하는지 기록한 뒤 조정하세요. 포트 충돌을 확인하는 구체적인 명령은 7890 포트 충돌 확인 및 mixed-port 변경 방법을 참고하세요.

3. DNS, Fake-IP와 이름 확인 경로

DNS 설정은 도메인에서 주소를 알아내는 방법과 커널이 도메인 및 연결 간의 연관성을 유지하는 방식을 결정합니다. DNS 설정은 프록시 규칙과 같지 않으며, 앱이 반드시 커널에 이름 확인 요청을 전달한다는 보장도 없습니다. 내장 DNS를 활성화해도 시스템이나 앱이 기존 확인 서버를 계속 사용할 수 있습니다. 시스템 DNS, TUN의 DNS 가로채기 또는 앱 프록시 프로토콜을 통해 도메인을 전달해야 해당 요청이 이 경로로 들어올 수 있습니다. 확인을 시작하기 전에 ‘앱, 시스템 이름 확인, 커널, 상위 DNS 서버’ 사이의 실제 흐름을 파악하세요.

기본 항목과 부트스트랩 이름 확인

enable은 내장 이름 확인 서비스를 활성화하고, listen은 수신 주소를 지정하며, nameserver는 일반 상위 DNS 서버를 설정합니다. 암호화 DNS 주소에 도메인이 포함된 경우에는 상위 서버의 호스트 이름부터 확인해야 할 수 있습니다. 이런 부트스트랩 상황에는 default-nameserver를 사용하며, 현재 네트워크에서 접속 가능하고 커널 요구사항을 충족하는 주소를 선택해야 합니다. 아래 예제는 테스트하기 쉽도록 로컬의 비표준 포트에서 수신하지만 운영체제의 DNS 설정을 자동으로 바꾸지는 않습니다.

dns:
  enable: true
  listen: "127.0.0.1:1053"
  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
  nameserver:
    - https://dns.alidns.com/dns-query

예제의 상위 서버는 설정 형식을 보여 주기 위한 값일 뿐이며 현재 네트워크에 적합한지는 직접 테스트해야 합니다. 암호화 DNS는 해당 이름 확인 경로의 전송을 보호하지만, 이후의 서비스 연결까지 반드시 프록시를 거친다는 뜻은 아닙니다. 일반 DNS 요청은 53번 포트를 사용하는 반면 예제는 1053번 포트를 사용합니다. 주소만 입력할 수 있는 일반 시스템 설정에는 포트가 포함된 문자열을 그대로 사용할 수 없습니다. 클라이언트의 연결 기능이나 지원되는 전달 서버를 이용해 구성하세요.

Fake-IP와 Redir-Host의 차이

fake-ip는 처리 대상 도메인에 합성 주소를 할당한 뒤 커널이 이후 연결을 다시 해당 도메인에 매핑하도록 합니다. 이를 통해 일부 경로에서 실제 주소를 미리 알아야 하는 의존성을 줄이고 도메인 규칙을 적용할 수 있습니다. redir-host는 실제 이름 확인 결과를 바탕으로 연결을 처리합니다. 실제 주소가 필요한 상황에 적합하지만, 규칙 판정은 연결 방식과 캐시, 도메인 연관 정보의 영향을 받습니다. 한 모드가 언제나 더 빠르다고 단순히 단정할 수는 없습니다.

fake-ip-filter는 합성 주소를 사용하지 않을 도메인을 지정하며, LAN 이름이나 실제 주소가 필요한 앱에 자주 사용됩니다. 호환성 문제가 실제로 발생한 도메인만 예외에 추가하고, 자주 사용하는 사이트 목록을 통째로 제외하지 마세요. DNS에서 합성 주소를 필터링해도 직접 연결 규칙이 자동으로 추가되지는 않습니다. 도메인이 실제 주소를 받더라도 연결은 규칙에 따라 프록시 그룹으로 전달될 수 있습니다. DNS 예외와 출구 정책은 각각 별도로 확인해야 합니다.

강화 모드로 전환한 뒤에도 시스템, 브라우저, 앱에 이전 캐시가 남아 있거나 기존 연결이 이전 경로를 계속 사용할 수 있습니다. 테스트할 때는 대상 앱의 관련 연결을 종료하고 필요한 경우 DNS 캐시를 갱신한 뒤 새 요청을 보내세요. 합성 주소가 보인다고 곧바로 이름 확인 오류라고 판단하지 마세요. 반면 클라이언트가 종료된 뒤에도 시스템에 합성 주소가 캐시되어 있으면 일시적으로 접속하지 못할 수 있습니다. 이때는 정상적인 이름 확인 경로를 복구하고 캐시를 갱신하세요.

도메인별 이름 확인과 프록시 서버 이름 확인

더 복잡한 설정에서는 nameserver-policy로 특정 도메인에 다른 상위 DNS 서버를 지정하거나, proxy-server-nameserver로 프록시 서버 도메인을 별도로 처리할 수 있습니다. 후자는 시작 시 순환 의존성을 방지하는 데 도움이 됩니다. 프록시 서버 주소를 아직 확인하지 못했는데, DNS 서버에 접속하려면 해당 프록시를 먼저 거쳐야 하는 상황이 이에 해당합니다. 이 항목들이 필요한지는 네트워크 환경과 커널 지원 여부에 따라 달라집니다. DNS 기본 기능부터 확인한 다음 정책을 하나씩 추가해야 전체 DNS 설정을 한꺼번에 복사하는 것보다 오류를 찾기 쉽습니다.

respect-rules를 활성화하면 DNS 상위 서버 연결에도 해당 규칙에 따른 라우팅이 적용됩니다. 이때 프록시 서버의 독립적인 이름 확인과 시작 순서를 함께 고려해야 합니다. 원격 DNS 서버, 프록시 그룹, 프록시 호스트 이름이 서로를 가리켜 자신이 시작되려면 먼저 자신이 준비되어야 하는 순환 구조를 만들지 마세요. 규칙 집합으로 DNS 정책을 매칭한다면 관련 규칙 집합이 정상적으로 로드되었는지도 확인하세요. 서비스 트래픽 분기 전에 DNS 서버 선택부터 실패할 수 있습니다.

4. 프록시 노드 항목과 프로토콜별 조건

proxies는 원격 프록시 엔드포인트를 정의하며, 각 항목에는 해당 프로토콜에 필요한 필드가 있어야 합니다. 노드 이름은 로컬에서 참조하기 위한 식별자이고, 서버 주소는 실제 연결 대상이며, 포트는 원격 서비스가 수신하는 포트입니다. 이 값들은 로컬의 mixed-port를 대신할 수 없습니다. 노드를 직접 설정하기 전에 서비스 제공업체에서 전체 매개변수를 확인하세요. 서버 주소와 비밀번호만 알고 있다고 해서 암호화 방식, 전송 계층, 인증서 검증에 필요한 정보까지 확보한 것은 아닙니다.

이름, 유형, 주소와 인증 정보

name은 중복되지 않고 알아보기 쉬운 값이어야 합니다. 정책 그룹은 이 이름으로 노드를 참조합니다. type은 뒤에 오는 항목을 해석하는 방식을 결정하므로, 한 프로토콜의 비밀번호를 다른 프로토콜 예제에 그대로 넣어서는 안 됩니다. server에는 도메인이나 주소를 입력할 수 있고, port는 유효한 포트 번호의 정수여야 합니다. 아래는 Shadowsocks 노드 맵 구조 예제입니다. 주소와 비밀번호는 설명용 값이므로 실제 사용 시 서비스 제공업체가 제공한 값으로 바꾸세요.

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

cipher는 서버 설정과 일치해야 합니다. 이름이 더 최신처럼 보인다는 이유만으로 임의로 바꾸지 마세요. 비밀번호에 공백, 샵 또는 콜론이 있으면 파싱 과정에서 문자열이 바뀌지 않도록 올바르게 따옴표로 묶어야 합니다. udp: true는 해당 노드에서 UDP 기능을 허용한다는 뜻입니다. 모든 앱의 UDP가 연결 경로에 들어온다는 보장은 없으며, UDP를 지원하지 않는 원격 서비스에 이 기능을 추가할 수도 없습니다. 실제 동작은 연결 방식, 프로토콜, 서버 설정에 따라 달라집니다.

TLS 인증 및 전송 설정

TLS를 사용하는 노드는 실제 연결 주소와 인증서 검증에 사용하는 서버 이름을 구분해야 합니다. 프로토콜에 따라 sni 또는 servername을 사용하며, 필드 이름이 모든 프로토콜에서 통용되는 것은 아닙니다. 아래는 Trojan으로 이 관계를 설명합니다. server는 연결할 주소를 정하고, sni는 TLS 핸드셰이크에서 기대하는 호스트 이름을 지정합니다. 두 값이 같은지는 브라우저에서 접속하는 주소로 추측하지 말고 서버 배포 방식에 따라 확인하세요.

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

skip-cert-verify: false는 인증서 검증을 유지합니다. 인증서 오류가 발생하면 설정을 잘못됐다고 판단하기 전에 시스템 시간, 예상 호스트 이름, 서버 인증서 체인, 연결 리디렉션 여부부터 확인하세요. 검증을 끄면 인증서 신원 오류가 가려질 수 있으므로 모든 TLS 문제의 기본 해결책으로 사용해서는 안 됩니다. WebSocket이나 gRPC 같은 전송을 사용할 때는 프로토콜에 필요한 경로, 서비스 이름, 요청 헤더도 확인하세요. 포트 연결에 성공했다고 해서 상위 계층 설정까지 일치하는 것은 아닙니다.

구독 노드와 외부 노드 제공자

구독은 proxies를 직접 생성할 수도 있고, proxy-providers를 통해 노드 모음을 제공할 수도 있습니다. 후자는 이름이 지정된 리소스이며 보통 정책 그룹에서 use로 참조합니다. proxies 목록에 노드 이름 하나를 적는 것과는 다릅니다. 제공자의 원격 주소, 캐시 경로, 업데이트 간격, 상태 확인은 각각 다른 역할을 합니다. 다운로드 성공과 노드 연결 가능 여부도 별개입니다. 다운로드 성공은 설정 리소스를 가져왔다는 뜻일 뿐입니다.

외부 노드를 사용할 때는 먼저 리소스가 커널이 받아들일 수 있는 구조인지 확인하고, 정책 그룹이 올바른 제공자 이름을 참조하는지 점검하세요. 일부 서비스는 클라이언트에서 가져오는 전체 설정을 반환하므로 노드만 담긴 제공자 파일처럼 사용할 수 없습니다. 클라이언트에서 구독 변환을 지원한다면 변환 과정에서 프로토콜 및 필드가 누락되지 않았는지 확인하세요. 특히 전송 설정, 인증서 이름, 전용 옵션에 유의해야 합니다. 노드 개수가 비슷하다고 해서 설정 내용까지 동일한 것은 아닙니다.

노드 이름을 직접 바꾸면 해당 이름을 참조하는 모든 정책 그룹에 영향을 줍니다. 노드를 삭제하기 전에 설정에서 이름을 검색하세요. 일괄 변경 시에는 같은 문자열이 규칙이나 설명에도 들어 있을 수 있으므로 주의해야 합니다. 구독을 업데이트하면 이름이 바뀔 수 있으므로 특정 노드 몇 개를 고정 참조하는 사용자 그룹은 주기적으로 확인하세요. 설정을 공유하거나 도움을 요청할 때는 서버 주소, 비밀번호, 구독 URL, 계정을 식별할 수 있는 정보도 함께 가리세요. 필드 구조와 오류 유형은 대부분의 1차 진단에 충분합니다.

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

정책 그룹을 사용하면 출구 선택과 규칙 매칭을 분리할 수 있습니다. 규칙은 안정적인 이름 하나만 가리키고, 노드를 바꾸거나 선택 방식을 조정할 때는 그룹 안에서 처리하면 됩니다. proxy-groups의 각 항목에는 이름, 유형, 후보 출처가 포함됩니다. 후보는 노드, 내장 정책 또는 다른 정책 그룹일 수 있습니다. 이름은 단순한 화면 표시가 아니라 참조 계약입니다. 이름을 바꾸면 규칙과 상위 그룹도 함께 수정해야 기존 연결이 끊기지 않습니다.

수동 선택과 자동 탐색

select는 클라이언트 화면에서 사용자가 후보를 선택하므로 출구를 직접 제어하기 좋습니다. url-test는 테스트 결과에 따라 후보를 선택하고, fallback은 후보 순서를 따르면서 사용 가능한 출구를 유지하는 데 중점을 두며, load-balance는 지정한 정책에 따라 연결을 분산합니다. 네 가지는 이름만 다른 같은 항목이 아닙니다. 사용자가 직접 고정할지, 자동으로 비교할지, 우선순위에 따라 대체할지, 연결을 분산할지 먼저 정한 뒤 필요한 매개변수를 설정하세요.

proxy-groups:
  - name: Proxy
    type: select
    proxies:
      - Auto
      - DIRECT

  - name: Auto
    type: url-test
    proxies:
      - "예시 SS"
      - "예시 Trojan"
    url: https://www.gstatic.com/generate_204
    interval: 300
    tolerance: 50

이 조각은 앞 장의 설명용 노드 두 개를 참조하므로 해당 노드 정의가 실제로 있어야 사용할 수 있습니다. 여기서 interval은 테스트 간격(초)을 뜻하고, tolerance는 후보 간 작은 차이로 인해 선택이 자주 바뀌는 것을 줄이는 데 사용됩니다. 화면에 표시되는 실시간 측정값은 아닙니다. 현재 환경에서 접속 가능하고 응답이 안정적인 주소를 테스트 대상으로 선택하세요. 테스트 실패가 그 주소에 대한 제한 때문일 수도 있으며, 모든 서비스 접속이 불가능하다는 뜻은 아닙니다.

테스트 결과가 실제 서비스 품질을 모두 보여 주지는 않습니다

상태 확인은 보통 특정 URL에 접속한 결과를 측정하며 다운로드 속도, 동영상 재생 품질, 모든 사이트의 접속 가능 여부와 같지 않습니다. 특정 출구의 테스트는 성공했지만 실제 서비스 접속에 실패한다면 대상 서비스의 제한, 프로토콜, 지역 또는 원격 네트워크 경로가 원인일 수 있습니다. 이때는 테스트 간격만 반복해서 바꾸거나 한 번의 테스트 성공으로 모든 네트워크 계층이 정상이라고 판단하지 말고, 실제 서비스에 새 연결을 시도하면서 연결 상세 정보를 확인하세요.

후보에 DIRECT가 있으면 사용자가 직접 선택하거나 그룹 동작에 따라 직접 연결될 수 있습니다. 특정 서비스가 반드시 프록시를 거쳐야 한다면 해당 그룹에 편의상 직접 연결 후보를 넣지 마세요. 반대로 로컬 서비스용 그룹에는 원격 프록시를 허용할지 명확히 정해야 합니다. 정책 그룹 이름은 용도나 선택 방식을 반영하게 지으세요. ‘자동’, ‘대체’, ‘직접 연결’을 비슷한 이름으로 섞어 두면 화면에서 잘못 선택하기 쉽고 문제를 알아채기도 어렵습니다.

제공자 참조, 그룹 중첩과 순환 참조

use로 제공자를 참조할 때는 구독 화면에 표시되는 제목이 아니라 proxy-providers 아래에 정의된 키를 입력해야 합니다. 필터 식으로 노드를 선택하는 경우에는 유효한 후보가 하나 이상 남는지도 확인하세요. 이름 규칙이 바뀌면 필터 결과가 비어 있을 수 있습니다. 수정 후에는 그룹에 실제로 어떤 옵션이 표시되는지 확인한 다음 규칙을 점검하세요. 규칙은 대상 그룹을 선택했지만 그룹에 사용 가능한 노드가 없는 상황을 피해야 합니다.

그룹은 다른 그룹을 참조해 ‘서비스 그룹에서 수동 그룹 또는 자동 그룹을 선택’하는 식으로 계층을 구성할 수 있습니다. 다만 의존 관계는 최종적으로 노드나 내장 정책으로 이어져야 합니다. A 그룹이 B 그룹을 참조하고 B 그룹이 다시 A 그룹을 참조하면 순환 구조입니다. 그룹 이름을 바꿔도 해결되지 않습니다. 복잡한 설정은 서비스 규칙, 서비스 그룹, 출구 그룹, 노드로 이어지는 간단한 흐름도로 나타내 보세요. 단계가 많을수록 각 단계의 현재 선택 항목을 확인해야 합니다. 첫 번째 단계에서 보이는 선택이 실제 출구와 같다고 단정할 수 없습니다.

클라이언트는 보통 수동 선택을 기억할 수 있지만, 이 값은 YAML의 기본 정렬이 아니라 실행 데이터에 저장될 수 있습니다. 설정을 다시 불러온 뒤에도 선택이 유지되는지는 클라이언트와 커널의 저장 방식에 따라 다릅니다. 노드를 목록 맨 위로 옮겨도 이미 저장된 선택이 바뀌지 않을 수 있습니다. 문제를 해결할 때는 현재 선택된 값을 직접 확인하고 필요하면 다시 선택한 뒤 새 연결로 검증하세요. 파일 순서만 보고 실행 상태를 추측하지 마세요.

6. 규칙 문법, 순서와 기본 경로

rules는 순서가 있는 판단 목록이지, 순서가 없는 태그 모음이 아닙니다. 커널은 현재 연결에서 확인할 수 있는 정보를 기준으로 위에서 아래로 규칙을 검사하고, 하나를 찾으면 해당 정책을 적용한 뒤 뒤쪽의 ‘더 구체적인’ 규칙을 계속 찾지 않습니다. 따라서 우선순위는 무엇보다 규칙의 위치로 정해집니다. 트래픽 분기 결과를 확인할 때는 규칙 내용뿐 아니라 앞쪽에 더 넓은 도메인·주소 규칙이나 기본 경로 규칙이 있는지도 확인하세요. 구독 생성 규칙과 사용자 규칙의 병합 위치도 특히 유의해야 합니다.

자주 쓰는 규칙 유형과 매칭 범위

유형매칭 대상사용 시 주의사항
DOMAIN도메인 하나와 정확히 일치다른 하위 도메인은 자동으로 포함하지 않음
DOMAIN-SUFFIX도메인 자체와 모든 하위 도메인에 일치단순한 임의 문자열 끝부분 매칭이 아님
DOMAIN-KEYWORD도메인에 포함된 키워드와 일치필요한 서비스보다 넓은 범위가 매칭될 수 있음
IP-CIDRIPv4 주소 대역과 일치도메인 이름 확인을 유발하는지 고려해야 함
IP-CIDR6IPv6 주소 대역과 일치IPv4 규칙과 별도로 관리
MATCH나머지 연결과 일치보통 마지막 규칙으로 배치

도메인 규칙에는 호스트 이름만 입력하고 https://, 경로, 쿼리 매개변수는 포함하지 마세요. 특정 사이트를 프록시로 연결하려고 브라우저 주소 전체를 DOMAIN에 붙여 넣으면 안 됩니다. 한 페이지가 여러 도메인에 요청을 보낼 수도 있으므로 메인 페이지의 호스트만 지정하면 정적 리소스, 인증, API 요청은 처리되지 않을 수 있습니다. 연결 기록에서 필요한 호스트를 확인한 뒤 정확히 일치하는 규칙이나 하위 도메인 규칙을 선택하세요.

rules:
  - DOMAIN,router.home.arpa,DIRECT
  - DOMAIN-SUFFIX,local,DIRECT
  - IP-CIDR,127.0.0.0/8,DIRECT,no-resolve
  - IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
  - DOMAIN-KEYWORD,github,Proxy
  - DOMAIN-SUFFIX,googleapis.com,Proxy
  - GEOIP,CN,DIRECT
  - MATCH,Proxy

주소 규칙과 no-resolve

no-resolve는 해당 주소 규칙을 평가하기 위해 도메인을 추가로 조회하지 않는다는 뜻이며, 전체 DNS 기능을 끄는 설정은 아닙니다. 연결 대상이 이미 주소라면 커널이 주소 규칙과 계속 비교할 수 있습니다. 도메인만 있고 판단에 사용할 주소를 얻지 못했다면 이 규칙이 적용되지 않을 수 있습니다. 이 매개변수는 규칙이 이름 확인을 유발해야 하는지에 따라 선택하세요. 모든 규칙에 추가해야 하는 성능 옵션처럼 사용하면 안 됩니다.

GEOIP는 IP 주소의 위치 데이터베이스를 기반으로 판단합니다. 회사의 소재지나 사용자의 실제 위치를 기준으로 하는 것은 아닙니다. 도메인이 해외 사업자의 주소를 사용하거나 지역 서비스가 공용 네트워크를 사용하는 경우 예상과 실제 매칭 결과가 달라질 수 있습니다. 데이터베이스가 업데이트되면 결과도 바뀔 수 있으므로 반드시 고정된 방식으로 처리해야 하는 서비스는 광범위한 지역 규칙 앞에 구체적인 도메인 예외를 추가하세요. 데이터 파일을 사용할 수 있는지는 커널 로그에서 확인해야 합니다.

규칙 집합, 프로세스 매칭과 적용 범위

RULE-SET을 사용하면 규칙 모음을 rule-providers가 관리하는 리소스로 분리해 업데이트하고 재사용할 수 있습니다. 제공자의 동작 유형과 파일 내용은 서로 일치해야 합니다. 도메인 목록, 주소 목록, 기존 규칙 목록은 임의로 서로 바꿔 사용할 수 없습니다. 원격 규칙 집합을 선언해도 다운로드가 완료된 것은 아닙니다. 최초 실행이나 네트워크 제한, 잘못된 캐시 경로 등의 상황에서는 먼저 로드 로그를 확인한 뒤 해당 집합을 참조하는 규칙이 작동하는지 살펴보세요.

프로세스 규칙은 운영체제와 연결 방식에서 프로세스 정보를 제공할 수 있어야 작동합니다. 라우터 기기가 다른 단말의 연결을 받는다고 해서 원격 단말 내부의 앱 이름까지 알 수 있는 것은 아닙니다. 프로세스 이름 매칭이 모든 플랫폼에서 동일하게 지원된다고 여겨서도 안 됩니다. 이 규칙을 사용하기 전에 현재 클라이언트의 지원 범위를 확인하세요. 일반적인 웹사이트 분기에는 구체적인 도메인 규칙이 재현하기 쉽고 여러 기기에서 설정을 공유하기도 편합니다.

마지막의 MATCH,Proxy는 나머지 트래픽을 프록시 그룹으로 보내고, MATCH,DIRECT는 직접 연결합니다. 서로 다른 기본 정책이므로 예제를 무조건 따라 하지 말고 실제 요구에 맞게 선택하세요. 이 규칙을 목록 맨 앞에 두면 아래 규칙은 적용되지 않습니다. 수정한 뒤에는 테스트 앱의 기존 연결을 종료하거나 새 요청을 보내세요. 일반적으로 이미 설정된 연결은 규칙을 다시 불러와도 출구가 자동으로 바뀌지 않습니다.

규칙이 매칭되었다는 것은 대상 정책이 결정되었다는 뜻일 뿐, 출구 연결 성공을 보장하지는 않습니다. 로그에서 Proxy가 선택된 뒤 핸드셰이크 오류가 발생한다면 그룹의 실제 선택 항목과 노드 설정을 추가로 확인하세요. 같은 규칙을 여러 번 넣어도 해결되지 않습니다. 반대로 요청 기록이 전혀 없다면 시스템 프록시나 TUN 등 연결 계층으로 돌아가 확인하세요. 아직 커널에 들어오지 않은 트래픽의 규칙을 계속 수정해도 달라지는 것은 없습니다.

7. 구독 덮어쓰기와 설정 병합

구독 파일은 원격 업데이트를 담당하고 사용자 설정은 로컬 환경 설정을 담습니다. 둘을 한 파일에 섞으면 다음 업데이트 때 충돌이 발생하기 쉽습니다. 덮어쓰기는 포트, DNS, 서비스 규칙, 사용자 그룹 등을 안정적으로 보관한 뒤 클라이언트가 최종 설정을 생성하도록 하는 기능입니다. 먼저 현재 클라이언트가 전체 교체, 항목 병합, 규칙 앞에 삽입, 스크립트 처리 중 어떤 방식을 지원하는지 확인하세요. 기능 이름이 비슷해도 실제 병합 방식은 다를 수 있으므로 다른 클라이언트의 설정 절차를 그대로 따라 하면 안 됩니다.

스칼라, 맵과 목록의 처리 방식

포트와 모드 같은 스칼라 항목에는 보통 최종 값 하나만 남으므로 나중에 적용된 값이 앞선 값을 대체할 수 있습니다. DNS는 중첩된 맵이라 도구에 따라 재귀적으로 병합하거나 섹션 전체를 교체합니다. 규칙과 정책 그룹은 목록이며 모두 교체하거나 앞에 삽입하거나 뒤에 추가하는 방식이 자주 쓰입니다. YAML은 데이터 형식만 정의하므로 클라이언트의 병합 의미까지 결정하지 않습니다. 아래는 입력하려는 항목 조각의 예시이며, 모든 클라이언트에서 그대로 같은 결과가 나오리라는 보장은 없습니다.

mixed-port: 7890
mode: rule

dns:
  enable: true
  enhanced-mode: fake-ip

rules:
  - DOMAIN,router.home.arpa,DIRECT

도구가 rules를 전체 교체 항목으로 처리하면 위 예제에서 기존 구독 규칙이 모두 사라질 수 있습니다. 반대로 기존 MATCH 뒤에 규칙을 추가하면 새 규칙이 적용되지 않을 수도 있습니다. 해당 클라이언트가 지원하는 규칙 앞 삽입 기능을 사용하거나, 목록 순서를 직접 조정할 수 있는 스크립트에서 처리한 뒤 결과를 확인하세요. 덮어쓰기 편집기에 ‘저장 성공’이라고 표시된다는 이유만으로 규칙이 올바른 위치에서 적용된다고 판단하면 안 됩니다.

병합 후에도 참조 관계를 유지해야 합니다

서비스 그룹을 추가할 때는 구독이 업데이트된 뒤에도 참조 대상 노드나 제공자가 남아 있는지 확인해야 합니다. 규칙을 추가할 때는 대상 정책 이름이 병합 과정에서 삭제되거나 바뀌지 않았는지도 살펴보세요. 구독에 이미 Proxy라는 그룹이 있다면 같은 이름의 사용자 그룹을 추가해 충돌하거나 덮어쓰는 결과가 생길 수 있습니다. 병합 도구가 자동으로 중복을 정리한다고 기대하기보다 로컬 용도를 구분하는 이름을 사용하고, 생성할 때마다 이름이 고유한지 확인하는 편이 안전합니다.

DNS 덮어쓰기는 중첩 항목을 특히 주의해서 확인해야 합니다. enhanced-mode만 바꾸려 했는데 dns 섹션 전체를 교체하면 기존 상위 DNS 서버, 도메인별 정책, 프록시 서버 이름 확인 설정이 함께 사라질 수 있습니다. 반대로 재귀 병합은 더 이상 필요하지 않은 이전 항목을 남길 수 있습니다. 수정한 줄만 검색하지 말고 병합된 DNS 섹션 전체를 확인해 기존 설정과 새 설정이 일관된 이름 확인 경로를 구성하는지 살펴보세요.

노드 제공자와 규칙 제공자도 같은 위험이 있습니다. 캐시 경로 충돌로 리소스끼리 덮어쓸 수 있고, 이름이 바뀌면 참조 대상이 사라지며, 파일 형식이 달라지면 기존 동작 유형이 맞지 않을 수 있습니다. 구독을 업데이트하기 전에 작동하는 설정을 보관하고, 업데이트 뒤에는 로드 로그와 그룹 내용을 확인하세요. 문제가 생기면 먼저 확인된 정상 상태로 되돌린 뒤 구체적인 차이를 비교하세요. 오류가 발생한 결과에 패치를 계속 추가하지 마세요.

로컬 유지보수 절차와 공유 시 주의사항

세 가지 자료를 보관하는 것이 좋습니다. 원격 구독 출처, 로컬 사용자 설정 조각, 최종 실행 설정입니다. 앞의 두 자료는 설정이 어디에서 왔는지 보여 주고, 세 번째 자료는 실제로 어떤 설정이 실행되는지 보여 줍니다. 비교할 때는 최상위 키와 목록 길이를 먼저 살펴본 뒤 주요 규칙 위치, 그룹 이름, DNS 경로를 확인하세요. 모든 원격 노드를 사용자 파일에 복사할 필요는 없습니다. 그러면 구독 업데이트로 인한 주소 변경이나 노드 추가·삭제가 반영되지 않아 유지보수 부담만 수동 작업으로 옮겨갑니다.

덮어쓰기 스크립트가 코드를 실행할 수 있다면 설정을 처리할 권한이 있는 프로그램으로 취급하세요. 작동 원리를 이해할 수 있는 코드만 사용하고, 규칙 하나를 삽입하기 위해 출처가 불분명한 전체 스크립트를 받아들이지 마세요. 예제를 공유할 때는 실제 구독 URL, 인증 정보, 개인 경로를 삭제하세요. 화면 캡처라도 쿼리 문자열 전체에 계정 정보가 포함될 수 있습니다. 실제 계정 정보 대신 설명용 값을 사용해 필드 위치는 유지하면서 설정 구조 문제를 재현할 수 있습니다.

8. 설정 검증과 단계별 문제 해결

문법, 참조, 수신, 이름 확인, 규칙, 원격 연결 순서로 검증하세요. 이 순서를 따르면 관련 없는 항목을 수정하는 일을 줄일 수 있습니다. 파일이 아직 정상적으로 로드되지 않았다면 노드 선택을 바꿔도 의미가 없고, 요청이 커널에 들어오지 않았다면 트래픽 분기 규칙을 바꿔도 영향을 주지 않습니다. 시작하기 전에 클라이언트 이름, 사용 중인 커널, 연결 방식, 방금 수정한 항목을 기록하세요. 실제 구독 내용을 공개할 필요는 없습니다. 가장 먼저 발생한 오류를 보관하세요. 이후에 발생한 수많은 연결 실패는 같은 기본 문제에서 비롯된 연쇄 오류일 수 있습니다.

먼저 정적 검사를 하고 시작 로그를 확인하세요

mihomo를 단독 실행한다면 테스트 매개변수로 설정을 확인할 수 있습니다. 아래 명령은 바이너리가 현재 디렉터리에 있고 설정 파일이 지정한 경로에 있다고 가정합니다. 검사 과정에서 설정이 참조하는 외부 리소스도 확인할 수 있으므로 오류 원인이 들여쓰기 문제만은 아닐 수 있습니다. 그래픽 클라이언트에서는 검사 및 다시 불러오기 기능을 우선 사용해 두 번째 인스턴스가 같은 포트를 점유하지 않도록 하세요. 어떤 방법을 사용하든 활성화하려는 파일과 같은 파일을 검증하는지 확인해야 합니다.

./mihomo -t -d ./config-dir -f ./config-dir/config.yaml

파싱 오류에는 보통 줄 번호나 가까운 항목이 표시되지만, 실제 원인은 닫히지 않은 따옴표, 목록 들여쓰기 변경, 중복된 최상위 항목처럼 바로 앞 줄에 있을 수 있습니다. 참조 오류는 이름을 따라가며 확인하세요. 규칙 대상이 존재하는지, 그룹 후보가 있는지, 제공자 이름이 일치하는지 살펴봅니다. 지원하지 않는 항목이 보이면 현재 커널에서 해당 기능을 구현했는지 먼저 확인하세요. 클라이언트 이름이 같아도 플랫폼과 설치 출처가 다르면 커널 지원 기능이 다를 수 있습니다.

포트와 요청 연결 경로 확인

설정이 로드된 뒤 수신이 정상적으로 시작됐는지 확인하세요. 데스크톱에 프록시 클라이언트가 여러 개 있으면 화면에는 하나만 열려 있어도 백그라운드 서비스가 이전 포트를 사용 중일 수 있습니다. 먼저 해당 프로세스를 확인한 다음 기존 인스턴스를 종료할지 새 설정의 포트를 바꿀지 결정하세요. 정체를 모르는 시스템 프로세스를 바로 종료하지 마세요. 다음으로 프록시를 명시적으로 지정한 요청을 보내 HTTP 연결 경로를 확인합니다. 이렇게 하면 시스템 프록시가 올바르게 설정되었는지를 잠시 별도 변수로 둘 수 있습니다.

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

이 명령은 로컬 혼합 포트를 사용하며, 대상은 연결 경로 확인을 위한 예시 사이트입니다. HTTP 응답을 받으면 이번 요청이 지정한 진입점을 통과했다는 뜻이지만 모든 앱이 연결되었다는 보장은 없습니다. 연결이 거부되면 먼저 수신 상태와 포트를 확인하세요. 프록시가 요청을 받은 뒤 시간 초과가 발생하면 규칙, 그룹 선택, 원격 오류를 확인합니다. 대상 사이트의 접근 제한은 로컬 진입점에 연결할 수 없는 상황과 다릅니다. 성공이 아닌 상태를 모두 프록시 오류로 해석하면 안 됩니다.

로그를 따라 이름 확인 및 출구 문제 찾기

이름 확인 오류는 실패한 도메인이 무엇인지에 따라 구분해야 합니다. 서비스 대상 도메인인지, 프록시 서버인지, 상위 DNS 서버 자체의 도메인인지 확인하세요. 프록시 엔드포인트를 확인할 수 없다면 부트스트랩 이름 확인과 순환 의존성을 먼저 점검하세요. LAN 이름만 실패한다면 로컬 DNS 서버, Fake-IP 필터, 연결 방식을 살펴보세요. 서비스 요청이 정상적으로 이름 확인되고 규칙까지 매칭되었다면 실제 정책과 최종 노드를 확인해 여러 단계의 그룹 선택으로 트래픽이 다른 출구에 전달되지 않았는지 살펴보세요.

TLS 오류는 시간, 호스트 이름, 인증서 체인을 먼저 확인하고 인증 오류는 비밀번호와 프로토콜 항목을 확인하세요. 연결 시간 초과가 발생하면 주소, 포트, 전송 매개변수, 네트워크 경로를 계속 살펴봅니다. 인증서 검증을 끄고 DNS를 바꾸고 모드를 전환하는 작업을 동시에 하지 마세요. 새로운 변수 때문에 원래 문제가 가려질 수 있습니다. 한 번에 한 종류의 항목만 수정하고 같은 대상에 새 연결을 보내 재검사해야 결과를 비교할 수 있습니다. 기존 연결 재사용, 캐시, 백그라운드 재시도가 관찰에 영향을 줄 수도 있습니다.

복구, 기록과 후속 유지보수

문제가 해결되면 변경한 항목, 해결된 오류 유형, 특정 네트워크에 의존하는지 등을 간단히 기록해 두세요. 클라이언트나 구독 업데이트 후에는 덮어쓰기의 영향을 받기 쉬운 위치부터 확인합니다. 디버깅 중 높인 로그 수준, 임시로 개방한 수신 주소, 추가 테스트 진입점도 일상적으로 필요한 값으로 되돌리세요. 설정이 복잡할수록 정상 작동이 확인된 기본 버전을 보관해야 환경 변화와 새 기능으로 인한 문제를 구분하기 쉽습니다.

명령줄 배포와 그래픽 클라이언트는 서비스를 관리하는 방식이 다릅니다. 특히 시스템 서비스와 데스크톱 프로그램이 같은 커널을 동시에 실행하지 않도록 주의하세요. Linux 환경의 설정은 mihomo 데스크톱 및 systemd 배포 절차를 참고하세요. 흔히 발생하는 문제는 자주 묻는 질문에서 확인할 수 있으며, 클라이언트를 바꾸려면 다운로드 페이지에서 플랫폼에 맞게 선택하세요. 설정이 올바르게 로드되고, 테스트 요청의 경로를 설명할 수 있으며, 일상적인 앱 동작이 기대와 일치해야 검증이 완료된 것입니다. 화면에 실행 중이라고 표시되는 것만으로는 충분하지 않습니다.