StackExchange / dnscontrol

Infrastructure as code for DNS!
https://dnscontrol.org/
MIT License
3.07k stars 389 forks source link

INWX: Quoted HTTPS entries don't work #2947

Open brknkfr opened 4 months ago

brknkfr commented 4 months ago

Describe the bug I can create HTTPS (https://github.com/StackExchange/dnscontrol/pull/2930) records on INWX provider, but the records are saved with quotes and they are not working.

Text field on INWX web interface looks like this:

1 . alpn="h2" port="443" ipv4hint="123.123.123.123"

Unfortunately, INWX doesn't like quotes and doesn't return anyhting for a HTTPS request (tested with dig -t HTTPS domain.tld).

A HTTPS record entry without quotes works. Changing it manually to following in the INWX web interface works.

1 . alpn=h2 port=443 ipv4hint=123.123.123.123

After that change, dig -t HTTPS domain.tld returns exptected result. But with that manually changed entry, dnscontrol won't work anymore.

./dnscontrol ppreview
CONCURRENTLY gathering 0 zone(s)
SERIALLY gathering 1 zone(s)
Serially Gathering: "domain.tld"
******************** Domain: domain.tld
#1: Domain "domain.tld" provider inwx Error: INWX: unparsable record received: unknown rtype (HTTPS) when parsing (1 . ipv4hint=123.123.123.123 alpn=h2 port=443) domain=(domain.tld)

To Reproduce Steps to reproduce the behavior:

  1. Create a dnsconfig.js file with a HTTPS record entry for the INWX provider and publish it.
  2. DNS queries for HTTPS records are empty.

Expected behavior dnscontrol should unquote the HTTPS entries for the INWX provider before publishing them. Unfortunately I do not know enought Go to create a pull request.

DNS Provider

brknkfr commented 4 months ago

Maybe you can help out? @tlimoncelli @patschi @christianbur

tlimoncelli commented 4 months ago

Interesting! It looks like both Cloudflare and IWNX reject quotes in those situations.

@fritterhoff: Sounds like we need to not generate those quotes. Maybe file a bug report with https://github.com/miekg/dns ?

fritterhoff commented 4 months ago

Yeah. I sadly forgot to fill a bug report and prepare a MR for this issue. Will do later.

fritterhoff commented 4 months ago

@tlimoncelli prop thats a corner case of the RFC. The RFC permits using:

Each SvcParamKey SHALL appear at most once in the SvcParams.  In
   presentation format, SvcParamKeys are lowercase alphanumeric strings.
   Key names contain 1-63 characters from the ranges "a"-"z", "0"-"9",
   and "-".  In ABNF [RFC5234],

   alpha-lc      = %x61-7A   ; a-z
   SvcParamKey   = 1*63(alpha-lc / DIGIT / "-")
   SvcParam      = SvcParamKey ["=" SvcParamValue]
   SvcParamValue = char-string ; See Appendix A.
   value         = *OCTET ; Value before key-specific parsing

And defines:

   ; non-special is VCHAR minus DQUOTE, ";", "(", ")", and "\".
   non-special = %x21 / %x23-27 / %x2A-3A / %x3C-5B / %x5D-7E
   ; non-digit is VCHAR minus DIGIT.
   non-digit   = %x21-2F / %x3A-7E
   ; dec-octet is a number 0-255 as a three-digit decimal number.
   dec-octet   = ( "0" / "1" ) 2DIGIT /
                 "2" ( ( %x30-34 DIGIT ) / ( "5" %x30-35 ) )
   escaped     = "\" ( non-digit / dec-octet )
   contiguous  = 1*( non-special / escaped )
   quoted      = DQUOTE *( contiguous / ( ["\"] WSP ) ) DQUOTE
   char-string = contiguous / quoted

Using this specs an enquoted string would be valid. I am not sure if a bug report for miekg/dns would be legit.

tlimoncelli commented 4 months ago

Thank you for finding that in the RFC (I was about to look for it myself!)

Yes, I agree. It would be more of a feature request for miekg/dns than a bug report.

That said, it would be easy to fix on our end. Something like (untested):

v := kv.String()
last := len(v)-1
if len(v) > 0 && v[0] == '"' && v[last] == '"' {
  inner := v[1:last]
  if !strings.ContainsAny(inner, "\" \t\\") {
      v = inner // Remove unnecessary quoting
  }
}

Bonus points for sending a feature request to miekg/dns :)

Tom

brknkfr commented 4 months ago

Btw, getting the records, with a "valid" HTTPS record on INWX, throws an error too.

./dnscontrol ppreview
CONCURRENTLY gathering 0 zone(s)
SERIALLY gathering 1 zone(s)
Serially Gathering: "domain.tld"
******************** Domain: domain.tld
#1: Domain "domain.tld" provider inwx Error: INWX: unparsable record received: unknown rtype (HTTPS) when parsing (1 . ipv4hint=123.123.123.123 alpn=h2 port=443) domain=(domain.tld)
fritterhoff commented 3 months ago

Thats a little bit strange. I will try to debug the HTTPS record the next few days again.

fritterhoff commented 3 months ago

Sorry I've been pretty busy the last few days. Sadly I only can really test AXFR and BIND with real data (and cloudflare with some test data)

For my use cases it is working fine... at least until now. Right now I only could offer to rewrite the (de)serialization with some own logic.