DNS 조회, 트래픽 분기, DNS 가로채기를 먼저 구분하기
웹페이지가 열리지 않는다고 해서 반드시 노드 문제인 것은 아닙니다. 도메인 조회가 실패했거나 잘못된 주소로 연결됐을 수 있고, 앱이 클라이언트 DNS를 사용하지 않을 수도 있습니다. 문제를 확인하기 전에 세 단계를 구분하세요. DNS 요청을 받는 곳, 주소를 반환하는 상위 DNS 서버, 그리고 이후 연결에 적용되는 프록시 규칙입니다.
- DNS 조회:
dns설정은 코어가 어떤 DNS 서버에 질의하고 응답을 어떻게 처리할지 정합니다. - 트래픽 분기:
rules와 정책 그룹은 연결에 DIRECT, 프록시 노드 또는 다른 아웃바운드 경로를 사용할지 결정합니다. DNS가 해외 IP를 반환한다고 연결이 자동으로 프록시를 통과하는 것은 아닙니다. - DNS 가로채기: 이 문서에서는 TUN 코어가 지정된 포트의 DNS 트래픽을 직접 가로채 내장 DNS로 전달하는 기능을 뜻합니다. 통신사가 응답을 변조하는 현상과는 다릅니다.
수정하기 전에 현재 정상 작동하는 설정을 내보내세요. 구독에서 가져온 설정이라면 클라이언트의 오버라이드, 확장 설정 또는 병합 기능을 사용하는 것이 좋습니다. 구독으로 생성된 파일을 직접 수정하면 다음 업데이트 때 변경 사항이 사라질 수 있습니다. 한 번에 한 부분씩 수정하고, 다시 불러온 뒤 최종 적용된 설정을 확인하세요.
nameserver와 default-nameserver의 역할
nameserver는 일반 도메인 조회에 사용하는 상위 DNS 서버 목록입니다. IP 주소만 지정하면 보통 일반 DNS를 의미하며 기본 포트는 53입니다. https://는 DoH로, 일반적으로 TCP 443을 사용합니다. tls://는 DoT로, 일반적으로 TCP 853을 사용합니다. 암호화 프로토콜은 DNS 서버까지의 질의 전송을 보호하지만, 서버에 항상 연결할 수 있다는 보장은 없으며 트래픽 분기를 대신하지도 않습니다.
| 항목 | 주요 용도 | 확인할 사항 |
|---|---|---|
enable | 내장 DNS 사용 | true로 설정해도 요청이 실제로 코어에 전달되는지 확인해야 합니다. |
listen | 로컬 DNS 수신 주소 제공 | 주소와 포트가 시스템 DNS 설정과 일치하는지 |
default-nameserver | 도메인으로 지정한 DNS 서버를 조회하기 위한 초기 해석 | 현재 네트워크에서 연결 가능한 IP 주소를 우선 사용 |
nameserver | 일반 도메인 조회 처리 | 상위 DNS 연결 여부, 응답 결과, 지연 시간 |
nameserver-policy | 지정한 도메인에 사용할 DNS 서버 선택 | 규칙 범위가 지나치게 넓지 않은지, 내부 도메인이 잘못된 DNS 서버로 전달되지 않는지 |
DNS 서버의 도메인도 먼저 조회해야 함
https://dns.alidns.com/dns-query를 사용하려면 코어가 먼저 dns.alidns.com의 주소를 알아야 합니다. 이때 필요한 것이 초기 해석입니다. default-nameserver를 모든 조회 실패 시 사용하는 예비 목록으로 생각하지 마세요. fallback과 역할이 다릅니다.
또한 127.0.0.1:1053처럼 코어 자체의 수신 주소를 여기에 입력하지 마세요. 상위 DNS 조회가 같은 DNS 진입점으로 되돌아가면 루프가 생길 수 있습니다. 다른 로컬 DNS 서비스를 지정할 때도 해당 서비스가 요청을 다시 Clash로 전달하지 않는지 확인하세요.
fallback은 단순한 시간 초과 대체 수단이 아닙니다
fallback을 설정하면 해당 조회에 대해 코어가 주 DNS와 예비 DNS에 보통 동시에 요청을 보내고, fallback-filter로 어느 쪽의 응답을 사용할지 판단합니다. ‘nameserver가 5초 동안 실패하기를 기다린 뒤 fallback을 요청한다’는 방식이 아닙니다. 실제 처리 방식은 캐시, 도메인 정책, 코어 구현에 따라서도 달라집니다.
fallback-filter로 응답을 선별하는 방법
geoip: true: GeoIP 기반 판별을 사용합니다.geoip-code: CN과 함께 설정하면 주 DNS가 지정 지역에 속하지 않는 주소를 반환할 때 fallback 응답을 사용합니다.ipcidr: 주 DNS 응답이 목록에 지정된 주소 범위에 해당하면 fallback 응답을 사용합니다. 예시의240.0.0.0/4는 일반 공인 IP로 사용하면 안 되는 예약 주소 범위를 판별하는 데 쓰입니다.domain: 지정한 도메인은 fallback 측의 DNS 정책을 바로 사용합니다. 주 DNS를 신뢰하기 어려운 것으로 확인된 일부 도메인에 적합합니다.
GeoIP 판별은 코어에서 사용할 수 있는 지리 정보 데이터에 의존합니다. 판별 대상은 IP의 지역 정보이지, 응답이 진짜인지 여부가 아닙니다. 해외 IP도 정상적인 CDN 응답일 수 있고, 국내 IP라고 해서 반드시 올바른 응답인 것도 아닙니다. 이 필터를 켜기 전에 지리 데이터베이스가 사용 가능한지 확인하고, 더 많은 조회가 fallback 서버의 연결 상태에 좌우된다는 점을 고려하세요.
병합해서 사용할 수 있는 mihomo DNS 설정
아래에는 최상위 dns 항목만 표시하며, 노드·구독·프록시 그룹은 포함하지 않습니다. 현재 정상 작동하는 아웃바운드 설정은 유지하고 기존 DNS 항목 전체를 교체하거나 오버라이드로 병합하세요. YAML 파일 하나에 최상위 dns:를 두 번 작성하면 안 됩니다. 예시에서는 시스템의 기존 53 포트 서비스와 충돌하지 않도록 로컬 1053 포트를 사용합니다.
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"
default-nameserver:
- 223.5.5.5
- 119.29.29.29
nameserver:
- https://dns.alidns.com/dns-query
- https://doh.pub/dns-query
fallback:
- https://1.1.1.1/dns-query
fallback-filter:
geoip: true
geoip-code: CN
ipcidr:
- 240.0.0.0/4
이 설정을 적용할 수 있는 범위
예시의 공용 DNS 서버는 구체적인 설정 사례일 뿐, 모든 네트워크에서 직접 연결할 수 있다는 뜻은 아닙니다. 1.1.1.1:443에 연결할 수 없다면 이 fallback 구성을 사용하지 마세요. 우선 fallback과 fallback-filter를 잠시 제거하고 주 DNS가 정상 작동하는지 확인한 다음, 연결이 확인된 예비 DNS 서버를 추가하세요.
dns.ipv6: false는 내장 DNS가 일반적인 AAAA 응답을 제공하지 않도록 설정합니다. 운영체제의 IPv6를 끄는 것은 아니며, 모든 앱이 IPv6 연결을 직접 설정하는 것도 막지 않습니다. IPv4와 IPv6를 함께 사용하려면 IPv6 라우팅, 노드, TUN 지원을 확인한 뒤 활성화하세요.
Fake-IP 모드에서는 코어가 먼저 198.18.0.0/16 범위의 가상 주소를 앱에 반환하고, 이후 매핑을 통해 도메인 정보를 유지할 수 있습니다. 이런 주소가 보인다고 해서 보통 DNS 오염은 아닙니다. 실제 조회와 연결 과정은 아웃바운드 유형과 규칙에 따라 달라집니다. fake-ip-filter에 지정된 도메인은 가상 응답을 사용하지 않지만, 적절한 실제 DNS 서버는 여전히 필요합니다. 필터를 설정한다고 공용 DNS가 내부 호스트를 인식하게 되는 것은 아닙니다.
dns-hijack는 dns 항목이 아닌 TUN 항목에 설정합니다
listen: 127.0.0.1:1053만 설정해도 시스템의 모든 DNS 요청이 자동으로 이 포트로 전송되지는 않습니다. 시스템 DNS 설정은 보통 IP 주소만 허용하고 사용자 지정 1053 포트는 지원하지 않습니다. 테스트할 때는 포트를 지정할 수 있지만, 일상적으로 사용하려면 TUN 가로채기, 시스템 전달 서비스 또는 명확한 다른 DNS 연결 방식이 필요합니다.
아래는 최상위 tun 항목만 따로 보여주는 예시이며, dns와 같은 수준에 두어야 합니다. 클라이언트가 이미 TUN 설정을 생성했다면 필요한 항목만 병합하고 같은 이름의 항목을 중복해서 만들지 마세요.
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
- tcp://any:53
any:53은 TUN으로 들어오는 일반 UDP DNS 요청을 가로채며, 두 번째 항목은 TCP 53을 추가로 처리합니다.auto-route는 라우팅을 자동으로 설정하지만, 실제로 가로챌 수 있는 범위는 시스템 권한, 인터페이스, 플랫폼 구현에 따라 달라집니다.- Windows에서는 보통 클라이언트 서비스나 관리자 권한이 필요합니다. macOS에서는 해당 네트워크 구성 요소를 허용해야 하며, Android에서는 일반적으로 시스템 VPN 권한으로 트래픽 가로채기 경로를 만듭니다.
- 클라이언트에 TUN 스위치가 있다면 화면의 상태와 실행 로그를 모두 확인해 YAML 설정과 화면의 오버라이드가 서로 덮어쓰지 않는지 살펴보세요.
DNS 상위 서버를 프록시로 연결하려면 노드 도메인부터 초기 해석하세요
DoH를 사용한다고 요청이 반드시 프록시를 통과하는 것은 아닙니다. mihomo에서 respect-rules를 사용하면 DNS 상위 서버 연결에 라우팅 규칙을 적용할 수 있습니다. 이를 활성화한 뒤에는 프록시 노드 자체의 도메인을 조회할 proxy-server-nameserver도 설정해야 합니다. 그렇지 않으면 ‘DNS 서버에 연결하려면 프록시가 필요한데, 프록시에 연결하려면 DNS가 필요한’ 의존성 루프가 생길 수 있습니다.
dns:
respect-rules: true
proxy-server-nameserver:
- https://dns.alidns.com/dns-query
이 항목은 기존 DNS 설정에 병합할 추가 필드일 뿐, 앞 절의 전체 설정을 대체하지 않습니다. 프록시 노드의 도메인을 조회하는 DNS 서버는 프록시가 연결되기 전에도 사용할 수 있어야 합니다. 활성화한 뒤 rules를 확인하세요. DoH 대상이 여전히 DIRECT 규칙에 해당하면 직접 연결되며, 프록시 그룹에 해당하면 그룹 내 노드도 사용 가능해야 합니다.
내부 도메인에 별도 DNS 서버 지정하기
회사 도메인, NAS, 라우터 관리 도메인은 보통 내부 DNS 서버에서 조회해야 합니다. nameserver-policy로 실제 내부 DNS 서버를 지정할 수 있지만, 주소는 현재 네트워크에서 확인해야 하며 다른 환경의 게이트웨이 주소를 그대로 사용하면 안 됩니다. TUN이 53 포트를 가로채면서 상위 DNS 요청을 다시 코어로 돌려보내 루프가 생기지 않는지도 확인하세요.
고정 장비가 몇 대뿐이라면 명시적인 hosts 매핑을 사용할 수도 있습니다. 내부 도메인 하나 때문에 모든 공용 도메인을 로컬 라우터 DNS로 돌리지 마세요. 반대로 공용 DoH가 회사 내부 전용 도메인을 조회할 수 있다고 기대해서도 안 됩니다.
4단계로 시간 초과, DNS 오염, 가로채기 실패를 구분하기
1단계: 설정이 실제로 적용됐는지 확인
설정을 다시 불러온 뒤 로그를 확인하고 YAML 들여쓰기, 필드 유형, 포트 충돌, 알 수 없는 설정 항목부터 점검하세요. YAML은 탭이 아닌 공백으로 들여씁니다. 시작 로그에 수신 실패가 표시되면 먼저 1053 포트를 다른 프로세스가 사용 중인지 확인하세요. 화면에는 수정 성공으로 표시되지만 로그에 변화가 없다면 클라이언트가 구독 오버라이드로 수동 설정을 덮어쓰는지 확인하세요.
2단계: 내장 DNS에 직접 질의
macOS 또는 Linux에 dig가 설치되어 있다면 수신 주소와 포트를 지정할 수 있습니다. 첫 번째 명령은 A 레코드를 확인하고 두 번째는 AAAA 응답을 확인합니다. Fake-IP 모드에서 첫 번째 명령이 가상 주소를 반환하는 것은 로컬 진입점이 응답한다는 뜻일 뿐, fallback이 정상 작동한다는 증거는 아닙니다.
dig @127.0.0.1 -p 1053 example.com A
dig @127.0.0.1 -p 1053 example.com AAAA
Windows에서는 nslookup 대화형 모드에서 포트를 지정할 수 있습니다. 아래 명령을 한 줄씩 입력하고, 마칠 때 exit를 입력하세요.
nslookup
server 127.0.0.1
set port=1053
set type=A
example.com
3단계: 시스템 요청이 코어에 전달되는지 확인
TUN을 켠 다음 서버를 지정하지 않고 시스템 DNS 조회를 실행하면서 코어 로그를 확인하세요. 1053 포트로 직접 조회하면 정상이지만 시스템 조회가 실패한다면 nameserver를 계속 바꾸기보다 라우팅, TUN 권한, 앱 자체 DNS 설정을 먼저 점검하세요. 브라우저에서 웹페이지가 열린다는 사실만으로는 충분하지 않습니다. 브라우저가 별도의 DoH나 기존 캐시를 사용했을 수 있습니다.
4단계: DNS 조회와 연결을 따로 확인
이전에 문제가 있었던 도메인을 선택하고 DNS 오류, 적용된 규칙, 최종 아웃바운드를 확인하세요. 짧은 시간 동안 디버깅해야 한다면 로그 수준을 일시적으로 높이고, 작업이 끝나면 원래대로 되돌리세요. 로그를 공유하기 전에 구독 주소, 토큰, 노드 인증 정보를 삭제하세요. 상위 DNS를 변경한 뒤 관련 캐시를 지우거나 코어를 재시작하고 같은 도메인의 첫 요청과 반복 요청을 비교하세요. 캐시 적중을 DNS 서버의 속도 향상으로 오해하지 않도록 주의해야 합니다.
| 증상 | 먼저 확인할 항목 | 다음 조치 |
|---|---|---|
| 로컬 1053 DNS 조회 시간 초과 | DNS 스위치, 수신 주소, 포트 충돌 | 먼저 DNS 진입점을 복구한 뒤 외부 DNS 서버를 확인합니다. |
| 코어에 조회 기록은 있지만 상위 DNS 응답 시간 초과 | 443 또는 853 연결 가능 여부, 초기 해석, 아웃바운드 규칙 | 연결이 확인된 상위 DNS 서버 하나만 남깁니다. |
| 일부 도메인에서만 fallback 사용 후 속도가 느려짐 | GeoIP 필터와 예비 DNS 서버의 연결 가능 여부 | 필터 조건을 확인한 뒤 예비 DNS 서버를 테스트합니다. |
| Fake-IP 응답은 오지만 연결 실패 | 매핑, TUN 라우팅, 규칙, 노드 상태 | 연결 로그를 따라 확인하고 가상 주소를 오류로 간주하지 않습니다. |
| 공용 사이트는 정상인데 내부 도메인은 실패 | 내부 DNS와 도메인 정책 | 내부 도메인 영역에 연결 가능한 내부 DNS 서버를 지정합니다. |
안정적으로 설정하려면 nameserver 하나를 먼저 정상 작동시키고, 시스템 DNS 연결을 확인한 다음 fallback 필터를 추가하고, 마지막으로 DNS 상위 서버의 프록시 라우팅을 설정하세요. 각 단계를 따로 검증해야 문제가 DNS 진입점, 상위 서버 연결, 후속 연결 중 어디에서 발생하는지 알 수 있습니다.