coredns / rfc

Propsals and request for comments for CoreDNS
0 stars 11 forks source link

Add ACME protocol support for certificate management into TLS plugin #13

Open mariuskimmina opened 2 years ago

mariuskimmina commented 2 years ago

This is a first draft and still contains open questions, and is subject to change.

I hope to work on this project in the context of Goolge Summer of Code (GSoC) and will be applying for that in the upcoming application period from April 04 - April 19.

I saw that there were 2 previous proposals for an ACME addition and reused a lot of there work - so a lot of credit goes to them and hopefully the third times the charm.

mariuskimmina commented 2 years ago

Following up on our discussion on the original issue, I updated the proposal so that only the DNS challenge will be supported by this change, the HTTP challenge is out of scope. CoreDNS also needs to be the authoritative DNS server for the domain.

mariuskimmina commented 2 years ago

Hey @yongtang, I would appreciate some feedback on this when you can find the time. I have also send in my application for GSoC - so I'm sure that I want to work on this.

yongtang commented 2 years ago

@mariuskimmina The proposal overall looks great! I also saw your proposal in GSoC's page. /cc @greenpau

mariuskimmina commented 2 years ago

So, I started working on this and I am hitting a first roadblock - to solve the DNS Challenge CoreDNS needs to be ready to accept DNS requests, which happens after all the plugins have been parsed. So, when parsing the TLS plugin and trying to solve the ACME Challenge, CoreDNS is not yet accepting any DNS requests. What I can do is put the whole ACME Challenge Code into a go-routine and let CoreDNS start while the Challenge Code is being executed - but then (I think) I cannot tell CoreDNS to use the certificate any more because it's already done parsing the config.

So, Ideally when parsing the TLS plugin config I want to be able to start serving DNS just for the challenge and then stop serving DNS again to go on parsing other plugins - is there a way to do something like that? @yongtang @greenpau

yongtang commented 2 years ago

@mariuskimmina Sorry for the late reply. Let me take a look and get back to you during the weekend.

mariuskimmina commented 2 years ago

@yongtang After digging a bit deeper into the core code, I found it to be possible to create barebones (no plugins) dnsserver.Server inside the plugin code and start to serve DNS requests - so it seems doabble to

  1. Start a barebones dnsserver.Server
  2. Start the ACME Challenge
  3. Solve the challenge (wait for a request)
  4. Receive a Certificate
  5. Shutdown the created dnsserver.Server
  6. Continue parsing other plugins as usual

But no other plugin seems to have done something like this - does it seem reasonable to do it this way? I would of course add a timeout to the challenge so that if something goes wrong CoreDNS doesn't get stuck on startup.

Also don't worry about late replies - I appreciate any help I can get

mariuskimmina commented 2 years ago

Status update: I just successfully solved an ACME DNS Challenge and received a certificate - so the approach seems to be working. Code is still a mess and I need to add a lot of logic around it, but the general approach appears to be working. :)

For my tests I'm using pebble as a CA running on localhost, CoreDNS is also running on localhost and set as the authoritative DNS Server in /etc/resolv.conf In this setup I can request a certifcate for dns.example.com, CoreDNS answers the dns request to _acme_challenge.example.com and I receive a certificate.

yongtang commented 2 years ago

@mariuskimmina Happy to let you know that your proposal has been accepted by GSoC. Congratulations 🎉

I am out-of-office this week but I will send you a meeting invite so Paul and me can have a sync up with you. You can also find my email from my github profile.

mariuskimmina commented 2 years ago

Thanks for bringing me the great news, even before an official anouncement - I am looking forward to talking to you and to bringing this feature into CoreDNS :grinning: