Clash DNS 설정 방법: nameserver·fallback 및 DNS 하이재킹 설정 가이드
dns의 enhanced-mode, nameserver, fallback, fallback-filter, dns-hijack 설정을 YAML 예제로 살펴보고 DNS 오염 방지와 분할 조회 방법을 알아봅니다.
먼저 커널과 DNS 요청 경로 확인하기
핵심은 DNS 조회가 먼저 Clash DNS로 들어오게 한 다음, 사용할 상위 DNS를 정하는 것입니다. nameserver만 바꿔서는 시스템, 브라우저, 로컬 네트워크 기기의 모든 DNS 요청이 자동으로 이쪽으로 전달되지 않습니다. 웹페이지가 열린다고 해서 조회가 이 설정을 거쳤다는 뜻도 아닙니다. 시스템 캐시, 브라우저의 보안 DNS, 앱 자체 조회 기능이 우회 경로로 작동할 수 있습니다.
‘Clash 클라이언트’는 화면을 제공하는 프로그램이며, YAML을 실제로 해석하는 것은 커널입니다. 원본 Clash, 구버전 Premium 커널, Clash Meta(현 mihomo)는 지원하는 설정 항목이 완전히 같지 않습니다. 이 문서의 예제는 mihomo 커널을 기준으로 합니다. 구버전 커널에는 proxy-server-nameserver나 TUN 설정을 그대로 적용하지 마세요. 먼저 클라이언트의 ‘정보’ 메뉴나 시작 로그에서 커널 이름과 버전을 확인한 뒤, 해당 커널에 맞게 설정을 검증하세요.
- 현재 설정을 백업하고 기존
dns,tun, 클라이언트의 DNS 덮어쓰기 설정을 기록해 둡니다. - ‘프로필’에서 실제로 활성화된 설정 파일을 확인합니다. 구독 설정 덮어쓰기 기능이 있다면 다음 구독 업데이트 때 사라질 임시 파일이 아니라 저장되는 덮어쓰기 설정을 수정하세요.
- 실행 중인 설정이나 병합된 설정을 내보내 확인하고, 화면에서 설정한 DNS가 YAML을 덮어쓰지 않는지 살펴봅니다.
- 한 번에 한 그룹의 설정만 바꾸고, 다시 불러온 뒤 시작 오류와 조회 로그를 확인한 다음 다음 단계로 진행합니다.
dns 설정: 수신 주소와 조회 모드 선택하기
| 항목 | 기능 | 설정 참고 |
|---|---|---|
enable | 커널 DNS 서비스 활성화 | true로 설정해도 DNS 요청이 들어올 경로를 따로 마련해야 합니다 |
listen | DNS 요청을 받는 주소 설정 | 로컬 테스트에는 127.0.0.1:1053 사용 가능 |
enhanced-mode | 확장 조회 모드 선택 | 일반적으로 fake-ip 또는 redir-host 사용 |
fake-ip-range | 가상 IPv4 주소 대역 | 예: 198.18.0.1/16 |
default-nameserver | DNS 상위 서버의 호스트명을 조회하는 서버 | 조회 과정의 순환 의존을 막으려면 IP 주소 형식의 DNS 서버를 사용하세요 |
nameserver | 기본 DNS 상위 서버 목록 | 프록시 노드 목록이나 엄격한 주·대기 서버 목록이 아닙니다 |
fake-ip가 가상 주소를 반환해도 조회 실패는 아닙니다
fake-ip는 도메인에 가상 주소를 할당하고 도메인과 주소의 대응 정보를 저장합니다. 앱이 이 주소에 연결하면 커널이 도메인을 복원해 규칙을 적용할 수 있습니다. 조회 결과가 198.18.x.x로 나오는 것은 일반적인 동작입니다. 이를 공용 DNS가 반환한 실제 주소와 직접 비교하거나 ping이 되지 않는다는 이유로 설정 실패라고 판단하지 마세요.
redir-host는 실제 조회 결과를 사용하므로 실제 IP가 필요한 프로그램과 호환성이 더 좋을 수 있습니다. 다만 DNS 오염과 도메인 정보 보존에 더 신경 써야 합니다. 어느 모드든 트래픽이 반드시 프록시를 통과하게 하지는 않습니다. 조회 모드는 도메인과 주소를 처리하고, 연결 경로는 규칙이 결정합니다.
listen 설정은 시스템 DNS 설정이 아닙니다
127.0.0.1:1053은 이 기기에서 비표준 포트로 DNS 서비스를 제공하는 주소입니다. 대부분의 시스템 DNS 설정에는 IP 주소만 입력할 수 있으며 기본 포트 53을 사용하므로, 이 주소와 포트를 그대로 입력할 수 없습니다. 따라서 먼저 조회 명령으로 1053 포트를 검증한 뒤 TUN 하이재킹을 설정합니다. 다른 기기에서도 사용하려고 0.0.0.0:53으로 무작정 바꾸지 마세요. 수신 범위가 넓어지므로 포트 충돌, 방화벽, 로컬 네트워크 접근 범위도 확인해야 합니다.
nameserver: 최소 설정으로 상위 DNS 확인하기
다음은 mihomo의 dns 설정 예제입니다. 노드 설정 전체가 아니며 구독, 프록시 그룹, 규칙은 포함하지 않습니다. 기존 설정에 합칠 때는 최상위 dns:를 하나만 유지하세요. 같은 키를 가진 두 번째 설정을 파일 끝에 그대로 덧붙이면 안 됩니다.
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
- https://doh.pub/dns-query
여기서 default-nameserver는 dns.alidns.com, doh.pub 같은 상위 DNS 호스트명을 조회합니다. 실제 DNS 조회는 nameserver가 처리합니다. DoH는 HTTPS를 사용하며 일반적인 연결 포트는 443입니다. 하지만 암호화된다고 해서 서비스에 항상 연결할 수 있거나 모든 프록시 출구에 적합한 결과를 보장하는 것은 아닙니다.
- 목록을 ‘첫 번째 서버가 안 될 때만 두 번째 서버 사용’으로 이해하지 마세요. 커널은 여러 서버에 동시에 조회하거나 자체 선택 정책을 사용할 수 있습니다. 목록 순서는 안정적인 주·대기 우선순위가 아닙니다.
- 상위 DNS를 한꺼번에 여러 개 입력하지 마세요. 우선 연결 가능한 서버 한두 개만 사용하면 장애가 발생했을 때 어느 구간에서 시간 초과가 났는지 파악하기 쉽습니다.
- IPv6 설정 범위에 유의하세요. 여기서
dns.ipv6: false는 DNS가 AAAA 조회에 빈 결과를 반환하도록 할 뿐, 시스템 IPv6를 끄거나 앱이 이미 알고 있는 IPv6 주소에 연결하는 것을 막지는 않습니다.
프록시 서버 주소가 도메인인 경우 mihomo의 dns.proxy-server-nameserver 설정으로 노드 서버 도메인을 조회할 수 있습니다. 프록시를 통해 접속하는 웹사이트를 조회하는 상위 DNS 설정은 아닙니다. ‘노드 도메인 조회 실패’가 발생하면 이 조회 경로가 독립적으로 작동하는지 먼저 확인하세요. 프록시 서버에 연결해야 프록시 서버를 조회할 수 있는 순환 의존을 방지해야 합니다.
fallback과 fallback-filter: 단순한 시간 초과 대기 서버가 아닙니다
fallback은 이름 때문에 동작을 오해하기 쉽습니다. fallback-filter와 함께 조회 결과를 걸러내며, nameserver가 시간 초과된 뒤에만 작동하는 설정이 아닙니다. 상위 DNS를 두 그룹 설정하면 양쪽에서 모두 조회가 발생할 수 있습니다. 어떤 결과를 채택할지는 필터 조건과 커널 구현에 따라 달라집니다.
다음 설정은 기존 dns 블록에 추가하고 nameserver와 같은 수준에 배치합니다. 검증되지 않은 지역 데이터베이스에 의존하지 않도록 GeoIP 판별은 끄고, 명시적인 도메인 조건과 의심스러운 주소 필터만 보여 줍니다.
fallback:
- https://cloudflare-dns.com/dns-query
fallback-filter:
geoip: false
ipcidr:
- 0.0.0.0/32
- 127.0.0.0/8
domain:
- '+.google.com'
- '+.github.com'
세 가지 필터 조건의 역할
domain: 지정한 도메인에 fallback 조회 결과를 사용합니다. 예제의+.github.com은 해당 도메인과 하위 도메인에 일치하며, 웹사이트가 자동으로 프록시를 사용하게 하는 설정은 아닙니다.ipcidr: 일반 상위 DNS가 반환한 주소가 지정된 네트워크 대역에 포함되면 fallback 결과를 사용합니다. 예제에서는 0 주소와 루프백 주소를 의심스러운 결과로 처리합니다. 내부 도메인이 실제로 루프백 주소를 사용해야 한다면 이 필터를 그대로 적용하면 안 됩니다.geoip및geoip-code: GeoIP 판별을 활성화하면 일반 상위 DNS의 결과가 예상 지역에 해당하는지 확인하고, 필요할 때 결과를 대체할 수 있습니다. 흔히geoip: true,geoip-code: CN으로 설정하지만 데이터베이스에 의존합니다. 해외 CDN 주소라고 해서 반드시 DNS 오염을 뜻하는 것은 아닙니다.
‘특정 도메인은 항상 특정 DNS로 조회’하는 것이 주된 목적이라면 복잡한 fallback 조건을 늘리는 대신 먼저 nameserver-policy를 고려하세요. 이 설정은 조회에 사용할 상위 DNS를 선택하며, 프록시 출구는 여전히 연결 규칙이 결정합니다.
nameserver-policy:
'+.cn':
- https://dns.alidns.com/dns-query
'+.github.com':
- https://cloudflare-dns.com/dns-query
이 설정도 dns 안에 배치합니다. 정책에 일치하는 조회는 지정된 상위 DNS에서 처리되므로 fallback의 기본 필터 로직으로 결과를 추측하지 마세요. 처음에는 ‘정책별 DNS’와 ‘fallback 필터링’ 중 하나만 선택해 검증하고, 로그와 결과가 일치하는 것을 확인한 뒤 함께 사용하세요.
dns-hijack: TUN에서 53번 포트 DNS 요청 가로채기
mihomo에서 dns-hijack은 dns가 아니라 최상위 tun 설정에 속합니다. TUN으로 들어와 조건에 일치하는 DNS 트래픽을 커널 DNS 모듈로 전달합니다. 다음 예제는 기존 TUN 설정과 함께 사용해야 합니다. 클라이언트 화면에서 TUN을 관리한다면 화면 설정이 YAML을 덮어쓰지 않도록 최종 실행 설정을 확인하세요.
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을 켜려면 일반적으로 시스템 관리자 권한이나 클라이언트의 서비스 모드가 필요합니다. 기존 설정에 이미 tun:이 있다면 그 안의 항목을 수정하고 같은 이름의 블록을 다시 선언하지 마세요.
any:53을 설정해도 다음 요청은 자동으로 가로채지지 않습니다
- 브라우저 DoH: 보통 HTTPS 443 포트를 사용하므로 53번 포트 조건에 해당하지 않습니다. 문제를 확인할 때는 브라우저의 ‘보안 DNS’를 잠시 끄세요. Firefox에서는 보통 ‘설정’ → ‘개인 정보 및 보안’ → ‘HTTPS를 통한 DNS’에서 설정할 수 있습니다. 테스트가 끝나면 사용 환경에 맞게 다시 켜세요.
- Android 비공개 DNS: 엄격 모드는 보통 DoT 853 포트를 사용합니다. 기기에 따라 ‘설정’ → ‘네트워크 및 인터넷’ → ‘비공개 DNS’에서 설정할 수 있습니다. 제조사마다 메뉴 이름이 다를 수 있으며, 일반 UDP 53번 포트 트래픽처럼 처리할 수 없습니다.
- TUN에 들어오지 않은 트래픽: 로컬 네트워크의 직접 연결 경로, 다른 VPN, 특수 네트워크 인터페이스, 시스템 처리 경로 등으로 트래픽이 TUN을 우회할 수 있습니다. 시스템 DNS가 라우터를 가리키더라도 해당 트래픽이 실제로 가로채졌는지 확인해야 합니다.
DNS 수신 성공, TUN 활성화, DNS 하이재킹 적용은 서로 다른 세 가지 상태입니다. 휴대폰에서는 VpnService 권한과 다른 VPN과의 충돌도 확인해야 합니다. 데스크톱에서는 서비스 권한, 라우팅, 방화벽을 살펴보세요. 요청이 들어오는 경로 문제를 해결하려고 DNS 서버를 계속 바꾸지 마세요.
검증 순서: 설정 확인, 지정 조회, 시스템 요청 경로
1단계: YAML과 시작 로그 확인
이 기기에서 mihomo를 직접 실행할 수 있다면 설정 파일이 있는 디렉터리에서 다음 명령을 실행하세요. 클라이언트 사용자는 화면의 설정 검사 기능을 이용해도 됩니다. 명령 검사에 통과했다는 것은 설정을 해석할 수 있다는 뜻일 뿐, 상위 DNS에 연결할 수 있다는 의미는 아닙니다.
mihomo -t -f config.yaml
알 수 없는 설정 항목이 나오면 먼저 커널을 확인하고, 들여쓰기나 중복 키 오류가 있다면 파일부터 수정하세요. 로그에 address already in use가 표시되면 1053 포트를 점유한 프로세스를 찾거나 테스트 포트를 바꾸세요. 수신 포트 충돌은 상위 DNS URL을 바꿔서 해결할 수 없습니다.
2단계: 로컬 1053 포트에 직접 조회하기
dig가 설치된 macOS 또는 Linux에서는 다음 세 명령을 실행할 수 있습니다. 첫 번째는 UDP 조회, 두 번째는 TCP 조회, 세 번째는 AAAA 응답을 확인합니다.
dig @127.0.0.1 -p 1053 www.example.com A
dig @127.0.0.1 -p 1053 www.example.com A +tcp
dig @127.0.0.1 -p 1053 www.example.com AAAA
Windows에서는 nslookup을 대화형 모드로 실행한 다음 테스트 포트를 설정할 수 있습니다. 테스트가 끝나면 exit를 입력해 종료하세요.
nslookup
server 127.0.0.1
set port=1053
set type=A
www.example.com
exit
fake-ip 모드에서 A 레코드가 가상 주소를 반환하는 것은 정상입니다. 실제 상위 DNS 결과를 확인하려면 설정을 백업한 뒤 잠시 redir-host로 전환하고, 다시 불러온 다음 관련 캐시를 지우고 조회 결과를 비교하세요. 테스트 후에는 원래 설정으로 복구합니다. fake-ip 응답 시간을 실제 상위 DNS의 네트워크 지연으로 간주하지 마세요.
3단계: 시스템 기본 DNS 경로 확인
로컬 조회가 정상인 것을 확인한 뒤 TUN을 켜고 시스템 기본 DNS로 조회하면서 클라이언트 로그를 살펴보세요. Windows에서는 ipconfig /flushdns로 시스템 DNS 캐시를 지울 수 있습니다. systemd-resolved를 사용하는 Linux에서는 resolvectl flush-caches를 실행하세요. 브라우저에도 자체 캐시와 연결 정보가 남을 수 있으므로 브라우저를 다시 시작하거나 별도로 캐시를 지워야 합니다.
| 증상 | 먼저 확인할 항목 | 다음 조치 |
|---|---|---|
| 로컬 1053 조회 시간 초과 | DNS 수신, 설정 로드, 상위 DNS 연결 여부 | 시작 로그를 확인하고 상위 DNS 하나만 두고 재시도 |
| 지정 조회는 정상인데 브라우저에서 오류 | 보안 DNS, 캐시, 시스템 DNS 경로 | 브라우저 DoH를 잠시 끄고 기본 조회 결과와 비교 |
| 도메인은 조회되지만 웹사이트 연결 시간 초과 | 프록시 그룹, 연결 규칙, 대상 포트 | 연결 기록에서 도메인, 적용된 규칙, 출구 확인 |
| 노드 도메인만 조회 실패 | 노드 조회가 프록시에 의존하는지 확인 | proxy-server-nameserver와 라우팅 의존 관계 확인 |
| 구독을 업데이트한 뒤 설정이 사라짐 | 설정 병합과 덮어쓰기 우선순위 | 클라이언트의 저장형 덮어쓰기를 사용하고 실행 설정 확인 |
일상적인 설정: 조회 경로를 명확하게 유지하기
일상적으로 사용할 때는 ‘하나의 DNS 진입점, 연결 가능한 소수의 상위 DNS, 명확한 규칙 모드’부터 시작하세요. 특정 상위 DNS를 고정해야 할 때 nameserver-policy를 추가하고, 실제로 잘못된 결과를 걸러야 할 때만 fallback-filter를 설정하세요. 정책을 하나 더할 때마다 어떤 도메인이 영향을 받는지, 상위 DNS가 어떤 경로로 연결되는지, 실패했을 때 어디서 로그를 확인할 수 있는지 설명할 수 있어야 합니다.
DNS 암호화는 DNS 서버까지의 조회 전송을 보호하지만 모든 연결 정보를 숨기는 기능은 아닙니다. DNS 누출 검사 페이지에 특정 DNS 서비스가 표시되더라도 모든 앱 트래픽의 경로를 알 수 있는 것은 아닙니다. 예상한 경로를 우회하는지 확인하려면 웹페이지 테스트 한 번에 의존하지 말고 패킷 캡처, DNS 조회 로그, 연결 기록을 함께 살펴보세요.
마지막으로 세 가지 역할을 기억하세요. nameserver는 조회할 DNS 서버를 정하고, fallback-filter는 어떤 조회 결과를 선택할지 판단하며, tun.dns-hijack은 어떤 일반 DNS 요청을 커널에 전달할지 정합니다. 이 세 단계를 나눠 검증하면 ‘범용 DNS 설정’을 통째로 계속 바꾸는 것보다 문제를 빠르게 찾을 수 있습니다. 다른 기본 설정은 YAML 가이드를, 연결 및 시작 오류는 문제 해결 가이드를 참고하세요.