Use SFTdyn to host your own dynamic dns server. The github page describes the whole setup process so there's no point in going over it again.
This article will show you how you can create a free letsencrypt certificate for these dynamic domains without running a http server on them. ( in case you want to use them for something like a smtp service or a http server that's not supported by the certbot plugins ).
When setting up SFTdyn you configured bind to accept local updates. We'll use the same key for the certbot dns plugin so it can do dns challenges for creating and renewing certificates.
The certbot dns plugin needs a configuration file ( ~/.secrets/certbot/rfc2136.ini ) that looks like this:
# Target DNS server ( always use an ip address here )
dns_rfc2136_server = 18.104.22.168
# Target DNS port
dns_rfc2136_port = 53
# TSIG key name ( this has to be set to local-ddns )
dns_rfc2136_name = local-ddns
# TSIG key secret ( get this from the ddns server's /var/run/bind/session.key )
dns_rfc2136_secret = splfUqpteoHQ43DDzGKvMS6L3oCjzv20WpKfhxhgWo0=
# TSIG key algorithm
dns_rfc2136_algorithm = HMAC-SHA256
The secret will probably change when you restart bind, so make sure to update the rfc2136.ini file after you do it. Or you can add the contents of the /var/run/bind/session.key file to the named.conf.local file and then change the key's name to something like "remote-key" and then also change the ~/.secrets/certbot/rfc2136.ini file to reflect the name of the new key so you don't have to bother to copy the key every time you restart bind.
When all this is set up just run :
certbot certonly --dns-rfc2136 --dns-rfc2136-credentials ~/.secrets/certbot/rfc2136.ini -d <my-domain-name>
Virtualmin has this nice feature where you can enable dynamic host and virtualhost updates so when your ip changes virtualmin updates the ips in the virtualhosts definitions. Without this feature your sites would not work anymore if your ip changes and you would have to update the ips manually.
The problem with this feature is that it only supports the DynDNS service and not everyone is using this service to update their host when their ip changes.
I'm using my own dynamic dns service and the good news is that this service is using the same protocol as DynDNS so virtualmin needs little change in order to support it.
All I had to do was add a way of specifying the hostname and port of the dynip update server.
Here's the patch for virtualmin ( tested with 3.75 and 3.76 ) :
Q: Why would you want to run your own dynamic DNS service?
A: Because you have your own domains that you want to use as the parent domains for your hosts and you already have all required ingredients ( a linux server with a static ip that's always up and runs bind and apache with php )
Q: How do you run your own dynamic DNS service?
A: get DDNS Server, read the README file and set it up. The nice thing about this script is that it uses the same protocol as the popular DynDNS service so any dynamic ip update client like ddclient would work with this script. Of course the client would have to allow you to specify the hostname or ip and port of the dynamic dns server.
Oh and one more thing, if you're running bind you're probably running it in a chroot environment so you'll have to apply the following patch to DDNS Server ( current version 1.0.0 ) to make it work with the chrooted bind :
This patch adds a new configuration option named BIND_CHROOT ( in config.php ) that has to be set to the path of the chroot environment where bind runs. Eg. on centos 5.3 this is /var/named/run-root .
For any questions or suggestions hit the comments.