1. 설정 파일 구조와 실제 적용 순서

config.yaml은 연결을 받아들이는 진입점, 도메인 이름 확인, 사용할 수 있는 출구와 출구 선택 규칙을 정의합니다. “앱 트래픽 → 로컬 포트 또는 TUN → 규칙 판정 → 프록시 그룹 → 노드 또는 직접 연결” 순서로 살펴보면 이해하기 쉽습니다. DNS는 도메인 확인에 사용되지만, 모든 연결이 반드시 하나의 DNS 경로를 거치는 것은 아닙니다.

이 글에서는 일반적인 파일 배치 순서에 따라 설명합니다. YAML 최상위 항목은 보통 순서를 바꿔도 됩니다. dns를 rules보다 앞에 적었다고 해서 규칙보다 우선순위가 높아지는 것은 아닙니다. 실제 순서가 중요한 부분은 rules 안의 규칙 목록입니다. 지원 프로토콜과 일부 항목은 커널에 따라 다르며, 기존 Clash와 Clash Meta(현 mihomo)의 설정 기능도 완전히 같지는 않습니다.

  • 최상위 항목: dns:, proxies: 등의 항목은 줄의 맨 앞에서 시작합니다.
  • 들여쓰기: 각 단계마다 공백 2칸을 사용하고 Tab은 쓰지 않는 것이 좋습니다. 목록 항목 앞의 - 도 유지하세요.
  • 이름 참조: 프록시 그룹명과 노드명은 문자열이 정확히 일치해야 합니다. 대소문자와 공백도 동일하게 맞추세요.
  • 클라이언트에서 생성되는 설정: 구독, 오버라이드, 병합 스크립트, 앱 설정이 함께 실행 설정을 만들 수 있습니다. 따라서 디스크에 저장된 YAML 파일 하나만 수정해도 커널 동작이 바로 바뀌지 않을 수 있습니다.

2. 포트, 실행 모드, 제어 API

포트 항목은 클라이언트가 로컬에서 연결을 받는 위치를 지정하며, 원격 노드 서버의 포트와는 다릅니다. 아래에서는 혼합 프록시 포트 7890을 예로 듭니다. 숫자는 설명을 위한 예시이므로 실제 설정과 포트 사용 현황을 확인하세요.

mixed-port: 7890
allow-lan: false
mode: rule
log-level: info
항목역할사용 시 참고 사항
portHTTP 프록시 포트HTTP 프록시와 CONNECT 터널을 지원합니다. 웹 서버 포트가 아닙니다.
socks-portSOCKS 프록시 포트앱에서 프록시 유형으로 SOCKS를 직접 선택해야 합니다.
mixed-portHTTP·SOCKS 공용 포트하나의 포트에서 두 가지 프록시 연결을 모두 받습니다. 앱 설정에서는 올바른 프로토콜을 선택해야 합니다.
allow-lanLAN 연결 허용 여부LAN 공유 여부는 수신 주소, 시스템 방화벽, 접근 인증 설정에도 영향을 받습니다.
mode실행 모드rule은 규칙에 따라 출구를 선택하고, global은 전역 정책을 사용하며, direct는 직접 연결합니다.
external-controller관리 API 수신 주소상태 조회와 정책 전환에 사용하며, 앱의 프록시 연결 포트로는 사용할 수 없습니다.

7890과 9090을 혼동하면 안 되는 이유

실행 설정에서 mixed-port가 7890이라면 브라우저의 수동 프록시에 호스트 127.0.0.1, 포트 7890을 입력하세요. 별도로 external-controller: 127.0.0.1:9090이 설정되어 있다면 9090은 관리 API 포트입니다. 이 값을 브라우저 프록시 설정에 입력하면 연결되지 않습니다.

관리 인터페이스는 가급적 루프백 주소에만 바인딩하고 별도의 secret을 설정하세요. LAN 프록시를 허용하더라도 관리 인터페이스까지 모든 네트워크 어댑터에 노출하지 마세요. 시스템 프록시 설정은 대개 클라이언트에서 관리하므로 mixed-port만 바꿔서는 모든 앱이 새 포트를 사용한다고 보장할 수 없습니다.

3. dns: DNS 서버, 수신 주소, Fake-IP

dns 항목은 커널의 DNS 기능을 설정합니다. enable은 사용 여부, listen은 DNS 수신 주소, nameserver는 상위 DNS 서버를 지정합니다. DNS 수신 포트는 HTTP·SOCKS 포트와 다른 서비스에 속하므로 프록시 포트를 DNS 서버 포트로 사용할 수 없습니다.

dns:
  enable: true
  listen: 127.0.0.1:1053
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  nameserver:
    - 223.5.5.5
    - 1.1.1.1

이 예시는 루프백 주소의 1053 포트에서 DNS 요청을 받습니다. 지정된 IP 주소의 상위 DNS 서버는 일반 DNS를 사용하며, 암호화된 DNS를 의미하지 않습니다. 수신 포트를 열어도 운영체제 DNS가 자동으로 변경되지는 않습니다. 앱, 운영체제의 DNS 경로 또는 TUN의 DNS 가로채기를 별도로 연결해야 합니다.

Fake-IP 주소는 실제 서버 주소가 아닙니다

fake-ip 모드에서는 설정된 주소 대역에서 가상 주소를 할당하고, 커널이 해당 주소와 도메인의 대응 관계를 저장해 이후 연결을 도메인 기준으로 처리합니다. 조회 결과가 198.18.로 시작한다면 먼저 해당 연결이 여전히 커널을 거치는지 확인하세요. 이 주소를 원격 웹사이트의 실제 IP로 단정해서는 안 됩니다.

  • 앱 호환성: 일부 기기 검색, 게임, 실제 DNS 응답에 의존하는 앱은 fake-ip-filter 설정을 확인해야 할 수 있습니다. 처음부터 광범위한 와일드카드 항목을 추가하지 마세요.
  • 상위 DNS 서버 연결: 현재 네트워크에서 선택한 DNS 서버에 접속할 수 있는지 먼저 확인하세요. 암호화 DNS를 새로 추가할 때는 서버 도메인을 확인하기 위한 초기 DNS 조회도 고려해야 합니다.
  • 고급 항목: mihomo의 respect-rules, proxy-server-nameserver 등은 각기 다른 라우팅 및 DNS 확인 용도로 사용됩니다. 실제 커널 문서에 따라 설정하고, DNS 요청의 출구 정책과 일반 트래픽 규칙을 혼동하지 마세요.

문제를 확인할 때는 지정 포트를 지원하는 환경에서 dig @127.0.0.1 -p 1053 example.com을 실행해 응답 여부를 확인할 수 있습니다. 이 명령은 지정된 DNS 수신 포트가 응답하는지만 검사하며, 시스템 트래픽이 처리되는지 또는 노드에 연결할 수 있는지까지 증명하지는 않습니다.

4. proxies: 노드 정의와 프로토콜 매개변수

proxies는 노드 객체 목록입니다. 각 객체에는 보통 name, type, server, port가 포함되며, 나머지 항목은 프로토콜에 따라 달라집니다. 예를 들어 Shadowsocks에는 cipher, password가 필요하고, 다른 프로토콜은 UUID, TLS 또는 전송 계층 매개변수를 요구할 수 있습니다. type만 바꿔서는 프로토콜을 전환할 수 없습니다.

proxies:
  - name: "로컬 테스트 노드"
    type: ss
    server: 127.0.0.1
    port: 8388
    cipher: aes-128-gcm
    password: "local-demo-only"

노드 이름과 서버 주소는 별개입니다

name은 프록시 그룹에서 참조하고 앱 화면에 표시하는 이름이며, server는 실제 연결 대상입니다. “로컬 테스트 노드”의 이름을 바꾸면 해당 노드를 참조하는 프록시 그룹의 이름도 함께 수정해야 합니다. 노드의 port: 8388은 서버 포트이며, 로컬 수신 포트인 mixed-port: 7890과 숫자가 연결되어 있지 않습니다.

콜론이나 샵 기호가 포함된 문자열, 또는 불리언 값으로 해석될 수 있는 문자열은 따옴표로 감싸는 것이 좋습니다. 인증 정보도 문자열로 처리하세요. 설정 파일이나 로그를 공유할 때는 비밀번호, 토큰, 전체 구독 URL을 숨겨야 합니다. 노드 표시 이름만 바꿔서는 민감한 정보가 제거되지 않습니다.

5. proxy-groups: 규칙과 노드 사이의 정책 계층

proxy-groups는 노드나 다른 프록시 그룹을 묶어 규칙에서 참조할 수 있는 출구를 만듭니다. 규칙에서는 보통 변경되지 않는 그룹명을 지정하고, 구독 업데이트 때 그룹 안의 노드를 교체합니다. 이렇게 하면 “어떤 트래픽을 이쪽으로 보낼지”와 “현재 어떤 노드를 사용할지”를 따로 관리할 수 있습니다.

proxy-groups:
  - name: "수동 출구"
    type: select
    proxies:
      - "로컬 테스트 노드"
      - DIRECT
  • select: 사용자나 관리 API가 구성원을 직접 선택합니다. 원하는 출구를 명확히 지정할 때 적합합니다.
  • url-test: 연결 테스트 결과에 따라 구성원을 자동으로 선택합니다. 테스트 URL, 간격, 허용 오차가 선택에 영향을 주며, 테스트 결과가 실제 다운로드 속도와 같지는 않습니다.
  • fallback: 목록 순서에 따라 사용 가능한 구성원을 선택합니다. 지연 시간이 가장 짧은 노드를 찾는 방식이 아니라 주·보조 전환에 적합합니다.
  • load-balance: 지원되는 분산 정책에 따라 연결별로 구성원을 선택합니다. 일반 연결 하나를 여러 노드의 대역폭으로 자동 합산하지는 않습니다.

위 목록은 앞에서 정의한 “로컬 테스트 노드”와 기본 출구인 DIRECT를 참조합니다. 노드를 삭제하고 참조를 남겨 두면 설정 오류가 발생합니다. 그룹은 다른 그룹을 참조할 수 있지만 A가 B를 참조하고 B가 다시 A를 참조하는 식의 순환 참조는 피해야 합니다.

구독 노드가 반드시 proxies에 직접 들어가는 것은 아닙니다

proxy-providers를 사용하면 제공자에서 노드를 불러올 수 있으며, 프록시 그룹은 use로 제공자 이름을 참조합니다. 따라서 최상위 항목에 proxies: []가 있다고 해서 노드가 없다고 단정할 수는 없습니다. 제공자가 정상적으로 로드되었는지, 그룹에 use가 설정되어 있는지, 앱 화면에 필터가 적용되어 있는지 함께 확인하세요.

6. rules: 위에서 아래로 판정하고, 일치하면 출구 선택

mode: rule에서는 커널이 목록 순서대로 규칙을 확인하고, 처음 일치한 규칙에 지정된 정책을 사용합니다. 규칙은 보통 “규칙 유형, 조건, 출구”로 구성됩니다. MATCH는 조건이 필요 없으며, 보통 다른 규칙에 걸리지 않은 연결을 처리하도록 마지막에 둡니다.

rules:
  - DOMAIN,example.com,수동 출구
  - DOMAIN-SUFFIX,example.org,DIRECT
  - IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
  - MATCH,수동 출구
규칙대상확인할 점
DOMAIN정확히 일치하는 도메인example.com은 하위 도메인까지 자동으로 포함하지 않습니다.
DOMAIN-SUFFIX도메인과 하위 도메인example.org는 www.example.org에도 적용됩니다.
IP-CIDR대상 IPv4 대역no-resolve는 해당 규칙만을 위해 도메인을 별도로 조회하지 않게 합니다. 전체 DNS를 끄는 옵션은 아닙니다.
RULE-SET규칙 제공자 참조해당 rule-providers 정의와 사용 가능한 규칙 데이터가 있어야 합니다.
MATCH나머지 연결앞쪽에 배치하면 뒤에 있는 규칙이 적용될 기회를 차단합니다.

“LAN 직접 연결” 규칙은 예시의 192.168.0.0/16만으로 모든 환경을 처리할 수 없습니다. 실제 네트워크에서는 10.0.0.0/8, 172.16.0.0/12 또는 IPv6 주소를 사용할 수도 있습니다. 예시를 완성된 규칙 목록으로 간주하지 말고, 로컬 네트워크 대역과 서비스 검색 방식을 고려해 규칙을 추가하세요.

MATCH,수동 출구를 첫 줄로 옮기면 뒤에 있는 도메인 규칙은 실행되지 않습니다. “규칙을 작성했는데 적용되지 않는” 경우 먼저 규칙 모드인지 확인한 다음, 앞서 적용되는 규칙과 클라이언트가 추가한 오버라이드를 점검하세요. 마지막으로 연결 기록에서 일치한 규칙과 실제 출구를 확인합니다.

7. 최소 설정 예시와 TUN의 역할

아래는 설정 구조를 확인하기 위한 최소 구성입니다. 혼합 포트, 커널 DNS, 규칙 모드를 켜고 직접 연결만 포함된 프록시 그룹 하나를 둡니다. 원격 프록시 기능은 제공하지 않으며, YAML 로드 여부와 포트 수신 상태, 그룹명 참조가 일치하는지 먼저 확인할 때 적합합니다.

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

dns:
  enable: true
  listen: 127.0.0.1:1053
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  nameserver:
    - 223.5.5.5

proxies: []

proxy-groups:
  - name: "수동 출구"
    type: select
    proxies:
      - DIRECT

rules:
  - DOMAIN-SUFFIX,example.com,DIRECT
  - MATCH,수동 출구

TUN은 트래픽을 처리하는 진입점이며, 분기 규칙을 대신하지 않습니다

TUN은 가상 네트워크 인터페이스를 통해 트래픽을 처리하며, 시스템 프록시를 따르지 않는 앱에서 주로 사용합니다. proxies에 속하지 않으며 잘못된 노드 인증 정보를 자동으로 해결하지도 않습니다. 관련 항목을 지원하는 mihomo를 예로 들면 기존 설정에 아래 내용을 별도로 추가할 수 있습니다. 이 설정이 기존 Clash의 모든 커널에서 통용되는 것은 아닙니다.

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

실제로 사용하려면 운영체제 권한, 가상 네트워크 어댑터 지원, 올바른 라우팅이 필요합니다. dns-hijack은 해당 경로로 들어오는 관련 DNS 트래픽을 처리하는 항목이며, 앱에서 자체적으로 사용하는 HTTPS 암호화 DNS까지 모두 가로챈다는 뜻은 아닙니다. 클라이언트 화면에서 이미 TUN을 관리하고 있다면 생성된 설정을 먼저 확인하고, 여러 곳에서 서로 반대되는 설정을 동시에 관리하지 마세요.

8. 수정, 검증, 롤백 순서

  1. 복사본 보관: 현재 Profile을 내보내고 선택된 프록시 그룹 구성원을 기록하세요. 구독 원본과 로컬 오버라이드는 각각 백업합니다.
  2. 한 번에 한 종류만 수정: 먼저 포트를 바꾸고 확인한 다음 DNS를 점검하고, 마지막으로 노드와 그룹, 규칙을 조정하세요. 커널 교체, TUN 활성화, DNS 전체 교체를 한꺼번에 진행하지 마세요.
  3. 설정 검사 실행: mihomo 명령줄을 사용하고 설정 파일이 현재 디렉터리에 있다면 mihomo -t -f ./config.yaml을 실행하세요. 다른 커널은 먼저 -h로 옵션을 확인합니다. 명령줄 검사를 통과해도 네트워크 연결이 보장되는 것은 아닙니다.
  4. 실제 실행 설정 확인: 다시 불러온 뒤 로그를 확인해 YAML 파싱 오류, 존재하지 않는 노드 참조, 사용 중인 수신 주소 등의 문제가 없는지 점검하세요.
  5. 단계별 확인: 로컬 수신 포트, DNS 응답, 노드 연결, 규칙 적용 순으로 확인합니다. 연결 기록을 볼 때는 대상 도메인, 적용된 규칙, 프록시 그룹, 최종 선택된 구성원을 함께 기록하세요.
  6. 문제가 생기면 롤백: 이전에 정상 작동하던 Profile로 되돌리고 시스템 프록시나 TUN 설정도 원래대로 복구한 다음 차이를 확인하세요. 원인을 덮기 위해 출처를 알 수 없는 설정 파일을 연달아 가져오지 마세요.

오류 증상으로 관련 항목 찾기

  • 불러올 때 줄 번호 오류가 표시됨: 먼저 들여쓰기, 따옴표, 콜론, 목록 형식을 확인한 뒤 오류가 난 줄의 앞줄에 필요한 구조가 빠졌는지 살펴보세요.
  • 프록시 또는 정책을 찾을 수 없다는 메시지가 표시됨: rules, proxy-groups, proxies 사이의 이름 참조가 일치하는지 확인하세요.
  • 주소가 이미 사용 중이라는 메시지가 표시됨: 현재 설정의 7890, 1053 포트 등을 다른 프로세스나 별도의 커널이 사용 중인지 확인하세요.
  • 도메인은 조회되지만 연결할 수 없음: 노드 서버, 프로토콜 매개변수, 현재 선택된 구성원, 외부 네트워크 연결을 추가로 확인하세요. DNS만 반복해서 수정하지 마세요.
  • 수동 변경 사항이 업데이트 후 사라짐: 구독 캐시 파일을 수정한 것은 아닌지 확인하고, 유지할 설정은 클라이언트가 지원하는 오버라이드나 병합 기능으로 옮기세요.

설정을 읽을 때는 먼저 진입점 포트를 확인한 뒤, 규칙이 참조하는 그룹과 그룹 안의 구성원을 따라가세요. 마지막으로 DNS와 TUN 연결 조건을 따로 점검합니다. 이 관계를 이해해야 “파일이 로드됨”, “규칙이 적용됨”, “연결을 실제로 사용할 수 있음”이라는 서로 다른 결과를 구분할 수 있습니다. 자세한 설정 방법은 고급 설정에서, 항목의 의미는 용어집에서 확인하세요.