POWERDNS: Allow editing the SOA record#3404
Conversation
|
Hey @jpbede! Can I get your approval plz? |
|
Hmm this could cause conflicts when PowerDNS manages (incrementing on its own when a API update happens) the SOA serial and have the |
|
I've committed @jpbede's suggestion, but I'll go through and test with the various options to get a verification on behavior. |
Awesome, thanks a lot! I currently have no way of doing this. |
|
Testing with the main 3 options: DEFAULT, INCREASE, EPOCH TLDR: I suspect that if the serial for INCREASE was set to 1 before the initial push, the serial would not have changed similar to DEFAULT. EPOCH I suspect by nature will always change. So with this, usage on a domain that is present already in the wild would possibly need two pushes to update the serial. One for the SOA and one for the serial. Definitely worth mentioning, but looks safe to use! DEFAULT: INCREASE EPOCH |
|
Also, I didn't want to continue testing the SOA-EDIT and SOA-EDIT-INCREASE as I suspected after the three above behavior would be the same. If there's any state that is wanted to test though I'll be happy to set it up locally. |
|
Would be great if you could update the documentation and add a phrase that using Then I'm more than happy with this @tlimoncelli |
|
I think it's incorrect in saying you cannot use |
|
Yes, could you add this to the docs? |
|
Do you think we can remove the extra commit on the SOA |
|
Ah yes, sure |
|
Ready for merge? |
|
@tlimoncelli Ready to merge from my side |
| The SOA record is supported for use, but behavior is slightly different than expected. | ||
| If the SOA record is used, [PowerDNS will not increase the serial](https://doc.powerdns.com/authoritative/dnsupdate.html#soa-serial-updates) if the SOA record content changes. | ||
| This itself comes with exceptions as well, if the `SOA-EDIT-API` is changed to a different value the logic will update the serial to a new value. | ||
| See [this issue for detailed testing](https://github.com/StackExchange/dnscontrol/pull/3404#issuecomment-2628989200) of behavior. |
There was a problem hiding this comment.
Sorry for the late reply, I’ve been really busy. What’s the reasoning behind not including these results in the documentation? I believe it could be helpful for someone less familiar with GitHub. Also, with a code refactor, these examples could be updated.
cc: @Veratil, @tlimoncelli.
There was a problem hiding this comment.
To me, the description of behavior is well enough defined without an overload of information for those that do not need it.
Co-authored-by: Tom Limoncelli <tlimoncelli@stackoverflow.com>
|
I think this change might have introduced a regression, if you do not manually specify SOA-records powerdns will remove your SOA-record and render your zone(s) invalid. This regardless of I.e., dual provider setups are /sometimes/ impossible, as not all providers allow you to specify SOA-records. I will try to update this thread with more information and debug logs later on. |
|
Illustration of my last post, e.g. "delete SOA if not explicit"-regression. The issue here is that the change is breaking. E.g. the text from patch-notes is quite miss-representing the scale of the change:
I think that the This would not work: D("test.org", REG_CHANGEME
, DnsProvider(DSP_PDNS) // <- powerdns, NEEDS SOA explicitly
, DnsProvider(DSP_DDNS) // <- DDNS, forbids SOA explictly
, DefaultTTL(3600)
, SOA("@", "ns.example.org.", "webmaster.example.org.", 3600, 600, 604800, 1440) // How to do here??
, NAMESERVER("ns.example.org.")
, TXT("@", "A STRING")
, A("@", "127.0.0.3")
)Tried with all of the possible Prior to proper zone-setup (e.g. zones exist in pdns but SOA is default): ## 192.168.1.90 port 5355 is running an otherwise empty latest version `pdns` nameserver.
> dig @192.168.1.90 -p 5355 soa test.com test.org +short
a.misconfigured.dns.server.invalid. hostmaster.test.com. 1769590229 10800 3600 604800 3600
a.misconfigured.dns.server.invalid. hostmaster.test.org. 1769590230 10800 3600 604800 3600
> dig @192.168.1.90 -p 5355 axfr test.com test.org +short
a.misconfigured.dns.server.invalid. hostmaster.test.com. 1769590933 10800 3600 604800 3600
a.misconfigured.dns.server.invalid. hostmaster.test.com. 1769590933 10800 3600 604800 3600
a.misconfigured.dns.server.invalid. hostmaster.test.org. 1769590933 10800 3600 604800 3600
a.misconfigured.dns.server.invalid. hostmaster.test.org. 1769590933 10800 3600 604800 3600
## v4.15 - prior to dnscontrol SOA-support for pdns, leaves SOAs untouched
> docker run --rm -it -v "$(pwd):/dns" ghcr.io/stackexchange/dnscontrol:4.15.0 preview --config testzones/testzones.js
CONCURRENTLY gathering 0 zone(s)
SERIALLY gathering 2 zone(s)
Serially Gathering: "test.com"
Serially Gathering: "test.org"
******************** Domain: test.com
INFO#1: No nameservers declared for domain "test.com"; skipping registrar. Add {no_ns:'true'} to force
******************** Domain: test.org
INFO#1: No nameservers declared for domain "test.org"; skipping registrar. Add {no_ns:'true'} to force
Done. 0 corrections.
## v4.16 - after dnscontrol SOA-support for pdns, result is to delete SOAs
> docker run --rm -it -v "$(pwd):/dns" ghcr.io/stackexchange/dnscontrol:4.16.0 preview --config testzones/testzones.js
CONCURRENTLY gathering 0 zone(s)
SERIALLY gathering 2 zone(s)
Serially Gathering: "test.com"
Serially Gathering: "test.org"
******************** Domain: test.com
1 correction (localpdns)
#1: - BATCHED DELETEs for test.com
- DELETE test.com SOA a.misconfigured.dns.server.invalid. hostmaster.test.com. 10800 3600 604800 3600 ttl=3600
INFO#1: No nameservers declared for domain "test.com"; skipping registrar. Add {no_ns:'true'} to force
******************** Domain: test.org
1 correction (localpdns)
#1: - BATCHED DELETEs for test.org
- DELETE test.org SOA a.misconfigured.dns.server.invalid. hostmaster.test.org. 10800 3600 604800 3600 ttl=3600
INFO#1: No nameservers declared for domain "test.oth"; skipping registrar. Add {no_ns:'true'} to force
Done. 2 corrections.Now, lets try pushing as well to see what happens. First off v4.15. ## 192.168.1.90 port 5355 is running an otherwise empty latest version `pdns` nameserver.
> dig @192.168.1.90 -p 5355 soa test.com test.org +short
a.misconfigured.dns.server.invalid. hostmaster.test.com. 1769590229 10800 3600 604800 3600
a.misconfigured.dns.server.invalid. hostmaster.test.org. 1769590230 10800 3600 604800 3600
> dig @192.168.1.90 -p 5355 axfr test.com test.org +short
a.misconfigured.dns.server.invalid. hostmaster.test.com. 1769590933 10800 3600 604800 3600
a.misconfigured.dns.server.invalid. hostmaster.test.com. 1769590933 10800 3600 604800 3600
a.misconfigured.dns.server.invalid. hostmaster.test.org. 1769590933 10800 3600 604800 3600
a.misconfigured.dns.server.invalid. hostmaster.test.org. 1769590933 10800 3600 604800 3600
## push with v4.15
> docker run --rm -it -v "$(pwd):/dns" ghcr.io/stackexchange/dnscontrol:4.15.0 push --config testzones/testzones.js
******************** Domain: test.com
WARNING: No nameservers declared; skipping registrar. Add {no_ns:'true'} to force.
******************** Domain: test.org
WARNING: No nameservers declared; skipping registrar. Add {no_ns:'true'} to force.
Done. 0 corrections.
> dig @192.168.1.90 -p 5355 soa test.com test.org +short
a.misconfigured.dns.server.invalid. hostmaster.test.com. 1769590933 10800 3600 604800 3600
a.misconfigured.dns.server.invalid. hostmaster.test.org. 1769590933 10800 3600 604800 3600
> dig @192.168.1.90 -p 5355 axfr test.com test.org +short
a.misconfigured.dns.server.invalid. hostmaster.test.com. 1769590933 10800 3600 604800 3600
a.misconfigured.dns.server.invalid. hostmaster.test.com. 1769590933 10800 3600 604800 3600
a.misconfigured.dns.server.invalid. hostmaster.test.org. 1769590933 10800 3600 604800 3600
a.misconfigured.dns.server.invalid. hostmaster.test.org. 1769590933 10800 3600 604800 3600No changes! Let's try v4.16. > dig @192.168.1.90 -p 5355 soa test.com test.org +short
a.misconfigured.dns.server.invalid. hostmaster.test.com. 1769590933 10800 3600 604800 3600
a.misconfigured.dns.server.invalid. hostmaster.test.org. 1769590933 10800 3600 604800 3600
> dig @192.168.1.90 -p 5355 axfr test.com test.org +short
a.misconfigured.dns.server.invalid. hostmaster.test.com. 1769590933 10800 3600 604800 3600
a.misconfigured.dns.server.invalid. hostmaster.test.com. 1769590933 10800 3600 604800 3600
a.misconfigured.dns.server.invalid. hostmaster.test.org. 1769590933 10800 3600 604800 3600
a.misconfigured.dns.server.invalid. hostmaster.test.org. 1769590933 10800 3600 604800 3600
## Push with v4.16
> docker run --rm -it -v "$(pwd):/dns" ghcr.io/stackexchange/dnscontrol:4.16.0 push --config testzones/testzones.js
CONCURRENTLY gathering 0 zone(s)
SERIALLY gathering 2 zone(s)
Serially Gathering: "test.com"
Serially Gathering: "test.org"
******************** Domain: test.com
1 correction (localpdns)
#1: - BATCHED DELETEs for test.com
- DELETE test.com SOA a.misconfigured.dns.server.invalid. hostmaster.test.com. 10800 3600 604800 3600 ttl=3600
SUCCESS!
INFO#1: Skipping registrar "none": No nameservers declared for domain "test.com". Add {no_ns:'true'} to force
******************** Domain: test.org
1 correction (localpdns)
#1: - BATCHED DELETEs for test.org
- DELETE test.org SOA a.misconfigured.dns.server.invalid. hostmaster.test.org. 10800 3600 604800 3600 ttl=3600
SUCCESS!
INFO#1: Skipping registrar "none": No nameservers declared for domain "test.org". Add {no_ns:'true'} to force
Done. 2 corrections.
# No anser for soa
> dig @192.168.1.90 -p 5355 soa test.com test.org +short
# transfer failed, because the zone is obviously broken without SOA
> dig @192.168.1.90 -p 5355 axfr test.com test.org +short
; Transfer failed.
; Transfer failed.From a Running v4.15 again does not "reinstate" the SOAs. # v4.15
> docker run --rm -it -v "$(pwd):/dns" ghcr.io/stackexchange/dnscontrol:4.15.0 preview --config testzones/testzones.js
CONCURRENTLY gathering 0 zone(s)
SERIALLY gathering 2 zone(s)
Serially Gathering: "test.com"
Serially Gathering: "test.org"
******************** Domain: test.com
INFO#1: No nameservers declared for domain "test.com"; skipping registrar. Add {no_ns:'true'} to force
******************** Domain: test.org
INFO#1: No nameservers declared for domain "test.org"; skipping registrar. Add {no_ns:'true'} to force
Done. 0 corrections.Lets try to add some records without SOA (identical previews): # v4.15
> docker run --rm -it -v "$(pwd):/dns" ghcr.io/stackexchange/dnscontrol:4.15.0 preview --config testzones/testzones.js
CONCURRENTLY gathering 0 zone(s)
SERIALLY gathering 2 zone(s)
Serially Gathering: "test.com"
Serially Gathering: "test.org"
******************** Domain: test.com
3 corrections (localpdns)
#1: ± BATCHED CHANGE/CREATEs for test.com
+ CREATE test.com NS ns.example.org. ttl=300
+ CREATE test.com A 127.0.0.3 ttl=3600
+ CREATE test.com TXT "A STRING" ttl=3600
******************** Domain: test.org
3 corrections (localpdns)
#1: ± BATCHED CHANGE/CREATEs for test.org
+ CREATE test.org NS ns.example.org. ttl=300
+ CREATE test.org A 127.0.0.3 ttl=3600
+ CREATE test.org TXT "A STRING" ttl=3600
Done. 6 corrections.
# v4.16
> docker run --rm -it -v "$(pwd):/dns" ghcr.io/stackexchange/dnscontrol:4.16.0 preview --config testzones/testzones.js
CONCURRENTLY gathering 0 zone(s)
SERIALLY gathering 2 zone(s)
Serially Gathering: "test.com"
Serially Gathering: "test.org"
******************** Domain: test.com
3 corrections (localpdns)
#1: ± BATCHED CHANGE/CREATEs for test.com
+ CREATE test.com NS ns.example.org. ttl=300
+ CREATE test.com A 127.0.0.3 ttl=3600
+ CREATE test.com TXT "A STRING" ttl=3600
******************** Domain: test.org
3 corrections (localpdns)
#1: ± BATCHED CHANGE/CREATEs for test.org
+ CREATE test.org NS ns.example.org. ttl=300
+ CREATE test.org A 127.0.0.3 ttl=3600
+ CREATE test.org TXT "A STRING" ttl=3600
Done. 6 corrections.Pushing with v4.15 or v4.16 (without explicit SOA) does not reinstate SOAs. E.g., running once with v4.16+ without explicit SOA will bork zones which further v4.15 runs will not "fix". Adding in an explicit SOA for # v4.15 which "fails" due to not supporting SOA-records
> docker run --rm -it -v "$(pwd):/dns" ghcr.io/stackexchange/dnscontrol:4.15.0 preview --config testzones/testzones.js
2026/01/28 09:21:07 1 Validation errors:
2026/01/28 09:21:07 ERROR: domain test.org uses SOA records, but DNS provider type POWERDNS does not support them
exiting due to validation errors
# v4.16 is all happy and wants to create a SOA-record
> docker run --rm -it -v "$(pwd):/dns" ghcr.io/stackexchange/dnscontrol:4.16.0 preview --config testzones/testzones.js
CONCURRENTLY gathering 0 zone(s)
SERIALLY gathering 2 zone(s)
Serially Gathering: "test.com"
Serially Gathering: "test.org"
******************** Domain: test.com
******************** Domain: test.org
1 correction (localpdns)
#1: ± BATCHED CHANGE/CREATEs for test.org
+ CREATE test.org SOA ns.example.org. webmaster.example.org. 3600 600 604800 1440 ttl=3600
Done. 1 corrections.Pushing with v4.16 puts docker run --rm -it -v "$(pwd):/dns" ghcr.io/stackexchange/dnscontrol:4.16.0 push --config testzones/testzones.js
CONCURRENTLY gathering 0 zone(s)
SERIALLY gathering 2 zone(s)
Serially Gathering: "test.com"
Serially Gathering: "test.org"
******************** Domain: test.com
******************** Domain: test.org
1 correction (localpdns)
#1: ± BATCHED CHANGE/CREATEs for test.org
+ CREATE test.org SOA ns.example.org. webmaster.example.org. 3600 600 604800 1440 ttl=3600
SUCCESS!
Done. 1 corrections.
## test.com still borked
> dig @192.168.1.90 -p 5355 soa test.com test.org +short
ns.example.org. webmaster.example.org. 1769592085 3600 600 604800 1440
## test.com still borked
> dig @192.168.1.90 -p 5355 axfr test.com test.org +short
; Transfer failed.
ns.example.org. webmaster.example.org. 1769592085 3600 600 604800 1440
127.0.0.3
ns.example.org.
"A STRING"
ns.example.org. webmaster.example.org. 1769592085 3600 600 604800 1440From <pdns-server>: AXFR-out zone 'test.com', client '192.168.1.42', failed: not authoritative
<pdns-server>: AXFR-out zone 'test.org', client '192.168.1.42', transfer initiatedI think above should be enough to illustrate that the v4.16 change is breaking with regards to SOA and |
|
Ping @tlimoncelli @jpbede wrt above. Is the best way forward a PR updating the |
|
😩 I can't believe I overlooked this. Sorry if this affected anyone. |
Yes. Please update the doc ( |
|
Created #4028 . |
PowerDNS treats the SOA record like any other, and allows editing it through the API. This PR adds the ability to use the SOA modifier with the PowerDNS provider.
Whether this is allowed for any situation where you do not own the host itself, I cannot say if this will work or not. I have no way to test that. I can only test on hosts that I own. That being said, this does work!
Side mention, the docs say:
But in practice when I did
noone@test.internal(and me forgetting the.originally):Also note that the MBox needed a trailing
.but did not error and ended upnoone.test.internal.test.internal:)