DNS 누수 판단하기: 먼저 예상 DNS 경로부터 확인
Clash DNS 누수란 도메인 조회가 의도한 DNS 경로를 거치지 않는 상황을 말합니다. 예를 들어 연결은 프록시를 통하지만, 시스템의 DNS 조회는 라우터나 인터넷 서비스 제공업체의 DNS 서버로 전송될 수 있습니다. 웹사이트가 정상적으로 열리고 외부 IP가 프록시 노드로 표시되더라도, 도메인 조회는 다른 경로를 이용할 수 있습니다. 따라서 웹 접속 여부와 DNS가 설정대로 처리되는지는 따로 확인해야 합니다.
먼저 목표를 분명히 하세요. 기존 DNS 조회를 모두 로컬 커널이 처리하게 하려는 것인지, 상위 DNS 서버로 향하는 연결까지 프록시를 통하게 하려는 것인지에 따라 확인할 부분이 다릅니다. 전자는 트래픽 가로채기가 핵심이고, 후자는 DNS 상위 서버 연결의 라우팅 정책도 살펴봐야 합니다. DoH나 DoT를 사용한다는 사실만으로 조회가 암호화되었다고 할 수는 있지만, 프록시 노드에서 전송되었다는 점까지 입증되지는 않습니다.
- 클라이언트: 설정, 시스템 프록시, 서비스 권한과 인터페이스 옵션을 관리합니다.
- 커널: DNS 조회, Fake-IP 매핑, 규칙 매칭과 연결 전달을 처리합니다.
- 구독: 노드, 규칙 또는 전체 설정을 제공합니다. 업데이트 과정에서 로컬 변경 사항이 덮어써질 수 있습니다.
- 애플리케이션: 시스템 리졸버를 사용하거나 자체 DoH를 내장해 시스템 DNS 설정을 우회할 수 있습니다.
점검 단계: 외부 IP, DNS 리졸버, 로컬 트래픽을 나눠 확인
1단계: 프록시를 끈 상태의 기준값 확인
직접 인터넷에 접속해도 되는 테스트 환경에서 시스템 프록시와 TUN을 끄고 공인 IP, 시스템 DNS 주소, DNS 테스트 페이지에 표시되는 리졸버 정보를 기록합니다. 기업 네트워크나 관리 대상 기기에서는 정해진 네트워크 정책을 임의로 해제하지 마세요. 기준값은 비교용일 뿐이며, 테스트 사이트에 표시된 국가나 도시만으로 누수를 판단해서는 안 됩니다.
Windows에서는 PowerShell로 네트워크 어댑터별 DNS를 확인할 수 있습니다. 무선 랜, 이더넷, VPN, 가상 어댑터가 동시에 표시될 수 있으므로 현재 화면의 첫 번째 항목만 확인하지 마세요.
Get-DnsClientServerAddress -AddressFamily IPv4
Get-DnsClientServerAddress -AddressFamily IPv6
ipconfig /all
2단계: 설정을 켜고 같은 항목을 다시 테스트
- 사용하려는 시스템 프록시 또는 TUN을 켠 뒤 현재 적용된 설정과 선택된 정책 그룹을 확인합니다.
- 외부 IP를 다시 확인하고 브라우저의 ‘보안 DNS’ 기능이 켜져 있는지도 기록합니다.
- DNS 테스트를 실행해 리졸버 IP, 소속 및 테스트 시간을 기록하세요. ‘통과’라는 표시만 저장해서는 안 됩니다.
- 클라이언트의 연결 기록이나 디버그 로그에서 상위 DNS 서버 연결을 찾아 대상 주소와 실제로 적용된 아웃바운드 정책을 확인합니다.
- 캐시된 응답을 DNS가 작동하지 않는 것으로 오해하지 않도록, 캐시에 없는 도메인으로 조회를 반복합니다.
공용 DNS는 애니캐스트와 분산형 출구를 사용할 수 있습니다. 테스트 페이지에 표시되는 리졸버 위치가 연결 지점과 일치하지 않을 수 있으며, 프록시 노드가 있는 도시와 다를 수도 있습니다. 일부 도메인은 로컬 리졸버를 사용하도록 설정되어 있다면 로컬 DNS 응답도 의도된 동작일 수 있습니다. 핵심은 응답 결과가 도메인별 정책 및 아웃바운드 기록과 일치하는지 확인하는 것입니다.
3단계: 지정한 로컬 포트로 커널을 검증
커널이 127.0.0.1:1053에서 대기한다고 가정하면, 포트를 지정할 수 있는 dig로 DNS 응답을 확인할 수 있습니다. 여기서 1053은 예시 포트이며 모든 클라이언트의 기본값은 아닙니다. 시스템에 dig가 설치되어 있지 않다면 테스트를 위해 굳이 다른 도구로 바꿀 필요는 없습니다.
dig @127.0.0.1 -p 1053 example.com A
dig @127.0.0.1 -p 1053 example.com AAAA
로컬 리스닝 포트에 직접 조회해 응답을 받았다는 사실은 커널 DNS가 응답한다는 점만 보여 줍니다. 시스템 DNS, TUN 하이재킹, 브라우저의 DNS 처리까지 정상인지 확인하려면 실제 애플리케이션의 요청도 테스트해야 합니다. Windows의 nslookup은 기본적으로 53번 포트를 사용하므로, 1053번 포트에서 대기하는 서비스에 기본 포트로 조회해 실패하더라도 이를 서비스 장애로 단정할 수 없습니다.
Fake-IP: 도메인 매핑을 유지하는 기능이지, 암호화 DNS는 아닙니다
enhanced-mode: fake-ip를 사용하면 커널은 해당 도메인에 가상 IP를 응답하고 도메인과 가상 IP의 매핑을 유지합니다. 이후 애플리케이션이 이 주소에 연결하면 커널이 도메인을 복원해 규칙을 적용하거나 도메인 정보를 프록시 아웃바운드에 전달할 수 있습니다. 실제 주소는 연결 과정의 후반부에서 조회될 수도 있고, 프로토콜과 아웃바운드 구현에 따라 원격 프록시 서버가 처리할 수도 있습니다.
흔히 사용하는 Fake-IP 주소 풀은 198.18.0.1/16입니다. 이 주소 대역은 가상 매핑용이지 노드의 공인 IP가 아닙니다. 조회 결과가 이 범위의 주소라면 모드가 정상 작동하는 경우가 많습니다. 이를 원격 서버 주소로 입력하거나 시스템의 공용 DNS 목록에 수동으로 추가하지 마세요.
| 설정 | 주요 기능 | 이 설정만으로 보장되지 않는 항목 |
|---|---|---|
fake-ip | 가상 IP를 반환하고 도메인 매핑을 저장 | 상위 DNS 조회의 암호화 또는 프록시 아웃바운드 여부 |
redir-host | 애플리케이션에 실제 DNS 응답 주소를 반환 | 애플리케이션의 DNS 요청이 반드시 커널을 거치는지 여부 |
fake-ip-filter | 필터 규칙에 맞는 도메인을 처리하며, 실제 주소를 반환할 때 주로 사용 | 프록시 분기 규칙을 대체하는 기능 |
로컬 네트워크 검색, 일부 기기 관리 페이지, 실제 주소에 의존하는 애플리케이션에는 예외 설정이 필요할 수 있습니다. 먼저 해당 도메인만 지정한 뒤 범위를 넓히세요. 다수의 공용 도메인을 Fake-IP 필터 목록에 추가하면 DNS 응답 방식이 달라져 문제 원인을 파악하기 어려워질 수 있습니다. 필터 목록은 DNS 응답 방식을 제어하고 rules는 연결의 아웃바운드를 제어하므로 서로 대체할 수 없습니다.
nameserver 설정: 일반 도메인 조회와 초기 조회 구분하기
아래는 각 필드의 역할을 설명하기 위한 mihomo DNS 설정 예시이며, 완성된 구독 설정이 아닙니다. 기존 노드, 정책 그룹과 규칙은 유지한 채 해당 필드만 실제 적용 설정에 병합하세요. 같은 YAML 계층에는 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"
- "localhost"
default-nameserver:
- 223.5.5.5
nameserver:
- https://dns.alidns.com/dns-query
proxy-server-nameserver:
- https://dns.alidns.com/dns-query
listen: 루프백 주소에 바인딩해 DNS 서비스를 로컬 네트워크에 직접 노출하지 않도록 합니다. 다른 기기에서도 사용해야 한다면 접근 범위도 별도로 설정하세요.default-nameserver: 주로 DNS 상위 서버의 도메인을 조회하는 데 사용합니다. 시작 단계에서 ‘리졸버 주소를 먼저 알아내야 하는’ 문제를 해결합니다.nameserver: 일반 도메인 조회에 사용할 상위 서버 목록입니다. 실제 처리 방식에는 도메인별 정책 등 다른 필드도 영향을 줍니다.proxy-server-nameserver: 프록시 노드의 도메인을 조회합니다. 아직 구축되지 않은 프록시 경로에 노드 조회가 의존하는 상황을 방지하는 데 도움이 됩니다.ipv6: false: 해당 DNS 모듈의 IPv6 응답을 제한합니다. 운영체제의 IPv6를 끄거나 모든 IPv6 연결을 차단하는 설정은 아닙니다.
DoH 연결을 위해 인증서 검증을 끄지 마세요. 시스템 시간, 상위 서버 주소, 네트워크 연결 상태와 초기 DNS 조회를 먼저 점검하세요. DNS 상위 서버 연결에도 분기 규칙을 적용하려면 mihomo의 respect-rules 같은 설정을 사용할 수 있지만, 노드 도메인 조회와 DNS 상위 서버의 아웃바운드 의존성도 함께 처리해야 합니다. 규칙을 확인하지 않고 respect-rules: true만 추가하면 DNS 조회가 순환하거나 여전히 직결 정책이 적용될 수 있습니다.
fallback과 도메인 정책: 대체 DNS는 기본 서버 실패 후에만 작동하지 않습니다
fallback은 ‘첫 번째 DNS가 시간 초과된 경우에만 대체 DNS를 조회한다’는 뜻으로 오해하기 쉽습니다. fallback을 사용하는 일반적인 조회 과정에서는 커널이 기본 리졸버와 fallback에 동시에 요청한 뒤 fallback-filter를 기준으로 결과를 선택할 수 있습니다. 따라서 공용 리졸버를 fallback에 넣어도 평소에 조회가 전달되지 않는다는 뜻은 아닙니다.
fallback-filter는 지리 정보, IP 대역, 도메인 등의 조건에 따라 결과 선택에 영향을 줄 수 있습니다. 지리 정보 데이터베이스가 오래되었을 수 있고 CDN이 다른 지역의 주소를 반환할 수도 있습니다. 특정 지역 코드를 일반적인 DNS 오염 판정 기준으로 삼아서는 안 됩니다. 문제를 점검할 때는 검증 가능한 상위 서버부터 사용하고 필요에 따라 fallback을 추가하세요. 리졸버를 한꺼번에 여러 개 설정하는 것보다 원인을 찾기 쉽습니다.
도메인별 상위 서버 지정: nameserver-policy
로컬 네트워크 도메인은 보통 내부 DNS가 필요합니다. 아래 예시는 +.home.arpa를 192.168.1.1로 전달합니다. 해당 주소가 현재 네트워크의 내부 DNS 서버인 경우에만 사용하세요. 이는 명시적으로 지정한 로컬 조회 경로이므로 ‘모든 조회가 프록시 노드에서 나가야 한다’를 기준으로 삼아서는 안 됩니다.
dns:
nameserver-policy:
"+.home.arpa":
- 192.168.1.1
이 내용은 필드 일부에 불과하므로 앞서 나온 기존 dns 매핑에 병합해야 합니다. 파일 끝에 같은 키를 중복으로 추가하지 마세요. 실제 내부 IP가 필요한 도메인이라면 Fake-IP 필터 정책도 확인해야 합니다. 도메인 조회가 내부 DNS를 사용한다고 해서 애플리케이션 연결도 자동으로 내부 네트워크를 이용하는 것은 아닙니다. 해당 연결을 허용하는 LAN 규칙도 필요합니다.
TUN DNS 하이재킹: 53번 포트 가로채기는 모든 DNS 조회를 가로채는 것이 아닙니다
시스템 프록시는 프록시 설정을 따르는 애플리케이션에 주로 적용되며, 시스템 DNS를 일괄적으로 가로채지는 않습니다. TUN은 가상 네트워크 어댑터와 라우팅으로 트래픽을 처리하고, dns-hijack를 함께 설정해야 조건에 맞는 기존 DNS 요청을 커널로 전달할 수 있습니다. 아래 설정은 클라이언트 서비스 권한과 해당 플랫폼의 지원이 필요합니다. 기존 TUN 설정에 병합하세요.
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
- tcp://any:53
any:53은 UDP 53번 포트 조회를 매칭하고, tcp://any:53은 TCP 53번 포트를 추가로 처리합니다. 실제 가로채기 결과는 운영체제 라우팅, TUN 스택, 제외된 네트워크 대역, 다른 VPN의 영향을 받습니다. 특히 LAN DNS를 향하는 요청이 TUN으로 들어오는지는 패킷 캡처로 확인하세요. 네트워크 어댑터를 바꾼 뒤에도 다시 테스트해야 합니다. 시작할 때 연결된 한 네트워크만 확인해서는 안 됩니다.
별도로 확인해야 할 세 가지 트래픽
- 브라우저 DoH: 대개 HTTPS 443 연결로 처리되므로 53번 포트 하이재킹 규칙이 자동으로 바꾸지 않습니다. 문제를 점검할 때는 브라우저의 보안 DNS를 잠시 끄거나, 명확한 암호화 DNS 구성에 포함하세요.
- DoT 및 기타 암호화 DNS: DoT는 보통 TCP 853 포트를 사용합니다. 애플리케이션 내부의 암호화 DNS는 실제 프로토콜과 아웃바운드 연결을 기준으로 점검해야 합니다.
- IPv6 및 다중 네트워크 어댑터: IPv4가 가로채졌다고 IPv6도 가로채졌다고 볼 수는 없습니다. IPv6 라우팅, DNS 주소와 클라이언트 지원 여부를 확인하고
dns.ipv6옵션에만 의존하지 마세요.
패킷 캡처에는 udp.port == 53 || tcp.port == 53을 Wireshark 표시 필터로 사용할 수 있습니다. 물리 네트워크 어댑터에서 예상하지 않은 리졸버로 평문 DNS가 계속 전송된다면 원인을 추적해야 합니다. 루프백이나 가상 어댑터에서 가로채기 전의 조회가 보이는 것만으로 외부 누수라고 단정할 수는 없습니다. 이 필터로는 DoH의 실제 조회 내용을 볼 수 없으며, 다른 포트에 DNS 트래픽이 없다는 점도 증명할 수 없습니다.
문제 해결 순서와 설정 검증
| 증상 | 먼저 확인할 항목 | 확인 방법 |
|---|---|---|
| 로컬 1053 포트에 응답이 없음 | DNS 옵션, 포트 충돌, 설정 로드 오류 | 커널 시작 로그와 포트 리스닝 상태 확인 |
| 로컬 조회는 정상인데 브라우저 결과가 다름 | 브라우저 보안 DNS, 캐시, 프록시 확장 프로그램 | DNS 설정을 통일한 뒤 새 도메인으로 다시 테스트 |
| TUN을 켜면 모든 도메인 조회가 시간 초과됨 | 권한, 상위 서버 연결 상태, DNS 조회 순환 | 노드 도메인과 초기 상위 DNS 조회부터 확인 |
| 공용 도메인은 정상인데 내부 네트워크 이름은 조회되지 않음 | 도메인별 상위 서버 정책, Fake-IP 필터, LAN 규칙 | 내부 DNS와 커널 DNS에 각각 조회해 비교 |
| 구독을 업데이트한 뒤 문제가 다시 발생함 | 설정 덮어쓰기 순서와 실제 적용된 설정 | 업데이트 전후 DNS 및 TUN 필드 비교 |
DNS 모드나 상위 서버를 변경한 뒤에는 관련 캐시를 지우고 다시 테스트하세요. Windows에서는 ipconfig /flushdns를 실행해 시스템 캐시를 비울 수 있습니다. 브라우저와 커널도 별도 캐시를 보유할 수 있으므로 각자의 캐시 삭제 기능을 사용하거나 재시작해야 합니다. 이미 연결된 세션은 DNS를 다시 조회하지 않을 수 있으니, 오래 유지된 페이지를 새로 고치는 데 그치지 말고 새 연결을 만들어 테스트하세요.
- 설정 적용 확인: 커널이 설정을 정상적으로 불러왔고 DNS 리스닝 주소와 포트가 테스트 명령과 일치합니다.
- 가로채기 확인: 실제 애플리케이션의 일반 DNS 요청이 의도한 대로 커널을 거치며, 예외 경로의 목적도 명확합니다.
- 상위 서버 확인: 일반 조회, 초기 조회, 노드 도메인 조회에 각각 어떤 상위 서버가 사용되는지 설명할 수 있습니다.
- 아웃바운드 확인: 프록시를 거쳐야 하는 DNS 상위 서버 연결에 올바른 정책이 적용되는지 확인합니다. DoH 주소만으로 추정해서는 안 됩니다.
- 재시작 후 확인: 클라이언트 재시작, 구독 업데이트, 네트워크 변경 후에도 다시 점검해 설정이 유지되는지 확인합니다.
DNS 누수 방지는 스위치 하나로 해결되지 않습니다. 애플리케이션의 DNS 처리 방식, 시스템 라우팅, 커널 설정과 상위 서버 연결이 함께 작동해야 합니다. Fake-IP는 도메인 매핑을, nameserver는 DNS 서버 선택을, TUN 하이재킹은 조건에 맞는 요청의 가로채기를 담당합니다. 세 항목을 각각 검증해야 문제가 발생한 계층을 찾을 수 있습니다. 자세한 개념은 Fake-IP 프로토콜 참고 자료를, 설정 가져오기와 덮어쓰기 방법은 사용 가이드를 확인하세요.