When i go to my local port range on Debian 7, i can see that my ephemeral port range is:
cat /proc/sys/net/ipv4/ip_local_port_range
32768 61000
My /etc/sysctl.conf
is empty.
Normally that would mean that all requests coming out from this nameserver resolver should use ports in that range. However, using tcpdump
, when i look at a DNS request & answer created with dig
, I can see that the request can use a sending port as low as 1500.
For instance, in the following tcpdump
example (tcpdump udp and port 53 and host server.domain
), the request came from port 15591. It is way below the server lowest port limit for ephemeral ports that we saw before: 32768. In other words, using dig
, DNS requests are out of the local port range.
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)
I wonder what could have change the port range of ephemeral ports on my Debian 7 & 8. Only thing that is perhaps worth to mention. I have used on one of them ifenslave
& one uses ifenslave
to bond two ethernet ports.
The resolver is the server itself and
#cat /etc/resolv.conf
nameserver ::1
but it does exactly the same with nameserver 127.0.0.1
because ipv4 & ipv6 shares /proc/sys/net/ipv4/ip_local_port_range
(reference) & also I have tried it.
To avoid confusion with IPv6, I have decided to use Ipv4 only. I have only added nameserver 127.0.0.1
to /etc/resolv.conf
.
Results below are with nameserver 127.0.0.1
in /etc/resolv.conf
only.
Then, I issued rndc flush
to flush the DNS cache from resolver and dig google.com
I opened a second terminal window and typed tcpdump udp and port 53
:
Lots of records but I noticed, whatever the request (A,PTR...) & receiving host, DNS requests CAN be issued from port lower than 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
This issue is related to my firewall. Since ephemeral ports can be issued from (my own guess) 1024 to 65000, it means that I can't block input traffic coming from ports higher than 1024 just like in the old days. If I do this I will slow down or block DNS resolution.
UPDATE: thank you, I understand that if I want to use a server as a DNS resolver it means that I have to consider that UDP port range 1024:65535 is the ephemeral port range.
I don't think there is anything wrong with your
ip_local_port_range
setting or that it wouldn't normally be applicable to this type of scenario, I rather believe this is directly related to making spoofing DNS replies harder.We see in your
strace
output that you havedig
sending a datagram to127.0.0.1
(some resolver server running there) but thetcpdump
output seems to be relating to the traffic from that resolver server, notdig
itself.Plain old DNS (without DNSSEC) relies on only the [transaction id (16 bits)](https://www.rfc-editor.org/rfc/rfc1035#section-4.1.1) and the data in the *question* section to match up the response received over UDP with the query that was sent earlier.
With UDP datagrams easy to spoof and with only 16 bits of randomness that need to be guessed if you have a specific name as the target, this makes it quite possible to guess the right transaction id (32k guesses on average) before the real answer arrives.
Therefore, all modern resolver servers will go out of their way to randomize a source port to increase the number of random bits that need to be guessed.
You really wants as large a span of ports as is possible so presumably it will randomize in the whole range of ports >1024, which will add a significant number of bits of randomness compared to what your OS's default handling would give you.
Ie, I think it's simply considered "best practice" to ignore the normal OS handling of local ports for sockets.