고급 설정 예상 읽기 시간 12분

Clash DNS 설정 가이드: nameserver·fallback·fake-ip 리디렉션

DNS 설정의 각 필드를 살펴봅니다. enhanced-mode 선택, nameserver와 fallback의 역할, fallback-filter 조건, dns-hijack 설정과 주요 구성 예제를 다룹니다.

DNS 설정의 네 가지 단계

Clash DNS 문제를 해결할 때는 먼저 쿼리 유입, 해석 모드, 업스트림 선택, 연결 라우팅을 구분하세요. 앱의 도메인 쿼리가 어느 DNS 서버로 전달되는지는 시스템, 브라우저, 트래픽 가로채기 방식에 따라 달라집니다. Clash가 쿼리를 받은 뒤에야 dns 설정에 따라 처리합니다. 최종 연결 경로는 프록시 모드와 rules가 결정하므로, 특정 DNS 주소를 설정했다고 해서 반드시 특정 노드를 사용하는 것은 아닙니다.

단계주요 필드확인할 항목
쿼리 유입listen、tun.dns-hijack앱의 DNS 쿼리가 코어에 도달하는가
해석 모드enhanced-mode실제 IP 주소와 매핑 주소 중 무엇을 반환하는가
업스트림 선택nameserver、fallback-filter어떤 그룹의 해석 결과를 채택하는가
연결 라우팅rules、proxy-groups실제 연결이 어떤 경로로 나가는가

구독 원문, 클라이언트 편집기에서 보이는 설정, 실제 실행 설정은 서로 다른 파일일 수 있습니다. 구독을 갱신하면 원문이 덮어써질 수 있으므로, 클라이언트의 재정의 또는 병합 설정 기능을 사용해 변경 사항을 보존하세요. 병합 후 최종 결과를 확인하고, 같은 YAML 맵에 dns:나 tun:을 중복으로 작성하지 마세요.

nameserver, fallback 및 부트스트랩 DNS

nameserver: 일반 업스트림이지 프록시 노드가 아닙니다

nameserver는 DNS 업스트림 목록입니다. 일반 DNS 주소나 코어가 지원하는 DoH·DoT 주소를 입력할 수 있습니다. 일반 주소 223.5.5.5는 보통 UDP 53을 사용하고, https://1.1.1.1/dns-query는 DoH로 HTTPS 443을 통해 연결합니다. 업스트림은 현재 네트워크에서 접근 가능해야 하며, 프로토콜 이름만으로 요청 성공이 보장되지는 않습니다.

dns:
  enable: true
  listen: 127.0.0.1:1053
  ipv6: false
  enhanced-mode: redir-host
  default-nameserver:
    - 223.5.5.5
    - 119.29.29.29
  nameserver:
    - 223.5.5.5
    - 119.29.29.29
  fallback:
    - https://1.1.1.1/dns-query
  fallback-filter:
    geoip: true
    geoip-code: CN
    ipcidr:
      - 240.0.0.0/4

이 예시는 필드 간 관계를 설명하기 위한 조각이며, 전체 노드 설정이 아닙니다. 127.0.0.1:1053은 로컬에서만 수신 대기하므로 명시적인 DNS 쿼리 테스트에 쓸 수 있습니다. 이 포트가 열려 있다고 해서 운영체제가 모든 DNS 요청을 자동으로 이 주소에 전달하는 것은 아닙니다. ipv6: false는 해당 DNS 모듈의 AAAA 응답 동작을 제어할 뿐, 운영체제의 IPv6를 끄거나 모든 IPv6 연결을 차단하지는 않습니다.

default-nameserver: DNS 업스트림 호스트 이름 해석

업스트림을 https://dns.example.com/dns-query처럼 호스트 이름으로 지정하면 연결을 시작하기 전에 해당 이름의 IP 주소를 알아야 합니다. default-nameserver는 이 부트스트랩 해석을 담당합니다. 부트스트랩 루프를 피하기 위해 예시에서는 IP 주소를 직접 사용했습니다. 모든 서비스 도메인을 먼저 조회하는 기본 서버도, 프록시 노드 전용 해석기도 아닙니다.

mihomo는 프록시 노드의 도메인을 해석하는 proxy-server-nameserver도 제공합니다. 노드 주소가 도메인이고 해석 경로에 순환 참조가 생기는 경우 이 설정을 따로 확인해야 합니다. 웹사이트 도메인 해석 실패와 노드 도메인 해석 실패를 같은 문제로 취급하지 마세요.

fallback: 예비 결과이지 순차 대기 목록이 아닙니다

fallback을 설정하면 일반적으로 기본 그룹과 예비 그룹에 쿼리를 병렬로 보내고, 필터 조건에 따라 사용할 결과를 결정합니다. “nameserver 시간 초과를 기다린 다음 fallback을 하나씩 시도한다”고 이해하면 안 됩니다. 여러 주소의 응답 경쟁, 캐시, 실패 처리는 코어 구현에 따라 달라지며, 목록 순서가 엄격한 우선순위를 뜻하지도 않습니다.

DoH는 DNS 서비스까지의 구간에 HTTPS를 사용한다는 뜻입니다. 프록시 경로를 자동으로 활성화하지 않으며, 브라우저가 자체 보안 DNS를 사용하는 것도 막지 못합니다. DNS 요청이 라우팅 규칙을 따르는지는 코어 필드, 최종 설정, 로그를 함께 확인해야 합니다.

fallback-filter: 어떤 결과를 바꿔 사용할까

fallback-filter는 IP 주소의 지역 정보를 바꾸는 설정이 아니라, 예비 결과를 선택할 조건을 지정합니다. 위 설정의 geoip: true와 geoip-code: CN은 기본 그룹에서 반환한 주소가 지정 지역 조건을 충족하지 않으면 예비 그룹 결과를 우선하도록 합니다. GeoIP 데이터에 의존하므로 데이터가 오래됐거나 CDN 라우팅이 바뀌거나 IP의 위치 정보가 부정확하면 선택 결과도 달라질 수 있습니다.

  fallback-filter:
    geoip: false
    ipcidr:
      - 240.0.0.0/4
    domain:
      - '+.example.com'

이 조각은 기존 dns 설정 아래에 넣어 앞 예시의 fallback-filter를 대체하세요. example.com은 문서용 예시 도메인이며 실제 서비스에 사용할 도메인 목록이 아닙니다. 여기서는 지역 판별을 끄고 주소 대역과 도메인 조건만 남겨 문제를 분리해 확인합니다. 사설 네트워크 대역을 검증 없이 모두 필터링하지 마세요. 사내 도메인, 라우터 관리 페이지, 가정용 NAS는 사설 IP로 해석되어야 할 수 있습니다.

또 다른 흔한 오해는 fallback-filter.domain을 프록시 규칙으로 여기는 것입니다. 이 설정은 DNS 결과의 출처만 제어하며 DOMAIN-SUFFIX 규칙을 만들지 않습니다. 웹사이트가 예비 DNS 결과를 사용하더라도 연결은 DIRECT 규칙으로 처리될 수 있습니다.

fake-ip와 redir-host의 차이

fake-ip: 먼저 도메인 매핑 생성

enhanced-mode: fake-ip는 해당 쿼리에 매핑 주소를 반환합니다. 앱이 이 주소에 연결하면 코어가 원래 도메인을 복원해 규칙을 매칭하고 연결을 처리할 수 있습니다. 따라서 명령줄에 198.18.x.x가 보인다고 해서 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://1.1.1.1/dns-query

198.18.0.1/16은 벤치마크 테스트 전용 주소 공간에 속합니다. 사용하기 전에 로컬 라우팅을 확인해 테스트 네트워크와 충돌하지 않도록 하세요. 매핑 주소를 반환한 뒤 관련 연결이 다시 코어를 통과해야 합니다. DNS는 Clash를 거치지만 데이터 연결이 트래픽 가로채기를 우회하면 앱이 해당 주소에 접속하지 못할 수 있습니다.

fake-ip-filter는 지정한 도메인에 실제 해석 결과를 반환하도록 설정합니다. 위 예시는 일반적인 제외 목록 방식이며 다른 필터 모드와 함께 사용하지 않습니다. 실제 도메인에 맞춰 내부 서비스를 목록에 추가할 수 있습니다. 다만 .local은 mDNS로 처리되는 경우가 많으므로, 필터 목록에 넣어도 Clash가 모든 멀티캐스트 검색 요청을 프록시한다는 뜻은 아닙니다.

redir-host: 실제 주소 반환

redir-host는 실제 해석 주소를 반환하고, DNS 기록을 이용해 도메인과 연결을 연관 짓습니다. 실제 IP가 필요한 호환성 환경에 적합하지만, 여러 도메인이 같은 IP를 공유하거나 앱이 자체적으로 해석하거나 캐시를 오래 유지하면 도메인 연관 정보가 완전하지 않을 수 있습니다. 어느 모드도 스니핑과 같은 기능은 아닙니다. mihomo의 sniffer는 이후 연결 정보에서 도메인을 식별하는 별도의 메커니즘입니다.

TUN dns-hijack: 쿼리를 코어로 전달

dns-hijack는 tun 아래에 두는 필드이며 dns의 하위 필드가 아닙니다. mihomo에서 흔히 쓰는 설정은 다음과 같습니다. 앞 절의 DNS 설정과 합칠 때 두 최상위 필드는 같은 들여쓰기 수준에 두세요.

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

any:53은 TUN으로 들어오는 일반 UDP 53 쿼리를 가로채고, tcp://any:53은 TCP 53을 추가로 처리합니다. 가로챈 쿼리는 코어의 DNS 모듈에서 처리하므로 시스템 DNS 서버를 127.0.0.1:1053으로 직접 지정할 필요는 없습니다. 단, 패킷이 실제로 TUN 경로를 통과하고 해당 플랫폼이 필요한 라우팅 및 가로채기 기능을 지원해야 합니다.

가로채기를 쉽게 하려고 dns.listen을 0.0.0.0:53으로 바꾸지 마세요. 수신 대기 범위가 달라지고 시스템 DNS 서비스와 포트 충돌이 발생할 수 있습니다. LAN 기기에 DNS를 제공해야 하는 경우에만 외부 수신을 설정하고, 방화벽으로 접속 출처와 접근 가능한 네트워크를 제한하세요.

자주 쓰는 구성과 선택 기준

사용 환경권장 시작 구성중점 확인 사항
먼저 업스트림 해석 문제를 확인redir-host + 로컬 1053 포트 수신지정한 쿼리에서 실제 주소를 가져오는가
도메인 기준으로 안정적인 라우팅이 필요함fake-ip + TUN 가로채기매핑 주소로 향하는 연결이 코어에 도달하는가
사내 네트워크나 가정용 서비스가 많음도메인별 DNS 지정 및 필터 예외 설정내부 도메인이 공용 DNS로 전송되지 않는가
두 DNS 그룹의 결과를 비교해야 함nameserver + fallback + 명확한 필터 조건선택된 결과가 예상 조건에 맞는가

mihomo에서는 nameserver-policy로 특정 도메인의 업스트림을 지정할 수 있습니다. 예를 들어 회사 DNS가 192.168.50.1이고 내부 도메인에 문서용 예시 접미사 corp.example을 사용한다면 기존 dns 설정 아래에 다음을 추가할 수 있습니다.

  nameserver-policy:
    '+.corp.example':
      - 192.168.50.1

실제 환경에서는 실제 내부 도메인 접미사와 접근 가능한 DNS 주소로 바꾸고, 해당 도메인을 fake-ip-filter에도 추가해야 하는지 확인하세요. 도메인 정책, 예비 결과 필터, 연결 규칙은 서로 다른 계층의 설정입니다. 문제를 해결할 때는 서로 겹치는 정책을 먼저 제거하고 기본 해석을 확인한 뒤 하나씩 다시 추가하세요.

DNS 연결이 라우팅 규칙을 따르게 하려면 mihomo의 respect-rules를 proxy-server-nameserver 등의 설정과 함께 구성해 “노드에 연결하려면 먼저 노드를 해석해야 하는” 순환을 피해야 합니다. 기본 설정을 확인하기 전에는 이 옵션과 여러 도메인별 업스트림 정책을 한꺼번에 추가하지 않는 것이 좋습니다.

검증 순서와 문제 진단

1단계: 설정과 수신 대기 확인

해당 mihomo 실행 파일로 설정 구문을 검사한 다음 클라이언트에서 다시 불러오세요. 아래 예시는 현재 디렉터리에 실제 설정 파일 config.yaml이 있고 dig가 설치되어 있다고 가정합니다.

mihomo -t -f config.yaml
dig @127.0.0.1 -p 1053 example.com A
dig @127.0.0.1 -p 1053 example.com A +tcp

구문 검사에 성공해도 모든 업스트림에 접근할 수 있다는 뜻은 아닙니다. UDP 쿼리는 성공하지만 TCP 쿼리가 실패하면 수신 대기 설정과 로컬 방화벽을 먼저 확인하세요. 두 쿼리 모두 시간 초과되면 dns.enable, 포트 사용 여부, 실제 실행 설정을 확인하세요. fake-ip 모드에서 매핑 주소가 반환되는 것은 로컬 매핑 경로가 동작한다는 뜻일 뿐, 이것만으로 실제 업스트림이 정상인지 확인할 수는 없습니다.

2단계: 시스템 경로 확인

127.0.0.1과 포트를 직접 지정하는 것은 코어가 해당 주소에서 수신 중인지 테스트하는 방법입니다. 이어서 nslookup example.com을 실행해 시스템의 기본 해석 경로를 확인하세요. 두 결과가 다르다고 반드시 문제가 있는 것은 아닙니다. 하지만 모든 쿼리가 코어를 거쳐야 한다면 시스템 DNS, TUN 라우팅, 브라우저의 보안 DNS 설정을 확인해야 합니다.

3단계: 연결 및 출구 경로 확인

  1. 캐시를 비우고 기존 탭이나 앱 연결을 닫은 다음 다시 접속해 보세요.
  2. 클라이언트의 연결 목록에서 대상 도메인, 적용된 규칙, 최종 정책 그룹을 확인하세요.
  3. 도메인 해석은 성공했지만 연결이 시간 초과되면 DNS를 바로 바꾸지 말고 노드 연결 상태, 프록시 프로토콜, 대상 포트를 확인하세요.
  4. 내부 서비스만 실패한다면 내부 DNS와 공용 DNS로 각각 조회해 도메인별 업스트림 정책이 빠졌는지 확인하세요.
  5. DNS가 우회되는 것으로 의심되면 패킷 캡처로 물리 네트워크 어댑터에서 나가는 UDP/TCP 53, 853 및 알려진 DoH 연결을 확인하세요. 공용 테스트 페이지에 표시된 리졸버 위치만으로는 로컬 요청 경로를 입증할 수 없습니다.

한 번에 한 단계씩 조정하세요. 먼저 코어의 DNS 해석을 확인하고, 다음으로 앱 쿼리가 코어에 도달하는지 확인한 뒤 연결 규칙을 살펴보세요. 그래야 업스트림 접근 불가, 필터 조건 오류, fake-ip 연결 우회, TUN 미가로채기 문제를 구분할 수 있습니다. 각 필드의 전체 구성은 설정 문서에서, 설치 및 구독 가져오기 절차는 사용 가이드에서 확인하세요.

Clash 다운로드클라이언트 및 시스템 요구 사항