Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ordername for SOA not populated after setting NSEC3PARAM via API #14323

Open
2 tasks done
klaus-nicat opened this issue Jun 12, 2024 · 2 comments · May be fixed by #14325
Open
2 tasks done

ordername for SOA not populated after setting NSEC3PARAM via API #14323

klaus-nicat opened this issue Jun 12, 2024 · 2 comments · May be fixed by #14325
Milestone

Comments

@klaus-nicat
Copy link
Contributor

Short description

When the NSEC3PARAM gets updated via API, the SOA RR misses the ordername. I think that ordername population works fine but after that, the serial gets incremented and a new SOA without ordername gets inserted.

Environment

  • Operating system: Ubuntu 22.04
  • Software version: 4.9.0
  • Software source: self compiled

Steps to reproduce

I created a simple zone with a SOA and 2 NS records. Then I set the NSEC3PARAM via the API.

curl -v --data '{"nsec3param":"1 0 2 -"}' -X PUT -H "Content-Type: application/json" -H 'X-API-Key: XXXX' http://83.136.xx.yy:8081/api/v1/servers/localhost/zones/dnssec-signiert.ch

The corresponding backend query log is:

[webserver] bb3906e0-ccd9-4072-b5a3-60aacde9c88d Handling request "/api/v1/servers/localhost/zones/dnssec-signiert.ch"
gpgsql Connection successful. Connected to database 'regdns' on '127.0.0.1'.
Query 139913391597392: Statement: select id,name,master,last_check,notified_serial,type,options,catalog,account from domains where name=$1
Query 139913391597392: Parameters: $1 = 'dnssec-signiert.ch'
Query 139913391597392: 311 us to execute
Query 139913391597392: 327 us total to last row
Query 139913391642608: Statement: SELECT content,ttl,prio,type,domain_id,disabled::int,name,auth::int FROM records WHERE disabled=false and type=$1 and name=$2
Query 139913391642608: Parameters: $1 = 'SOA', $2 = 'dnssec-signiert.ch'
Query 139913391642608: 308 us to execute
Query 139913391642608: 332 us total to last row
Query 139913391688656: Statement: select kind,content from domains, domainmetadata where domainmetadata.domain_id=domains.id and name=$1
Query 139913391688656: Parameters: $1 = 'dnssec-signiert.ch'
Query 139913391688656: 403 us to execute
Query 139913391688656: 421 us total to last row
Query 139913391591440: Statement: select cryptokeys.id, flags, case when active then 1 else 0 end as active, case when published then 1 else 0 end as published, content from domains, cryptokeys where cryptokeys.domain_id=domains.id and name=$1
Query 139913391591440: Parameters: $1 = 'dnssec-signiert.ch'
Query 139913391591440: 394 us to execute
Query 139913391591440: 411 us total to last row
Query 139913391688656: Statement: select kind,content from domains, domainmetadata where domainmetadata.domain_id=domains.id and name=$1
Query 139913391688656: Parameters: $1 = 'dnssec-signiert.ch'
Query 139913391688656: 392 us to execute
Query 139913391688656: 409 us total to last row
Query 139913391681024: Statement: delete from domainmetadata where domain_id=(select id from domains where name=$1) and domainmetadata.kind=$2
Query 139913391681024: Parameters: $1 = 'dnssec-signiert.ch', $2 = 'NSEC3PARAM'
Query 139913391681024: 355 us to execute
Query 139913391547040: Statement: insert into domainmetadata (domain_id, kind, content) select id, $1, $2 from domains where name=$3
Query 139913391547040: Parameters: $1 = 'NSEC3PARAM', $2 = '1 0 2 -', $3 = 'dnssec-signiert.ch'
Query 139913391547040: 542 us to execute
Query 139913391681024: Statement: delete from domainmetadata where domain_id=(select id from domains where name=$1) and domainmetadata.kind=$2
Query 139913391681024: Parameters: $1 = 'dnssec-signiert.ch', $2 = 'NSEC3NARROW'
Query 139913391681024: 263 us to execute
Query 139913391632848: Statement: SELECT content from public.intercept_domainmetadata2020($1,$2)
Query 139913391632848: Parameters: $1 = 'dnssec-signiert.ch', $2 = 'API-RECTIFY'
Query 139913391632848: 297 us to execute
Query 139913391632848: 313 us total to last row
Query 139913391632848: Statement: SELECT content from public.intercept_domainmetadata2020($1,$2)
Query 139913391632848: Parameters: $1 = 'dnssec-signiert.ch', $2 = 'PRESIGNED'
Query 139913391632848: 463 us to execute
Query 139913391632848: 479 us total to last row
Query 139913391642608: Statement: SELECT content,ttl,prio,type,domain_id,disabled::int,name,auth::int FROM records WHERE disabled=false and type=$1 and name=$2
Query 139913391642608: Parameters: $1 = 'SOA', $2 = 'dnssec-signiert.ch'
Query 139913391642608: 284 us to execute
Query 139913391642608: 308 us total to last row
Query 139913391524720: Statement: SELECT content,ttl,prio,type,domain_id,disabled::int,name,auth::int,ordername FROM records WHERE (disabled=false OR $1) and domain_id=$2 order by name, type
Query 139913391524720: Parameters: $1 = '0', $2 = '569438'
Query 139913391524720: 299 us to execute
Query 139913391632848: Statement: SELECT content from public.intercept_domainmetadata2020($1,$2)
Query 139913391632848: Parameters: $1 = 'dnssec-signiert.ch', $2 = 'PRESIGNED'
Query 139913391632848: 230 us to execute
Query 139913391632848: 246 us total to last row
Query 139913391591440: Statement: select cryptokeys.id, flags, case when active then 1 else 0 end as active, case when published then 1 else 0 end as published, content from domains, cryptokeys where cryptokeys.domain_id=domains.id and name=$1
Query 139913391591440: Parameters: $1 = 'dnssec-signiert.ch'
Query 139913391591440: 355 us to execute
Query 139913391591440: 374 us total to last row
Query 139913391632848: Statement: SELECT content from public.intercept_domainmetadata2020($1,$2)
Query 139913391632848: Parameters: $1 = 'dnssec-signiert.ch', $2 = 'NSEC3PARAM'
Query 139913391632848: 257 us to execute
Query 139913391632848: 274 us total to last row
Query 139913391632848: Statement: SELECT content from public.intercept_domainmetadata2020($1,$2)
Query 139913391632848: Parameters: $1 = 'dnssec-signiert.ch', $2 = 'NSEC3NARROW'
Query 139913391632848: 219 us to execute
Query 139913391632848: 233 us total to last row
Query 139913391524720: 1978 us total to last row

>>>>>>>> Here the ordername gets set for all 3 RRs with name dnssec-signiert.ch
Query 139913391522224: Statement: update records set ordername=$1,auth=$2 where domain_id=$3 and name=$4 and disabled=false
Query 139913391522224: Parameters: $1 = 'q5qdlikeq1jl4ptaslr7h1u6cipp57fk', $2 = 't', $3 = '569438', $4 = 'dnssec-signiert.ch'
Query 139913391522224: 1006 us to execute
Query 139913391632848: Statement: SELECT content from public.intercept_domainmetadata2020($1,$2)
Query 139913391632848: Parameters: $1 = 'dnssec-signiert.ch', $2 = 'SOA-EDIT-API'
Query 139913391632848: 447 us to execute
Query 139913391632848: 464 us total to last row
Query 139913391642608: Statement: SELECT content,ttl,prio,type,domain_id,disabled::int,name,auth::int FROM records WHERE disabled=false and type=$1 and name=$2
Query 139913391642608: Parameters: $1 = 'SOA', $2 = 'dnssec-signiert.ch'
Query 139913391642608: 253 us to execute
Query 139913391642608: 279 us total to last row
Query 139913391632848: Statement: SELECT content from public.intercept_domainmetadata2020($1,$2)
Query 139913391632848: Parameters: $1 = 'dnssec-signiert.ch', $2 = 'SOA-EDIT'
Query 139913391632848: 254 us to execute
Query 139913391632848: 270 us total to last row
Query 139913391702416: Statement: delete from records where domain_id=$1 and name=$2 and type=$3
Query 139913391702416: Parameters: $1 = '569438', $2 = 'dnssec-signiert.ch', $3 = 'TYPE6'
Query 139913391702416: 293 us to execute

>>>>>>>> Here the SOA gets replaced without ordername
Query 139913391702416: Statement: delete from records where domain_id=$1 and name=$2 and type=$3
Query 139913391702416: Parameters: $1 = '569438', $2 = 'dnssec-signiert.ch', $3 = 'SOA'
Query 139913391702416: 425 us to execute
Query 139913391602064: Statement: insert into records (content,ttl,prio,type,domain_id,disabled,name,ordername,auth) values ($1,$2,$3,$4,$5,$6,$7,$8,$9)
Query 139913391602064: Parameters: $1 = 'secdev1-tst.rcode0.net rcodezero-soa.ipcom.at 2024061216 10800 3600 604800 30', $2 = '30', $3 = '0', $4 = 'SOA', $5 = '569438', $6 = 'f', $7 = 'dnssec-signiert.ch', $8 = NULL, $9 = 't'
Query 139913391602064: 1571 us to execute
[webserver] bb3906e0-ccd9-4072-b5a3-60aacde9c88d Result for "/api/v1/servers/localhost/zones/dnssec-signiert.ch": 204, body length: 0
[webserver] bb3906e0-ccd9-4072-b5a3-60aacde9c88d 83.136.xx.yy:48290 "PUT /api/v1/servers/localhost/zones/dnssec-signiert.ch HTTP/1.1" 204 306

We use heavy DB triggers and rewrite some PDNS queries but as far as I see the problem is just caused by the final serial increment which sets ordername=NULL.

Expected behaviour

Serial increment should also set the ordername of SOA.

Actual behaviour

Serial increment deletes the ordername of SOA.

@dwfreed
Copy link
Contributor

dwfreed commented Jun 12, 2024

This is where the serial increase happens that is shown in the log:

pdns/pdns/ws-auth.cc

Lines 907 to 925 in 1049daf

// Increase serial
string soa_edit_api_kind;
domainInfo.backend->getDomainMetadataOne(zonename, "SOA-EDIT-API", soa_edit_api_kind);
if (!soa_edit_api_kind.empty()) {
SOAData soaData;
if (!backend.getSOAUncached(zonename, soaData)) {
return;
}
string soa_edit_kind;
domainInfo.backend->getDomainMetadataOne(zonename, "SOA-EDIT", soa_edit_kind);
DNSResourceRecord resourceRecord;
if (makeIncreasedSOARecord(soaData, soa_edit_api_kind, soa_edit_kind, resourceRecord)) {
if (!domainInfo.backend->replaceRRSet(domainInfo.id, resourceRecord.qname, resourceRecord.qtype, vector<DNSResourceRecord>(1, resourceRecord))) {
throw ApiException("Hosting backend does not support editing records.");
}
}
}

Indeed, it fails to preserve or repopulate the ordername when increasing. A possible simple fix would be to move the serial bump to before the rectify call. This entire function runs in a single backend transaction, so all of the changes this function makes would be committed in one go.

@klaus-nicat
Copy link
Contributor Author

... A possible simple fix would be to move the serial bump to before the rectify call. This entire function runs in a single backend transaction, so all of the changes this function makes would be committed in one go.

This sounds like an easy an effective workaround.

@klaus-nicat klaus-nicat linked a pull request Jun 13, 2024 that will close this issue
7 tasks
@Habbie Habbie added this to the auth-5 milestone Jun 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants