How can I add private nameservers to my Hestia Control Panel setup on Google Cloud?

I currently have Hestia Control Panel up and running on a Google Compute Engine VM using Cloud Flare (free plan) with my domain registered at NameCheap. I have about a dozen clients on a reseller plan elsewhere that I want to migrate to this VM, but I would like to run my own nameservers on multiple IP addresses for better resiliency and branding.

I originally had everything running with one nameserver on one IP address before switching to cloudflare. Once I switched to CloudFlare, I was able to have two CloudFlare Nameservers. But Now I canā€™t seem to get any nameserver working correctly without using CloudFlare DNS.

Let me preface by saying that Iā€™m not super-well versed in the intricacies of setting up servers, firewalls, and DNS from scratch (though Iā€™m no stranger to the command-line).

Before anyone asks, I did wait an appropriate length of time (where applicable) at each step to allow for DNS propagation.

I first had trouble when trying to add a second IP Address within GCP to my VM instance. I did finally somewhat succeed when I followed this guide. Everything worked at each step along the way, but when testing at the end of the instructions I found that the server didnā€™t respond. I tried to correct the situation by setting up an additional Google firewall rule as I had for the initial Hestia CP installation. It didnā€™t help (though Iā€™m unsure if I did it correctly so that it would apply to the new IP address).

I then went back within NameCheapā€™s advanced DNS section for my domain and added both Google IP Addresses as ns1 and ns2. I then set them as the custom nameservers in the main domain section but when I tested them online with MXtoolbox or dnschecker they didnā€™t respond either.

I then tried to switch back to the original pre-Cloudflare single nameserver but that didnā€™t work.

It currently appears that Iā€™m stuck with CloudFlare so Iā€™m temporarily re-enabling CloudFlare to get everything live again, but scratching my head on how to proceed. Iā€™m considering starting over at the beginning.

Trying to use two IPs on the same VM to present the illusion of two nameservers sounds anything but robust. If that is not what you were attempting, I apologize for the misunderstanding. If it is, you may want to pull back a little and figure out what you hope to achieve, reflect on why you think it is a good idea, and evaluate whether the actions you are planning really accomplish your objectives.

If you want to use HestiaCP for production DNS, you may want to look into setting up a cluster on separate VPS, possibly even in separate regions, so that you have some actual redundancy.

Unless you are on a Business or Enterprise plan, use of Cloudflare will require the use of their nameservers. You can use a Partial (CNAME) setup on those top tier plans. You can also use custom (sometimes referred to as vanity) nameservers with those plans, which would help with your branding goal while still using Cloudflare nameservers.

Get a second VPS with almost 0 resources and use that as secondary name server

Otherwise it is a terrible idea

1 Like

Thatā€™s kind of what I was trying to figure out.

No, not trying to have the ā€œillusionā€ of two nameservers. I actually want multiple nameservers. As I mentioned above, Iā€™m not too well-versed in this stuff. I donā€™t want to use CloudFlare at all. My needs are pretty small, so I should be able to without any enterprise class systems at all, and with only a dozen clients, I should be able to get by on a very small system. The work I do is mostly for small non-profit organizations and churches.

@eris, I have two servers running now, the main control panel which will also act as ns1 and a second vps with almost 0 resources for the secondary nameserver ns2. After banging my head against this for a few days (cloudflare was a huge mistake) and reinstalling many times to correct for errors, I still donā€™t have working nameservers. I get the following error:

I followed these steps in the documentation to get to this point:

Master ā†’ Slave DNS cluster with the Hestia API

Preparing your Slave server(s):

  1. Whitelist your master server IP in Configure Server ā†’ Security ā†’ Allowed IP addresses for API
  2. Enable API access for admins (or all users).
  3. Create an API key under the admin user with at least the sync-dns-cluster permission.
  4. Create a new DNS sync user as follows:
  • Has email address (something generic)
  • Has the role dns-cluster
  • You may want to set ā€˜Do not allow user to log in to Control Panelā€™ if they are not a regular user
  1. Edit /usr/local/hestia/conf/hestia.conf, change DNS_CLUSTER_SYSTEM='hestia' to DNS_CLUSTER_SYSTEM='hestia-zone'.
  2. Edit /etc/bind/named.conf.options, do the following changes, then restart bind9 with systemctl restart bind9:
# Change this line
allow-recursion { 127.0.0.1; ::1; };
# To this
allow-recursion { 127.0.0.1; ::1; your.master.ip.address; };
# Add this line
allow-notify{ your.master.ip.address; };

Preparing your Master server:

  1. On the Master server, open /etc/bind/named.conf.options, do the following changes, then restart bind9 with systemctl restart bind9.
# Change this line
allow-transfer { "none"; };
# To this
allow-transfer { your.slave.ip.address; };
# Or this, if adding multiple slaves
allow-transfer { first.slave.ip.address; second.slave.ip.address; };
# Add this line, if adding multiple slaves
also-notify { second.slave.ip.address; };
  • Run the following command to enable each Slave DNS server, and wait a short while for it to complete zone transfers:
v-add-remote-dns-host <your slave host name> <port number> '<accesskey>:<secretkey>' '' 'api' '<your chosen slave user name>'

when I try to verify, it get the following:

root@ns2:~# v-list-dns-domains dns-cluster
DOMAIN IP TPL TTL DNSSEC REC SPND DATE


And if I try this on the secondary nameserver:

root@ns2:~# v-sync-dns-cluster
Error: DNS_CLUSTER is not enabled

But yet if I try to run v-add-remote-dns-host ā€˜:ā€™ ā€˜ā€™ ā€˜apiā€™ ā€˜ā€™ again on the master (with the appropriate edits of course) I get an error saying that itā€™s already there.

If I list domains on the master:

v-list-dns-domains myusername
DOMAIN       IP              TPL       TTL    DNSSEC  REC  SPND  DATE
------       --              ---       ---    ------  ---  ----  ----
zapaname.us  35.209.100.171  child-ns  14400  no      14   no    2024-10-01

But if I check it online with dnschecker, it never shows up.

Namecheap shows my two private nameservers (which I have created in the advanced section and applied to the custom nameservers under the domain name):

Host                IP Address
ns1.zapaname.us     35.209.100.171
ns2.zapaname.us     35.208.110.23
1 Like

Iā€™d suggest that you start by fixing your lame delegation and your invalid DNSSEC. Hopefully fixing that will clear up the failure to respond to UDP queries.

https://dnsviz.net/d/zapaname.us/dnssec/

Ok, so funny story here - in the 3rd paragraph of the OP I said:

And when I read:

I first thought I was being insulted - then I looked it up. I didnā€™t even know it was called ā€œlame delegation.ā€ :rofl:

I donā€™t know where to begin fixing this. I thought that setting up my private nameserver glue records at NameCheap under the advanced section and then pointing my domain to those same nameservers in the general settings for that domain at NameCheap would send everything over to the hestia servers I set up on those ip addresses using the guide in the hestia documentation (I havenā€™t even started turning on DNSSEC yet).

If I use NameCheapā€™s nameservers, everything works, I just have to manually enter everything over at NameCheap. However this is not what I want and is specifically one of the reasons why I want to use Hestia.

I did look at the link you provided, but the first tab that shows up is indecipherable for me at this point, however the servers tab is more informative showing the correct nameserver names and parent zone glue records but indicating that there is no child zone. It seems to me this would be something I have not set properly within my master Hestia CP, is that correct?

You should start creating a firewall rule to accept connections on port 53 (TCP and UDP) on both servers (35.209.100.171 and 35.208.110.23).

Thank you @sahsanu ! That got ns1 working on the main control panel (but ns2) and now the nameservers are at least visible. I would recommend putting port requirements in the documentation somewhere - at least in the setup guide (and Iā€™m willing to work on a pull request if my suggestion seems the right way to go).

Hereā€™s what I currently have in the firewall:

Protocols and ports
tcp:25, 53, 80, 110, 143, 443, 465, 587, 993, 995, 8083
udp:25, 53, 80, 110, 143, 443, 465, 587, 993, 995, 8083

Probably too much, but at least it started the master nameserver working.

But all is not well yet, the cluster/ns2 still isnā€™t working.

Does anyone have an idea whatā€™s wrong here? I reinstalled everything. I now have separate vps servers up, but ns2 still doesnā€™t appear to sync. When I check it here it says that the primary name server is not listed at parent and at least one name server failed to respond in a timely manner (my guess is that it didnā€™t respond at all). Oh, and if i create a new DNS domain such as tmp.zapaname.us, the SOA shows up as ns1.zapaname.us, so I know I must have done something wrong, but I canā€™t figure out what (it did that with my main domain as well, but I just edited ns1 out of the SOA to get it to work for now). Why would the SOA be ns1.zapaname.us instead of just zapaname.us? Iā€™d really like to get this up and running. My clients are all small nonprofits and its costing me about $90/mo out of my own pocket to keep their hosting running for them (which I canā€™t afford to keep doing).

Iā€™ve never used Hestia to host my DNS so I donā€™t know the reason secondary name server is not synchronizing but regarding this:

It is related to the SOA record, your current SOA record shows the MNAME as zapaname.us.:

$ dig zapaname.us SOA +short
zapaname.us. root.zapaname.us. 2024101807 7200 3600 1209600 180

and that is not correct, the MNAME (Master Name or Primary Name) must be the primary name server for that zone so in your case it must be ns1.zapaname.us.

Ok, I fixed that. When I changed the SOA back it fixed the issue regarding the ā€œprimary name serverā€ not listed at parent. I misunderstood what was supposed to be in the SOA record.

Now I just have to see why my slave DNS is not working at all. This is what I get when checking both nameservers:

$ nslookup zapaname.us ns1.zapaname.us
Server:		ns1.zapaname.us
Address:	35.209.100.171#53

Name:	zapaname.us
Address: 35.209.100.171
$ nslookup zapaname.us ns2.zapaname.us
Server:		ns2.zapaname.us
Address:	35.208.110.23#53

** server can't find zapaname.us: REFUSED

At this point I tried the following on ns2 as root:

root@ns2:~# v-sync-dns-cluster
Error: DNS_CLUSTER is not enabled

Then I tried it on ns1 (itā€™s named cp since itā€™s the main control panel):

root@cp:~# v-sync-dns-cluster
v-sync-dns-cluster no_email
Error: api connection to ns2.zapaname.us failed.

Remote dns host has been suspended.After resolving issue run following commands:

v-unsuspend-remote-dns-host ns2.zapaname.us
v-sync-dns-cluster ns2.zapaname.us


--
Hestia Control Panel
cp.zapaname.us

Also, in the ns2 control panel config section under DNS Server it says:

DNS Server: bind9
DNS Cluster: No

While the main CP says:

DNS Server: bind9
DNS Cluster: Yes
Host #1
ns2.zapaname.us

And I did ā€œEdit /usr/local/hestia/conf/hestia.conf, change DNS_CLUSTER_SYSTEM='hestia' to DNS_CLUSTER_SYSTEM='hestia-zone'ā€ on the slave nameserver following the setup guide.

on both servers, I changed /usr/local/hestia/conf/hestia.conf to

DNS_CLUSTER_SYSTEM='hestia-zone'

and then on the master I deleted the slave with

v-delete-remote-dns-host

and then added it back with

v-add-remote-dns-host

The zones are syncing between master and slave now, but the slave (ns2.zapaname.com at 35.208.110.23) still isnā€™t responding to queries and various DNS tools:

dig zapaname.us @ns2.zapaname.us

; <<>> DiG 9.18.28-0ubuntu0.22.04.1-Ubuntu <<>> zapaname.us @ns2.zapaname.us
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 56203
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: acfcb362bb034e76010000006712e84e439172bcbb9e2a5e (good)
;; QUESTION SECTION:
;zapaname.us.                   IN      A

;; Query time: 8 msec
;; SERVER: 35.208.110.23#53(ns2.zapaname.us) (UDP)
;; WHEN: Fri Oct 18 22:59:26 UTC 2024
;; MSG SIZE  rcvd: 68

On ns2 server check the bind service:

systemctl restart bind9
systemctl status bind9 --no-pager -l
grep -F 'named[' /var/log/syslog | tail -n 20

Thank you for all your help:

It does fine until:

Oct 19 04:37:23 ns2.zapaname.us named[288984]: managed-keys-zone: Key 20326 for zone . is now trusted (acceptance timer complete)
Oct 19 04:37:23 ns2.zapaname.us named[288984]: resolver priming query complete: success
Oct 19 04:37:23 ns2.zapaname.us named[288984]: zone zapaname.us/IN: refresh: unexpected rcode (SERVFAIL) from primary 35.208.110.23#53 (source 0.0.0.0#0)

Full output:

root@ns2:~# systemctl restart bind9
root@ns2:~# systemctl status bind9 --no-pager -l
ā— named.service - BIND Domain Name Server
     Loaded: loaded (/lib/systemd/system/named.service; enabled; vendor preset: enabled)
     Active: active (running) since Sat 2024-10-19 04:52:37 UTC; 12s ago
       Docs: man:named(8)
    Process: 289909 ExecStart=/usr/sbin/named $OPTIONS (code=exited, status=0/SUCCESS)
   Main PID: 289912 (named)
      Tasks: 6 (limit: 1141)
     Memory: 5.7M
        CPU: 55ms
     CGroup: /system.slice/named.service
             ā””ā”€289912 /usr/sbin/named -u bind

Oct 19 04:52:37 ns2.zapaname.us named[289912]: network unreachable resolving './NS/IN': 2001:500:12::d0d#53
Oct 19 04:52:37 ns2.zapaname.us named[289912]: network unreachable resolving './DNSKEY/IN': 2001:500:9f::42#53
Oct 19 04:52:37 ns2.zapaname.us named[289912]: network unreachable resolving './NS/IN': 2001:500:9f::42#53
Oct 19 04:52:37 ns2.zapaname.us named[289912]: network unreachable resolving './DNSKEY/IN': 2001:500:2f::f#53
Oct 19 04:52:37 ns2.zapaname.us named[289912]: network unreachable resolving './DNSKEY/IN': 2001:500:2d::d#53
Oct 19 04:52:37 ns2.zapaname.us named[289912]: network unreachable resolving './DNSKEY/IN': 2001:500:12::d0d#53
Oct 19 04:52:37 ns2.zapaname.us named[289912]: managed-keys-zone: Key 20326 for zone . is now trusted (acceptance timer complete)
Oct 19 04:52:37 ns2.zapaname.us named[289912]: resolver priming query complete: success
Oct 19 04:52:37 ns2.zapaname.us named[289912]: zone prairiejewels.com/IN: refresh: unexpected rcode (SERVFAIL) from primary 35.208.110.23#53 (source 0.0.0.0#0)
Oct 19 04:52:37 ns2.zapaname.us named[289912]: zone zapaname.us/IN: refresh: unexpected rcode (SERVFAIL) from primary 35.208.110.23#53 (source 0.0.0.0#0)
root@ns2:~# 


root@ns2:~# grep -F 'named[' /var/log/syslog | tail -n 20
Oct 19 04:52:37 ns2 named[289912]: network unreachable resolving './NS/IN': 2001:500:2::c#53
Oct 19 04:52:37 ns2 named[289912]: network unreachable resolving './DNSKEY/IN': 2001:500:1::53#53
Oct 19 04:52:37 ns2 named[289912]: network unreachable resolving './NS/IN': 2001:500:1::53#53
Oct 19 04:52:37 ns2 named[289912]: network unreachable resolving './DNSKEY/IN': 2001:503:ba3e::2:30#53
Oct 19 04:52:37 ns2 named[289912]: network unreachable resolving './NS/IN': 2001:503:ba3e::2:30#53
Oct 19 04:52:37 ns2 named[289912]: network unreachable resolving './DNSKEY/IN': 2001:7fd::1#53
Oct 19 04:52:37 ns2 named[289912]: network unreachable resolving './NS/IN': 2001:7fd::1#53
Oct 19 04:52:37 ns2 named[289912]: network unreachable resolving './DNSKEY/IN': 2001:500:12::d0d#53
Oct 19 04:52:37 ns2 named[289912]: network unreachable resolving './NS/IN': 2001:500:12::d0d#53
Oct 19 04:52:37 ns2 named[289912]: network unreachable resolving './DNSKEY/IN': 2001:500:9f::42#53
Oct 19 04:52:37 ns2 named[289912]: network unreachable resolving './NS/IN': 2001:500:9f::42#53
Oct 19 04:52:37 ns2 named[289912]: network unreachable resolving './DNSKEY/IN': 2001:500:2f::f#53
Oct 19 04:52:37 ns2 named[289912]: network unreachable resolving './DNSKEY/IN': 2001:500:2d::d#53
Oct 19 04:52:37 ns2 named[289912]: network unreachable resolving './DNSKEY/IN': 2001:500:12::d0d#53
Oct 19 04:52:37 ns2 named[289912]: managed-keys-zone: Key 20326 for zone . is now trusted (acceptance timer complete)
Oct 19 04:52:37 ns2 named[289912]: resolver priming query complete: success
Oct 19 04:52:37 ns2 named[289912]: zone prairiejewels.com/IN: refresh: unexpected rcode (SERVFAIL) from primary 35.208.110.23#53 (source 0.0.0.0#0)
Oct 19 04:52:37 ns2 named[289912]: zone zapaname.us/IN: refresh: unexpected rcode (SERVFAIL) from primary 35.208.110.23#53 (source 0.0.0.0#0)
Oct 19 04:53:23 ns2 named[289912]: zone zapaname.us/IN: refresh: unexpected rcode (SERVFAIL) from primary 35.208.110.23#53 (source 0.0.0.0#0)
Oct 19 04:53:32 ns2 named[289912]: zone prairiejewels.com/IN: refresh: unexpected rcode (SERVFAIL) from primary 35.208.110.23#53 (source 0.0.0.0#0)
root@ns2:~# 

The ns2 server is trying to get the zone from the primary server 35.208.110.23 but that ip belongs to ns2, the ip for ns1 is 35.209.100.171

On ns2, double check that you are using the right ip for the primary name server /etc/bind/named.conf.options

It should look like:

allow-recursion { 127.0.0.1; ::1; 35.209.100.171; };
allow-notify{ 35.209.100.171; };
1 Like

Yes, thatā€™s exactly what it has

allow-recursion { 127.0.0.1; ::1; 35.209.100.171; };
allow-notify{ 35.209.100.171; };

On ns2 server, show the block for zone zapaname.us on file /etc/bind/named.conf and also show the same data on ns1 server.

ns1 server:

zone "zapaname.us" in {type master; dnssec-policy default; inline-signing yes; file "/home/Zappy29681/conf/dns/zapaname.us.db";};

ns2 server:

zone "zapaname.us" in {type slave; masters { 35.208.110.23; }; file "/home/dns-cluster/conf/dns/zapaname.us.db";};