dnscontrol icon indicating copy to clipboard operation
dnscontrol copied to clipboard

Ignore A record only for dynamic DNS while updating others

Open timkgh opened this issue 3 years ago • 4 comments

A sub-domain foo.example.com has an A record (IPv4 address) set by a dynamic DNS client, static IPv6 (AAAA) managed by dnscontrol and TXT/SPF record also managed by dnscontrol.

Is there a way to tell dnscontrol to not touch the A record but update only the AAAA and TXT records? IGNORE_NAME and IGNORE_TARGET do not seem to do the trick.

timkgh avatar Sep 23 '22 05:09 timkgh

It seems what's needed here is for IGNORE_TARGET to also support A type records (or any record type), not just CNAME. Are there technical reasons why the current implementation is limited to CNAME? IGNORE_TARGET("foo.example.com", "A")

timkgh avatar Sep 23 '22 18:09 timkgh

It only supports CNAMEs due to an overabundance of caution. The IGNORE*() code is a bit flakey so we started with just the one RTYPE needed at the time.

I'd gladly accept a PR that expands it to "A" records or all records. (Edit: I listed the wrong rtype originally)

As a temporary work-around, you could use a CNAME that points to a static AAAA record.

Tom

tlimoncelli avatar Sep 23 '22 18:09 tlimoncelli

I'd like the A record to be ignored, that's the one managed by a dynamic DNS client. AAAA, TXT should all be managed by dnscontrol.

timkgh avatar Sep 23 '22 18:09 timkgh

I stand corrected. I was thinking in reverse :)

tlimoncelli avatar Sep 23 '22 19:09 tlimoncelli

@tlimoncelli 🙏 any chance we could prioritize improving this situation? it's important for those of us dealing with dynamic IP addresses. 🙏

timkgh avatar Nov 02 '22 16:11 timkgh

Hi @timkgh . Sadly I won't have time to work on that kind of feature. My time is booked up with other projects for many months. This is a community-driven project. By that I mean that new features come from the community. I'd be glad to coach a volunteer.

I had another idea for a workaround: Have DNSControl ignore all records at that label. Use the native system for maintaining the A, TXT, and other records at that FQDN.

HTH, Tom

tlimoncelli avatar Nov 02 '22 19:11 tlimoncelli

By native I assume just set the records straight up in the Cloudflare UI or whatever the DNS provider is?

Yet another idea is to wrap dnscontrol in a script that first fetches the current value for the A record and puts it in the dnsconfig.js file before it calls dnscontrol to apply the changes, in effect making it a nop. There's a slight chance of a race though.

timkgh avatar Nov 02 '22 21:11 timkgh

By native I assume just set the records straight up in the Cloudflare UI or whatever the DNS provider is?

Yes, exactly.

tlimoncelli avatar Nov 02 '22 21:11 tlimoncelli

I was thinking about this more. What you need is a change to IGNORE_NAME(), not IGNORE_TARGET().

This will get an error because we are ignoring "foo" and updating "foo":

D("example.com", REG,
     IGNORE_NAME("foo"),
     AAAA("foo", "2607:f8b0:4006:80b::200e"),
     TXT("foo", "my text"),
)

The error will look something like:

    integration_test.go:213: runTests: incdiff error: trying to update/add IGNORE_NAMEd record: foo TXT

Either that shouldn't be an error (which could be unsafe) or IGNORE_NAME() should accept an optional parameter that lets you specify which record types should be ignored. Something like IGNORE_NAME("foo", "AAAA,TXT")

Tom

tlimoncelli avatar Nov 04 '22 20:11 tlimoncelli

Note to self: The current diff mechanism is made more complex by the IGNORE*() functions. We could simplify this with a different algorithm:

  1. There is a point where we have the "existing" and "desired" records. Existing is what records were downloaded via the API. Desired is what records were specified in the dnsconfig.js file.
  2. Query "existing" list for records that match all the IGNORE_NAME() and `IGNORE_TARGET() patterns. Any matches should be added to desired list.
  3. If "NO_PURGE" is set, add to "found" any records from "existing" that don't already exist. (This can be tricky: What do you do if the only difference is the TTL? I'd say... don't include the TTL in the comparison.)
  4. Now the diff algorithm can be greatly simplified. We don't have to deal with all the exceptions and edge-cases we were doing before.

The problem with this algorithm is that there is a race condition for the (few) providers that required changes on a label to include all the records on that label. For example, if you have three "A" records on "foo.example.com" and want to delete one of them, you do that with an API call such as "update foo.example.com with the 2 remaining A records". In that case, there is a chance that we might undo a change if it happens at the exact same time. I wouldn't worry about such changes as they are rare, but ... if you do something a million times, rare things happen.

tlimoncelli avatar Nov 04 '22 20:11 tlimoncelli

Would the fix for IGNORE_TARGET be as easy as relaxing this check to allow A records?

Yes. (and updating the integration tests)

tlimoncelli avatar Nov 05 '22 11:11 tlimoncelli

I was thinking about this more. What you need is a change to IGNORE_NAME(), not IGNORE_TARGET().

Ah I see. I finally realized IGNORE_TARGET is not what I want, I misunderstood what it did, it would have to match by the existing record IP address. It's IGNORE_NAME as you correctly pointed out.

timkgh avatar Nov 05 '22 22:11 timkgh

@tlimoncelli Volunteering PR #1808, for dynamic DNS A record support.

bits01 avatar Nov 06 '22 02:11 bits01

Awesome work @bits01 😍

@tlimoncelli how often do you release new versions?

timkgh avatar Nov 07 '22 16:11 timkgh

Releases aren't on a specific schedule. Would you be willing to build from master to test it out before I publish the release?

tlimoncelli avatar Nov 07 '22 17:11 tlimoncelli

Releases aren't on a specific schedule. Would you be willing to build from master to test it out before I publish the release?

Just tried it on macOS and Cloudflare and it does exactly what I need 👍

timkgh avatar Nov 07 '22 17:11 timkgh

great! I'll try to do an official release this week.

tlimoncelli avatar Nov 07 '22 17:11 tlimoncelli