DNS 누수와 DNS 리졸버 위치 차이부터 구분하기
Clash에서 프록시를 켰는데 DNS 테스트 페이지에 현재 이용 중인 통신사가 표시된다면, 일부 DNS 요청이 기기의 네트워크를 통해 직접 전송되고 있을 수 있습니다. 하지만 테스트 결과에 여러 국가나 리졸버가 표시된다고 해서 반드시 누수인 것은 아닙니다. 먼저 어떤 도메인은 로컬에서 조회해도 되는지, 어떤 도메인은 프록시를 통해 조회해야 하는지 정한 뒤 하나씩 확인하세요.
이 문서의 설정은 Clash Meta(mihomo) 코어를 기준으로 합니다. 구버전 Clash와 일부 모바일 클라이언트, 다른 프록시 도구는 지원하는 설정 항목이 다를 수 있습니다. 변경하기 전에 클라이언트의 코어 정보나 실행 로그에서 코어 이름을 확인하고 현재 설정을 백업하세요. 클라이언트 이름만 보고 respect-rules 또는 아래 TUN 설정의 지원 여부를 판단하지 마세요.
| 확인된 결과 | 가능한 원인 | 다음 단계 |
|---|---|---|
| 페이지에 표시된 출구 IP가 프록시 노드에 속함 | 웹 연결은 프록시를 통하지만 DNS 경로는 아직 확인되지 않음 | DNS 확장 테스트 진행 |
| 리졸버에 현재 이용 중인 통신사가 표시됨 | 시스템, 브라우저 또는 코어가 상위 DNS에 직접 연결했을 가능성 | 로그와 53번 포트 패킷 캡처 대조 |
| 공용 DNS 사업자가 리졸버로 표시됨 | 요청이 공용 재귀 리졸버에 도달함 | 해당 리졸버로 향하는 연결의 출구 경로 확인 |
| 예상한 국내외 리졸버가 함께 표시됨 | 도메인별 DNS 조회를 의도적으로 설정한 결과일 수 있음 | 리졸버 수가 아니라 설정한 정책에 따라 판단 |
기준 결과 만들기: 노드, 브라우저, 테스트 조건 고정
세 가지 조건별로 결과 기록
- 프록시 끄기: 공인 IP, 통신사 이름, DNS 테스트 결과를 기록해 로컬 네트워크의 기준값으로 삼습니다.
- 시스템 프록시만 켜기: 같은 노드를 유지하고 TUN을 끈 채 표준 테스트와 확장 테스트를 다시 실행합니다. 시스템 프록시는 프록시 설정을 따르는 앱을 주로 처리하며, 시스템의 모든 DNS 요청을 자동으로 가져오지는 않습니다.
- TUN 켜기: 노드, 규칙, 브라우저를 그대로 둔 상태에서 DNS 하이재킹을 켜고 다시 테스트합니다. 리졸버 주소와 테스트 시간, 현재 이용 중인 통신사가 표시되는지 기록하세요.
DNS leak test 또는 BrowserLeaks의 DNS 테스트 페이지를 사용할 수 있습니다. 매번 테스트를 새로 실행하고, 페이지에 남은 이전 결과를 새 결과로 착각하지 마세요. 두 차례 연속 테스트하세요. 한 번만 이상이 나타난다면 브라우저 캐시, 노드 변경 여부, 설정을 다시 불러왔는지부터 확인합니다.
브라우저 자체 DNS를 일시적으로 끄기
데스크톱 Chrome에서는 보통 「설정」→「개인 정보 보호 및 보안」→「보안」→「보안 DNS 사용」에서 설정합니다. Firefox에서는 대개 「설정」→「개인 정보 보호 및 보안」→「DNS over HTTPS」에 있습니다. 테스트하는 동안 브라우저 자체 DoH를 먼저 끄세요. 메뉴 이름은 버전에 따라 달라질 수 있습니다. 문제를 해결한 뒤 DoH를 다시 켜려면 해당 연결의 출구 경로를 별도로 확인하세요.
시크릿 창을 열어도 보안 DNS가 자동으로 꺼지지는 않습니다. 브라우저가 HTTPS로 별도 리졸버에 연결하면 보통 443번 포트를 사용합니다. TUN이 이 연결을 처리하더라도 dns-hijack의 53번 포트 규칙이 해당 연결을 코어의 DNS 조회로 바꾸지는 않습니다.
- Windows에서 시스템 DNS 캐시를 비우려면
ipconfig /flushdns를 실행합니다. - systemd-resolved를 사용하는 Linux에서는
resolvectl flush-caches를 실행할 수 있습니다. 다른 배포판은 실제 DNS 서비스에 맞는 방법을 사용하세요. - 클라이언트의 DNS 캐시도 지우거나 클라이언트를 다시 시작한 다음, 테스트 페이지를 닫았다가 다시 여세요. 시스템 캐시만 지워서는 모든 앱의 캐시가 삭제되지 않습니다.
fake-ip의 역할: 도메인 매핑을 유지하며 조회를 자동으로 숨기지는 않음
enhanced-mode: fake-ip는 조건에 맞는 도메인에 합성 IP 주소를 반환합니다. 흔히 사용하는 주소 풀은 198.18.0.1/16입니다. 앱이 이 주소에 연결하면 mihomo가 매핑된 도메인을 복원한 뒤 규칙과 출구 처리를 적용합니다. 따라서 기기에서 198.18로 시작하는 DNS 결과가 보이는 것은 일반적으로 정상이며, 원격 서버가 실제로 해당 IP 대역에 있다는 뜻은 아닙니다.
fake-ip는 앱에 반환되는 DNS 응답을 바꿉니다. 이후 실제 DNS 조회가 필요한지, 어느 리졸버가 처리하는지, 조회 요청이 직접 연결되는지 프록시를 통하는지는 연결 방식, 출구 프로토콜, DNS 설정에 따라 달라집니다. fake-ip만 켜서는 모든 상위 DNS 조회가 프록시를 통한다고 보장할 수 없습니다.
필터 목록은 호환성 예외에만 사용
로컬 네트워크 기기 검색, 프린터, 실제 IP 주소에 의존하는 일부 프로그램에는 fake-ip-filter가 필요할 수 있습니다. 예를 들어 +.lan, +.local을 로컬 도메인 확인의 출발점으로 삼을 수 있지만, 해당 이름에 응답할 로컬 DNS 서비스가 여전히 필요합니다. 필터 목록에 이름을 추가해도 mDNS가 자동으로 활성화되거나 라우터가 자동으로 검색되지는 않습니다.
특정 앱의 문제를 해결하려고 모든 도메인을 필터 목록에 넣지 마세요. 먼저 문제가 발생한 도메인을 확인하고 예외 범위를 최소화한 뒤 해당 도메인의 DNS 경로를 다시 테스트합니다. 실제 IP를 반환하는 것과 DNS가 유출되는 것은 서로 다른 문제입니다.
설정 예시: 도메인별 DNS 조회와 상위 연결 경로
아래는 참고용 mihomo dns 및 tun 설정 예시이며, 전체 구독 설정이 아닙니다. 기존 노드, 정책 그룹, 규칙은 유지하세요. 같은 이름의 필드가 이미 있다면 기존 항목에 병합하고, 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'
- '+.local'
respect-rules: true
default-nameserver:
- 223.5.5.5
- 119.29.29.29
proxy-server-nameserver:
- https://dns.alidns.com/dns-query
nameserver:
- https://1.1.1.1/dns-query
nameserver-policy:
'+.cn':
- https://dns.alidns.com/dns-query
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
- tcp://any:53
| 항목 | 예시에서의 역할 |
|---|---|
default-nameserver | DNS 서버 도메인을 조회하기 위한 초기 리졸버이며, 모든 서비스 도메인의 기본 상위 서버는 아님 |
proxy-server-nameserver | 프록시 노드 도메인을 별도로 조회해 프록시 연결 전 DNS 의존성 순환을 줄임 |
nameserver | DNS 조회 정책에 일치하지 않은 일반 도메인 요청 처리 |
nameserver-policy | 조회 도메인에 따라 리졸버를 선택하며 웹 연결에 사용할 프록시 노드는 지정하지 않음 |
respect-rules | DNS 상위 서버 연결에 라우팅 규칙을 적용하되 실제로 선택된 출구는 별도 확인 필요 |
이 예시에서 추가로 확인할 사항
- 상위 서버 출구: 일반 도메인을 프록시를 통해 조회하려면
1.1.1.1:443연결이DIRECT가 아니라 의도한 프록시 그룹에 연결되는지 확인하세요. 직접 연결된다면 기존 규칙의 순서와 대상을 조정해야 합니다.respect-rules: true한 줄에만 의존해서는 안 됩니다. - 중국 본토 도메인 조회:
+.cn은 해당 도메인 범위만 일치시키며, 중국 본토의 모든 웹사이트를 뜻하지 않습니다. 중국 본토 서비스도 .com을 사용할 수 있고, 해외 서비스도 .cn을 사용할 수 있습니다. 필요하면 실제 도메인에 맞는 세부 정책을 추가하세요. - 초기 DNS 조회: 예시에는 로컬에서 연결할 수 있는 초기 리졸버와 노드 도메인용 리졸버가 그대로 포함되어 있습니다. 이 조회는 직접 전송될 수 있습니다. 노드 도메인을 포함한 모든 DNS 조회가 로컬 네트워크를 거치지 않도록 하려면 연결 가능한 초기 조회 경로를 별도로 설계해야 합니다. 이 설정을 그대로 복사하지 마세요.
- DoH 연결 가능 여부: HTTPS는 전송 내용을 암호화하지만 연결이 프록시를 통한다는 뜻은 아닙니다. 현재 네트워크에서 해당 리졸버에 직접 연결할 수 없다면 먼저 라우팅을 해결하거나 연결 가능한 상위 서버로 바꾸세요.
TUN DNS 하이재킹: 53번 포트는 처리하지만 모든 DNS 프로토콜을 처리하지는 않음
예시에는 UDP와 TCP 53번 포트 하이재킹을 모두 지정했습니다. 관련 패킷이 실제로 TUN에 들어와야 적용됩니다. 다른 VPN, 정적 라우팅, 앱의 인터페이스 바인딩이 TUN을 우회하면 이 규칙은 작동하지 않습니다. auto-route는 라우팅을 자동 설정하고 auto-detect-interface는 출구 인터페이스를 찾습니다. 둘 다 시스템 권한과 실제 라우팅 테이블을 함께 확인해야 합니다.
수신 포트와 하이재킹 대상은 서로 다름
listen: 127.0.0.1:1053은 코어가 로컬 DNS 수신 주소를 제공한다는 뜻입니다. 반면 dns-hijack은 TUN으로 들어온 지정 DNS 요청을 코어에 전달합니다. TUN 하이재킹을 켰다고 시스템 DNS를 반드시 “127.0.0.1:1053”으로 설정할 필요는 없습니다. 대부분의 시스템 DNS 설정 화면은 포트를 포함한 주소도 지원하지 않습니다.
루프백 주소에서만 수신하면 외부 기기의 접근을 제한할 수 있습니다. 로컬 네트워크 기기에 DNS를 제공하려면 수신 주소, 방화벽, 게이트웨이를 별도로 설계하세요. 이 기기의 누수를 해결하려고 모든 인터페이스에 개방하지 마세요.
- DNS over TLS: 일반적으로 TCP 853번 포트를 사용하므로 위의 53번 포트 규칙 두 개에는 해당하지 않습니다.
- DNS over HTTPS: 보통 HTTPS 443번 포트를 사용하므로 일반 네트워크 연결과 동일하게 출구 경로를 확인해야 합니다.
- Android 비공개 DNS: 문제를 확인하는 동안 시스템의 「비공개 DNS」 설정에서 사용자 지정 제공업체를 끈 뒤 클라이언트 DNS를 테스트할 수 있습니다.
- IPv6:
dns.ipv6: false는 코어의 AAAA 조회 처리 방식을 제어합니다. 시스템 IPv6를 끄거나 기존 IPv6 연결을 자동으로 처리하지는 않습니다.
재테스트 및 문제 위치 확인: 로컬 요청에서 상위 연결까지 추적
설정이 실제 적용됐는지 먼저 확인
- 오버라이드를 저장하고 설정을 다시 불러온 뒤, 로그에서 알 수 없는 필드, YAML 들여쓰기 오류, 포트 바인딩 오류가 있는지 확인합니다.
- TUN 어댑터와 관련 서비스가 실행 중인지 확인합니다. Windows에서는 보통 클라이언트 서비스나 적절한 권한이 필요합니다. 화면에서 스위치를 켰다고 라우팅이 설정된 것은 아닙니다.
- 로그 상세 수준을 일시적으로 높여 테스트 중 도메인, 규칙, 출구 기록을 확인합니다. 문제를 해결한 뒤에는 평소 사용하는 로그 수준으로 되돌리세요.
- 캐시를 지우고 같은 노드로 테스트를 다시 실행한 다음 새 결과를 처음 기록한 기준값과 비교합니다.
dig가 설치된 기기에서는 코어의 수신 주소로 직접 질의해 DNS 모듈이 응답하는지 먼저 확인할 수 있습니다.
dig @127.0.0.1 -p 1053 example.com A
dig @127.0.0.1 -p 1053 example.com AAAA
fake-ip 모드에서는 A 조회가 합성 IP를 반환할 수 있습니다. 예시처럼 DNS IPv6를 끄면 AAAA 조회에 주소가 반환되지 않을 수 있습니다. 아래 명령은 코어에 직접 질의해 수신 주소만 확인할 뿐, 시스템 요청이 TUN에 의해 처리되는지는 검증하지 않습니다. 일반 앱에서 연결을 시도하고 라우팅을 관찰해야 합니다.
패킷 캡처로 남아 있는 우회 경로 확인
TUN 가상 어댑터만 보지 말고 실제 물리 네트워크 어댑터에서 패킷을 캡처하세요. Wireshark에서는 다음 표시 필터를 사용할 수 있습니다. 853번 포트는 흔히 쓰이는 암호화 DNS 연결을 찾는 데 도움이 되지만 모든 암호화된 DNS 방식을 포착하지는 않습니다.
udp.port == 53 || tcp.port == 53 || tcp.port == 853
기기에서 통신사 DNS로 일반 도메인 조회가 계속 전송된다면 시스템 DNS 서비스, 브라우저, 다른 VPN, TUN 제외 라우트를 확인하세요. 초기 리졸버나 노드 도메인 조회만 보인다면 앞서 정한 범위에 비춰 정상인지 판단합니다. DoH는 443번 포트를 사용하므로 이 필터에서 결과가 없다고 모든 문제가 해결됐다고 볼 수는 없습니다.
자주 묻는 질문 및 완료 기준
fake-ip를 켰는데도 테스트 페이지에 통신사가 표시되면 어떻게 하나요?
테스트 요청이 코어에 들어왔는지 먼저 확인하세요. 들어왔다면 상위 DNS 연결의 출구와 기존 fallback을 확인합니다. 들어오지 않았다면 브라우저 자체 DNS, 시스템 비공개 DNS, TUN 라우팅부터 확인하세요. fake-ip 주소 풀을 계속 바꾸는 것으로는 이런 경로 문제를 해결하기 어렵습니다.
nameserver-policy가 해당 웹사이트를 자동으로 직접 연결하나요?
아닙니다. nameserver-policy는 도메인을 어느 리졸버에 전달할지 결정합니다. 웹사이트 연결의 출구는 rules, 모드, 정책 그룹 설정이 결정합니다. DNS 서버 연결의 출구와 대상 웹사이트 연결의 출구를 각각 확인하고 하나의 연결로 혼동하지 마세요.
네트워크를 바꾸면 왜 다시 문제가 생기나요?
Wi-Fi와 유선 네트워크를 전환하면 게이트웨이, 인터페이스, 시스템 DNS가 바뀝니다. 절전 모드에서 복귀한 뒤에는 이전 라우트가 남을 수도 있습니다. TUN 서비스, 기본 인터페이스, 로컬 DNS 수신 주소를 다시 확인하고 캐시를 지운 뒤 테스트하세요. 클라이언트를 끈 뒤 시스템에서 DNS 조회가 되지 않는다면 먼저 시스템 DNS와 라우트를 복구하고 기본 네트워크 연결이 정상인지 확인한 다음 설정을 불러오세요.
어떤 상태여야 문제가 해결된 건가요?
- 프록시를 통해 조회해야 하는 테스트 도메인의 상위 연결이 의도한 프록시 출구를 사용합니다.
- 일반 앱의 53번 포트 조회가 코어로 들어오고, 물리 네트워크 어댑터에서 정책에 어긋나는 평문 조회가 나타나지 않습니다.
- 브라우저 DoH, 시스템 비공개 DNS, IPv6 경로를 각각 확인합니다. 한 경로만 끄는 것으로는 충분하지 않습니다.
- 구독 업데이트, 클라이언트 재시작, 네트워크 전환 후에도 다시 테스트해 오버라이드와 라우팅이 계속 적용되는지 확인합니다.
DNS 보호의 핵심은 조회 경로를 설명하고 다시 테스트할 수 있게 만드는 것입니다. fake-ip는 도메인 매핑을 제공하고 nameserver-policy는 리졸버를 선택하며 TUN 하이재킹은 요청 진입점을 통일합니다. 마지막으로 라우팅 규칙으로 상위 연결의 출구를 정해야 합니다. 네 단계가 모두 맞아야 테스트 결과를 명확히 해석할 수 있습니다.