Experiments with External DNS

Hi all,

Configuring email service to work safely, effectively and reliably involves tight control over a myriad of non-intuitive DNS entries. Having run email services on other platforms I can safely what I most appreciate about MiaB is that it generates and checks that myriad of DNS entries. To effect those DNS entries the MiaB code is tightly integrated with the domain name service NSD4 which it sets up and expects to see running as authorative for the box.yourdomain.tld as well as all the domains the box runs email for. With so many DNS service providers to cater for, that strategy is by far the simplest to implement, so I fully understand why it was chosen.

That being said, MiaB does make provision for using an external DNS supplier. It works just fine but has two consequences:

  1. It makes some of the system checks non-deterministic - i.e. saying “this isn’t as it’s supposed to be, but it might be OK if you using external DNS”.

  2. It places a high burden on the user who has to export zone fies every time a change is made, compare that with what has been presented to the external DNS provider and apply the changes manually.

I’ve been running in that mode for a nuber of months. I even wrote a few python scripts to do manipulate the downloaded zone file or the generated .txt file for it with the changes I require for my external DNS provider.

Over this past few days I was forced by external circumstances to move my MiaB servers from ESXi to Proxmox. For my external DNS requirements I’ve been running two additional virtual machines purely as BIND9 based domain name servers backing each other up as blind masters feeding my external DNS provider which by public records (registrar) are authorative for my domains. Moving my MiaB servers also meant moving those servers.

After the first round of moving the machines was done (once I learned how and when to restore the backup) there was so much time left in the maintenance window I negotiated with my users that I felt it might be a good time to try something different. Seeing that I’ve never experienced MiaB in its intended mode where it sets up the box as a serving authoritative DNS server exposed to the public, I dedided to give that a go and see how it goes.

Naturally it was an easier setup to do as it didn’t involve external DNS servers or my BIND9 based VMs, so I was rather pleased with it from that perspective. I declared my DNS provider as secondary in the prescribed manner and was in the process of confirming that the DNS changes I made was getting through fast and reliably.

That’s when disaster struck. I subscribe to a package at my DNS provider which allows me specific limits, none of which I’ve ever been in danger of exceeding. While on my summary page at my DNS provider, I noticed that my number of records now exced my allowed limit and to my horror it was still rising.

I jumped on their support channel and we found the problem. Though I haven’t and never intend to activate DNSSEC, the DNS records being sent from MiaB’s NSD service were all signed records anyway and the DNS provider counts each of the signatures (RRSIG) as its own record. Like I said, I’ve looked into DNSSEC before, weighed the pros and cons and ultimately decided I better steer clear of it. (If you must know why, they short version is that DNSSEC can and often does fail because of expired or unavailable keys that should be reotated regularly for it to be of any real value. The counter for the failures is active monitoring. Service providers will sell you monitoring and automatically rotating keys, but at a substantial cost. One could argue that email is already bound to DNS and therefore able to tolerate temporary failures, but when your web service is also impacted it’s a completely different scenario. DNSSEC failures puts egg on web sites’ faces.)

Faced with having to upgrade my DNS package (for purposes I don’t actually use) or find a way to get rid of the extra records, I had to make a choice. I quick look at the MiaB DNS code confirmed that it’s unlikely that I’d be able to get MiaB to recognise that I don’t want DNSSEC and stop producing signed records at all in the time available to me.

So I reverted back to having my two BIND9 based DNS servers up and running but didn’t want to let go of the benefit of automatic updates from the files MiaB generates. I then wrote a fews lines of bash script using the incron daemon and scp to detect changes to the /etc/nsd/zone directory, pick out the *.txt files only, transfer those to the bind based servers and kick off a zone reload on there.

The solution I came up with in a hurry (by the time I saw the unexpectedly high record count on the DNS provider’s site I only had a few hours left before my maintenance window closed) works like clockwork. Well enough to have spurred the idea of writing up a post about it that could get tagged into the guide category in due course.

But there’s issues my solution doesn’t resolve, which makes me hesitant and eager to explore other alternative first.

  1. The zone files generated still lists ns1.box.mydomain.tld and ns2.box.mydomain.tld as NS records. It includes the specified secondary name servers, but won’t let go of including those.
  2. The secondary name servers are getting notified of zone changes. this is correct behaviour for “true secondary” servers but defeats the purpose I’m chasing. Luckily my DNS provider lets me specify which servers to accept transfers from so by excluding the actual box.mydomain.tld IPs from that list (limiting it only to the two BIND9 based DNS servers’ IPs) I was able to dodge that bullet at the expense of errors in syslog as NSD reports that its attempted zone transfers were refused.
  3. I found out that as it stands, MiaB runs both NSD and BIND9 already. Knowing a fair bit about configuring both by now I feel it’s entirely possible to configure them so that a separate BIND9 based DNS server isn’t needed, which would make the solution a lot more accessible to others using external DNS.

My previous request for supporting blind DNS masters in MiaB was turned down, and in effect this is heading towards a second version of that. But the emphasis and target audience has moved slightly from specifically supporting BLIND masters to improved support for External DNS with selective out-of-band automated transfer of the zone file and definitive control over what NS records gets published. That way the status checks can drop the “if you are using external DNS this might be OK” uncertainty and perform the correct checks given the known external DNS configuration.

In technical terms what I suggest we look into is to include a dns/external.yaml file in the distribution similar to the dns/custom.yaml file with a get_external_dns_config function to read its contents into memory. Functions like check_primary_hostname_dns can then check if a domain is sepecified as external and if it is, adapt its checks to confirm that that it is correct instead of assuming it should onfirm that ns1.box.mydomain.tld resolves and is set as nameserver for the domain. The idea would be for the new external DNS config to name user supplied script file which transfers the required zone files from /etc/nsd/zones to wherever it needs to go and trigger the required reload.

As I wrote the above and read code to confirm names etc. github my eyes fell on the has_dnssec checks being done in check_primary_hostname_dns function and I wonder this: Why can do_dns_update in update_dns.py not do the same check and if dense is not used, skip all the signing and then let write_nsd_conf know to specify the serveddomain.tld.txt file for the zone rather than the serveddomain.tld.txt.signed file? It wouldn’t address ALL the issues but it seems the logical thing to do. On that note, I’m not convinced that checking if the DS record is set or not is the ideal test to see if DNSSEC is enabled or not becaue it’s self-referencing in a way. If makes the assumption that DNSSEC should be activated and reports that it isn’t, but there’s not a way to say that it should not be activated. I’d prefer a check-box for a domain stating if DNSSEC is being used or not. If it’s off but the DS record is ON it can be reported as a fault, and similarly if it’s OFF but thre is no DS record that can be reported as a fault (rather than the current warning) with instructions as to how to get the DS record set.

Anyway, I’m happy and even eager to do one and only one of three things. Either:

  1. develop a guide based on how I implemented automated updates of external DNS from MiaB’s generated zone files,
  2. help code a PR which introduces explicit external DNS settings, or
  3. refrain from stepping on any toes with my specific requirements and suggestions.

It all depends on your feedback, so let’s hear it.

Please sum up what is the issue? I cannot follow.

MiaB currently treats External DNS users as second class citizens and assumes DNSSEC will get enabled. I’ve put forward ways to improve how External DNS and DNSSEC is configured and checked.

In the end I am offering to help implement whatever works best for everyone affected or to let it go and keep my solutions to myself.

What are the benefits?

You can write in points:
Or others

  1. Feeding DNS records to External DNS solution is automated - less human error and effort.
  2. Status Check code would know whether External DNS is being used or not, and give more accurate feedback based on that.
  3. DNS Update and Status Check will know if DNSSEC is meant to be enabled or not.
  4. If DNSSEC is intentionally disabled the server’s work can be reduced (no more daily signing cron job) and the number of records stored in DNS cut by 75%.

Do you know how to code this?

I can. I wouldn’t have offered otherwise.

But I know better than to suppose I can write it a way @JoshData would feel it’s his own work or approve of it at all? MiaB has been and remains a single maintainer project. I’m only willing to do work on it with Josh’s blessing and support. I’m not here to step on toes.

Would I code it at all?
That entirely depends if the PR would be welcomed, and that would depend entirely on whether there are other users looking for this or not. My previous proposal was turned down in principle before I did any work on it, as per:

Bottom line?
I can and will live with my scripting based workaround for as long as I’m the only one needing it but if other want it too I’m happy to do it better at the code level itself.

Like I said before - the MiaB community should decide, not me.

1 Like

If you are using external DNS without DNSSEC, you can simply ignore the messages about name servers and DNSSEC, and Mail in a Box will work just fine.

By the way, this is probably why these messages are in a darker shade of green. If DNSSEC were mandatory, the message would probably be red, so there’s no reason to feel like a second-class citizen because of these messages. :wink:

Why don’t you make a pull request Pull requests · mail-in-a-box/mailinabox · GitHub

I see the quota supoort is there yet it is missing from the official version.

1 Like

Just going out and coding it for my own purposes only would be repeating the same mistake of implementing a feature without a valid set of use cases to test it against. I’ve been in this game far too long to get excited by the mere opportunity to write some code for the fun of it.

It’s less about the time and money, a little more about focus and energy and a whole lot about life being too short to spend any of it on something nobody will use.

I’ve going to make another short post referring to these two, in which I will simply ask that anybody that currently uses or wish to use the External DNS option announce themselves so we can start a conversation about how that should work.

Well I might be the first to comment on that post then.

I use external DNS and do not use MIAB DNS. I choose to use CloudFlare DNS, which has a rather nice import feature. I’m not sure if I ever figured out DNSSEC but this isn’t exactly something that is required for the solution to work. Would I like to enable that, maybe. I also don’t run IPv6, not because I dont want to or dont understand it but because FirstLight Fiber (ISP) does not support it if you request a IPv4 Static IP.

Exporting the file from MIAB now doesnt give direct import into CloudFlare, but it gets me close modify a few things my hand before the import.

CloudFlare domains are basically – pass on the cost of the domain to the end user, so I feel they are a good place to get a domain name from and would be my recommendation to anyone that asked. I think this project recommends Gandi for Domains.

I don’t mind the DNSMSG because I looked the issue deep in the eye and made a conscious decision to avoid using it but I’m empathetic to those who don’t have the benefit of such certainty. That said, the question isn’t about whether Mail in a Box would work just fine or not, but about the concequences of the assumption being made that DNSSEC will ultimately get turned on so it might as well go ahead with signing the DNS records, and provide fresh signatures every day regardless of the implications that has for External DNS users.

Haha, yeah. It’s not the messages that brought me to that conclusion, but rather the sentiment throughout MiaB that if you’re using External DNS you’re biting the hand that feeds you so don’t expect any sympathy, you’re on your own. But the point is moot as you say, now that Josh has chimed in the way he did.

That’s just it, isn’t it? There are 10 kinds of people in the world, those who read binary and those who don’t. :rofl: If you’ve grown up being better at expressing yourself in programming languages than English like me it’s the most natural thing in the world to take that “modify a few things” bit and do it automatically in whatever programming tool gets the job done the easiest whether it’s sed or awk or even python. I need my mind, fingers and time for other things, so I’d rather spend a little more time on the solution when I have it all within frame to put a permanent automated solution in place which I can then just monitor and largely forget about until it fails than having to keep that entire domain of intricacies in active memory all year long. I’m responsible for a very complex software solution and simply can’t spare the mind space to keep all I need to remember about email’s DNS settings in mind as well.

The DNSSEC DS Record section of the Mail-in-a-Box Setup Guide states that “When [DNSSEC is] enabled, mail between Mail-in-a-Boxes will always be encrypted.” which I find curious. Other sources on the web makes it clear that DNSSEC does not result in data encryption but in authentication only, so that statement must be made on the strength of some MiaB specific code or setup whereby other MiaB servers are somehow identified and encryption of the mail stream is enabled. Even if there is such code and setup (probably DANE TLSA related) then the statement should probably more explicitly state that email sent between any two MiaB servers that have DNSSEC turned would be encrypted as well. But as far as I’ve understood from other sources DNSSEC does not trigger encryption of the email stream.

It’s besides the point for me though, since my reasons for rejecting DNSSEC has to do with reliability of DNS resolution for live web-site purposes. Reading that statement just triggered my curiosity about how such a connection get made.

Perhaps someone can point me to the area in the code that makes that happen?