DNS 요청 경로, 업스트림, 응답 선택부터 구분하기
Clash DNS 문제를 해결하려면 요청 경로를 따라가며 확인해야 합니다. 앱이 요청을 어디로 보내는지, 코어가 요청을 받았는지, 어떤 업스트림을 선택했는지, 마지막으로 어떤 응답을 앱에 돌려줬는지 살펴보세요. nameserver만 바꿔도 브라우저의 DNS 요청이 Clash로 들어온다고 보장할 수는 없습니다. TUN을 켜더라도 앱 자체의 암호화 DNS가 일반 포트 가로채기로 처리된다는 보장도 없습니다.
이 문서의 설정은 mihomo 코어를 기준으로 합니다. 구버전 Clash와 클라이언트마다 지원하는 필드와 덮어쓰기 방식이 다를 수 있습니다. 먼저 클라이언트의 코어 정보에서 실제 실행 중인 코어를 확인한 다음, 최종 적용된 설정을 살펴보세요. 클라이언트 화면의 스위치 이름은 YAML 필드를 대신하지 않습니다.
| 필드 | 설정 위치 | 담당 기능 |
|---|---|---|
enable / listen | dns | 내장 DNS 사용 여부와 요청을 받을 주소 및 포트 설정 |
nameserver | dns | 일반 도메인 조회에 사용하는 기본 업스트림 |
fallback | dns | 보조 조회에 참여하며 필터 로직이 선택할 수 있는 업스트림 |
fallback-filter | dns | fallback 결과를 사용할 조건 판단 |
dns-hijack | tun | TUN 경로에서 일치하는 DNS 트래픽을 내장 DNS로 전달 |
nameserver: 코어가 사용하는 DNS 업스트림
nameserver는 내장 DNS에서 사용할 기본 DNS 서버 목록입니다. 일반 DNS 주소뿐 아니라 코어가 지원하는 DoH 및 DoT 주소도 지정할 수 있습니다. 여기에 입력하는 것은 DNS 서비스 주소이지 프록시 노드가 아닙니다. 노드 서버 주소를 넣으면 대개 유효한 DNS 응답을 받을 수 없습니다.
검증 가능한 최소 설정부터 시작하기
dns:
enable: true
listen: 127.0.0.1:1053
ipv6: false
enhanced-mode: redir-host
nameserver:
- 223.5.5.5
- 119.29.29.29
기존 설정에 병합해 사용할 DNS 설정 예시이며, 완성된 프록시 설정은 아닙니다. 1053은 내장 DNS 테스트용 리슨 포트로, 일반적인 혼합 프록시 포트 7890과 다릅니다. 루프백 주소는 로컬 기기에서만 접근할 수 있어 DNS 조회 경로를 먼저 검증하기에 적합합니다. LAN 기기에 DNS 서비스를 제공하려면 리슨 주소, 방화벽, 접근 범위를 별도로 고려해야 합니다.
redir-host는 실제 DNS 응답을 확인하기 쉬워 초기 테스트에 적합하지만, 이 모드를 계속 사용해야 한다는 뜻은 아닙니다.ipv6: false는 이 예시에서 AAAA 레코드 문제를 간단히 확인하기 위한 설정입니다. 운영체제의 IPv6를 끄거나 모든 IPv6 연결을 차단하는 설정은 아닙니다.- 업스트림을 여러 개 지정해도 첫 번째 항목부터 차례대로 응답을 기다린다고 볼 수 없으며, 이 설정만으로 각 요청에 실제 사용된 업스트림을 알 수도 없습니다.
DoH 주소도 먼저 DNS 조회가 필요할 수 있습니다
업스트림을 https://dns.alidns.com/dns-query로 바꾸면 코어는 먼저 dns.alidns.com의 IP 주소를 알아내야 합니다. default-nameserver는 DNS 서버 자체의 도메인을 조회하는 부트스트랩용 설정이며, 일반 웹사이트의 기본 DNS 서버 목록이 아닙니다. 도메인 이름을 미리 조회하지 않아도 되는 IP 주소를 부트스트랩 서버로 사용하면 시작 단계의 의존성 순환을 줄일 수 있습니다.
dns:
enable: true
listen: 127.0.0.1:1053
enhanced-mode: redir-host
default-nameserver:
- 223.5.5.5
- 119.29.29.29
nameserver:
- https://dns.alidns.com/dns-query
DoH는 클라이언트와 해당 DNS 서비스 사이의 DNS 전송을 암호화할 뿐, 모든 앱의 연결이 자동으로 프록시를 거치게 하지는 않습니다. 업스트림에 연결할 수 있는지, DNS 요청이 어떤 경로로 나가는지, 웹사이트 연결에 어떤 규칙이 적용되는지는 각각 확인해야 합니다.
fallback과 fallback-filter: 단순한 장애 전환이 아닙니다
fallback을 “첫 번째 DNS가 시간 초과된 다음에만 쓰는 두 번째 DNS”라고 이해하면 안 됩니다. 설정에 따라 코어는 기본 업스트림과 보조 업스트림에 동시에 조회를 요청하고, fallback-filter 조건에 따라 어느 쪽의 응답을 사용할지 결정할 수 있습니다. 실제 요청 횟수는 캐시, 조회 정책, 코어 구현에 따라서도 달라집니다.
필터 조건은 도메인에 적용하거나 기본 조회 결과의 IP를 검사할 수 있습니다. 도메인이 지정한 조건에 해당하면 fallback 응답을 바로 사용할 수 있으며, IP 조건은 기본 응답을 보조 응답으로 대체할지 판단하는 데 쓰입니다. 둘 다 연결 경로를 정하는 규칙은 아닙니다. fallback DNS 응답을 사용한다고 해서 해당 웹사이트 연결이 반드시 프록시를 거치는 것은 아닙니다.
지역 판정을 추가하기 전에 IP 조건부터 명확히 설정하기
dns:
enable: true
listen: 127.0.0.1:1053
ipv6: false
enhanced-mode: redir-host
default-nameserver:
- 223.5.5.5
nameserver:
- https://dns.alidns.com/dns-query
fallback:
- https://1.1.1.1/dns-query
- https://8.8.8.8/dns-query
fallback-filter:
geoip: false
ipcidr:
- 0.0.0.0/32
- 127.0.0.0/8
이 예시에서는 GeoIP 필터링을 명시적으로 끄고 두 주소 범위만 조건으로 사용합니다. 기본 업스트림이 반환한 주소가 0.0.0.0/32 또는 127.0.0.0/8에 해당하면 보조 DNS 응답을 사용합니다. 이해를 돕기 위한 예시이며, 모든 비정상 DNS 응답을 판별하는 완전한 규칙은 아닙니다. 적용하기 전에 현재 네트워크에서 두 보조 DoH 서비스에 실제로 연결할 수 있는지도 확인하세요.
루프백 주소는 로컬 개발, 광고 차단 또는 조직 내부 정책에서 의도적으로 사용되기도 합니다. 따라서 특수한 주소가 보인다고 무조건 오류로 단정하지 마세요. 사설 주소 대역 전체를 필터에 추가한 뒤에도 내부 도메인이 기존처럼 조회되리라고 기대해서는 안 됩니다.
geoip와 domain의 역할 구분
geoip: true와geoip-code: CN을 함께 설정하면 기본 응답 IP의 국가 코드를 기준으로 필터링합니다. 지정한 지역에 속하지 않는 응답은 fallback으로 대체될 수 있습니다. 판정 기준은 페이지 내용이 아니라 IP 위치 데이터입니다.- GeoIP 판정에는 관련 데이터가 필요합니다. 데이터가 없거나 오래되었거나 IP의 지역 정보가 실제 서비스 위치와 다르면 결과에 영향을 줍니다. 지역 판정을 DNS 조회가 올바르다는 증거로 여겨서는 안 됩니다.
domain에는+.example.com처럼 fallback을 사용할 도메인 패턴을 지정할 수 있습니다. 여기서 example.com은 문법 설명용 예시이므로, 실제 설정에는 필요한 도메인만 추가하세요.fallback-filter는 보조 업스트림이 반환하는 모든 유해한 콘텐츠를 걸러내는 기능도, 광고 차단 목록도 아닙니다.
dns-hijack: 53번 포트의 DNS 요청을 내장 DNS로 전달
업스트림을 설정한 다음에는 앱의 DNS 요청이 실제로 코어에 들어오는지도 확인해야 합니다. TUN 모드에서 dns-hijack은 TUN을 통과하는 DNS 트래픽을 감지해 내장 DNS로 전달합니다. 요청이 들어오는 경로를 처리하는 기능이지 nameserver를 대신하거나, 연결할 수 없는 업스트림을 고쳐 주는 기능은 아닙니다.
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
- tcp://any:53
이 설정은 앞의 dns: 섹션과 나란히 병합합니다. any:53은 UDP 53번 포트의 DNS 요청을 감지하고, tcp://any:53은 TCP DNS를 추가로 처리합니다. 일반 DNS는 UDP만 사용하는 것이 아닙니다. 응답이 잘려 재시도하거나 일부 앱이 동작할 때 TCP를 사용할 수 있습니다.
auto-route는 트래픽이 TUN으로 들어오도록 경로를 자동 설정하며, 일반적으로 해당 시스템의 권한이 필요합니다. 클라이언트는 플랫폼에 따라 서비스 모드나 권한 승인 절차를 통해 코어를 시작할 수 있습니다. 경로 생성에 실패할 수 있으므로 화면에 TUN이 켜졌다고 표시되는 것만으로는 트래픽이 정상적으로 가로채졌다고 판단할 수 없습니다.
DNS 가로채기 범위는 플랫폼에 따라서도 달라집니다. 로컬 네트워크 DNS, 루프백 주소 또는 특정 인터페이스로 향하는 요청은 예상한 TUN 경로를 거치지 않을 수 있습니다. 특히 라우터 주소를 시스템 DNS로 사용하는 경우에는 실제 조회와 로그로 확인하세요. any가 운영체제의 모든 DNS 요청을 뜻한다고 해석해서는 안 됩니다.
Fake-IP와 구독 설정 덮어쓰기: 혼동하기 쉬운 두 가지
198.18로 시작하는 주소가 반환되어도 반드시 DNS 오류인 것은 아닙니다
enhanced-mode: fake-ip에서는 코어가 앱에 매핑 주소를 반환하고, 이 매핑을 사용해 도메인과 이후 연결을 연결할 수 있습니다. 일반적인 설정에서는 fake-ip-range: 198.18.0.1/16을 사용합니다. 이 주소 대역이 보이면 먼저 현재 강화 모드를 확인하고, 곧바로 fallback을 바꾸지는 마세요.
Fake-IP 응답을 사용해도 코어가 실제 DNS 조회를 전혀 하지 않는 것은 아닙니다. 이후 조회 여부와 업스트림은 연결 처리 및 정책에 따라 달라집니다. fake-ip-filter는 Fake-IP 응답을 사용하지 않을 도메인을 지정하며, 업스트림 응답을 필터링하는 fallback-filter와는 기능이 다릅니다. 실제 주소가 필요한 내부망 앱은 도메인 예외와 내부망 DNS 경로부터 확인하세요.
구독 캐시를 직접 수정하면 업데이트 후 변경 사항이 사라질 수 있습니다
많은 클라이언트는 구독 설정, 로컬 덮어쓰기, 화면 설정을 합쳐 실행 설정을 만듭니다. 구독에서 내려받은 파일을 직접 수정하면 다음 업데이트 때 덮어써질 수 있습니다. DNS 설정을 여러 곳에서 동시에 관리하면 최종 적용값이 방금 수정한 설정과 달라질 수도 있습니다.
- 현재 정상 작동하는 설정을 먼저 백업하고 시스템 프록시와 TUN의 활성화 상태를 기록하세요.
- 클라이언트가 지원하는 영구 덮어쓰기 기능을 선택하고 DNS 변경 설정의 출처를 하나로 정리하세요.
- 설정을 다시 불러온 다음 최종 적용된
dns및tun섹션을 확인하고, 리슨 포트와 들여쓰기 수준을 점검하세요. - 구독을 한 번 업데이트한 뒤 덮어쓰기 설정이 유지되는지 확인하세요. 처음 가져왔을 때만 테스트해서는 안 됩니다.
검증 순서: 내장 DNS를 먼저 확인한 뒤 시스템 요청 처리 확인
업스트림을 바꾸고 Fake-IP와 TUN을 한꺼번에 켜면 문제의 원인을 구분하기 어렵습니다. 먼저 redir-host와 127.0.0.1:1053으로 DNS 조회가 되는지 확인한 다음, 필요한 기능을 하나씩 다시 활성화하세요. 아래 명령은 확인 방법이며 이 사이트의 네트워크 환경에서 직접 테스트한 결과가 아닙니다.
1단계: 설정을 확인하고 리슨 포트에 직접 조회하기
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
첫 번째 명령을 실행하려면 로컬에서 mihomo를 직접 실행할 수 있어야 하며 실제 설정 파일 경로를 지정해야 합니다. 클라이언트가 관리하는 코어라면 해당 클라이언트의 설정 검사 기능을 사용하세요. 다음 두 명령은 dig가 설치된 시스템에서 UDP와 TCP 조회를 각각 검증합니다. 명령이 종료됐는지만 보지 말고 status, ANSWER SECTION, 실제 응답을 확인하세요.
Windows에서는 nslookup을 실행해 대화형 모드로 들어간 다음 서버와 포트를 지정할 수 있습니다. 이때 DNS 포트인 1053을 지정해야 하며 HTTP/SOCKS 혼합 프록시 포트를 가리키면 안 됩니다.
nslookup
set port=1053
server 127.0.0.1
example.com
exit
2단계: 직접 조회와 시스템 기본 DNS 조회 비교하기
1053포트에 직접 조회해도 시간 초과가 발생하면 코어 실행 여부, 포트 리슨 상태, 로그에 기록된 업스트림 연결 오류부터 확인하세요.- 직접 조회는 정상이지만 서버를 지정하지 않은
nslookup example.com이 실패한다면 시스템 DNS, TUN 라우팅, 가로채기 범위를 집중적으로 확인하세요. - 명령줄에서는 정상인데 브라우저에서만 실패한다면 브라우저의 보안 DNS, 프록시 설정, 캐시를 확인하세요. DNS 조회가 정상이어도 대상 웹사이트의 TCP 또는 TLS 연결이 정상이라는 뜻은 아닙니다.
- 설정을 바꾼 직후에도 이전 결과가 나오면 코어를 다시 불러오고 관련 앱의 캐시를 정리하세요. Windows에서는
ipconfig /flushdns로 시스템 DNS 캐시를 비울 수 있지만, 코어나 브라우저가 각각 관리하는 모든 캐시까지 삭제되지는 않습니다.
| 증상 | 먼저 확인할 항목 | 먼저 하지 말아야 할 작업 |
|---|---|---|
| 1053 포트에 응답이 없음 | enable 설정, 포트 충돌, 코어 로그 | 연결 분기 규칙을 계속 수정하기 |
| 기본 업스트림은 되지만 fallback이 시간 초과됨 | 보조 DNS 서비스 연결 여부와 해당 서비스의 아웃바운드 경로 | 연결할 수 없는 업스트림을 계속 추가하기 |
| 내부망 도메인만 조회 실패 | 내부망 DNS, 도메인별 DNS 지정, Fake-IP 예외 | 모든 DNS 요청을 공용 DNS로 보내기 |
| Fake-IP는 반환되지만 웹페이지가 열리지 않음 | 이후 연결도 같은 코어로 들어오는지 확인 | 매핑 주소만 보고 DNS 오염으로 단정하기 |
최종 점검은 세 가지 질문으로 정리할 수 있습니다. 요청이 내장 DNS에 들어왔는지, 업스트림이 유효한 응답을 반환했는지, 이후 연결이 예상대로 처리됐는지 확인하세요. nameserver와 fallback은 DNS 조회에 사용할 서버를, fallback-filter는 응답 선택을, dns-hijack은 TUN DNS 요청 경로를 담당합니다. 이 경계를 기준으로 하나씩 수정해야 설정 변경과 문제 증상을 연결해 파악할 수 있습니다. 정책 그룹과 TUN을 더 설정하려면 mihomo 고급 설정 가이드를 참고하세요.