DNS 유출이란 무엇인가
웹사이트 주소를 입력하면 운영체제는 먼저 도메인 이름을 IP 주소로 바꾸는 DNS 조회를 합니다. 이 요청이 가는 경로가 ISP 기본 서버나 사무실·학교 게이트웨이에 붙어 있는 리졸버라면, 어떤 사이트를 “이름만” 찾아봤는지가 그 관리 주체 쪽 로그에 남을 수 있습니다. HTTP 트래픽은 터널 안으로 넣었는데 DNS만 밖으로 새는 현상을 흔히 DNS 유출이라고 부릅니다.
Clash 계열 클라이언트는 규칙 엔진과 함께 내장 DNS를 제공해, 이 경로를 앱 안으로 끌어들일 수 있습니다. 다만 GUI 옵션 이름이 제각각이고, fake-ip와 redir-host는 동작 철학이 달라서 잘못 맞추면 “프록시는 타는데 조회만 시스템으로 간다”는 상황이 생깁니다. 본문은 기술적 동작 설명에 한정하며, 허용된 용도와 관할 법규는 사용자 본인이 확인해야 합니다.
Clash를 켰는데도 유출이 나는 흔한 이유
첫째, 시스템 DNS가 그대로 우선일 때입니다. 일부 앱은 프록시를 거치지 않고 OS에 직접 질의하거나, VPN/프록시가 DNS만 가로채지 못한 채 HTTP 레이어만 넘깁니다. 둘째, IPv6 경로가 열려 있는데 규칙·터널은 IPv4 위주로만 잡혀 있으면, AAAA 조회나 트래픽이 우회할 수 있습니다. 셋째, 브라우저 DNS over HTTPS 같은 별도 설정이 켜져 있으면 Clash 밖에서 해석이 끝나 규칙과 어긋납니다.
넷째, fake-ip 모드에서 예외 목록이나 규칙 순서가 어색하면 실제 IP를 얻기 위해 시스템 리졸버로 되돌아가는 패턴이 보이기도 합니다. 즉 “한 군데만” 고치기보다 조회 경로 전체를 같은 정책으로 맞추는 것이 핵심입니다. 전체 지연과 DNS의 관계는 속도 최적화 가이드와 함께 보면 트레이드오프를 이해하기 쉽습니다.
dns 섹션 기본: listen·enable·ipv6
Mihomo(Clash Meta) 계열에서는 dns: 블록으로 내장 리졸버를 켜고, 로컬에서 받을 주소와 향상 모드를 지정합니다. 아래는 이해를 돕는 축약 예시이며, 키 이름은 사용 중인 코어 버전의 공식 문서와 반드시 대조해야 합니다.
# dns block sketch — comments in English per project convention
dns:
enable: true
listen: 0.0.0.0:1053
ipv6: false
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
nameserver:
- https://dns.example/dns-query
fallback:
- https://dns.fallback.example/dns-query
fallback-filter:
geoip: true
geoip-code: CN
listen은 로컬에서 DNS를 받을 포트입니다. 다른 소프트웨어와 충돌하면 포트를 바꾸고, GUI의 “시스템 DNS/터널 DNS” 설정이 그 주소를 가리키는지 확인하세요. ipv6: false는 환경에 따라 다르게 두는 경우가 많습니다. IPv6 회선이 활성인데 터널이 IPv4만 다루면 우회 유출 소지가 있으므로, 끄거나 켤 때는 실제로 어떤 레코드가 쓰이는지 테스트로 검증하는 편이 안전합니다.
enhanced-mode: fake-ip와 redir-host 선택
fake-ip는 앱이 조회한 이름에 대해 Clash가 임시 가짜 IP를 돌려주고, 실제 연결 시점에 코어가 다시 이름을 해석해 규칙에 맞는 출구로 보내는 방식입니다. 규칙 매칭이 빨라지고 지역별 스플릿과 잘 어울리지만, 일부 앱은 “가짜 주소”를 일반 공인 주소처럼 다루다가 오동작할 수 있어 fake-ip-filter로 예외를 둡니다.
redir-host는 전통적으로 실제 DNS 응답을 기반으로 규칙을 적용하는 쪽에 가깝습니다. 호환성은 좋을 수 있으나, 어떤 리졸버가 질의를 대신 수행하느냐에 따라 유출 여부가 갈립니다. 즉 redir-host라고 해서 자동으로 안전해지는 것이 아니라, nameserver·proxy-server-nameserver 등이 기대한 경로(프록시 경유 DoH 등)로 묶여 있어야 합니다.
nameserver·fallback·프록시 경유 DNS
일반적으로 nameserver는 기본 풀, fallback은 메인이 막히거나 오염 의심일 때 쓰는 보조 풀로 구성합니다. fallback-filter의 GeoIP 조건은 “특정 지역 응답이면 fallback으로 재시도” 같은 식으로 동작하게 할 수 있어, 오염 DNS에 의한 잘못된 IP를 줄이는 데 도움이 됩니다.
민감한 질의를 프록시 출구와 같은 관할의 DoH로 보내고 싶다면, 코어가 지원하는 프록시 경유 nameserver 문법을 사용합니다. 이때도 중요한 것은 “설정 문구가 아니라 실제 패킷이 어디로 나가는지”이므로, 한 번은 로그나 캡처 도구로 확인해 보는 것이 좋습니다. 규칙과 DNS를 같이 다루는 상위 설계는 Rule Provider 가이드에서 이어집니다.
TUN 모드·DNS 하이재킹과의 관계
시스템 프록시만으로는 잡히지 않는 앱이 있을 때 TUN 가상 인터페이스로 전체 트래픽을 끌어들이는 방식을 씁니다. 이때 Clash가 UDP 53을 가로채거나, 플랫폼별로 “DNS만 터널로” 보내는 옵션을 제공하는 경우가 있습니다. 이름은 dns-hijack, auto-route, strict-route 등 클라이언트마다 다르므로, 사용 중인 GUI의 도움말을 기준으로 켜고 끄세요.
TUN을 켰다고 끝이 아니라, 로컬 루프백이나 LAN의 정상 DNS까지 모두 막아 버리면 셀프 서비스·기업 SSO 같은 앱이 깨질 수 있습니다. 이럴 때는 예외 라우트나 분할 터널을 쓰되, “예외로 나간 DNS가 무엇인지”를 인지한 상태에서 선택해야 합니다. 모바일에서 앱별 분리가 필요하면 Android 가이드의 Per-App 설명도 참고하세요.
유출 여부 점검하는 실무 순서
- 프록시·TUN을 평소와 같이 연 상태에서, 공신력 있는 DNS leak 테스트 페이지를 연다.
- 표시되는 리졸버 목록에 ISP 이름·본국 주소가 남는지 본다. 기대는 사용 중인 DoH/프록시 측 인프라 또는 “없음/차단”에 가깝다.
- 브라우저의 보안 DNS 설정을 끄고 다시 시험해 차이를 본다.
- 터미널에서
dig나nslookup로 동일 도메인을 조회해, 응답 서버가 어디인지 확인한다. - 코어 로그의 DNS 관련 항목에서 실패·폴백이 반복되지 않는지 본다.
한 번 통과했다고 영구 보장은 아닙니다. OS 업데이트·브라우저 업데이트·회사 VPN이 바뀌면 경로가 달라질 수 있으므로, 정책이 바뀔 때마다 짧게 재점검하는 습관이 좋습니다.
WebRTC·기타 채널에 대한 짧은 주의
DNS만 막아도 WebRTC나 일부 P2P 스택이 로컬 인터페이스 정보를 노출하는 사례는 별개의 주제입니다. “완전한 익명성”을 목표로 한다면 브라우저 확장·실험 플래그 등 추가 조치가 필요하고, 그 범위는 본문의 Clash DNS 설정과 겹치지 않습니다. 목표를 ISP 기본 DNS 로그로의 이름 유출 최소화로 한정할 때 이 가이드가 가장 잘 맞습니다.
책임과 투명성
오픈 소스 코어의 변경 이력과 이슈는 Mihomo GitHub 저장소에서 확인할 수 있습니다. 다만 설치 패키지는 서명·배포 채널 관점에서 공식 다운로드 페이지를 우선하는 편이 안전합니다. 네트워크 정책은 국가·조직마다 다르므로, 직장·학교 장비에서는 내부 규정을 따르세요.
정리
DNS 유출 방지의 중심은 “프록시 ON”이라는 스위치가 아니라, 이름 조회가 실제로 어떤 서버에 도달하는가입니다. dns.enable과 enhanced-mode, nameserver 체인, TUN·IPv6·브라우저 보안 DNS를 한 흐름으로 맞추고, 테스트로 검증하면 체감 프라이버시가 분명히 좋아집니다. 처음에는 최소 구성으로 시작해, 로그와 leak 테스트를 보며 단계적으로 옵션을 늘리면 밤샘 디버깅을 줄일 수 있습니다.
규칙형 클라이언트는 한 번 구조를 잡아 두면 구독·DNS·분류 정책을 같은 프로필에서 일관되게 유지하기 쉽습니다. GUI와 코어를 최신에 가깝게 맞춰 두면 파서와 DNS 스택 동작도 안정적인 편입니다.
초보자는 Clash 사용 문서에서 기본 흐름을 익힌 뒤, 이 글의 DNS 축을 덧붙이면 이해 속도가 빨라집니다.