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

Error updating DNS record: unexpected acceptor flag is not set: expecting a token from the acceptor, not in the initiator #160

Closed
lduriez opened this issue Jul 28, 2021 · 22 comments

Comments

@lduriez
Copy link

lduriez commented Jul 28, 2021

Hello,

I'm trying to create an A record into DNS Windows Server. I'm trying to use it with gssapi because I already use kinit to get authenticate with kerberos ticket. But once I apply my terraform I got the following error :

terraform apply tfplan
dns_a_record_set.dns: Creating...
╷
│ Error: Error updating DNS record: unexpected acceptor flag is not set: expecting a token from the acceptor, not in the initiator
│ 
│   with dns_a_record_set.dns,
│   on main.tf line 156, in resource "dns_a_record_set" "dns":
│  156: resource "dns_a_record_set" "dns" {
│ 
╵

Did someone have the same issue ? I don't really understand what the error message explain to be honnest.

Terraform Version

terraform -v
Terraform v1.0.3
on linux_amd64
+ provider registry.terraform.io/hashicorp/dns v3.2.1

Affected Resource(s)

  • dns_a_record_set

Terraform Configuration Files

variable "hostname" {
  type    = string
}
variable "ip_address" {
  type        = string
  validation {
    condition     = can(regex("^192\\.168\\.22\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$", var.ip_address))
    error_message = "You should provide an IPv4 in CIDR 192.168.22.0/24."
  }
}
provider "dns" {
  update {
    server = "dns.domain.lan"
    gssapi {
      realm = "DOMAIN.LAN"
      username = "terraform"
      password = "***"
    }
  }
}
resource "dns_a_record_set" "dns" {
  zone = "domain.lan."
  name = var.hostname
  addresses = [var.ip_address]
}

Expected Behavior

Create the A record

Actual Behavior

Error when creating the A record

Steps to Reproduce

  1. terraform apply

Important Factoids

My Kerberos ticket is valid, as I use it for over things.
My computer is not part of the Windows Active Directory.
Here is my krk5.conf :

[logging]
        default = FILE:/var/log/krb5lib.log
 
[libdefaults]
        default_realm = DOMAIN.LAN
        dns_fallback = no
        dns_lookup_kdc = no
 
[realms]
        DOMAIN.LAN = {
            default_principal_flags = +preauth
            admin_server = dns.domain.lan
            kdc = dns.domain.lan
            default_domain = DOMAIN.LAN
            dns_lookup_kdc = false
            dns_lookup_realm = false
        }
         
 
[domain_realm]
.domain.lan = DOMAIN.LAN
domain.lan = DOMAIN.LAN

References

This issue look similar, but they said that A record are OK for them:

@SamKirsch10
Copy link

Check to see if the record you're trying to make is already there, but a different type. I just got this error trying to make an A record, but forgot a long time ago I had made the same record as CNAME.

Example:

TF PLAN:

  # dns_a_record_set.a_record["sam-test2"] will be created
  + resource "dns_a_record_set" "a_record" {
      + addresses = [
          + "10.219.7.233",
        ]
      + id        = (known after apply)
      + name      = "sam-test2"
      + ttl       = 3600
      + zone      = "zone.local."
    }

Record already exists: sam-test2.zone.local CNAME somethingelse.zone.local

Errors out same as above.

@lduriez
Copy link
Author

lduriez commented Aug 12, 2021

Hello SamKirsh,

Thanks for your reply.

I checked, and it doesn't exist in my DNS in any record type.

@edergillian
Copy link

edergillian commented Aug 14, 2021

I have the exact same issue. The only difference is that it actually creates the A record, but it errors out anyway.

I checked the TRACE log and the message received from the DNS server has status NOERROR.

These are my Terraform and provider versions:

terraform -version
Terraform v1.0.4
on linux_amd64
+ provider registry.terraform.io/hashicorp/dns v3.2.1
+ provider registry.terraform.io/hashicorp/vsphere v2.0.2

PS.: I can actually import the record created and, after that, any apply works correctly; but then, when I try to destroy, it gives me the same error on the first try, but deletes both the resource from the state file and the record on the DNS Server. On the second try, it removes everything else.

@bhoriuchi
Copy link

bhoriuchi commented Sep 28, 2021

I am able to reproduce this on windows dns server. It appears to only happen on the first request to a zone. The request says it fails but the record is created. subsequent applies work fine. The relevant log shows the dns request returning a refused status

2021-09-28T14:41:44.175-0700 [INFO]  plugin.terraform-provider-dns: 2021/09/28 14:41:44 [DEBUG] Receiving DNS message from server (*************:53):
;; opcode: UPDATE, status: REFUSED, id: 34458
;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

update:
request again fail after a certain time with no requests. in my case i performed an apply successfully and then after a few hours a destroy failed the first time with the same message and the subsequent destroy worked

Appears to be thrown from

https://github.com/jcmturner/gokrb5/blob/v8.4.2/gssapi/MICToken.go#L144
which is called by
https://github.com/bodgit/tsig/blob/v1.1.1/gss/gokrb5.go#L212

update2:

i have narrowed it down to this line of code
https://github.com/ns1/tsig/blob/master/gss/gokrb5.go#L150

updating to match the ns1 fork parameters https://github.com/ns1/tsig/blob/master/gss/gokrb5.go#L150 resolves the issue. i really have no idea what the difference in parameters makes but it appears to be an issue that can only be addressed with the tsig package.

// current package params
apreq, err := spnego.NewKRB5TokenAPREQ(cl, tkt, key, []int{gssapi.ContextFlagMutual, gssapi.ContextFlagReplay, gssapi.ContextFlagInteg}, []int{flags.APOptionMutualRequired})

// ns1 params
apreq, err := spnego.NewKRB5TokenAPREQ(cl, tkt, key, []int{gssapi.ContextFlagInteg, gssapi.ContextFlagMutual}, []int{gssapi.ContextFlagMutual})

@bodgit
Copy link
Contributor

bodgit commented Dec 3, 2021

Ideally I/we need to have a .pcap to debug this. Please capture all UDP & TCP port 53 traffic, (whole packets, not truncated), for the whole Terraform run.

An additional thought, does explicitly setting the transport to TCP help?:

provider "dns" {
  update {
    server    = "..."
    transport = "tcp"
    gssapi {
      ...
    }
  }
}

@PhilRanzato
Copy link

An additional thought, does explicitly setting the transport to TCP help?:

provider "dns" {
  update {
    server    = "..."
    transport = "tcp"
    gssapi {
      ...
    }
  }
}

Same error here, even with tcp

@vavdoshka
Copy link

vavdoshka commented Feb 14, 2022

For me, it was resolved after I implemented two things:

  • disabled Nonsecure dynamic updates for the managed hosted zone. Kept Secured only.
  • ensured the user has Create all child permissions in the managed hosted zone. This permission might be too permissive, depending on your use-case, but the point is that the user should have the right to do what it needs to).

if both or one of these is not implemented I got the same error Error updating DNS record: unexpected acceptor flag is not set: expecting a token from the acceptor, not in the initiator

@getSurreal
Copy link

@bodgit Your original PR does state that it requires "secure only" updates. Do you know why?
#30

@bodgit
Copy link
Contributor

bodgit commented May 11, 2022

I'm not sure I understand the question.

A windows DNS zone can be configured as requiring "secure only" updates which means every dynamic DNS update must be TSIG signed using GSS-TSIG, hence something like #30 was necessary.

A zone can be configured as permitting a mix of both secure and insecure updates, (and possibly insecure only, I can't recall). Insecure simply means no TSIG signature required so an unauthenticated user can send an update for potentially any record/type, modulo the restrictions Windows places on dynamic DNS updates in general.

No Windows administrator worth their salt is going to permit insecure updates outside of a toy environment.

@getSurreal
Copy link

I think I understand now. GSSAPI is what allows you to connect to a Secure Windows DNS. The DNS provider can update a nonsecure Windows DNS without the additional GSSAPI parameters.

@bodgit
Copy link
Contributor

bodgit commented May 11, 2022

GSSAPI is more widely used than just Windows DNS (the G stands for Generic), it's used by lots of services for authentication, usually if Kerberos is involved somehow (including the embraced-and-extended version Windows uses).

You can configure BIND to also use this method, the test suite for this provider does exactly that for testing purposes.

@getSurreal
Copy link

Thanks bodgit. I appreciate the additional details around GSSAPI. Regarding this open issue around Windows AD DNS, I think the behavior is as expected and can be closed.

@lduriez
Copy link
Author

lduriez commented May 13, 2022

For me, it was resolved after I implemented two things:

* disabled `Nonsecure` dynamic updates for the managed hosted zone. Kept `Secured only`.

* ensured the user has `Create all child permissions` in the managed hosted zone. This permission might be too permissive, depending on your use-case, but the point is that the user should have the right to do what it needs to).

if both or one of these is not implemented I got the same error Error updating DNS record: unexpected acceptor flag is not set: expecting a token from the acceptor, not in the initiator

I test that and I confirm It works fine

Thanks

@lduriez lduriez closed this as completed May 13, 2022
@mateuszdrab
Copy link

mateuszdrab commented May 23, 2022

For me, it was resolved after I implemented two things:

* disabled `Nonsecure` dynamic updates for the managed hosted zone. Kept `Secured only`.

* ensured the user has `Create all child permissions` in the managed hosted zone. This permission might be too permissive, depending on your use-case, but the point is that the user should have the right to do what it needs to).

if both or one of these is not implemented I got the same error Error updating DNS record: unexpected acceptor flag is not set: expecting a token from the acceptor, not in the initiator

I test that and I confirm It works fine

Thanks

Did you mean 'Create all child objects' permission on the DNS zone?
I'm having the same issue with a different project (https://github.com/kubernetes-sigs/external-dns), I wanted to try this workaround. My A records create fine, even in subdirectories but I can't get a CNAME to create.

@lduriez
Copy link
Author

lduriez commented May 23, 2022

I set dynamic updates to "secured only" to the hosted zone and it works for me

@mateuszdrab
Copy link

I set dynamic updates to "secured only" to the hosted zone and it works for me

What type of record are you creating? A or CNAME?

Thanks

@vavdoshka
Copy link

hey @mateuszdrab ,
regarding external-dns and C record, please check this
ensure you set --txt-prefix https://github.com/kubernetes-sigs/external-dns/blob/master/charts/external-dns/values.yaml#L113

@mateuszdrab
Copy link

hey @mateuszdrab ,
regarding external-dns and C record, please check this
ensure you set --txt-prefix https://github.com/kubernetes-sigs/external-dns/blob/master/charts/external-dns/values.yaml#L113

Thanks a lot, that was it.

I missed that parameter as I was mostly looking in the faq document and didn't realise Windows DNS would not allow same name cname and txt record. I thought it was just A or CNAME.

@lduriez
Copy link
Author

lduriez commented May 25, 2022

I set dynamic updates to "secured only" to the hosted zone and it works for me

What type of record are you creating? A or CNAME?

Thanks

I'm creating A record, didn't try with CNAME.

@mateuszdrab
Copy link

I set dynamic updates to "secured only" to the hosted zone and it works for me

What type of record are you creating? A or CNAME?
Thanks

I'm creating A record, didn't try with CNAME.

Thanks, I resolved the issue now thanks to the hint from @vavdoshka

It was due to the fact the TXT and CNAME can't have the same name so the txt record name is prefixed now with an underscore and all is well.
--txt-prefix=_ did the job

@bodgit
Copy link
Contributor

bodgit commented May 25, 2022

Yes, generally you cannot mix a CNAME record with any other record type for a given node:

If a CNAME record is present at a node, no other data should be present; this ensures that the data for a canonical name and its aliases cannot be different. (RFC 1034 section 3.6.2, RFC 1912 section 2.4) The exception is when DNSSEC is being used, in which case there can be DNSSEC related records such as RRSIG, NSEC, etc. (RFC 2181 section 10.1)

Copy link

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.
If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 22, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants