mihomo DNS 설정 가이드: nameserver, fallback, DNS 하이재킹 구성법

enhanced-mode, nameserver, fallback, fallback-filter, dns-hijack 등 DNS 설정 항목을 설명하고 상황별로 바로 참고할 수 있는 설정 예제를 제공합니다.

먼저 DNS 요청이 어디로 전달되는지 확인하세요

먼저 도메인 이름 확인과 연결 전달을 구분해야 합니다. DNS는 도메인 이름을 IP 주소로 변환하는 과정이고, 프록시 규칙은 연결을 직접 연결할지 프록시를 거칠지 결정합니다. 도메인이 정상적으로 확인됐다고 트래픽까지 프록시를 통과하는 것은 아닙니다. 시스템 프록시를 켰다고 시스템의 모든 DNS 조회가 mihomo로 전달되는 것도 아닙니다.

먼저 클라이언트에서 사용하는 코어를 확인하세요. mihomo는 Clash Meta의 이름이 바뀐 뒤에도 이어서 개발되고 있는 코어입니다. GUI 클라이언트는 설정 파일 생성, 코어 실행, 시스템 네트워크 관리를 담당합니다. 이 글은 mihomo 설정 항목을 기준으로 작성했으므로, 모든 예제를 구버전 Clash에 그대로 적용할 수는 없습니다. 클라이언트의 코어 정보 화면에서 버전을 확인하거나 아래 명령을 실행해 버전과 설정 검사 결과를 기록하세요.

mihomo -v
mihomo -t -f config.yaml

아래 순서대로 확인하세요. 문제가 발생한 단계만 수정하면 DNS, 노드, 규칙을 한꺼번에 바꾸는 것보다 원인을 찾기 쉽습니다.

  1. 앱에서 조회 시작: 브라우저는 자체 보안 DNS를 사용할 수 있고, 터미널 프로그램은 보통 시스템 리졸버를 호출합니다.
  2. 요청이 리졸버로 전달: 요청은 라우터, 시스템 DNS 또는 mihomo의 DNS 리스닝 포트에 도달할 수 있습니다.
  3. 코어에서 업스트림 선택: mihomo는 DNS 처리 정책에 따라 서버를 선택하고 설정에 따라 응답을 필터링합니다.
  4. 앱에서 연결 생성: 이후 연결은 코어가 프록시 규칙에 따라 출구를 선택합니다.

dns 섹션 이해하기: 리스닝, 모드, 업스트림을 따로 설정

먼저 각 항목의 역할을 확인하세요. 아래 표의 포트는 이 글에서 사용하는 예시이며, 모든 클라이언트의 기본값을 의미하지 않습니다. 현재 실행 중인 설정을 기준으로 확인하세요.

항목역할확인할 점
enable코어의 DNS 모듈 활성화true로 설정해도 요청이 코어로 전달되도록 해야 합니다
listenDNS 조회를 받을 리스닝 주소 지정127.0.0.1:1053은 로컬 기기에서만 접속할 수 있습니다
enhanced-mode향상된 DNS 처리 모드 선택일반적으로 fake-ip 또는 redir-host 사용
default-nameserverDNS 업스트림 서버 도메인 조회DNS 조회 경로를 시작할 때 사용하며, 모든 서비스 도메인의 기본 업스트림을 뜻하지는 않습니다
nameserver일반 DNS 업스트림 설정목록 순서를 장애 발생 시 하나씩 전환하는 순서로 해석할 수는 없습니다
fallback대체 응답 선택에 사용할 DNS 업스트림 지정주 업스트림 시간 초과 후에만 동작하는 예비 주소가 아닙니다
fallback-filter대체 DNS 응답을 사용할 조건 지정도메인, GeoIP, IP 대역을 함께 조건으로 사용할 수 있습니다

fake-ip와 redir-host 중 선택하기

먼저 호환성 요구 사항에 따라 모드를 선택하세요. fake-ip는 조건에 맞는 조회에 가상 주소를 할당하고 코어에 도메인 매핑을 저장합니다. 앱이 해당 주소로 연결하면 코어가 도메인을 찾아 연결을 처리할 수 있습니다. 예시에 나오는 198.18.0.1/16은 가상 주소 풀 설정이지, 공용 DNS에 설정할 서버 주소가 아닙니다.

실제 주소 조회가 필요한 프로그램이 있다면 도메인별로 fake-ip-filter를 추가하거나 redir-host와 비교해 보세요. 후자는 실제 조회 주소를 반환합니다. 모드를 바꾼 뒤에는 시스템과 앱의 DNS 캐시를 비우고 기존 연결을 다시 시작해야 합니다. 그렇지 않으면 이전 주소를 계속 사용해 설정이 적용되지 않은 것처럼 보일 수 있습니다.

상황 1: 최소 설정으로 nameserver 확인하기

먼저 업스트림 하나만 활성화하고, 기본 조회가 정상 작동한 뒤에 fallback을 추가하세요. 아래는 독립적인 진단용 설정으로, 로컬 혼합 프록시 포트 7890과 DNS 포트 1053을 사용합니다. 구독 노드는 포함하지 않으며 마지막 규칙은 모두 직접 연결로 설정되어 있습니다. DNS 경로를 테스트하기 위한 것으로, 완성된 프록시 설정은 아닙니다.

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

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:
    - 223.5.5.5
    - 119.29.29.29
  nameserver:
    - https://dns.alidns.com/dns-query

rules:
  - MATCH,DIRECT

기존 구독 설정을 유지하려면 여기서 dns 섹션만 병합하고, 예제의 rules로 기존 분기 규칙을 덮어쓰지 마세요. YAML에서 같은 수준의 dns:를 두 번 선언하지 말고 들여쓰기에는 공백을 사용하세요. 설정 검사를 통과한 뒤 클라이언트에서 코어 설정을 다시 불러오세요.

DoH와 초기 조회 이해하기

업스트림 주소의 프로토콜을 확인하세요. https://dns.alidns.com/dns-query는 DoH로, HTTPS를 통해 DNS 조회를 전송합니다. 일반 IP 주소 형식의 업스트림은 보통 기존 DNS를 사용합니다. DoH는 클라이언트와 해당 DNS 서비스 사이의 조회 전송을 암호화할 뿐, 이후 웹사이트 연결까지 모두 프록시를 거친다는 뜻은 아닙니다.

서비스 도메인을 조회하기 전에 먼저 업스트림 서버의 도메인을 확인할 수 있어야 합니다. 예시에서는 default-nameserver에 설정한 IP 주소로 DoH 서버 도메인을 초기 조회해, DoH에 접속해야 DoH 주소를 알 수 있는 순환 문제를 피합니다. 공용 DNS 서비스에 연결할 수 있는지는 현재 네트워크에 따라 달라지므로, 특정 주소 하나가 모든 환경에서 통한다고 가정하지 마세요.

상황 2: fallback과 fallback-filter 설정

서버를 추가하기 전에 대체 응답이 선택되는 방식을 먼저 이해하세요. fallback을 설정했다고 해서 일반 네트워크 장비의 ‘보조 DNS’처럼 동작하는 것은 아닙니다. 일반 및 대체 업스트림이 함께 조회에 참여할 수 있으며, 대체 응답을 사용할지는 필터 조건과 조회 상태 등에 따라 결정됩니다. 첫 번째 주소가 시간 초과될 때까지 단순히 기다리는 방식이 아닙니다.

아래 설정은 앞의 설정에서 dns 섹션 전체를 교체하는 예제입니다. GeoIP로 일반 업스트림의 응답을 판단하고, 240.0.0.0/4를 대체 응답을 사용해야 하는 IP 대역 조건으로 지정하는 방법을 보여 줍니다.

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:
    - 223.5.5.5
    - 119.29.29.29
  nameserver:
    - https://dns.alidns.com/dns-query
  fallback:
    - https://cloudflare-dns.com/dns-query
  fallback-filter:
    geoip: true
    geoip-code: CN
    ipcidr:
      - 240.0.0.0/4

필터 조건을 항목별로 확인하세요

  • 지역 조건 확인: geoip: true는 IP 주소의 지역 정보를 사용하도록 설정합니다. geoip-code: CN은 일반 응답이 해당 지역 조건에 맞지 않을 때 대체 응답을 우선 사용하는 조건입니다. ‘중국 본토 도메인을 모두 직접 연결’하는 프록시 규칙은 아닙니다.
  • 주소 대역 확인: ipcidr는 IP 대역 목록입니다. 일반 업스트림이 반환한 주소가 필터 대역에 포함되면 대체 응답을 선택합니다. 기업 내부망 대역을 무분별하게 추가하면 내부 서비스의 DNS 조회가 실패할 수 있습니다.
  • 데이터 의존성 확인: GeoIP 판단에는 사용 가능한 지리 데이터가 필요합니다. 데이터가 없거나 오래됐다면 DNS 서버를 계속 바꿔 원인을 가리는 대신 코어 로그의 데이터 로딩 오류부터 해결하세요.
  • 두 경로 모두 확인: 대체 DoH에도 연결할 수 있어야 합니다. 주 업스트림에서 응답을 받았더라도 대체 업스트림 연결이 정상이라는 뜻은 아닙니다.

특정 도메인의 조회 업스트림을 고정해야 한다면 대체 필터 대역을 계속 늘리기보다 도메인별 리졸버를 지정하는 nameserver-policy를 우선 검토하세요. 특히 기업 도메인은 기업 DNS에 맡기는 것이 좋습니다. 공용 리졸버에는 내부 레코드가 없을 수 있습니다.

DNS 업스트림 연결의 출구와 웹사이트 연결의 출구를 따로 확인하세요. 두 경로는 서로 다릅니다. DNS 업스트림 연결에도 라우팅 규칙을 적용하려면 respect-rules를 추가로 설정할 수 있습니다. 또한 프록시 서버 도메인을 조회하도록 현재 코어 요구 사항에 맞춰 proxy-server-nameserver를 설정하면 프록시 연결과 DNS 조회가 서로를 기다리는 상황을 피할 수 있습니다. 이 글의 최소 예제에서는 이 고급 설정을 사용하지 않습니다.

상황 3: TUN의 dns-hijack으로 53 포트 가로채기

먼저 항목을 올바른 위치에 두세요. dns-hijack은 최상위 tun 섹션에 속하며 dns 섹션에 넣지 않습니다. TUN은 가상 네트워크 인터페이스로, 코어는 이 인터페이스를 통해 라우팅된 IP 트래픽을 처리합니다. 여기서 DNS 하이재킹은 조건에 맞는 DNS 요청을 코어의 DNS 모듈로 리디렉션하는 것을 뜻합니다.

기존 설정의 dns 섹션은 유지하고 아래 tun 섹션을 병합하세요. 활성화하기 전에 클라이언트에 필요한 관리자 권한 또는 서비스 권한이 있는지 확인하고, 다른 VPN이 기본 경로를 동시에 가져가지 않도록 하세요.

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 리스닝 주소를 any:53으로 바꾸라는 뜻이 아닙니다. 실제로 요청을 가로챌 수 있는지는 시스템 라우팅, 인터페이스, 플랫폼 제한에도 영향을 받습니다.

가로채는 범위 확인하기

  • 브라우저 보안 DNS 확인: 브라우저가 자체적으로 사용하는 DoH는 보통 HTTPS 포트 443을 사용하므로, 53 포트를 가로채도 자동으로 코어 DNS 조회로 전환되지 않습니다.
  • 암호화 DNS 확인: DoT는 TLS를 통해 전송되는 DNS로, 보통 853 포트를 사용합니다. 따라서 위 두 규칙의 대상이 아닙니다.
  • LAN 대상 확인: 라우터를 향하는 DNS 트래픽이 TUN으로 전달되는지는 라우팅 설정에 따라 달라집니다. 모든 LAN 요청이 반드시 가로채진다고 가정하지 마세요.
  • 리스닝 노출 확인: 개인 컴퓨터에서 테스트할 때는 루프백 주소로 리스닝하는 것이 좋습니다. TUN을 작동시키려고 DNS를 모든 네트워크 인터페이스에 무조건 공개하지 마세요.

조회, 가로채기, 규칙 순으로 확인하기

먼저 코어의 리스닝을 테스트하고, 그다음 일상적인 접속을 확인하세요. 이렇게 하면 DNS 모듈이 응답하지 않는 문제와 시스템 조회가 모듈에 전달되지 않는 문제를 구분할 수 있습니다. 아래 명령은 확인 방법을 안내하는 예시이며, 현재 네트워크에서 공용 DNS가 실제로 얼마나 빠른지 보여 주는 결과는 아닙니다.

1단계: 1053 포트에 직접 조회

dig가 설치된 Linux 또는 macOS에서 아래 두 명령을 실행해 UDP와 TCP를 각각 테스트하세요. Windows에서는 뒤에 나오는 nslookup 명령으로 포트를 지정할 수 있습니다.

dig @127.0.0.1 -p 1053 example.com A
dig @127.0.0.1 -p 1053 example.com A +tcp
nslookup -port=1053 example.com 127.0.0.1

먼저 시간 초과 여부를 확인한 뒤 응답 유형을 확인하세요. fake-ip를 활성화한 상태에서 조건에 맞는 A 조회가 가상 주소 풀의 주소를 반환하는 것은 정상입니다. 이를 보고 업스트림이 잘못된 IP를 반환했다고 판단하면 안 됩니다. 실제 조회 결과와 비교하려면 잠시 redir-host로 바꾸고 설정을 다시 불러온 다음 캐시를 비우고 같은 조회를 실행하세요.

2단계: 시스템 기본 경로로 조회

nslookup example.com

포트를 지정한 조회 결과와 기본 조회 결과를 비교하세요. 1053 포트로는 정상적으로 조회되지만 기본 조회가 시간 초과된다면, nameserver를 바로 바꾸기보다 시스템 DNS, TUN 라우팅, 보안 소프트웨어를 먼저 확인하세요. 하이재킹을 활성화한 뒤에도 명령에 표시되는 DNS 서버 이름이 원래 대상일 수 있습니다. 코어 로그도 함께 확인해 실제로 어떤 구성 요소가 요청을 처리했는지 파악하세요.

3단계: 캐시를 비운 뒤 연결 출구 확인

Windows에서는 ipconfig /flushdns를 실행할 수 있습니다. systemd-resolved를 사용하는 Linux에서는 resolvectl flush-caches를 실행하세요. 그런 다음 브라우저를 다시 시작하거나 기존 연결을 닫고, 클라이언트의 연결 패널에서 도메인, 적용된 규칙, 출구를 확인하세요. 브라우저 자체 캐시와 연결 재사용은 시스템 캐시를 비워도 초기화되지 않을 수 있습니다.

추가 단서가 필요하면 log-level을 잠시 debug로 바꾸고 문제를 한 번 재현한 뒤 info로 되돌리세요. 로그를 공유하기 전에 구독 URL, 인증 정보, 민감한 도메인을 삭제하세요. 로그로 업스트림 시간 초과, 리스닝 실패, 라우팅 문제를 찾을 수 있지만 실행 설정 전체를 그대로 공개해서는 안 됩니다.

자주 발생하는 문제: 증상에 따라 수정 범위 좁히기

증상우선 확인할 항목다음 조치
로컬 1053 조회 시간 초과DNS 활성화 여부, 포트 충돌, 설정 재적용 여부시작 로그를 확인한 뒤 설정 문법 검사 실행
1053은 정상인데 일반 조회 실패시스템 DNS 경로와 TUN 라우팅요청이 코어에 전달되는지 확인하고, 대체 업스트림은 우선 바꾸지 않기
브라우저와 터미널의 결과가 다름브라우저 보안 DNS, 각각의 캐시, 프록시 확장 프로그램일시적으로 조회 경로를 통일한 뒤 같은 도메인을 조회
내부 사이트에 접속할 수 없음공용 DNS에 내부 레코드가 없는지, 가상 주소 호환성 문제인지 확인내부 도메인에는 기업 리졸버를 지정하고 필요한 경우 fake-ip 필터 추가
fallback을 켠 뒤 조회가 느려짐대체 업스트림 연결 상태와 필터 적용 범위단일 업스트림 설정으로 되돌린 뒤 필터 조건을 하나씩 복원
구독 업데이트 후 설정이 원래대로 돌아감클라이언트가 설정을 다시 생성하면서 수동 변경 내용을 덮어씀지원되는 오버라이드 설정으로 변경 사항을 옮기고 최종 결과 확인

마지막으로 세 가지를 확인하세요. 요청이 코어에 전달되는지, 업스트림이 올바른 응답을 반환하는지, 이후 연결에 예상한 규칙이 적용되는지 점검하면 됩니다. 한 번에 조건 하나만 바꾸고 수정 전후의 설정과 조회 결과를 보관하세요. 그래야 nameserver, fallback, dns-hijack 가운데 어떤 설정이 문제를 실제로 해결했는지 알 수 있습니다.

Clash 다운로드클라이언트 플랫폼 선택