V2Ray DNS設定ガイド:中国国内・海外ドメインの名前解決分離とDNS汚染対策

Xray設定のdnsセクションを例に、中国国内ドメインはローカルDNS、海外ドメインは暗号化されたリモートDNSで名前解決する分流構造と、expectIPsとDoHサーバーの組み合わせ方を解説します。

この記事の概要

プロキシへの接続は問題なくできていて、ドメイン名の名前解決品質を最適化したい方向け。読み終えると、中国国内・海外で分流するdnsセクションを自力で書けるようになり、expectIPsの検証の意味を理解したうえでv2rayNの設定項目に対応づけられるようになります。

DNS分流が解決する2つの問題

中国国内のネットワーク環境から海外ドメインを直接名前解決すると、応答が汚染されることがよくあります。返ってくるIPが目的のサイトのものではなく、接続がタイムアウトしたり、別のページに飛ばされたりします。暗号化されたリモート名前解決では問い合わせをTLSトンネルに包むため、汚染源が応答内容を改ざんできません。これが分流におけるDoHの中心的な役割です。

中国国内のドメインは逆です。リモート名前解決でも結果は得られますが、問い合わせ経路にプロキシが1ホップ余分に挟まり、さらに一部の中国国内CDNは名前解決の発生元によって異なるノードを返すため、リモート名前解決では遠方のノードを掴みやすくなります。中国国内ドメインはローカルDNSに任せて最寄りで名前解決すれば、CDNの振り分けも正確になります。

アプリがリクエストを送信ドメインルールに一致中国国内はローカルDNS海外はDoHIPで接続を確立
比較項目ローカルDNSリモートDoH
問い合わせ経路キャリアまたは公共DNSへ直接接続プロキシ経由の暗号化問い合わせ
対象ドメインgeosite:cn 中国国内ドメインgeosite:geolocation-!cn 海外ドメイン
汚染対策能力弱い(平文で問い合わせ)強い(TLS内で改ざん不可)
遅延の傾向低い(最寄りで名前解決)やや高い(プロキシが1ホップ挟まる)

分流の目的は、問い合わせを機械的に分けることではなく、2種類のドメインをそれぞれの名前解決経路に流しつつ、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"
  ]
}

1つ目は海外向けで、問い合わせはプロキシのアウトバウンド経由で送信されます。2つ目は中国国内向けで、expectIPsで応答の帰属を検証します。3つ目は素のアドレスによるフォールバックで、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に書けます。これはservers配列より優先され、問い合わせは外部に送信されません。内部ネットワークのホスト名やセルフホストのサービスドメインに向いています。

routingルールとdomainStrategyの連携

dnsセクションはドメインを誰が名前解決するかを決め、routingは接続がどのアウトバウンドを通るかを決めます。dnsセクションだけを設定してroutingを設定しないと、トラフィックがすべてプロキシ経由になる可能性があります。逆にroutingだけを設定してdnsを設定しないと、中国国内ドメインもリモート名前解決で汚染されます。この2つは必ずセットで設定してください。

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

domainStrategy 3つの値の使いどころ

結論: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. 海外サイトにアクセスし、ログでそのドメインが1つ目のDoHで名前解決され、問い合わせがプロキシ経由で送信されていることを確認します。
  3. 中国国内のサイトにアクセスし、問い合わせが223.5.5.5に届き、応答がgeoip:cnの検証を通過していることを確認します。
  4. コマンドラインでnslookup www.qq.com 223.5.5.5を実行し、ローカルDNS自体が使えることを確認します。

結論:expectIPsは検証器であり、ルーターではない

expectIPsは不合格な名前解決結果を破棄するだけで、トラフィックの向きは変えません。どのアウトバウンドを通るかはroutingルールが決めるので、expectIPsに分流を任せようとしないでください。

よくある問題とトラブルシューティング

分流を設定して問題が起きたら、次の4つの手順で順に確認してください。

分流を有効にしたら中国国内サイトがかえって遅くなった?

まずログで問い合わせがどのサーバーに当たったか確認します。よくある原因は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セクションの1つ目のdomainsとroutingの海外ルールが同じドメイン集合を使っているか確認し、ログレベルをdebugに上げて、問い合わせが実際にDoHエントリに当たっているか確かめてください。

config.jsonを手で編集したのに、ノードを選ぶと消えてしまう?

v2rayNはサーバーを切り替えるときに内蔵テンプレートで設定を再生成するため、手で編集したdnsセクションは上書きされます。分流の設定は「設定」→「パラメータ設定」→「DNS設定」で行い、生成された設定ファイルを直接編集しないでください。

v2rayNダウンロード