zenhack / simp_le

Simple Let's Encrypt client
GNU General Public License v3.0
224 stars 38 forks source link

Add a mode for mock certificate generation #105

Closed abbradar closed 6 years ago

abbradar commented 6 years ago

In NixOS we use simp_le for auto-issuing certificates for nginx and other servers. The problem is that often those services can't start for the first time because the certificate is not there yet. Currently we generate temporary self-signed certificates by hand; it'd be nice for simp_le to have a mode when it generates those instead of using ACME and places them in exactly the same layout it places genuine ones.

zenhack commented 6 years ago

Yeah, it would be good to have an obvious way to do this. My gut though is to generally leave features out if we can, and this feels like it should generally be easy to script around:

if [ ! -f /path/to/key.pem ] ; then
  openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -out fullchain.pem -nodes -subj '/CN=nixos.org'
  # Copy pem files into place
fi

The other thing I've done in the past with nginx is to have the https part of the config in a separate file, and in the main config file have e.g. include /etc/nginx/conf.d/*.conf. Then, only create the https config after the cert is obtained, so on first boot it just cleanly doesn't do https. But this is a bit more complex.

At the very least I think a wiki page or something might be a good idea. I'm willing to be convinced otherwise though.

wmertens commented 6 years ago

However, by not implementing it here, all downstream distros have to implement it separately, which quite is a lot of duplicate work, a source of bugs and a barrier to entry.

In NixOS we only recently discovered that the cert needs to include the CA, for example.

zenhack commented 6 years ago

You shouldn't need to include the CA for bootstrapping; what I'd do is:

If I understand correctly, the issue you all hit was that you were pointing simp_le at the manually generated cert file, rather than generating a fresh one and then copying? I kinda feel like that shouldn't be encouraged anyway, since it requires simp_le having write access to the web server's config (which on e.g. zenhack.net is root-only; even the web server only needs read), not just the relevant part of the web root (and $PWD).

Supporting generating a temporary bogus cert in the same file location would also be more fiddly to implement than the copying solution above.

My inclination is just to write a "how do I bootstrap?" FAQ entry; the logic isn't actually very complex, but definitely worth explaining since it's not necessarily obvious.

abbradar commented 6 years ago

@zenhack The problem is that requires detection and special handling of "bootstrapping" phase -- i.e. before running simp_le for a given domain we need first to check if certificates which server currently uses are self-generated ones and if not then run simp_le with certificates directory as working directory; if yes then run it in temporary directory and replace afterwards.

(That could be implemented of course and I understand why would you feel this isn't a simp_le problem -- I don't have a good opinion myself)

I kinda feel like that shouldn't be encouraged anyway, since it requires simp_le having write access to the web server's config

It seems we have a misunderstanding; in NixOS nginx runs with an immutable config which points to a directory for certs (/var/lib/acme/domain.net/fullchain.pem). nginx.service wants self-signed-certificates.service which checks if there are any existing certificates; if not, it generates temporary ones. Then periodically or by manual request acme-certificates.service starts which runs simp_le in /var/lib/acme/domain.net.

zenhack commented 6 years ago

Quoting Nikolay Amiantov (2018-04-17 05:52:26)

[1]@zenhack The problem is that requires detection and special handling of "bootstrapping" phase -- i.e. before running simp_le for a given domain we need first to check if certificates which server currently uses are self-generated ones and if not then run simp_le with certificates directory as working directory; if yes then run it in temporary directory and replace afterwards.

Why not just always do the latter?

abbradar commented 6 years ago

@zenhack Because then simp_le won't detect certificates that don't yet need to be updated (Certificates already exist and renewal is not necessary).

zenhack commented 6 years ago

Quoting Nikolay Amiantov (2018-04-17 14:13:26)

[1]@zenhack Because then simp_le won't detect certificates that don't yet need to be updated (Certificates already exist and renewal is not necessary).

You could, rather than using a temporary directory, just have a designated directory that you keep around, which would still have the old certs in it.

abbradar commented 6 years ago

@zenhack You mean keep workdir with certs (initially empty) and copy them from there replacing actual cert that e.g. nginx uses (which may have been self-generated before)? Good idea, could be done. I'll try to implement this next time we run into problems with current approach (we have now just fixed our self-signed certificates format to be compatible with simp_le).

zenhack commented 6 years ago

Quoting Nikolay Amiantov (2018-04-17 14:29:34)

[1]@zenhack You mean keep workdir with certs (initially empty) and copy them from there replacing actual cert that e.g. nginx uses (which may have been self-generated before)? Good idea, could be done. I'll try to implement this next time we run into problems with current approach (we have now just fixed our self-signed certificates format to be compatible with simp_le).

Yeah, that's what I had in mind.

abbradar commented 6 years ago

Let's close this; I feel it's concluded this shouldn't be implemented in simp_le.

zenhack commented 6 years ago

Sounds good. I opened a separate issue (#106), re: documenting the solution.