DNS 유출이란 무엇이고, 프록시가 연결돼도 왜 발생할 수 있는가
웹페이지가 열리고 속도 측정도 되고 지연이 정상으로 보인다고 해서 이번 접속이 완전히 프록시를 경유했다는 뜻은 아닙니다. DNS 유출이란 도메인 이름 해석 요청이 프록시 터널을 거치지 않고, 로컬 시스템에 설정된 DNS 서버(대개 통신사 DNS나 라우터가 할당한 DNS)로 직접 전송되는 것을 말합니다. 결과적으로 웹 데이터는 프록시를 경유했지만, "어떤 도메인에 접속하려는지"라는 정보는 로컬 네트워크의 DNS 서버에 노출되며, 외부 관찰자 입장에서는 접속 기록의 대략적인 윤곽이 여전히 재구성될 수 있습니다.
이 문제는 순수 규칙 모드(시스템 프록시 + 애플리케이션 계층 분기)에서 특히 자주 발생합니다. 대부분의 클라이언트는 시스템 프록시를 HTTP/SOCKS5로 설정하지만, 운영체제 자체가 발생시키는 DNS 조회(UDP 53 포트)는 기본적으로 이 프록시 경로를 거치지 않고 네트워크 인터페이스에 설정된 기본 DNS로 직행합니다. 일부 앱은 자체 DNS 해석 로직(예: 브라우저의 DoH)을 사용해 시스템 프록시의 제약을 더욱 벗어납니다. 그래서 "연결이 정상이다"와 "DNS가 깨끗하다"는 별개로 확인해야 하는 사안입니다.
또 다른 흔한 원인은 정책 그룹 전환입니다. 프록시 규칙에서 도메인 분기가 불완전하게 작성되어 특정 도메인이 DIRECT(직접 연결) 정책에 매칭되면, 해당 도메인의 DNS 조회 역시 로컬 기본 해석 경로를 거칠 가능성이 큽니다. 이 역시 유출에 해당하지만 범위가 더 좁고 은밀해 평소에는 발견하기 어렵습니다.
두 가지 검사 방법: 온라인 검사와 로컬 패킷 캡처
DNS 유출 여부를 확인하려면 온라인 도구와 로컬 패킷 캡처를 함께 사용하는 것이 좋습니다. 전자는 빠르게 결론을 주고, 후자는 정확히 어떤 조회가 유출됐는지 짚어낼 수 있습니다.
온라인 검사: DNS 서버의 소속을 확인
DNS 유출 검사를 지원하는 사이트를 열어, Clash가 켜져 있고 프록시가 적용된 상태에서 검사를 실행하면 페이지에 실제로 DNS 조회를 처리한 서버의 IP와 소속 지역이 표시됩니다. 정상이라면 이 서버들은 프록시 노드가 위치한 데이터센터나 설정에서 지정한 퍼블릭 DNS(예: Cloudflare, Google Public DNS의 IP 대역)에 속해야 하며, 사용 지역 통신사의 DNS 대역이어서는 안 됩니다. 검사 결과에 로컬 통신사 DNS가 나타난다면 실제로 유출이 있는 것입니다.
이런 검사를 할 때 두 가지에 주의하세요. 첫째, 노드를 전환한 뒤 몇 초 기다렸다가 검사해 정책 그룹과 DNS 캐시가 적용될 시간을 줘야 합니다. 둘째, 여러 번 검사하고 여러 검사 사이트로 교차 검증하세요. 한 번의 결과는 캐시 영향으로 가짜 음성이 나올 수 있습니다.
로컬 패킷 캡처: 유출된 정확한 도메인 찾기
온라인 검사는 "유출 여부"만 알려줄 뿐, "어떤 도메인이 유출됐는지" 알려면 패킷 캡처가 필요합니다. Windows에서는 Wireshark로 로컬 네트워크 인터페이스 트래픽을 캡처하면서 필터 조건에 udp.port == 53 || tcp.port == 853을 입력하세요. 각각 일반 DNS와 DNS over TLS에 해당합니다. 정상 작동 시 통신사 DNS나 라우터 게이트웨이 주소로 향하는 53번 포트 트래픽이 거의 보이지 않아야 합니다. 만약 보인다면 해당 패킷을 열어 Query 필드를 확인하면 정확히 어떤 도메인이 유출됐는지 알 수 있습니다.
macOS와 Linux에서는 명령줄 도구를 바로 사용할 수 있습니다:
sudo tcpdump -i any port 53 -n
실행 후 몇 개 사이트를 정상적으로 탐색하면서 출력된 목적지 주소가 모두 Clash 설정에서 지정한 DNS를 가리키는지 확인하세요(예를 들어 fake-ip 모드에서는 시스템 계층에서 내부망 가상 DNS 트래픽이 보여야 하며, 외부 53번 포트로 직접 연결되는 트래픽이 보이면 안 됩니다). 외부 DNS 서버로 직접 연결되는 패킷이 대량으로 캡처된다면 설정에 결함이 있다고 거의 확신할 수 있습니다.
enhanced-mode: fake-ip 원리와 설정 방법
Clash(및 Meta 커널 mihomo)가 제공하는 DNS 강화 해석은 유출 문제를 해결하는 가장 직접적인 방법입니다. 핵심 설정 항목은 dns.enhanced-mode이며, 흔히 쓰는 값은 fake-ip입니다. 동작 원리는 다음과 같습니다: 클라이언트가 시스템 DNS 요청 입구를 가로채, 앱이 도메인 해석을 요청하면 실제 공인 IP를 시스템에 돌려주지 않고 사설 주소 풀에서 "가짜 IP"를 할당해 해석 결과로 반환합니다. 앱은 이 가짜 IP로 정상적으로 연결을 시도하고, Clash 커널은 트래픽이 프록시 경로를 지날 때 이 가짜 IP로부터 실제 도메인을 역조회해 해당 정책 그룹과 실제 서버 주소로 처리합니다.
이렇게 하면 시스템과 애플리케이션 계층에서 실제 도메인 해석 요청이 외부 DNS 서버로 나가는 것을 전혀 볼 수 없게 되고, DNS 조회 단계 전체가 Clash 자체의 처리 경로 안에 완전히 포함되어 근본적으로 유출을 막을 수 있습니다. 대표적인 설정은 다음과 같습니다:
dns:
enable: true
listen: 0.0.0.0:1053
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
fake-ip-filter:
- '*.lan'
- localhost.ptlogin2.qq.com
- +.market.xiaomi.com
각 항목 설명: enable은 내장 DNS 서버를 켭니다. listen은 내장 DNS가 대기하는 로컬 포트를 지정하며, 시스템이나 TUN 네트워크 인터페이스가 해석 요청을 이곳으로 전달합니다. enhanced-mode를 fake-ip로 설정하면 가짜 주소 매핑이 활성화됩니다. fake-ip-range는 가짜 주소 풀의 대역을 지정하며, 보통 예약 대역을 사용해 실제 로컬 네트워크와의 충돌을 피합니다. fake-ip-filter는 화이트리스트로, 여기에 나열된 도메인(로컬 네트워크 기기 탐색, 일부 은행 앱의 인증서 바인딩 검사에서 흔히 볼 수 있음)은 가짜 주소가 아닌 실제 IP를 반환받아 기능 오류를 방지합니다.
강조할 점은, fake-ip는 시스템이 실제로 DNS 조회를 Clash의 내장 서버로 넘길 때만 작동한다는 것입니다. TUN 모드에서는 네트워크 인터페이스 계층이 모든 트래픽을 가로채므로 DNS 요청이 자연스럽게 여기로 흡수되어 유출 방지 효과가 가장 확실합니다. 순수 시스템 프록시 모드에서는 클라이언트가 시스템 DNS 설정을 자신의 리스닝 포트로 바꿔줘야 하는데, 이 단계가 시스템 네트워크 설정에 제대로 반영되지 않으면 fake-ip 설정이 정확해도 작동하지 않습니다. 이는 설정이 맞는데도 유출이 검출되는 흔한 원인 중 하나입니다.
nameserver 그룹과 fallback-filter의 유출 방지 세부 사항
가짜 주소는 "애플리케이션 쪽에서 무엇이 보이는가"의 문제를 해결하지만, 도메인을 실제 IP로 해석하는 작업은 여전히 nameserver 항목에서 지정한 상위 DNS 서버가 수행합니다. 이 단계 역시 유출 위험이 있습니다. 상위 DNS 자체가 신뢰할 수 없는 통신사 서버이거나 조회 과정이 암호화되지 않으면 중간 네트워크 장비에 기록될 수 있습니다. 국내/해외 분기 방식으로 두 그룹의 DNS를 설정하고 fallback-filter로 최종 판단을 하는 것을 권장합니다:
dns:
enable: true
enhanced-mode: fake-ip
nameserver:
- 223.5.5.5
- 119.29.29.29
fallback:
- tls://1.1.1.1:853
- tls://8.8.8.8:853
fallback-filter:
geoip: true
geoip-code: CN
ipcidr:
- 240.0.0.0/4
domain:
- +.google.com
- +.facebook.com
nameserver는 기본으로 우선 사용되는 해석 서버로, 보통 중국 본토 퍼블릭 DNS를 넣어 중국 본토 사이트의 해석 속도를 보장합니다. fallback은 대체 서버로, DNS over TLS를 지원하는 주소(예시의 tls:// 접두사 표기)를 사용해 해석 요청 자체도 암호화 채널을 거치게 함으로써 중간 노드의 감청이나 조작을 막는 것을 권장합니다. fallback-filter는 fallback을 언제 사용할지 결정합니다 — geoip-code: CN은 nameserver가 해석한 결과가 중국 본토 IP 대역에 속하면 그대로 신뢰하고, 그렇지 않으면 결과가 오염됐을 가능성이 있다고 판단해 fallback의 암호화 DNS로 다시 해석합니다. domain 목록에 있는 도메인은 강제로 fallback을 거치게 되어 국내 해석 결과를 더는 신뢰하지 않습니다.
이 이중 그룹 설정은 본질적으로 "가까운 곳에서 우선 해석 + 오염 시 대체"입니다. 중국 본토 사이트가 굳이 해외 DNS로 멀리 돌아가 속도가 느려지는 것을 막으면서도, 프록시가 필요한 도메인이 중국 본토 해석 결과에 오염돼 잘못된(심지어 감시받는) 주소로 유도되지 않도록 보장합니다. 설정을 마친 뒤에는 앞서 소개한 패킷 캡처 방법으로 검증할 수 있습니다: 해외 도메인의 해석 트래픽은 fallback에 설정된 암호화 DNS로 향해야 하며, 평문 53번 포트로 가면 안 됩니다.
흔한 점검 체크리스트
- 클라이언트가 실제로 강화 DNS를 활성화했는지 확인하세요. 일부 클라이언트는 DNS 모듈이 기본으로 꺼져 있어 설정에서 수동으로 켜야 합니다.
- TUN 모드에서는 가상 네트워크 인터페이스가 라우팅을 성공적으로 가로챘는지 확인하세요. 시스템 네트워크 설정의 DNS 항목은 Clash 내장 리스닝 주소를 가리키거나 가상 인터페이스에 의해 덮어써져 있어야 합니다.
- 브라우저가 별도로 DoH(DNS over HTTPS)로 해석 서버를 고정해두었다면 시스템 DNS 설정을 우회할 수 있으니, 브라우저 설정에서 이 기능을 끄거나 시스템 DNS를 사용하도록 변경해야 합니다.
- 라우터나 일부 보안 소프트웨어가 강제로 DNS 서버를 지정하면 Clash의 DNS 가로채기를 덮어쓸 수 있으므로, 시스템이나 라우터 계층에서 Clash 리스닝 포트로의 포워딩을 허용해야 합니다.
- 규칙 세트에 누락이 있어 일부 도메인이 DIRECT 정책을 타는 경우가 있으니, 분기 규칙을 정기적으로 점검하고 로그로 매칭된 정책 그룹이 예상과 맞는지 확인하는 것을 권장합니다.