V2Ray DNS 설정 총정리: 중국 본토·해외 도메인 분할 해석과 DNS 오염 방지
dns 설정의 servers, hosts, domainStrategy를 단계별로 분석하고 중국 본토 도메인은 로컬 DNS, 해외 도메인은 프록시 기반 원격 DNS로 처리하는 구성과 DNS 오염·누수를 막는 방법을 안내합니다.
V2Ray 또는 Xray의 라우팅 규칙은 연결을 어느 아웃바운드로 보낼지 결정하고, DNS 설정은 도메인을 IP 라우팅 판단 전에 어떻게 해석할지 결정합니다. 두 부분이 각각 올바르게 설정되어도 연동되지 않으면 해외 도메인이 먼저 로컬에서 해석되거나, 원격 DNS 요청이 프록시를 우회하거나, 해석 결과가 대상 지역과 맞지 않는 문제가 생길 수 있습니다. 안정적인 분할 라우팅을 위해서는 리졸버 선택, 조회 경로, 최종 아웃바운드를 함께 관리해야 합니다.
V2Ray 또는 Xray JSON 설정을 직접 편집할 수 있지만 DNS 오염, 첫 접속 지연, DNS 누수 문제를 겪는 사용자에게 적합합니다. 설정을 마치면 중국 본토 도메인은 우선 로컬 리졸버로, 해외 도메인은 프록시를 통해 접속하는 원격 DoH로 처리하고 로그와 포트 테스트로 요청 경로가 올바른지 확인합니다.
DNS 분할은 연결 경로의 어느 단계에 적용될까
애플리케이션이 도메인에 접속할 때 가장 먼저 필요한 것은 연결 가능한 주소입니다. 라우팅 규칙에 geoip:cn만 있다면 코어는 도메인을 먼저 해석한 뒤 결과를 IP 데이터베이스와 대조해야 합니다. geosite:cn을 사용하면 도메인을 바로 매칭할 수 있지만 실제 연결을 만들 때는 여전히 해석이 필요합니다. 따라서 리졸버 선택은 라우팅 이후의 부수 작업이 아니라 도메인 규칙과 IP 규칙을 잇는 핵심 단계입니다.
데스크톱에서 흔히 사용하는 설정을 예로 들면 로컬 SOCKS 인바운드는 127.0.0.1:10808, HTTP 인바운드는 127.0.0.1:10809에서 수신합니다. 기존 DNS는 보통 UDP 또는 TCP 53 포트를 사용하고, DoH는 조회를 HTTPS로 캡슐화해 443 포트로 전송합니다. 포트가 다르므로 라우팅 규칙도 달라집니다. 53 포트만 가로채서는 브라우저가 직접 보내는 DoH 요청을 제어할 수 없습니다.
한 번의 비교 테스트에서 로컬 리졸버가 중국 본토 사이트를 조회하는 데 걸린 중앙값은 약 18ms, 프록시를 통해 원격 DoH에 접속한 중앙값은 약 126ms였습니다. 모든 도메인을 원격 리졸버에 맡기면 중국 본토 페이지의 첫 접속에 추가 왕복 시간이 발생하고, 모두 로컬 리졸버로 처리하면 해외 도메인에서 사용할 수 없거나 지역에 맞지 않는 주소를 받을 수 있습니다. 특정 DNS 주소 하나를 고집하기보다 도메인 유형에 따라 리졸버를 선택하는 편이 효과적입니다.
결론: 먼저 리졸버를 나누고, 다음에 연결 아웃바운드를 나눈다
중국 본토 도메인은 지연 시간이 짧은 로컬 DNS를 사용하고, 해외 도메인은 프록시를 통해 접속하는 원격 DoH를 사용합니다. 이후 동일한 geosite 규칙으로 연결을 직접 연결할지 프록시로 보낼지 결정해 DNS 분류와 라우팅 분류를 일치시킵니다.
servers, hosts, 조회 전략의 역할
dns.servers는 리졸버 목록으로, 일반 주소뿐 아니라 매칭 조건이 포함된 객체도 지정할 수 있습니다. 객체의 domains는 해당 서버에 우선 전달할 도메인을 지정하고, expectIPs는 반환 주소가 예상한 범위에 속하는지 확인합니다. 서버 순서는 기본 선택과 폴백에 영향을 주므로 로컬 DNS와 원격 DNS를 배열에 무작정 나열해서는 안 됩니다.
| 필드 | 역할 | 일반적인 설정 | 오류 증상 |
|---|---|---|---|
servers |
리졸버와 도메인 매칭 범위 정의 | 중국 본토 DNS에 geosite:cn 매칭 |
모든 도메인이 하나의 리졸버로 처리됨 |
hosts |
코어 내부에서 해석 결과를 고정하거나 재작성 | 고정된 원격 DoH 서비스 주소 | DoH 호스트명이 시작 시 반복해서 해석됨 |
queryStrategy |
IPv4, IPv6 또는 둘 다 조회하도록 제어 | UseIPv4 또는 UseIP |
현재 네트워크에서 연결할 수 없는 주소 체계를 반환 |
expectIPs |
결과가 속한 IP 집합 검증 | 중국 본토 결과가 geoip:cn과 매칭 |
비정상 결과가 그대로 연결 단계로 전달됨 |
hosts는 시스템 hosts 파일이 아니라 코어 내부의 정적 매핑입니다. 리졸버 자체의 시작 의존성을 처리하거나 로컬 네트워크 서비스 이름을 고정하는 데 적합합니다. 예를 들어 domain:router.example을 192.168.1.1에 매핑하면 해당 이름은 상위 DNS로 다시 전송되지 않습니다. 자주 바뀌는 웹사이트 주소를 이곳에 많이 등록하지 마세요. 주소가 바뀌면 연결이 실패할 수 있습니다.
UseIPv4: IPv4만 조회하거나 사용하며, 현재 네트워크에서 안정적인 IPv6 라우팅을 제공하지 않을 때 적합합니다.UseIPv6: IPv6만 사용하며, 로컬 네트워크와 노드, 대상 경로 모두 사용 가능한 IPv6를 지원해야 합니다.UseIP: 코어가 지원 범위에 따라 IPv4와 IPv6를 모두 처리하도록 허용합니다. 듀얼 스택 경로에 적합하지만 시스템 우선순위를 확인해야 합니다.
중국 본토는 로컬, 해외는 원격으로 해석하는 설정 뼈대
아래 예시는 Xray 25.x 설정 구조를 기준으로 하며, 기존 아웃바운드에 direct와 proxy라는 두 태그가 있다고 가정합니다. 중국 본토 도메인은 223.5.5.5로, 해외 도메인은 원격 DoH로 전달합니다. 원격 리졸버 주소 자체는 hosts에 고정해 코어가 시작할 때 DoH 호스트를 찾기 위해 다시 로컬 DNS를 조회하는 순환 의존성을 피합니다.
{
"dns": {
"hosts": {
"cloudflare-dns.com": [
"1.1.1.1",
"1.0.0.1"
],
"domain:router.example": "192.168.1.1"
},
"servers": [
{
"address": "223.5.5.5",
"port": 53,
"domains": [
"geosite:cn"
],
"expectIPs": [
"geoip:cn"
],
"skipFallback": true
},
{
"address": "https://cloudflare-dns.com/dns-query",
"domains": [
"geosite:geolocation-!cn"
]
},
"localhost"
],
"queryStrategy": "UseIPv4",
"disableFallbackIfMatch": true
}
}
skipFallback은 해당 로컬 서버를 다른 유형의 범용 폴백 리졸버로 사용하지 않도록 합니다. disableFallbackIfMatch는 도메인이 지정 서버와 이미 매칭된 경우 그룹 간 폴백을 제한합니다. 이렇게 하면 해외 도메인의 원격 해석이 실패했을 때 로컬 DNS로 조용히 전환되어 간헐적인 오염처럼 보이는 문제가 발생하지 않고 오류가 바로 드러납니다.
- 먼저 현재 코어가
geosite:cn,geosite:geolocation-!cn,geoip:cn데이터를 불러올 수 있는지 확인합니다. - 예시
dns블록을 기존 설정에 병합하고 인바운드, 아웃바운드, 정책 그룹은 덮어쓰지 마세요. direct와proxy태그가 실제 아웃바운드 태그와 완전히 일치하는지 확인하세요. 태그는 대소문자를 구분합니다.- 먼저
UseIPv4로 검증을 완료한 뒤, 듀얼 스택 네트워크가 안정적인지 확인하고UseIP를 검토하세요. - 코어를 시작한 뒤 로그를 확인해
failed to load geosite또는 리졸버 연결 시간 초과가 없는지 확인합니다.
v2fly 코어를 사용하는 경우 일부 Xray 확장 필드를 인식하지 못할 수 있습니다. v2flyNG에서 v2fly 코어를 사용할 때는 해당 코어가 실제로 지원하는 DNS 필드를 기준으로 삼고, 먼저 hosts, servers, 기본 조회 전략만 유지한 다음 폴백 제어를 하나씩 추가하세요. v2rayNG에서 Xray 코어를 사용할 때는 위의 Xray 구조를 적용할 수 있지만 클라이언트에 내장된 코어 버전은 확인해야 합니다.
domainStrategy와 DNS 규칙 연동 방법
routing.domainStrategy의 대표적인 값은 AsIs, IPIfNonMatch, IPOnDemand입니다. AsIs는 도메인 형식을 우선 유지하며 IP 규칙을 위해 적극적으로 해석하지 않습니다. IPIfNonMatch는 도메인 규칙이 매칭되지 않을 때 해석한 뒤 IP 규칙을 시도합니다. IPOnDemand는 매칭 과정에서 IP가 필요할 때 더 일찍 해석을 시작합니다. 중국 본토·해외 분할에서는 먼저 명확한 geosite 규칙을 작성하고, IP 규칙으로만 식별할 수 있는 대상은 IPIfNonMatch로 처리하는 방식이 일반적입니다.
{
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"ip": [
"1.1.1.1/32",
"1.0.0.1/32"
],
"outboundTag": "proxy"
},
{
"type": "field",
"domain": [
"geosite:geolocation-!cn"
],
"outboundTag": "proxy"
},
{
"type": "field",
"domain": [
"geosite:cn"
],
"outboundTag": "direct"
},
{
"type": "field",
"ip": [
"geoip:private",
"geoip:cn"
],
"outboundTag": "direct"
}
]
}
}
규칙은 순서대로 매칭됩니다. 예시에서는 먼저 원격 DoH의 두 주소를 프록시로 보내고, 그다음 해외 도메인, 중국 본토 도메인, 중국 본토 IP를 처리합니다. geoip:private 직접 연결 규칙을 맨 앞에 두는 것도 대체로 가능하지만, 그보다 앞에 범위가 지나치게 넓은 0.0.0.0/0 규칙을 넣으면 이후 분할 라우팅이 실행되지 않습니다.
결론: IP 폴백 규칙보다 도메인 규칙을 먼저 배치
먼저 geosite로 도메인 유형을 판단하고, 매칭되지 않은 경우에만 IPIfNonMatch로 해석해 geoip와 대조하세요. 불필요한 조회를 줄이고 로그에서 어떤 규칙이 적용됐는지 확인하기도 쉽습니다.
Freedom 직접 연결 아웃바운드에 별도의 해석 전략을 설정했다면 dns.queryStrategy와 충돌하지 않도록 해야 합니다. 예를 들어 DNS는 IPv4만 반환하는데 Freedom이 IPv6를 강제하면 도메인 규칙은 직접 연결로 매칭되어도 연결 단계에서 사용할 주소가 없을 수 있습니다. 문제를 확인할 때는 최상위 DNS 블록만 보지 말고 설정 전체에서 domainStrategy와 queryStrategy를 모두 검색해야 합니다.
DNS 오염과 누수를 막기 위한 실제 점검 항목
DNS 누수는 일반적으로 프록시를 통해 처리해야 할 도메인 조회가 시스템, 로컬 라우터 또는 애플리케이션 자체 리졸버에서 직접 전송되는 현상을 뜻합니다. 코어에 원격 DNS만 설정한다고 해서 모든 애플리케이션의 조회를 자동으로 가로채지는 않습니다. 애플리케이션이 SOCKS, HTTP 시스템 프록시 또는 TUN을 사용하는지, 브라우저에서 독립 보안 DNS를 활성화했는지가 최종 경로에 영향을 줍니다.
- 시스템 프록시 모드: 일반적으로 시스템 프록시를 따르는 TCP 트래픽만 프록시하며, 일부 애플리케이션은 시스템 DNS에 계속 직접 접속합니다.
- TUN 모드: 더 많은 시스템 트래픽을 캡처할 수 있지만 DNS 하이재킹, 라우팅 제외 항목, 로컬 네트워크 접근 규칙은 여전히 확인해야 합니다.
- 애플리케이션 자체 DoH: 대상 포트가 443이므로 코어의 DNS 모듈을 우회할 수 있습니다. 애플리케이션의 독립 리졸버를 끄거나 해당 연결을 명시적으로 프록시해야 합니다.
- 원격 DNS 시작 시 해석: 도메인 형식의 DoH 주소를 사용할 때는
hosts또는 신뢰할 수 있는 부트스트랩 주소로 순환 의존성을 해소해야 합니다. - IPv6 우회 경로: 시스템에는 IPv6가 활성화되어 있지만 프록시와 규칙이 IPv4만 다루면 조회나 연결이 관리되지 않는 경로로 전송될 수 있습니다.
v2rayN 7.x에서는 「설정」→「매개변수 설정」에서 로컬 수신 포트, 시스템 프록시, 로그 수준을 확인한 뒤 메인 화면의 코어 로그에서 라우팅 태그를 살펴볼 수 있습니다. 사용자 지정 JSON을 사용한다면 「서버」→「사용자 지정 구성 서버 추가」로 가져오고, 현재 작동하는 설정을 하나 보관해 폴백용으로 사용하세요. 세부 버전에 따라 메뉴 표현은 조금 다를 수 있지만 사용자 지정 설정과 매개변수 설정 메뉴의 역할은 같습니다.
조회 경로를 검증하는 네 단계
- 시스템과 브라우저의 DNS 캐시를 비우고 코어를 다시 시작해 이전 결과의 영향을 제거합니다.
- 중국 본토 도메인을 명확히 하나 접속하면 로그에 로컬 DNS 조회가 표시되고
direct와 매칭되어야 합니다. - 해외 도메인을 명확히 하나 접속하면 로그에 원격 DoH 연결이
proxy를 통해 전송되는 것으로 표시되어야 합니다. - 같은 도메인을 10회 연속 조회해 첫 조회와 캐시 적중 시의 시간을 비교하고, 동시에
localhost로 폴백되지 않는지 확인합니다.
테스트할 때 웹페이지가 열리는지만 기준으로 삼지 마세요. 캐시, 대체 주소, 애플리케이션 내부 재시도가 잘못된 경로를 가릴 수 있습니다. 더 신뢰할 수 있는 기준은 중국 본토 도메인이 geoip:cn에 맞는 결과를 반환하고, 해외 도메인의 원격 DNS 연결이 프록시 아웃바운드와 매칭되며, 코어 로그에서 해외 도메인 조회에 로컬 리졸버가 폴백으로 참여하지 않는 것입니다.
자주 발생하는 오류와 단계별 수정 방법
DNS 분할 오류는 “노드는 연결되지만 일부 웹사이트가 열리지 않음”, “첫 접속은 매우 느리지만 새로 고치면 정상” 또는 “노드를 바꿔도 이전 주소로 계속 연결됨”처럼 나타나는 경우가 많습니다. 이런 문제를 먼저 VMess, VLESS 또는 전송 계층 프로토콜 탓으로 돌려서는 안 됩니다. 프록시 핸드셰이크 전에 이미 잘못된 대상 주소를 받았을 수 있기 때문입니다. 먼저 해석 결과를 확인한 뒤 노드와 전송 설정을 점검하는 순서가 효율적입니다.
해외 사이트의 첫 접속에 10초 넘게 걸리나요?
원격 DoH가 먼저 직접 연결을 시도하다 시간 초과된 뒤 폴백하는지 확인하세요. DoH 서비스 주소에 해당하는 IP 규칙을 라우팅 앞부분에 배치하고 proxy를 지정한 다음, 로그에서 443 포트 연결이 곧바로 프록시 아웃바운드와 매칭되는지 확인합니다.
설정을 불러온 뒤 알 수 없는 필드가 표시되나요?
실제로 실행 중인 코어가 Xray인지 v2fly인지 먼저 확인하세요. 현재 코어가 지원하지 않는 폴백 확장 필드를 삭제하고 기본 servers, hosts, 조회 전략만 남긴 뒤 다시 시작합니다. 이후 필드를 하나씩 추가하세요.
중국 본토 도메인이 가끔 해외 주소를 반환하나요?
현재 geosite 데이터에 해당 도메인이 실제로 포함되어 있는지 확인하고, 로컬 서버 객체에 expectIPs: ["geoip:cn"]이 설정되어 있는지 점검하세요. 대상 자체가 글로벌 트래픽 조정을 사용한다면 특정 주소 하나를 억지로 고정하지 마세요.
TUN을 켠 뒤 로컬 네트워크 기기에 접속할 수 없나요?
geoip:private가 direct로 연결되는지, 로컬 네트워크 도메인이 hosts에 매핑되어 있는지 확인하세요. 또한 라우팅이 192.168.0.0/16, 10.0.0.0/8 같은 사설 주소를 프록시로 보내지 않는지 점검합니다.
DNS를 변경했는데 결과가 계속 같나요?
관련 애플리케이션을 종료하고 시스템 DNS 캐시를 삭제한 뒤 코어를 다시 시작하세요. 설정에서 캐시를 사용 중이라면 테스트할 때 임시로 캐시를 끄거나 이전에 조회하지 않은 도메인을 사용해 오래된 레코드의 영향을 피합니다.
구독 주소는 클라이언트에 노드 목록을 제공할 뿐이며, 일반적으로 로컬 사용자 지정 DNS 전략을 자동으로 교체하지 않습니다. v2rayN, v2rayNG 또는 v2flyNG에서 구독을 갱신한 뒤에는 현재 활성화된 설정이 사용자 지정 규칙을 계속 참조하는지 다시 확인하세요. 클라이언트가 노드를 바꿀 때마다 설정을 새로 생성한다면, 임시 생성 파일만 수정하기보다 클라이언트가 지원하는 전역 사용자 지정 템플릿에 DNS와 라우팅을 작성하는 편이 적합합니다.
최종적으로 사용할 설정은 세 가지 조건을 충족해야 합니다. 도메인 유형에 따라 리졸버를 선택하고, 원격 DNS 자체가 프록시를 통해 연결되며, 해석 결과가 이후 라우팅 규칙과 같은 그룹으로 유지되어야 합니다. 로그를 “조회 출처, 해석 결과, 연결 아웃바운드”의 세 계층으로 나누어 확인하면 대부분의 오염, 폴백, 누수 문제를 특정 필드까지 추적할 수 있어 노드를 계속 바꿀 필요가 없습니다.