TechnitiumSoftware / DnsServer

Technitium DNS Server
https://technitium.com/dns/
GNU General Public License v3.0
3.84k stars 400 forks source link

Server loses IPv6 binding after restart #957

Open kuu-17 opened 5 days ago

kuu-17 commented 5 days ago

Expected Behavior:

On reboot, the DNS server should keep IP bindings listed in "Settings > General > DNS Server Local End Points"

Current Behavior:

Before restarting, the server works as expected. When the container is restarted and the DNS server comes online again, the server does not respond to DNS requests over IPv6 as it does before the restart. At this point, "ss -tulpn" shows bindings for 127.0.0.1:53, ::1:53, and 192.168.X.96:53, but not its IPv6 GUA.

To fix this issue, I had to remove the GUA binding from "Settings > General > DNS Server Local End Points", save, then add the GUA binding and save again. Then the DNS server will respond over IPv6 as normal and "ss -tulpn" shows all expected bindings.

Issue is reproducible in my environment by restarting the LXC container the DNS server is running on.

Environment:

DNS server running on LXC in Proxmox. LXC is running Rocky Linux 9.4 (Blue Onyx). Not using Docker.

"Settings > General > DNS Server Local End Points": 127.0.0.1:53

192.168.X.96:53

kuu-17 commented 5 days ago

Almost forgot, DNS Server is v12.2.1

ShreyasZare commented 4 days ago

Thanks for the post. Usually the reason for this is that the IP address was not available to bind when the DNS server was starting. So, I would suggest that you take a look at the DNS Logs from the admin panel and see if there are any errors listed related to this issue. The error message will tell exactly why the DNS server did not bind to the IPv6 address.

Post the complete error log here if you need help with understanding it.

kuu-17 commented 4 days ago
[2024-06-27 10:46:49 UTC] [[2001:XXXX:XXXX:XXXX::53:1]:53] [UDP] DNS Server failed to bind.

System.Net.Sockets.SocketException (99): Cannot assign requested address
   at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
   at System.Net.Sockets.Socket.Bind(EndPoint localEP)
   at DnsServerCore.Dns.DnsServer.StartAsync() in Z:\Technitium\Projects\DnsServer\DnsServerCore\Dns\DnsServer.cs:line 4347
[2024-06-27 10:46:49 UTC] [[2001:XXXX:XXXX:XXXX::53:1]:53] [TCP] DNS Server failed to bind.

System.Net.Sockets.SocketException (99): Cannot assign requested address
   at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
   at System.Net.Sockets.Socket.Bind(EndPoint localEP)
   at DnsServerCore.Dns.DnsServer.StartAsync() in Z:\Technitium\Projects\DnsServer\DnsServerCore\Dns\DnsServer.cs:line 4405
[2024-06-27 10:46:49 UTC] DNS Server (v12.2.1.0) was started successfully.

These are the only related errors I see in my logs

ShreyasZare commented 4 days ago

Thanks for the details. It just means that the IPv6 address is not available when the DNS server starts. Instead of specific IPv6 address, you can use the [::] any address so that the binding works but that depends on how your container network is setup. Another option is to somehow delay starting the DNS server when the container starts by adding sleep statement in systemd like below:

[Service]
ExecStartPre=/bin/sleep 10

This will ensure that the DNS server starts 10 sec later until then the IPv6 address should be available on the network adapter.

kuu-17 commented 4 days ago

That worked! A 1 second delay was enough to let the IPv6 address bind properly. I'd suspect less would work, too.

The IP address might not be available as soon as the DNS server is ready to start because of IPv6 functions like waiting for DAD, but I'm not entirely sure. It might be a good idea to have the DNS server retry IP bindings after a short delay if any initially fail, as there is no fault with the address itself.

Thank you for helping with this!

ShreyasZare commented 3 days ago

Good to know it worked. Will add a retry with delay in the DNS server.