I see that there is no PowerDNS plugin for caddy 2, although there was one for caddy 1. I am looking to implement a local ACME-CA using step-ca and have caddy do dns-challenges rather than http ones. For now I only have 2 questions:
Is anyone currently working on a PowerDNS plugin, either directly interfacing with its api or via an intermediate e.g. PowerDNS-Admin? If not is the libdns package relevant to this implementation or is it better to write the plugin from scratch?
Are there any other changes needed for a local acme setup with local dns challenge?
For the time being, you may use the lego-deprecated DNS plugin, which will give you access to all the DNS plugins that Caddy v1 had.
You can see the instructions here:
Nobody is working on one yet, that I know of.
And yes, the libdns interfaces are what we want new DNS plugins to target. Ideally once you have a base implementation, it can be moved to the libdns and caddy-dns organization. You can read this page to learn about how this all works:
Are you aware that Caddy actually comes with a local ACME server from smallstep, built-in?
Thank you, hopefully I will have time to research this. I don’t have experience with go yet so I hope someone can implement before me.
Yes I sort of remembered that point. Is it possible to expose this acme server for other applications? For example:
Create and manage tls certificates for mail server IMAP/POP3/SMTP ports. Either with a certbot or dns challenge
Manage multiple CAs, e.g. public let’s encrypt for https, private one for client certificates, etc.
Create and access control client certificates for a particular domain. I don’t yet understand if this has to be managed by the CA, mail server or another service
I have also found that certbot has a few PowerDNS plugins, although probably not maintained ones, e.g. the most recent one. Does caddy use certbot internally or with a plugin? If so can plugins be added to it?
Yep! That’s exactly why it’s available as a http handler!
Caddy completely replaces certbot. Caddy itself is an ACME client, and it’s the underlying function of its flagship feature, Automatic HTTPS:
Caddy is primarily an HTTP server, and the Caddyfile adapter aims to fill that niche, so it’s better to use JSON config if you need to manage non-HTTP domains. See this article for an example:
Yeah, you can configure multiple issuers. By default, Caddy enables the acme issuer (for Let’s Encrypt) and the zerossl issuer (for ZeroSSL – which is also ACME, but it came later so the names aren’t aligned). There’s also the internal issuer which is your local CA.
Yep, see the tls directive, which allows you to configure client_auth:
Nope, Caddy uses acmez which is its own ACME client implementation. This is because Caddy needs to have greater control over its underlying ACME client implementation so it can be more rigorous and reliable. Caddy used to use lego, another Let’s Encrypt client lib, but it wasn’t enough to support everything Caddy needed to do, and it was too rigid to change for Caddy (because it’s used by other users who have different goals in mind).
Isn’t this directive to access control the website? I am still new to this part so I don’t know how to create the client certificates for each user. As far as I understand I need a trusted CA to sign the server’s certificate and then create client certificates from that CA (still don’t know this step). I am following this guide for dovecot configuration. Anyway thanks for pointing this directive, I might use it for a different part later on.
So as I see there are a few possible configurations for my use-case:
Have caddy manange each example.com certificates with the json configuration, and share these certificates with the mail server or other services. Make a separate endpoint to get the client certificates and share the pem for this endpoint with the mail server to authenticate the user
Probably this is the most robust and future-proof
If I use the default configuration using Let’s Encrypt for the client certificate, is it secure? I have seen discussion that the CA should be private so not everyone can register, and I should be careful on which certificate in the trust chain I use for the client certificate authenticator (I believe this is the tls.client_auth.trusted_leaf_cert_file)
Still unclear how to get the client certificate
If setup for local network and a PowerDNS plugin, can it be used for all the dns challenges: caddy https server, json configured certificates, built-in acme_server?
Create a local acme_server in caddy and use something like certbot to manage the certificates for each service.
Probably easier to setup atm, but have to manage certbot as well
Is it possible to access control this endpoint?
Manage a separate CA and have caddy point to it for some necessary endpoints.
Most complicated setup, but it’s most customizable
Can you share some advice on these, and is there something to expect in future development?
Depends. If you configure client auth on the server side, then yes; if you configure it in the reverse proxy where Caddy acts as a client, then no, in that case it should grant access to a backend which requires it.
Definitely don’t use Certbot or other ACME tooling: Caddy has the ACME server and client built in, that should be all you need.
I’d go with the first plan if I were you. But I think in order for anyone here to be more helpful, you’ll need to be more specific. For example:
Which client certificate? For what? Installed where? Signed by what/whom? The best answer I can give with just that is: “From an ACME server”
I’m actually writing an in-depth expert chapter for setting up PKI services with Caddy (for sponsors), it covers a lot of your questions, I think, in the form of explanations and tutorials. But most of these things aren’t specific to Caddy…
The best example of the setup I’m trying to configure is for email-servers, but it will apply for prosody and other non-HTTP tls services. What I want to achieve is as follows:
Get certificate and private key for securing IMAP/POP3/SMTP, place these in a shared location not /var/lib/caddy/... and have caddy service automatically manage renewal. These I want to be publicly signed by LetsEncrypt/ZeroSSL. I think one way to achieve this is to DNS challenge, and edit the JSON config as linked in @francislavoie comment. I haven’t looked into how to manage caddy from json, but can I have multiple json files each adding a certificate to automate, and does it work together with Caddyfile?
Manage a private CA for managing client certificate authentication. Dovecot needs to have a signed server certificate from this CA in .pem format. From the same CA I will create client certificates for the users. From my discussion on the step-ca repository I have a minimal understanding of how to create the server/client certificates, and it is possible to tie it to an oauth authentication. There are a few concerns on this part:
Can caddy’s acme_server have the same oauth feature?
How can we automate the certificate management against this CA. Can caddy automate the server’s certificate renewal at least? Can it use dns challenge for this?
In caddy can we manage multiple CAs? At minimum the public LetsEncrypt/ZeroSSL and a private CA, but ideally I would like to be able to have each service having a different CA for user management. Also will these have a common root/intermediate certificate?
Caddyfile to JSON is one-way, you can’t get JSON from a Caddyfile. So what you do is write your Caddyfile, adapt it with caddy adapt, then apply any JSON changes to it (I recommend using jq the command line tool which can be used to modify JSON to append/merge things) then run Caddy from that JSON with caddy run --config path/to/caddy.json.