I need to remotely maintain DNS entries at my InterServer webhosting instance, and I want to use the
cPanel API v2 for that, because that’s basically all InterServer, the DNS and hosting service I currently use, is providing access to.
Link: cPanel documentation
Current situation and difficulties
My main goal was to find a way of implementing this with
certbot to enable automatic wildcard certificate renewals with Let’s Encrypt in a reverse proxy container. The reason for this (likely overly complex) setup is that I have a Synology DiskStation behind my home router, that serves some applications available publicly (e.g. a photo gallery). This device isn’t the only device that’s hosting externally accessible resources, but until now that wasn’t much of an issue: DSM, the OS that’s running Synology devices, comes with a reverse proxy package, that can serve other applications too, additionally to those installed directly on the DiskStation.
Recently I’ve switched to automated installations of my
RaspberryPis and other stuff, including applications hosted in containers on these
RaspberryPis and the DiskStation. So now the main problem is, that in order to get external services and more complex setups covered by the Synology reverse proxy, it’s configuration needs customization that needs to be carefully built, maintained and backed up, because it’s unsupported and gets overwritten with any update of the DSM. The whole process is hacky and highly annoying and unreliable.
First steps toward a solution
The very first thing to do was setting up a
Docker container that takes over the role of the reverse proxy. I’ve used a
linuxserver/swag container for that, because it comes with
certbot already. Docker is available through a package, and besides some more configuration hacking inside the DiskStation (that’s still way easier to replicate, if needed, and doesn’t need maintenance) it is a breeze to set up with the help of
docker-compose. I’ll describe that setup in another post later…
Nginx as reverse proxy
When this container is up and running it needs to be configured to serve as reverse proxy for all desired applications. The setup of
nginx is relatively easy to do for people not that much into such technical details, and also is pretty well documented. I may also write about my setup later, if I think it is special enough to be of value for anyone else but me.
Certbot for certificate auto-renewal
The next component in this setup is
certbot which is responsible for the automatic requests and renewals of SSL certificates. The easiest way for me to do this so far was letting the DSM do this. BUT: this implementation doesn’t support wildcard certificates, and that meant I needed a different solution now. I no longer wanted to go through the hassle of maintaining a dozen different certificates or have multiple unrelated server names hosted by one certificate. So for me the obvious solution for a centralized home-network reverse proxy is a wildcard certificate.
In a company’s network, or in bigger installations I probably wouldn’t use one wildcard certificate for everything, but - it’s my stuff, and I want one, so I’ll get one!…
The last piece of this puzzle is access to DNS, because the automated implementations of Let’s Encrypt auto-renewal of wildcard certificates works only with
TXT records in
DNS. Bots like
certbot come with a host of plugins for several
DNS providers - but InterServer is not amongst them. Fortunately they provide access to the
cPanel API, so this makes things a lot easier…right?
Well, not exactly.
Extra hurdles put up by shared webhosting
The price of a webhosting package can be higher than what’s on the regular invoice. In the case of InterServer it is the lack of access to
cPanel functionality in their shared Webhosting. Specifically the missing password to my own account. The way the InterServer webhosting is logging me into
cPanel is by creating a child session in
cPanel from out of my current session in the parent portal. I’ll then get forwarded to said child session and can administer my package from there. Except: I can not change my password, and I can not create additional
cPanel users (only FTP, Email etc.).
Use an API key instead
Luckily the system does allow for creating an API key, and after studying the
cPanel documentation I also found out how to use it.
So here are some example calls that one can use to either play around with it, put them into scripts for recurring tasks, or wrap a
PowerShell script around it for more complex usage.
BTW, the reason for using the outdated version 2 of the API is that there are no equivalent commands available in
Manual API calls
I’ve came up with the following calls against the API to test the communication with the API, as well as the creation and removal of
CNAME) records, which is necessary to get wildcard certificates issued by Let’s Encrypt.
Simple domain lookup
This is an easy way to verify general functionality, authentication, access permission etc.
curl -H'Authorization: cpanel USER:API_KEY' 'https://my_domain.com:2083/execute/DNS/lookup?domain=my_domain.com'
Get entire zone file
This dumps the entire zone file as is.
curl -H'Authorization: cpanel USER:API_KEY' 'https://my_domain.com:2083/json-api/cpanel?cpanel_jsonapi_user=user&cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=fetchzone&domain=my_domain.com'
Add CNAME record
The record name in this example is
curl -H'Authorization: cpanel USER:API_KEY' 'https://my_domain.com:2083/json-api/cpanel?cpanel_jsonapi_user=user&cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=add_zone_record&domain=my_domain.com&name=cname-test&type=CNAME&cname=www.other_domain.com'
Add TXT record
The record name in this example is
curl -H'Authorization: cpanel USER:API_KEY' 'https://my_domain.com:2083/json-api/cpanel?cpanel_jsonapi_user=user&cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=add_zone_record&domain=my_domain.com&name=le-test&type=TXT&txtdata=1234567890ABCDEF'
Get line number for specific name in zone file
In order to remove an entry we need to know first where that entry is located in the file.
Note: the name in the zone file is an FQDN including a trailing dot! So here the name to look up is
curl -H'Authorization: cpanel USER:API_KEY' 'https://my_domain.com:2083/json-api/cpanel?cpanel_jsonapi_user=user&cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=fetchzone_records&domain=my_domain.com&name=le-test.my_domain.com.&type=TXT'
Remove TXT record
When we know the number, the respective entry can be removed from the zone file.
curl -H'Authorization: cpanel USER:API_KEY' 'https://my_domain.com:2083/json-api/cpanel?cpanel_jsonapi_user=user&cpanel_jsonapi_apiversion=2&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=remove_zone_record&domain=my_domain.com&line=59'