V2Ray DNS 설정 가이드: 국내외 분할 해석과 오염 방지 설정법

Xray 설정의 dns 섹션을 예로 들어 국내 도메인은 로컬 DNS로, 해외 도메인은 암호화된 원격 DNS로 분할 해석하는 구조와 expectIPs 및 DoH 서버 조합 사용법을 설명합니다.

요약

프록시에 이미 정상적으로 연결되어 있고 도메인 해석 품질을 최적화하려는 사용자를 위한 글입니다.读完就能独立写出带境内境外分流的 dns 段,理解 expectIPs 的校验语义,并对应到 v2rayN 的参数设置项。

DNS 분할 해석이 해결하는 두 가지 문제

국내 네트워크 환경에서 해외 도메인을 직접 조회하면 응답이 오염되는 경우가 많습니다. 반환된 IP가 대상 사이트의 IP가 아니라서 연결이 타임아웃되거나 엉뚱한 페이지로 연결됩니다. 암호화된 원격 해석은 조회 패킷을 TLS 터널에 담아 보내므로 오염원이 응답 내용을 변조할 수 없습니다. 이것이 분할 해석에서 DoH가 하는 핵심 역할입니다.

국내 도메인은 반대입니다. 원격 해석으로도 결과를 얻을 수는 있지만 조회 경로에 프록시 홉이 하나 더 추가되고, 일부 국내 CDN은 해석 출처에 따라 다른 노드를 반환하므로 원격 해석은 지역을 벗어난 노드를 받기 쉽습니다. 국내 도메인은 로컬 DNS에 맡겨 가까운 노드로 해석하는 편이 CDN 스케줄링에 더 유리합니다.

앱이 요청 전송도메인 규칙 매칭국내 도메인은 로컬 DNS해외 도메인은 DoHIP 기준으로 연결 수립
비교 항목로컬 DNS원격 DoH
조회 경로ISP 또는 공공 DNS에 직접 연결프록시를 경유한 암호화 조회
적용 도메인geosite:cn 국내 도메인geosite:geolocation-!cn 해외 도메인
오염 방지 능력약함, 평문 조회강함, TLS 내부에서 변조 불가
지연 특성낮음, 가까운 노드로 해석다소 높음, 프록시 홉 하나 추가

분할 해석의 목표는 조회를 기계적으로 나누는 것이 아니라 두 종류의 도메인이 각자의 해석 채널을 이용하도록 하면서, routing 규칙과 dns 섹션이 동일한 도메인 집합을 사용하도록 하는 것입니다.

dns 섹션의 기본 구조와 분할 해석 작성법

Xray의 dns 섹션은 servers 배열이며 순서대로 매칭됩니다. 도메인이 어떤 항목의 domains 목록에 포함되면 해당 항목을 사용하고, domains가 없는 항목은 모든 도메인에 매칭되므로 마지막에 두어 폴백으로 사용합니다. 아래 내용을 설정 파일의 루트 노드에 넣으면 됩니다.

"dns": {
  "servers": [
    {
      "address": "https://1.1.1.1/dns-query",
      "domains": ["geosite:geolocation-!cn"],
      "tag": "proxy"
    },
    {
      "address": "223.5.5.5",
      "domains": ["geosite:cn"],
      "expectIPs": ["geoip:cn"]
    },
    "223.5.5.5"
  ]
}

첫 번째 항목은 해외 도메인을 담당하며 조회가 프록시를 통해 나갑니다. 두 번째 항목은 국내 도메인을 담당하며 expectIPs로 응답 소속을 검증합니다. 세 번째 항목은 domains가 없는 폴백으로, geosite 데이터에 등록되지 않은 도메인을 처리합니다. v2rayN이 생성하는 설정에서 프록시 아웃바운드 태그는 proxy, 직접 연결은 direct이므로 참조할 때 일치시켜야 합니다. 프록시 서버 주소는 IP를 직접 입력하는 편이 해석 단계를 줄여서 좋습니다.

로컬 DNS

주소
223.5.5.5 또는 119.29.29.29
매칭
geosite:cn
검증
expectIPs: geoip:cn
아웃바운드
direct

국내 도메인을 가까운 노드로 해석하여 CDN 스케줄링이 정확해집니다.

원격 DoH

주소
https://1.1.1.1/dns-query
매칭
geosite:geolocation-!cn
아웃바운드
tag: proxy
검증
선택 사항: geoip:!cn

조회가 프록시를 통해 나가므로 응답이 오염될 수 없습니다.

고정 해석이 필요한 도메인은 dns.hosts에 넣을 수 있습니다. dns.hosts는 servers 배열보다 우선순위가 높으며 조회가 외부로 나가지 않습니다. 내부 네트워크 호스트명이나 자체 운영 서비스 도메인을 여기에 두는 것이 적합합니다.

routing 규칙과 domainStrategy의 연동

dns 섹션은 도메인을 누가 해석할지 결정하고, routing은 연결이 어떤 아웃바운드를 사용할지 결정합니다. dns 섹션만 설정하고 routing을 설정하지 않으면 트래픽이 여전히 전부 프록시로 갈 수 있고, routing만 설정하고 dns를 설정하지 않으면 국내 도메인도 원격 해석으로 오염될 수 있습니다. 둘은 반드시 함께 설정해야 합니다.

"routing": {
  "domainStrategy": "IPIfNonMatch",
  "rules": [
    {
      "type": "field",
      "domain": ["geosite:cn"],
      "outboundTag": "direct"
    },
    {
      "type": "field",
      "domain": ["geosite:geolocation-!cn"],
      "outboundTag": "proxy"
    }
  ]
}

domainStrategy 세 가지 값의 적용 시나리오

결론: dns 섹션과 routing이 동일한 도메인 집합을 공유하도록 하세요

geosite:cn이 양쪽에 모두 등장하고, 해외 쪽은 geosite:geolocation-!cn으로 여집합을 취해 중간에 빈틈이 없어야 합니다. 그렇지 않으면 해석은 DoH로 나가는데 연결은 직접 연결로 가는 어긋남이 발생합니다.

expectIPs의 오염 방지 의미와 검증 방법

expectIPs는 라우팅 규칙이 아니라 해석 결과만 검증합니다. 결과가 주어진 geoip 목록에 없으면 버리고 순서대로 다음 서버를 시도합니다. 국내 항목에서 가장 많이 쓰는 작성법은 expectIPs: ["geoip:cn"]로, 로컬 DNS가 국내 IP만 받아들이도록 합니다.

{
  "address": "223.5.5.5",
  "domains": ["geosite:cn"],
  "expectIPs": ["geoip:cn", "geoip:private"]
}

expectIPs는 부정 표현도 지원하므로 해외 항목에 geoip:!cn을 추가해 국내 CDN 노드로 해석된 결과를 거부할 수 있습니다. 검증 실패 시 폴백 대신 바로 오류를 내고 싶다면 항목에 skipFallback: true를 추가하세요. geoip:private는 내부 네트워크 주소 대역을 허용하므로 내부 도메인이 잘못 버려지는 것을 방지합니다.

분할 해석이 적용되었는지 확인하기

  1. 설정 → 매개변수 설정 → 기본 설정에서 로그 레벨을 debug로 올린 뒤 노드에 다시 연결합니다.
  2. 해외 사이트 하나에 접속해 로그에서 해당 도메인이 첫 번째 DoH로 해석되고 조회가 프록시를 통해 나가는지 확인합니다.
  3. 국내 사이트 하나에 접속해 조회가 223.5.5.5로 들어가고 응답이 geoip:cn 검증을 통과하는지 확인합니다.
  4. 명령줄에서 nslookup www.qq.com 223.5.5.5를 실행해 로컬 DNS 자체가 정상 동작하는지 확인합니다.

결론: expectIPs는 검증기이지 라우터가 아닙니다

expectIPs는 부적합한 해석 결과를 버릴 뿐 트래픽 경로를 바꾸지 않습니다. 트래픽이 어떤 아웃바운드로 나갈지는 routing 규칙이 결정하므로 expectIPs가 분할 해석을 대신해 줄 것이라고 기대해서는 안 됩니다.

자주 묻는 질문과 문제 해결

분할 해석 설정 후 문제가 생기면 아래 네 가지 순서로 점검하세요.

분할 해석을 켠 뒤 국내 사이트가 오히려 느려졌어요?

먼저 로그에서 조회가 어떤 서버에 매칭되었는지 확인하세요. 흔한 원인은 geosite:cn 데이터가 오래되어 새 도메인이 등록되지 않아 원격 DoH로 나가는 경우입니다. geosite와 geoip 데이터 파일을 업데이트하거나 해당 도메인을 dns.hosts에 넣어 로컬 해석으로 고정하세요.

원격 DoH가 계속 타임아웃돼요?

DoH 항목의 tag가 프록시 아웃바운드를 가리키는지 확인하고, v2rayN에서 해당하는 '원격 DNS 프록시 사용' 옵션을 체크하세요. 1.1.1.1에 직접 연결할 수 없다면 주소를 https://dns.google/dns-query 또는 https://8.8.8.8/dns-query로 바꾸세요.

해외 도메인이 여전히 오염된 IP로 해석돼요?

해당 도메인이 geosite:geolocation-!cn 범위에 포함되지 않았을 가능성이 높습니다. dns 섹션 첫 번째 항목의 domains와 routing의 해외 규칙이 동일한 도메인 집합을 사용하는지 확인하고, 로그 레벨을 debug로 올려 조회가 실제로 DoH 항목에 떨어지는지 확인하세요.

config.json을 직접 수정했는데 노드를 선택하면 풀려요?

v2rayN은 서버를 전환할 때 내장 템플릿으로 설정을 다시 생성하므로 직접 수정한 dns 섹션이 덮어써집니다. 분할 해석 설정은 '설정' → '매개변수 설정' → 'DNS 설정'에서 완료하고, 생성된 설정 파일을 직접 편집하지 마세요.

v2rayN 다운로드