Well, on linux I’d use systemd’s resolved which would listen on localhost:53 (it would also point resolv.conf there) and then set resolved’s uplink server to your custom port. I don’t have the exact config in mind but it seems to support custom uplink ports(“expects IPv4 or IPv6 address specifications of DNS servers […] optionally take a port number separated with “:”[…]”)
Edit: found this: https://en.opensuse.org/Network_Management_With_Systemd
You create a (self-signed) CA certificate, put its certificate as the client ca in your web server.
Then you can create certificates using this CA that you distribute to your devices, only devices that have a certificate signed by your CA are allowed to connect.