먼저 결론부터 말하면, Android에서는 DNS 요청이 실제로 Clash에 전달되는지 확인한 다음 DNS 서버를 조정해야 합니다. nameserver는 일반 DNS 조회에 사용하는 업스트림 서버이고, fallback은 결과를 선별할 때 함께 사용하는 별도의 업스트림 그룹입니다. 단순히 “기본 서버가 끊긴 뒤에만 작동하는 서버”가 아닙니다. fake-ip는 앱에 어떤 주소를 반환할지 결정하고, DNS 가로채기는 어떤 요청을 코어로 전달할지 정합니다. 서로 다른 단계의 설정이므로 대체 관계가 아닙니다.

1. Android의 DNS 요청은 어떻게 Clash로 전달될까?

앱에서 도메인을 열면 보통 먼저 시스템 DNS 리졸버에 주소를 요청한 뒤 연결을 시작합니다. Android 클라이언트는 시스템 VPN 권한을 얻으면 가상 네트워크 인터페이스로 트래픽을 받을 수 있습니다. DNS까지 함께 처리하는지는 클라이언트의 VPN 구현, DNS 설정, 앱별 트래픽 제어에 따라 달라집니다.

  1. 앱이 시스템 DNS 조회 API를 호출하면, 시스템은 현재 네트워크에 지정된 DNS 주소로 조회 요청을 보냅니다.
  2. VPN 인터페이스가 처리 대상 트래픽을 받으면 클라이언트나 코어가 DNS 요청을 내부 리졸버로 전달합니다.
  3. 내부 리졸버는 캐시, 도메인별 정책, nameserver 등의 설정을 확인하고 필요한 경우 업스트림 서버에 조회를 요청합니다.
  4. 코어는 실제 주소나 Fake IP를 앱에 반환합니다. 앱이 해당 주소로 연결을 시도하면 코어가 규칙에 따라 직접 연결할지 프록시 노드를 사용할지 결정합니다.

따라서 “VPN 연결됨”은 서비스가 실행 중이라는 뜻일 뿐, 모든 앱의 DNS가 코어로 전달된다는 뜻은 아닙니다. VPN에서 제외된 앱이나 자체 암호화 DNS를 사용하는 브라우저는 다른 경로를 이용할 수 있습니다. 문제를 확인할 때는 VPN 제외 대상이 아닌 브라우저로 테스트하고, 브라우저의 ‘보안 DNS’를 잠시 끈 뒤 로그를 비교해 보세요.

DNS 가로채기는 주로 일반 53번 포트 요청을 처리합니다

일반적인 DNS 가로채기는 UDP 또는 TCP 53번 포트 요청을 대상으로 합니다. Android의 ‘비공개 DNS’ 엄격 모드는 보통 DNS over TLS를 사용하며 포트는 853입니다. 브라우저에 내장된 DNS over HTTPS는 대개 443번 포트를 사용합니다. 일반적인 53번 포트 가로채기 규칙만으로 이 요청들을 코어의 DNS 조회로 바꿀 수는 없습니다.

‘비공개 DNS’ 메뉴 위치는 Android 버전에 따라 다릅니다. 일반적으로 ‘설정’ → ‘네트워크 및 인터넷’ → ‘비공개 DNS’에서 찾을 수 있으며, 일부 기기에서는 ‘연결’ 또는 ‘연결 및 공유’ 아래에 있습니다. 문제 해결을 위해 기존 값을 기록해 둔 뒤 엄격 모드를 잠시 끄고 VPN에 다시 연결해 확인할 수 있습니다. 테스트 후 설정을 복원할지 결정하세요. 모든 기기에서 비공개 DNS를 꺼야 하는 것은 아닙니다.

2. dns 섹션의 각 항목은 어떤 역할을 할까?

항목용도 및 설정 참고사항
enable코어 DNS를 활성화합니다. 클라이언트가 실행 시 구독 설정의 값을 덮어쓸 수 있습니다.
listen코어 DNS의 수신 주소입니다. HTTP 프록시 포트와 다르며, 설정만으로 시스템 DNS가 가로채지는 것도 아닙니다.
default-nameserverDNS 업스트림 서버의 도메인 이름을 조회할 때 주로 사용합니다. 시작 단계의 DNS 조회 문제를 해결하는 데 쓰입니다.
nameserver일반 도메인 조회에 사용할 업스트림 서버 목록입니다. 더 구체적인 도메인 정책이 있으면 해당 정책이 우선 적용될 수 있습니다.
fallback대체 DNS 결과를 제공하는 업스트림 목록입니다. 필터 조건과 함께 결과를 선택하며, 순차 재시도 목록으로 이해하면 안 됩니다.
fallback-filter기본 DNS 결과 대신 fallback 결과를 사용할 조건을 지정합니다. 예를 들어 기본 DNS가 특정 주소 대역을 반환하는 경우입니다.
enhanced-modefake-ip 또는 redir-host 모드를 선택해 반환 주소와 도메인 연결 방식을 바꿉니다.
ipv6코어가 AAAA 조회를 처리하는 방식을 제어합니다. 기기의 모든 IPv6 트래픽을 차단하는 설정은 아닙니다.

default-nameserver는 ‘모든 사이트의 기본 DNS 서버’가 아닙니다

예를 들어 업스트림을 https://dns.alidns.com/dns-query로 설정하면, 이 HTTPS 서비스에 연결하기 전에 dns.alidns.com의 주소를 알아야 합니다. 부트스트랩 DNS 서버는 이 초기 조회를 처리합니다. IP 주소로 부트스트랩 서버를 지정하면 “DNS 서버의 주소를 알아내기 위해 같은 DNS 서버에 먼저 접속해야 하는” 순환 문제를 피할 수 있습니다.

기존 설정에서는 default-nameserver에 일반 IP 주소를 지정하는 경우가 많습니다. 코어마다 이 항목에서 지원하는 프로토콜 범위가 다르므로, 기존 설정을 옮길 때는 단순한 형식을 유지하는 편이 좋습니다. 업스트림 서버의 도메인을 조회하지 못했다고 해서 모든 프록시 노드가 동시에 작동하지 않는다고 단정하지 마세요.

listen에 7890을 지정하지 마세요

7890은 HTTP 또는 혼합 프록시 포트로 자주 사용되며 DNS 수신 포트와는 별개입니다. 아래 예시는 권한이 필요한 낮은 포트에 직접 바인딩하지 않도록 로컬 DNS 수신 주소로 127.0.0.1:1053을 사용합니다. Android 클라이언트는 내부 포트를 자체적으로 지정하거나 이 수신 주소를 사용하지 않을 수 있으므로 실제 실행 설정을 기준으로 확인하세요. listen만 설정해도 Android가 자동으로 DNS 요청을 보내지는 않습니다.

3. nameserver와 fallback 기본 설정

아래 설정은 각 항목의 관계를 이해하기 위한 예시이며, 모든 구독 설정에 그대로 적용할 수 있는 완성본은 아닙니다. 일반 DoH 업스트림 하나와 fallback DoH 업스트림 하나를 사용하고, GeoIP 필터는 끈 채 예약 주소 대역으로 필터 동작을 보여 줍니다. 두 HTTPS 서비스 모두 현재 네트워크와 라우팅 조건에서 접속할 수 있어야 합니다.

dns:
  enable: true
  listen: 127.0.0.1:1053
  ipv6: false
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  default-nameserver:
    - 223.5.5.5
    - 119.29.29.29
  nameserver:
    - https://dns.alidns.com/dns-query
  fallback:
    - https://1.1.1.1/dns-query
  fallback-filter:
    geoip: false
    ipcidr:
      - 240.0.0.0/4
  • 198.18.0.1/16은 도메인과 가상 주소를 연결하는 Fake IP 주소 풀입니다. 프록시 노드 주소를 입력하는 곳이 아닙니다.
  • 240.0.0.0/4는 여기서 비정상 응답을 걸러내는 예시로 사용합니다. 모든 예외 주소를 포함하는 목록도 아니며, 모든 잘못된 DNS 응답을 판별할 수 있는 것도 아닙니다.
  • geoip: false는 GeoIP 조건으로 fallback 결과를 선택하지 않도록 합니다. 이번 테스트에 지리 데이터베이스의 차이가 영향을 주지 않게 하기 위한 설정입니다.
  • ipv6: false는 문제 해결 범위를 먼저 좁히기 위한 설정입니다. IPv6가 필요하다면 노드, 네트워크, 트래픽 처리 경로가 모두 지원하는지 확인한 뒤 별도로 활성화해 테스트하세요.

업스트림 서버는 많을수록 좋은 것이 아닙니다. 서버가 늘면 조회량이 증가하고 응답 결과도 달라질 수 있습니다. 먼저 연결 가능하고 동작을 설명하기 쉬운 업스트림 하나로 기준을 잡은 뒤 도메인 정책이나 fallback을 추가하세요. 암호화 DNS는 기기와 해당 DNS 서비스 사이의 조회 전송을 보호할 뿐, 이후 웹사이트 연결까지 자동으로 프록시를 통과시킨다는 뜻은 아닙니다.

4. fallback-filter는 어떤 결과를 선택할까?

기존 Clash의 일반적인 구현에서는 fallback을 설정하면 두 업스트림 그룹에 동시에 조회를 보낼 수 있습니다. 코어는 필터 조건을 기준으로 사용할 응답을 선택하며, nameserver가 완전히 시간 초과될 때까지 기다린 뒤 fallback에 조회하는 방식은 아닙니다. 동시 조회, 캐시, 오류 처리 방식은 사용하는 코어에 따라 다를 수 있으므로 실제 구현을 확인하세요.

자주 사용하는 필터 조건 세 가지

  • GeoIP: 기존 설정에서는 geoip: true와 geoip-code: CN을 함께 사용해 기본 DNS 응답의 IP가 어느 지역에 속하는지를 기준으로 결과를 선택하는 경우가 많습니다. 판단 기준은 GeoIP 데이터베이스에 기록된 IP의 지리적 위치이며, 데이터베이스 버전에 따라 결과가 달라질 수 있습니다.
  • IP 대역: ipcidr은 기본 DNS 응답의 IP가 지정한 주소 범위에 속하는지 확인합니다. 예를 들어 위 설정의 예약 주소 대역에 해당하면 fallback 결과를 사용합니다.
  • 도메인: domain을 사용하면 일치하는 도메인에 fallback 결과를 적용할 수 있습니다. 구체적인 일치 문법은 코어 문서를 확인하세요. 프록시 규칙의 전체 행을 그대로 목록에 붙여 넣으면 안 됩니다.

GeoIP 필터를 켜면 해외 CDN 주소를 사용하는 정상 웹사이트도 fallback 조건에 걸릴 수 있습니다. 이는 필터 규칙에 따른 결과이며 기본 DNS 응답이 조작됐다는 증거는 아닙니다. 반대로 비정상 응답이 정상처럼 보이는 주소 범위에 포함될 수도 있습니다. 따라서 fallback-filter를 모든 DNS 응답의 진위를 자동으로 판별하는 보안 검사기로 여기면 안 됩니다.

mihomo의 도메인별 DNS 정책과 노드 도메인 조회

mihomo는 특정 도메인에 별도의 리졸버를 지정하는 nameserver-policy를 지원합니다. 프록시 노드 서버의 도메인 조회를 전담하는 proxy-server-nameserver도 제공합니다. 이 옵션을 이용하면 ‘노드 주소 조회’와 ‘사용자가 방문하는 웹사이트의 DNS 조회’를 나눠 문제를 확인할 수 있습니다. 이러한 확장 항목을 구형 Clash 코어에 그대로 적용하면 안 됩니다.

# mihomo의 dns 섹션에 넣는 필드 예시
nameserver-policy:
  '+.example.com':
    - https://dns.alidns.com/dns-query
proxy-server-nameserver:
  - https://dns.alidns.com/dns-query

여기서 example.com은 문법을 보여 주기 위한 예시 도메인이며, 실제 서비스 도메인을 자동으로 처리하지 않습니다. 도메인별로 업스트림을 지정하려면 대상 도메인을 입력하고 클라이언트가 해당 설정을 유지하는지 확인하세요. 정책, fallback, 노드 DNS를 한꺼번에 바꾸면 결과가 달라진 원인을 찾기 어렵습니다.

5. fake-ip와 redir-host 중 어떤 모드를 선택할까?

비교 항목fake-ipredir-host
앱에 반환되는 주소코어 주소 풀의 가상 IP업스트림 조회로 얻은 실제 IP
도메인 연결 방식가상 IP 매핑을 통해 도메인 관계를 유지DNS 레코드 등의 정보를 이용해 도메인과 실제 IP를 연결
주요 참고사항실제 DNS 주소에 의존하는 앱은 예외 설정이 필요할 수 있음실제 조회 결과와 IP 연결 정보에 더 의존하며 캐시의 영향을 받을 수 있음
문제 해결 시 확인할 점198.18.x.x가 보여도 반드시 오류인 것은 아님실제 IP를 받았더라도 연결이 올바른 경로를 사용한다는 뜻은 아님

일반적인 프록시 브라우징에는 우선 클라이언트의 기본 fake-ip 설정을 사용하는 것이 좋습니다. 앱이 가상 주소로 연결하면 코어가 연결된 도메인을 찾아 규칙에 따라 실제 연결 방식을 결정할 수 있습니다. 앱에 주소를 반환하기 전에 매번 대상 웹사이트의 실제 주소를 조회해야 하는 것은 아닙니다. 다만 실제 연결 경로, IP 기반 규칙, 구체적인 라우팅에 따라 DNS 조회가 필요할 수 있습니다.

화면 미러링, LAN 기기 검색 또는 특정 앱에서만 문제가 발생한다면 fake-ip-filter를 사용해 특정 도메인에는 Fake IP를 반환하지 않도록 할 수 있습니다. 먼저 관련 도메인을 확인한 뒤 필요한 범위만 예외로 추가하세요. 처음부터 모든 도메인을 제외하지 마세요. 필터 모드와 일치 기능은 버전마다 다를 수 있으므로 항목을 추가한 뒤 설정 로드 로그를 확인해야 합니다.

redir-host로 바꾸면 앱에 이전 DNS 결과나 연결 정보가 캐시되어 있을 수 있습니다. 프록시 서비스를 중지했다가 다시 시작하고, 테스트할 앱도 완전히 종료한 뒤 실행하세요. Fake IP 주소에 ping을 보내는 것은 프록시로 웹사이트에 접속할 수 있는지 판단하는 방법이 아닙니다.

6. Android DNS 가로채기와 TUN 설정의 차이

기본 Clash for Android의 VPN 트래픽 처리는 Android 클라이언트와 코어가 함께 구현하며, 데스크톱 TUN 설정을 휴대폰에 그대로 옮기는 것과는 다릅니다. 먼저 클라이언트의 ‘설정’에서 DNS 덮어쓰기, 네트워크 스택, 앱별 트래픽 제어 옵션을 확인하세요. 배포판마다 메뉴 이름이 다르므로 특정 배포판의 버튼 위치를 공통 경로로 간주하면 안 됩니다.

mihomo TUN 설정을 명시적으로 지원하는 클라이언트에서는 아래와 같은 필드를 사용할 수 있습니다. 이 예시는 가로채기 대상을 설명하기 위한 것이며 Android 클라이언트의 VPN 설정을 대신하는 완성된 방법은 아닙니다.

tun:
  enable: true
  dns-hijack:
    - any:53
    - tcp://any:53

any:53은 일반적인 UDP DNS 트래픽을 가로채는 설정이고, tcp://any:53은 TCP DNS를 추가로 처리합니다. 실제 작동 여부는 트래픽이 해당 TUN으로 전달되는지, 클라이언트가 이 설정을 허용하는지, 별도의 라우팅 제외 항목이 있는지에 달려 있습니다. Android 클라이언트가 VPN 인터페이스를 만들 때는 지원되는 설정 방식을 우선 사용하세요. 예시를 그대로 적용하려고 별도의 트래픽 처리 설정을 중복으로 만들면 안 됩니다.

7. 설정 변경 후 확인 순서와 자주 발생하는 문제

  1. 설정이 로드됐는지 확인합니다. 저장 후 설정을 다시 불러오고 YAML 들여쓰기, 알 수 없는 항목, 잘못된 주소 형식 오류가 있는지 확인하세요. 방금 수정한 설정 파일이 실제로 선택되어 있는지도 확인합니다.
  2. 실행 중 덮어쓰기를 확인합니다. 클라이언트에 ‘덮어쓰기’ 또는 ‘DNS 설정’ 메뉴가 있다면 해당 메뉴의 스위치와 서버 목록을 비교하세요. 구독 파일을 수정해도 최종 실행 설정이 바뀌지 않을 수 있습니다.
  3. 테스트 조건을 고정합니다. 브라우저 하나, 네트워크 하나, 노드 하나만 사용하고 Wi-Fi 또는 모바일 데이터 상태를 기록하세요. 먼저 브라우저 자체 DoH를 끈 뒤, 전에 열어 본 적 없는 도메인에 접속합니다.
  4. 로그를 확인합니다. 클라이언트가 지원하는 디버그 로그 수준으로 잠시 올리고 업스트림 시간 초과, TLS 오류, 노드 도메인 조회 실패 등의 기록을 찾으세요. 테스트가 끝나면 평소 로그 수준으로 되돌리고, 로그를 공유하기 전에 구독 URL과 인증 정보를 숨기세요.
  5. 한 번에 하나씩만 바꿉니다. ‘트래픽 처리 경로 → 업스트림 연결 가능 여부 → 모드 → fallback 필터’ 순서로 확인하세요. 네트워크가 정상화된 뒤 개인 설정을 하나씩 다시 적용합니다.

가로채기를 켠 뒤 모든 사이트에 접속할 수 없음

먼저 DNS 업스트림에 시간 초과가 발생하는지 확인하세요. 업스트림이 프록시를 통해서만 접속 가능하고, 프록시 노드의 도메인도 해당 업스트림에 의존해 조회된다면 시작 단계에서 순환 의존성이 생길 수 있습니다. 먼저 연결 가능한 부트스트랩 DNS 경로를 복구하세요. mihomo에서는 노드 도메인 조회를 별도로 설정하는 방법도 고려할 수 있습니다. 규칙 모드를 계속 바꾸는 것으로 문제를 덮으려 하지 마세요.

웹페이지는 열리지만 내부망 기기나 화면 미러링이 작동하지 않음

내부망 도메인을 조회할 때 공유기나 회사 DNS가 필요한지 확인하세요. 공용 DNS는 보통 가정용 공유기가 관리하는 기기 이름을 알지 못하며 회사 내부망의 DNS 레코드도 자동으로 조회할 수 없습니다. 코어가 지원한다면 해당 도메인에 로컬 업스트림을 지정하고 필요한 경우 Fake IP 예외를 추가하세요. LAN 주소가 프록시로 잘못 전달되고 있지 않은지도 확인합니다.

구독을 업데이트하면 DNS 수정 내용이 사라짐

원격 구독은 보통 새 콘텐츠로 기존 파일을 덮어씁니다. 클라이언트에서 지속적인 덮어쓰기, 병합 또는 패치 기능을 제공한다면 이를 이용해 DNS 설정을 저장하세요. 그런 기능이 없다면 로컬 사본을 보관하고 업데이트 후 어떤 항목을 다시 병합해야 하는지 기록해 두세요. 임시로 수정한 설정이 계속 적용된다고 생각하면 안 됩니다.

마지막으로 ‘어떤 주소로 DNS 조회가 됐는지’와 ‘연결이 어떤 경로로 나가는지’를 따로 확인하세요. 전자는 DNS 설정, 캐시, 트래픽 처리 경로에 따라 달라지고 후자는 프록시 규칙, 정책 그룹, 노드 상태에도 영향을 받습니다. 전체 설정 구조를 확인하려면 전체 문서를 참고하세요. DNS만 수정하고 규칙이나 네트워크 진입 경로를 놓치지 않도록 주의해야 합니다.