Clash DNS 누수 점검 방법: 브라우저 테스트·로그 분석·누수 방지 설정
테스트 결과와 시스템 DNS 경로, 클라이언트 로그를 바탕으로 fake-ip·원격 DNS·폴백 정책을 단계별로 설정합니다.
먼저 DNS 누수의 기준부터 확인하기
웹사이트에 접속할 때 애플리케이션은 보통 먼저 도메인을 DNS 리졸버에 전달한 뒤, 반환된 IP로 연결을 맺습니다. 프록시 연결이 Clash를 거친다고 해서 도메인 조회까지 같은 경로를 이용하는 것은 아닙니다. 시스템이 라우터, 인터넷 서비스 제공업체의 리졸버 또는 회사 네트워크의 내부 DNS로 계속 요청을 보낼 수 있습니다. 이때 웹사이트 본문 트래픽은 프록시를 통과하지만 도메인 조회는 로컬 네트워크에서 전송됩니다. 이것이 Clash DNS 누수를 점검할 때 핵심적으로 확인해야 할 현상입니다.
결과를 판단할 때 검사 페이지에 여러 DNS 서버가 표시되는지만 봐서는 안 됩니다. 공용 DNS 서비스는 애니캐스트, 포워딩 클러스터, 서로 다른 출구를 사용하므로 검사 사이트에 표시된 서버 주소가 설정에 입력한 주소와 반드시 같지는 않습니다. 여러 결과가 같은 DNS 서비스에 속할 수도 있습니다. 더 신뢰할 수 있는 방법은 리졸버의 네트워크 소속과 지리적 위치, 테스트 중 Clash 로그, 그리고 기기에서 실제로 발생한 53·853 포트 또는 HTTPS 요청을 함께 대조하는 것입니다.
DNS 누수, WebRTC 주소 노출, 프록시 출구 변경도 구분해야 합니다. WebRTC 테스트에 사설 네트워크 주소나 공인 후보 주소가 표시될 수 있지만, 이는 브라우저의 실시간 통신 경로이며 DNS 조회가 우회되었다는 뜻은 아닙니다. 프록시 출구 검사에서 로컬 공인 IP가 나타난다면 먼저 프록시 모드, 규칙 적용 여부, UDP 처리 상태를 확인해야 하며 DNS부터 바로 수정해서는 안 됩니다. 세 문제는 각각 별도로 증거를 수집해야 합니다.
자주 나타나는 누수 증상
- 프록시를 켠 뒤에도 DNS 검사 페이지에 가정용 인터넷이나 이동통신사의 리졸버가 표시됩니다.
- 다른 지역의 프록시 노드로 바꿔도 DNS 조회가 계속 로컬 네트워크에서 직접 전송됩니다.
- Clash 로그에는 웹사이트 연결이 보이지만 해당 도메인이 내장 DNS 모듈로 들어간 기록이 없습니다.
- 브라우저와 명령줄의 테스트 결과가 다르고, 둘 중 한 애플리케이션만 예상한 DNS 경로를 우회합니다.
- 시스템 프록시 모드에서는 웹페이지가 정상적으로 열리지만, 패킷 캡처에서 라우터로 향하는 UDP 53 요청이 계속 나타납니다.
브라우저 테스트·명령줄 조회·패킷 캡처를 단계별로 실행하기
브라우저 DNS 검사는 점검을 시작하기 좋은 방법입니다. 이런 페이지는 보통 무작위 하위 도메인을 여러 개 만들어 브라우저가 새 조회를 수행하게 한 뒤, 권한 DNS 서버에서 실제 재귀 리졸버를 확인합니다. 테스트 전에 다른 네트워크 사용 프로그램을 종료하고 운영체제와 브라우저의 DNS 캐시를 지운 다음 새 시크릿 창을 사용하세요. 캐시에 저장된 결과가 사용되면 조회가 생략되어 실제보다 깨끗한 결과가 나올 수 있습니다.
표준 테스트와 확장 테스트를 실행한 뒤 리졸버 IP, 네트워크 사업자, 국가 또는 지역을 먼저 기록합니다. 예상 결과는 설정 목표에 따라 달라집니다. Clash가 지정된 원격 DoH를 사용한다면 결과는 해당 서비스의 재귀 출구와 일치해야 합니다. 도메인 정책에 따라 중국 본토 도메인은 로컬 암호화 DNS로, 그 외 도메인은 원격 DNS로 보내도록 설정했다면 두 그룹의 서비스가 나타날 수 있습니다. 중요한 것은 각 결과가 명확한 설정과 일치하는지이지, 페이지에 주소 하나만 표시되는지가 아닙니다.
명령줄로 시스템 DNS와 지정 리졸버 구분하기
브라우저가 자체 보안 DNS를 사용할 수 있으므로 운영체제의 DNS 경로도 테스트해야 합니다. Windows에서는 nslookup 또는 PowerShell의 Resolve-DnsName을 사용할 수 있고, macOS와 Linux에서는 dig를 사용합니다. 이전에 접속하지 않은 도메인을 먼저 조회한 다음 명령 출력에 표시된 서버 주소를 확인하세요. 가정용 라우터 주소, 예를 들어 로컬 게이트웨이가 표시된다면 시스템이 여전히 라우터에 조회를 맡기고 있는 것입니다. 이것만으로 최종 조회가 반드시 누수되었다고 단정할 수는 없지만, 해당 명령의 DNS 진입점이 아직 Clash로 직접 지정되지 않았다는 뜻입니다.
nslookup example.net
Resolve-DnsName example.net
dig example.net
dig @127.0.0.1 -p 1053 example.net
마지막으로 Clash 또는 mihomo의 로컬 리스닝 포트를 명시해 조회하면 시스템 기본 조회와 비교하기 좋습니다. 명시적 조회는 예상대로인데 기본 조회만 라우터로 향한다면 문제는 시스템 DNS 지정이나 TUN의 DNS 하이재킹 단계에 있습니다. 두 조회 모두 원치 않는 리졸버로 연결된다면 커널 설정과 상위 DNS를 계속 확인해야 합니다.
포트와 대상 주소 캡처하기
기기가 로컬 네트워크나 공용 인터넷으로 기존 DNS를 직접 전송하는지 확인하려면 테스트 중 UDP/TCP 53 트래픽을 캡처합니다. Linux에서는 tcpdump를 사용할 수 있고, Windows에서는 시스템 네트워크 추적 도구를 활용하며, macOS에서도 활성 인터페이스에서 tcpdump를 실행할 수 있습니다. 인터페이스 이름은 실제 환경에 맞게 바꿔야 합니다.
sudo tcpdump -ni any 'port 53 or port 853'
sudo tcpdump -ni en0 'udp port 53 or tcp port 53'
패킷 캡처에서 라우터나 인터넷 서비스 제공업체의 DNS로 향하는 포트 53 요청이 보이면 직접 조회가 계속 발생한다는 강력한 증거입니다. 53번 트래픽이 보이지 않는다고 점검을 즉시 끝내서는 안 됩니다. 애플리케이션이 DoH를 사용해 DNS를 443 포트의 HTTPS 안에 캡슐화할 수 있기 때문입니다. 이때는 Clash 연결 로그, 브라우저 보안 DNS 설정, 대상 주소를 함께 판단해야 합니다.
시스템·Clash 커널·상위 리졸버를 따라 경로 추적하기
DNS 경로는 세 지점으로 나눌 수 있습니다. 애플리케이션이 누구에게 조회를 넘기는지, Clash가 조회를 받는지, Clash가 어떤 네트워크를 통해 상위 DNS에 접속하는지입니다. 이 세 가지를 각각 확인하는 편이 공용 DNS 주소를 계속 바꾸는 것보다 효과적입니다.
첫 번째 구간: 애플리케이션에서 시스템 또는 브라우저 리졸버까지
대부분의 데스크톱 애플리케이션은 운영체제의 DNS API를 호출하지만, 브라우저는 독립적인 DoH를 사용할 수 있고 일부 명령줄 프로그램은 지정한 서버에 직접 조회할 수도 있습니다. 시스템 프록시는 HTTP, HTTPS 또는 SOCKS 프록시 주소만 설정하므로 일반적으로 모든 시스템 DNS를 자동으로 바꾸지는 않습니다. 시스템 프록시 환경에서 브라우저가 로컬에서 먼저 도메인을 해석한 뒤 대상을 프록시에 넘기는 것은 흔한 경로입니다.
브라우저 테스트만 비정상이라면 먼저 브라우저의 보안 DNS를 확인하세요. 보안 DNS를 끄고 시스템과 Clash가 관리하게 하거나, Clash 설정과 일치하는 DoH 서비스로 명시할 수 있습니다. 여러 애플리케이션에서 동시에 로컬 DNS 요청이 발생한다면 운영체제 DNS, TUN 처리, 클라이언트 DNS 스위치를 우선 점검하세요.
두 번째 구간: 조회가 Clash 내장 DNS로 들어오는지 확인하기
설정에서 dns.enable이 켜져 있는지 확인하고, 로컬 리스닝 주소가 클라이언트 화면에 표시된 주소와 일치하는지 점검합니다. 일부 그래픽 클라이언트는 화면 설정을 바탕으로 실행 구성을 생성하므로 구독 파일의 DNS 항목이 덮어써질 수 있습니다. 문제를 해결할 때는 구독 원문만 보지 말고 커널이 실제로 불러온 설정을 확인해야 합니다.
로그 수준을 일시적으로 debug로 바꾸고 로그를 비운 다음 무작위 하위 도메인을 조회합니다. 로그 형식은 Clash 파생 버전과 클라이언트마다 다르지만 DNS 조회, 규칙 적용, 상위 요청 실패, 타임아웃, 폴백 선택을 중점적으로 찾아야 합니다. 로그에 해당 도메인이 전혀 없다면 요청이 아직 커널에 들어오지 않은 것입니다. 도메인은 보이지만 상위 DNS 연결이 직접 연결로 처리된다면 DNS 상위 서버의 연결 경로를 확인해야 합니다.
세 번째 구간: Clash에서 상위 DNS까지의 연결
조회가 내장 DNS로 들어가더라도 상위 DoH 또는 DoT 연결이 DIRECT로 이루어질 수 있습니다. 암호화는 전송 중 조회 내용의 무결성과 노출 범위를 보호하지만, 상위 연결에는 DNS 서비스의 대상 주소가 여전히 드러납니다. 원격 DNS 연결을 프록시 정책에 따라 전달하려면 현재 커널이 지원하는 프록시 지정 방식을 사용하거나 규칙 기반 DNS 상위 연결을 활성화하고, 프록시 서버 도메인에는 별도의 부트스트랩 리졸버를 준비해야 합니다.
프록시 노드 자체를 도메인으로 입력했다면 커널은 프록시 터널을 만들기 전에 노드 서버의 IP를 알아야 합니다. 아직 연결되지 않은 프록시를 통해 이 시작 의존성을 다시 해결하도록 요구할 수는 없습니다. mihomo의 proxy-server-nameserver는 프록시 서버 도메인 조회를 처리하고, default-nameserver는 DoH 상위 서버 자체의 도메인 조회 같은 기본 작업을 담당합니다. 두 항목의 역할은 다릅니다.
fake-ip·원격 DNS·폴백 정책으로 조회 경로 통합하기
Clash Meta 설정을 지원하는 mihomo 커널에서는 fake-ip가 자주 사용하는 향상된 DNS 모드입니다. 애플리케이션이 도메인을 조회하면 내장 DNS가 예약된 주소 풀의 매핑 주소를 먼저 반환합니다. 애플리케이션이 이 주소로 연결하면 커널이 매핑을 통해 원래 도메인을 복원한 뒤 규칙을 매칭하고 프록시를 선택합니다. 이를 통해 애플리케이션이 실제 IP를 로컬에서 미리 얻을 가능성을 줄이고 도메인 규칙 기반 분배도 쉽게 할 수 있습니다.
다음은 필드 간 관계를 이해하기 위한 기본 예시입니다. 공용 DNS 엔드포인트는 구조를 보여 주기 위한 예일 뿐이며, 실제 배포에서는 네트워크 접근성, 서비스 약관, 개인정보 보호 요구사항을 기준으로 선택해야 합니다. 클라이언트에 내장된 mihomo 버전에 따라 지원 문법이 다를 수 있으므로 변경 전에 현재 커널 문서를 확인하고 기존 설정을 보관하세요.
dns:
enable: true
listen: 0.0.0.0:1053
ipv6: true
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
fake-ip-filter-mode: blacklist
fake-ip-filter:
- "*.lan"
- "localhost.ptlogin2.qq.com"
- "time.*.com"
default-nameserver:
- 223.5.5.5
- 1.1.1.1
nameserver:
- https://dns.alidns.com/dns-query
- https://1.1.1.1/dns-query
proxy-server-nameserver:
- https://dns.alidns.com/dns-query
respect-rules: true
listen은 내장 DNS가 수신 대기할 위치를 결정합니다. 로컬 기기에서만 사용할 때는 클라이언트 구현의 접근 제한 기능을 함께 고려해야 하며, TUN 모드에서는 클라이언트가 리스닝과 하이재킹을 자동으로 관리하는 경우가 많습니다. fake-ip-range는 전용 주소 대역으로 도메인 매핑을 관리하므로 로컬 LAN, 컨테이너 네트워크, 기업 라우팅 대역과 겹치지 않아야 합니다.
fake-ip-filter는 fake-ip에 적합하지 않은 도메인을 제외하는 데 사용합니다. LAN 기기 검색, 시간 동기화, 일부 게임 플랫폼, 실제 로컬 네트워크 주소에 의존하는 서비스는 실제 IP를 반환해야 할 수 있습니다. 필터 항목은 실제 장애를 기준으로 하나씩 추가해야 합니다. 광범위한 도메인을 모두 필터 목록에 넣으면 많은 요청이 다시 실제 IP 조회로 처리되어 fake-ip가 DNS 경로를 통합하는 효과가 약해집니다.
respect-rules를 사용하면 DNS 상위 연결도 규칙을 따르지만, 활성화할 때는 프록시 서버 도메인을 proxy-server-nameserver로 해석할 수 있어야 합니다. 그렇지 않으면 프록시를 연결하려고 DNS를 기다리고, DNS는 다시 프록시를 기다리는 순환 의존성이 생길 수 있습니다. 구버전 Clash나 유지보수가 중단된 일부 파생 버전에는 같은 이름의 필드가 없을 수 있으므로 실제 커널 기능을 기준으로 판단하세요.
nameserver-policy로 도메인별 리졸버 지정하기
도메인마다 다른 DNS 경로가 필요하다면 nameserver-policy를 사용할 수 있습니다. 일반적으로 이 항목은 공통 nameserver보다 우선순위가 높아 내부 도메인, 특정 규칙 세트, 지역 도메인에 리졸버를 지정하기 좋습니다. 정책 범위가 지나치게 넓으면 검사 페이지에 여러 재귀 출구가 표시될 수 있으므로 각 규칙에는 명확한 목적이 있어야 합니다.
dns:
nameserver-policy:
"geosite:cn":
- https://dns.alidns.com/dns-query
"+.internal.example":
- 192.168.10.1
nameserver:
- https://1.1.1.1/dns-query
내부 도메인을 기업 또는 가정용 DNS에 맡기면 해당 요청은 로컬 네트워크로 들어갑니다. 이는 의도한 분기이므로 예기치 않은 누수와 혼동해서는 안 됩니다. 다만 와일드카드 규칙이 일반 공용 도메인까지 덮지 않도록 하고, 내부 리졸버가 신뢰할 수 있는 네트워크에서만 사용되는지도 확인해야 합니다.
fallback을 이해하고 템플릿을 기계적으로 복사하지 않기
일부 설정은 fallback과 fallback-filter를 사용합니다. 커널은 기본 리졸버와 폴백 리졸버에 동시에 질의한 뒤 지리적 IP, 도메인 유형, 예약 주소 등을 기준으로 결과를 선택할 수 있습니다. 이 기능은 주로 DNS 오염, 잘못된 응답, 네트워크별 가용성 문제를 처리하기 위한 것이며 DNS 조회가 자동으로 프록시를 통과하도록 보장하지는 않습니다.
dns:
nameserver:
- https://dns.alidns.com/dns-query
fallback:
- https://1.1.1.1/dns-query
fallback-filter:
geoip: true
geoip-code: CN
geosite:
- gfw
기본 리졸버와 폴백 리졸버가 모두 로컬에서 직접 연결된다면 검사 결과에 원치 않는 경로가 나타날 수 있습니다. 폴백을 설정할 때는 상위 DNS 연결의 라우팅 방식, 원격 엔드포인트의 안정성, 규칙 세트의 정상 로드 여부를 함께 확인해야 합니다. 최신 mihomo 설정에서는 nameserver-policy로 도메인별 선택을 더 명확하게 구현할 수도 있으므로 fallback을 유지할지는 사용 사례에 따라 결정하세요.
TUN 모드에서는 DNS 하이재킹과 애플리케이션 우회를 함께 처리하기
시스템 프록시는 주로 프록시 설정을 따르는 애플리케이션에 영향을 줍니다. 게임, 시스템 서비스, 일부 명령줄 프로그램, 자체적으로 연결을 만드는 소프트웨어는 이를 무시할 수 있습니다. TUN 모드는 가상 네트워크 인터페이스를 통해 더 넓은 IP 트래픽을 가로채므로 UDP, 프록시를 인식하지 못하는 애플리케이션, 시스템 DNS를 통합 처리하는 데 적합합니다. 다만 관리자 권한, 라우팅 설정, 플랫폼 네트워크 스택에 의존합니다.
mihomo의 TUN 설정에는 일반적으로 자동 라우팅과 DNS 하이재킹이 포함됩니다. 구체적인 필드는 버전과 클라이언트 래퍼에 따라 달라질 수 있으며, 대표적인 구조는 다음과 같습니다.
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
dns-hijack은 TUN을 통과하는 기존 53 포트 조회를 내장 DNS로 전달합니다. 활성화한 뒤에는 패킷을 다시 캡처해 요청이 물리 네트워크 카드에서 라우터로 직접 전송되지 않는지 확인해야 합니다. 일부 플랫폼의 보안 프로그램, 가상 머신, 컨테이너, VPN, 기업 네트워크 클라이언트는 더 높은 우선순위의 라우팅 및 필터 드라이버를 설치해 일부 트래픽이 TUN을 우회하게 만들 수 있습니다. 이때는 라우팅 테이블, 인터페이스 우선순위, 클라이언트 로그의 인터페이스 선택을 확인해야 합니다.
DNS 하이재킹은 일반적으로 기존 UDP/TCP 53을 대상으로 합니다. 브라우저 내장 DoH는 HTTPS 443을 사용하므로 53 포트 하이재킹만으로는 가로챌 수 없습니다. 브라우저 보안 DNS가 독립 서비스로 지정되어 있다면 DIRECT로 연결되거나 일반 연결 규칙에 따라 접속할 수 있습니다. 처리 방법은 두 가지입니다. 브라우저의 독립 DNS를 끄고 요청을 시스템과 Clash로 통합하거나, 브라우저 DoH를 유지하면서 해당 엔드포인트에 명확한 프록시 규칙을 지정하세요. 혼합 구성을 사용할 때는 각 경로를 기록해 브라우저 검사 결과를 커널 DNS 장애로 잘못 판단하지 않도록 해야 합니다.
IPv6도 테스트에 포함하기
로컬 네트워크가 IPv6를 지원하면 애플리케이션이 AAAA 레코드를 우선 조회하고 IPv6로 직접 연결할 수 있습니다. IPv4 출구와 A 레코드만 확인하면 이 경로를 놓치게 됩니다. 프록시 노드, 규칙, TUN이 IPv6를 완전히 지원한다면 DNS의 IPv6 기능을 유지한 채 A·AAAA 조회와 듀얼 스택 출구를 각각 테스트하세요. 현재 프록시 체인이 IPv6를 지원하지 않는다면 커널, 시스템 인터페이스, 라우팅 계층에서 일관되게 처리해야 하며, DNS 레코드 하나만 삭제한 뒤 직접 연결 가능한 IPv6 경로를 남겨서는 안 됩니다.
변경 후 정해진 점검 목록으로 재검사하기
누수 방지 설정이 제대로 작동하는지 확인하려면 캐시를 비운 뒤 새로운 조회를 만들어야 합니다. 이미 열려 있는 페이지만 새로 고치면 브라우저, 시스템 또는 Clash의 캐시 결과가 계속 사용될 수 있습니다. 먼저 클라이언트 커널을 재시작하고 시스템 DNS 캐시를 지운 뒤 기존 브라우저 프로세스를 종료하고, 무작위 하위 도메인으로 테스트를 시작하는 것이 좋습니다.
- 커널 설정 적용 여부 확인: 클라이언트 실행 설정과 시작 로그를 확인해 DNS 모듈, fake-ip, TUN에 구문 오류가 없는지 점검합니다.
- 프록시 출구 확인: 브라우저와 시스템 프록시를 따르지 않는 애플리케이션을 각각 테스트해 연결이 규칙에 따라 DIRECT 또는 대상 프록시 그룹으로 들어가는지 확인합니다.
- 브라우저 DNS 테스트 실행: 각 재귀 리졸버의 네트워크 소속을 기록하고 nameserver, 정책 기반 DNS, 브라우저 DoH 설정과 대조합니다.
- 시스템 명령줄 조회 실행: 기본 DNS 조회와 Clash 로컬 포트를 직접 조회한 결과를 비교해 시스템 진입점이 통합되었는지 확인합니다.
- 커널 로그 확인: 새 도메인으로 조회를 발생시켜 요청이 DNS 모듈에 들어가고 상위 요청이 성공하며 규칙과 프록시 체인이 예상대로 작동하는지 확인합니다.
- 물리 인터페이스 트래픽 캡처: 라우터나 공용 서버로 향하는 예기치 않은 53·853 포트 요청이 남아 있는지 확인합니다.
- 듀얼 스택과 장애 전환 테스트: IPv4와 IPv6를 각각 점검하고 상위 DNS 하나를 임시로 중지해 폴백이 계획하지 않은 로컬 리졸버로 전환되지 않는지 확인합니다.
자주 발생하는 문제와 점검 지점
| 증상 | 우선 확인할 항목 | 해결 방향 |
|---|---|---|
| 브라우저에는 로컬 리졸버가 표시되지만 명령줄은 정상 | 브라우저 보안 DNS, 확장 프로그램, 캐시 | 시스템 리졸버로 통합하거나 브라우저 DoH에 명확한 프록시 적용 |
| 시스템 조회는 라우터로 가지만 로컬 포트 직접 조회는 정상 | 시스템 DNS 주소, TUN, dns-hijack | 시스템 진입점을 수정하거나 정상적인 DNS 하이재킹 활성화 |
| respect-rules를 켠 뒤 노드에 연결할 수 없음 | 프록시 서버 도메인 조회 | proxy-server-nameserver를 설정해 시작 의존성 해소 |
| fake-ip를 켠 뒤 LAN 기기가 작동하지 않음 | fake-ip-filter와 로컬 주소 대역 | 영향받은 LAN 도메인에만 제외 항목 추가 |
| 검사 결과에 예상하지 않은 리졸버 두 그룹이 표시됨 | fallback, nameserver-policy, 브라우저 DoH | 항목을 하나씩 비활성화하고 로그로 실제 선택 확인 |
| IPv6에서만 로컬 출구가 표시됨 | AAAA 조회, TUN IPv6 라우팅, 노드 기능 | 듀얼 스택을 일관되게 가로채거나 네트워크 조건에 맞춰 IPv6를 함께 비활성화 |
최종 목표는 검사 페이지에 특정 국가나 정해진 개수의 DNS 주소가 표시되게 하는 것이 아닙니다. 애플리케이션 조회가 예상한 진입점으로 들어가고, Clash가 규칙에 따라 상위 DNS를 선택하며, 상위 연결이 계획한 DIRECT 또는 프록시 정책으로 전송되고, 폴백과 IPv6도 이 설계를 우회하지 않게 만드는 것이 목표입니다. 이 네 단계가 로그, 명령줄, 패킷 캡처로 서로 검증될 때 DNS 누수 점검이 완료됩니다.
계속 설치 및 설정하기
운영체제와 프로세서 아키텍처에 맞는 Clash 클라이언트를 선택한 다음 빠른 시작 안내에 따라 구독 가져오기, 프록시 모드, DNS를 설정하세요.