Debian ネームサーバー リゾルバで dig を使用したローカル ポート範囲と UDP 送信ポートの違い

Debian ネームサーバー リゾルバで dig を使用したローカル ポート範囲と UDP 送信ポートの違い

Debian 7 のローカル ポート範囲にアクセスすると、一時ポート範囲が次のようになっていることがわかります。

cat /proc/sys/net/ipv4/ip_local_port_range
32768   61000

私のは/etc/sysctl.conf空です。

通常、これは、このネームサーバー リゾルバから送信されるすべてのリクエストがその範囲のポートを使用する必要があることを意味します。ただし、 を使用してtcpdump、 で作成された DNS リクエストと応答を確認するとdig、リクエストが 1500 という低い送信ポートを使用できることがわかります。

たとえば、次のtcpdump例 ( tcpdump udp and port 53 and host server.domain) では、要求はポート 15591 から送信されています。これは、前に見た一時ポートのサーバーの最低ポート制限である 32768 よりはるかに低い値です。つまり、 を使用するとdig、DNS 要求はローカル ポート範囲外になります。

11:57:33.704090 IP baremetal.15591 > M.ROOT-SERVERS.NET.domain: 41939% [1au] A? r.arin.net. (39)
11:57:33.704400 IP baremetal.41573 > M.ROOT-SERVERS.NET.domain: 40945% [1au] A? t.arin.net. (39)
11:57:33.704541 IP baremetal.22658 > M.ROOT-SERVERS.NET.domain: 44090% [1au] AAAA? t.arin.net. (39)
11:57:33.705295 IP baremetal.13277 > M.ROOT-SERVERS.NET.domain: 42356% [1au] A? v.arin.net. (39)
11:57:33.705499 IP baremetal.48755 > M.ROOT-SERVERS.NET.domain: 32253% [1au] A? w.arin.net. (39)
11:57:33.705639 IP baremetal.55309 > M.ROOT-SERVERS.NET.domain: 64660% [1au] AAAA? w.arin.net. (39)
11:57:33.705812 IP baremetal.56652 > M.ROOT-SERVERS.NET.domain: 43023% [1au] A? y.arin.net. (39)
11:57:33.706012 IP baremetal.26383 > M.ROOT-SERVERS.NET.domain: 42377% [1au] AAAA? y.arin.net. (39)
11:57:33.706172 IP baremetal.12895 > M.ROOT-SERVERS.NET.domain: 13206% [1au] AAAA? z.arin.net. (39)

Debian 7 および 8 の一時ポートのポート範囲を変更した原因は何だったのか疑問に思います。おそらく言及する価値があるのは 1 つだけです。私はそのうちの 1 つで使用しておりifenslave、もう 1 つはifenslave2 つのイーサネット ポートを結合するために使用しています。

リゾルバはサーバー自体であり、

#cat /etc/resolv.conf
nameserver ::1

nameserver 127.0.0.1しかし、 ipv4とipv6は共有しているため、まったく同じことを行います/proc/sys/net/ipv4/ip_local_port_range参照)&私も試してみました。

IPv6 との混乱を避けるため、 IPv4 のみを使用することにしました。 のみnameserver 127.0.0.1を追加しました/etc/resolv.conf

以下の結果はnameserver 127.0.0.1範囲内/etc/resolv.confのみです。

次に、rndc flushリゾルバからDNSキャッシュをフラッシュし、dig google.com

2番目のターミナルウィンドウを開いて、次のように入力しましたtcpdump udp and port 53

レコードはたくさんありますが、リクエスト(A、PTR...)と受信ホストに関係なく、DNSリクエストは32768未満のポートから発行できることに気付きました。

>strace -f dig www.google.com 2>&1 | egrep 'sendmsg|recvmsg|connect|bind'
open("/usr/lib/libbind9.so.80", O_RDONLY) = 3
[pid 10651] bind(20, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
[pid 10651] recvmsg(20, 0x7f5dd95cab60, 0) = -1 EAGAIN (Resource temporarily unavailable)
[pid 10651] sendmsg(20, {msg_name(16)={sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("127.0.0.1")}, msg_iov(1)=[{"\251\261\1\0\0\1\0\0\0\0\0\0\3www\6google\3com\0\0\1\0\1", 32}], msg_controllen=0, msg_flags=0}, 0 <unfinished ...>
[pid 10651] <... sendmsg resumed> )     = 32
[pid 10651] recvmsg(20, {msg_name(16)={sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("127.0.0.1")}, msg_iov(1)=[{"\251\261\201\200\0\1\0\1\0\4\0\4\3www\6google\3com\0\0\1\0\1"..., 65535}], msg_controllen=32, {cmsg_len=32, cmsg_level=SOL_SOCKET, cmsg_type=0x1d /* SCM_??? */, ...}, msg_flags=0}, 0) = 184

この問題は私のファイアウォールに関連しています。エフェメラル ポートは (私の推測では) 1024 から 65000 まで発行できるため、昔のように 1024 より大きいポートからの入力トラフィックをブロックすることはできません。ブロックすると、DNS 解決が遅くなったりブロックされたりします。

更新: ありがとうございます。サーバーを DNS リゾルバーとして使用する場合は、UDP ポート範囲 1024:65535 が一時ポート範囲であることを考慮する必要があることを理解しました。

答え1

あなたの設定に何か問題があるとは思いませんip_local_port_rangeし、このタイプのシナリオには通常適用されないとも思いません。むしろ、これは DNS 応答のスプーフィングを困難にすることに直接関係していると思います。

出力を見ると、データグラムを(そこで実行されている何らかのリゾルバ サーバーに)送信してstraceいることがわかりますが、出力はリゾルバ サーバー自体ではなく、そのリゾルバ サーバーからのトラフィックに関連しているようです。dig127.0.0.1tcpdumpdig


従来の DNS (DNSSEC なし) は、[トランザクション ID (16 ビット)](https://www.rfc-editor.org/rfc/rfc1035#section-4.1.1) と *question* セクションのデータのみに依存して、UDP 経由で受信した応答と以前に送信されたクエリを照合します。

UDP データグラムは簡単に偽装でき、ターゲットとして特定の名前がある場合に推測する必要があるランダム性は 16 ビットだけなので、実際の回答が届く前に正しいトランザクション ID を推測することは可能です (平均 32,000 回の推測)。

したがって、すべての現代のリゾルバサーバーはソースポートをランダム化するためにわざわざ努力する推測する必要のあるランダムビットの数を増やすためです。

可能な限り広いポート範囲が必要なので、おそらく 1024 を超えるポートの全範囲でランダム化が行われ、OS のデフォルトの処理で得られるものと比較して、かなりの数のランダム性ビットが追加されます。


つまり、ソケットのローカル ポートの通常の OS 処理を無視することが、単に「ベスト プラクティス」であると考えられます。

関連情報