Debian Wheezyを実行しているVMがあり、リゾルバがすぐに応答しても、いくつかのホスト名の検索を完了するのに数秒かかります。奇妙なことに、ルックアップはgetaddrinfo()
影響を受けますgethostbyname()
が、そうではありません。
ローカルパーサーが破損する可能性を排除するためにGoogleパーサーに切り替えました。私の/etc/resolv.conf
外観は次のとおりです。
search my-domain.com
nameserver 8.8.4.4
nameserver 8.8.8.8
鉱山nsswitch.conf
には次の行があります。
hosts: files dns
私のものには/etc/hosts
普通のものが1つも含まれていません。
試してみるtelnet webserver 80
と、名前が解決される前に数秒間停止します。出力[1]は、呼び出しltrace
中に中断が発生したことを示しています。getaddrinfo()
getaddrinfo("ifconfig.me", "telnet", { AI_CANONNAME, 0, SOCK_STREAM, 0, 0, NULL, '\000', NULL }, 0x7fffb4ffc160) = 0 <5.020621>
ただし、tcpdump
表示ネームサーバーはすぐに応答し、telnet
2番目の応答でのみブロックを解除します。応答はまったく同じです。
05:52:58.609731 IP 192.168.1.75.43017 > 8.8.4.4.53: 54755+ A? ifconfig.me. (29)
05:52:58.609786 IP 192.168.1.75.43017 > 8.8.4.4.53: 26090+ AAAA? ifconfig.me. (29)
05:52:58.612188 IP 8.8.4.4.53 > 192.168.1.75.43017: 54755 4/0/0 A 219.94.235.40, A 133.242.129.236, A 49.212.149.105, A 49.212.202.172 (93)
[...five second pause...]
05:53:03.613811 IP 192.168.1.75.43017 > 8.8.4.4.53: 54755+ A? ifconfig.me. (29)
05:53:03.616424 IP 8.8.4.4.53 > 192.168.1.75.43017: 54755 4/0/0 A 219.94.235.40, A 133.242.129.236, A 49.212.149.105, A 49.212.202.172 (93)
05:53:03.616547 IP 192.168.1.75.43017 > 8.8.4.4.53: 26090+ AAAA? ifconfig.me. (29)
05:53:03.618907 IP 8.8.4.4.53 > 192.168.1.75.43017: 26090 0/1/0 (76)
ホストファイアウォールログを確認しましたが、ポート53でブロックされたエントリはありません。
最初のDNS応答が無視される原因は何ですか?
[1]構造内をltrace.conf
見るためにファイルにいくつかの行を追加しました。addrinfo
答え1
最初の DNS 応答は無視されません。getaddrinfo()
最初のAAAAクエリ(ID:26090)への応答が受信されるまで返されません。したがって、ここで実際の質問は、コンピュータがすでにAクエリ(ID:54755)に対する応答を受信しており、AAAAクエリへの即時応答を受信していない理由です。
getaddrinfo()
IPv4とIPv6の違いの1つgethostbyname()
は、前者はIPv4とIPv6の両方をサポートしていますが、後者はIPv4のみをサポートしていることです。したがって、0()にgetaddrinfo()
設定して呼び出すと、応答が届くまで(またはタイムアウトに達するまで)返されません。ai_family
AF_UNSPEC
両方A および AAAA クエリはドメイン名を提供しました。gethostbyname()
Aレコードのみを照会します。
tcpdump
特に、出力の一部を削除した場合、問題の原因が何であるかをリモートで確認するのは困難です。 VMとGoogleのパブリックDNSリゾルバ間のDNSトラフィックを選択的にフィルタリング/削除できます。 KVM Debian Wheezy VMを使用して問題を再現しようとしましたが、その行はtelnet ifconfig.me
ほぼすぐに印刷されましたTrying <IP_address_here>...
(すでに名前が解決されたことを意味します)。
答え2
これは、VMwareインフラストラクチャの前にあるJuniperファイアウォールに設定されている過度に厳しいルールが原因で発生しました。
私は会話の両側を見ることができるようにテストパーサーを作成しました。その回答に記載されているようにgetaddrinfo()
アドレスファミリが指定されていない場合、次の回答は次のとおりです。みんな帰る前に(または私の場合はタイムアウト)家族を扶養してください。
ネットワークを運営する同僚が指摘した。
Juniperファイアウォールのデフォルトの動作は、そのセッションに一致するDNS応答が受信されるとすぐにDNS関連セッションを閉じることです。
したがって、ファイアウォールはIPv4応答を確認し、仮想マシンのクエリに応答したことを確認し、そのポートへのインバウンドパスを閉じます。したがって、その後のIPv6応答パケットは破棄されます。なぜ2番目のパケットがすべて通過したのかわかりませんが、ファイアウォールでこの機能を無効にすると問題が解決しました。
以下は、Juniper Knowledge Baseから抜粋した関連コンテンツです。
以下は、DNS 応答パケットがドロップされるシナリオです。
- 最初の DNS クエリ パケットがファイアウォールに到達し、許可ポリシーが設定されると、DNS トラフィック セッションが作成されます。デフォルトのタイムアウトは60秒です。
- セッションが終了する前に新しいDNSクエリが送信され、既存のセッションと一致するため(ソースポートと宛先ポート/ IPペアは常に同じであるため)ファイアウォールによって転送されます。セッションタイムアウトは、新しく到着したパケットによっては更新されません。
- 最初のDNSクエリ応答(応答)がデバイスに到達すると、作成されたDNSセッションは残りのタイムアウトに関係なくタイムアウトします。
- DNS 応答がファイアウォールを通過すると、セッションは期限切れになります。
- セッションが存在しないため、以降のすべてのDNS応答はファイアウォールによって削除されます。
この回答に投票するには、Kempniuの回答にも投票してください。それがなければ、私はまだVMのいくつかの構成問題を見つけて迷っていました。