I am running BIND9 to achieve this very thing.
You can set up different “views” in BIND. Different zonefiles are served to different clients based on the IP address.
I have an external view that allows AXFR transfers to my public slave DNS provider, and an internal view for clients accessible over my VPN. I use DNS-01 challenges to issue valid Let’s Encrypt certificates to both LAN-facing and public-facing services.
My DNS server is running on my VPN coordination server, but, if I was not doing that, I’d run it on my router.
I do not use dnsmasq, so I am not sure if it supports split-view DNS, but if it does not, you can try coredns as a lightweight alternative.
My HumbleBundle donations go to the EFF, which is my indirect way of supporting Let’s Encrypt. I used to support the Internet Archive before they went political (and, consequently, to shit).