I’m trying to figure out how to generate a cert beforehand so the new webserver comes up as HTTPS immediately and not after a few hours of LE configuration/openssl/etc. I can’t enable port 443 on the existing ISP-hosted site, so figured I had to wait until the migration is complete and DNS gets updated to generate the certs. But I have full control over the new boxes and can enable port 80/443 on them to the public–but of course DNS is still pointing to our ISP-hosted site.
I guess I don’t fully understand the cert process yet. Does LE validate the directory hash file over port 80 or port 443?
With the Let’s Encrypt service, there are a few supported ways you can complete validation. The most common is over port 80 (http-01), but there are also methods for port 443 (tls-sni-01), or via DNS.
If you need a certificate before you switch. your best bet would be to use the DNS verification method, as you don’t need to worry about updating any A or CNAME records for it, and instead need to add a TXT record that will verify you.
Alternately, if you have the ability, you could set up a redirect on your existing server to make any request for the /.well-known/* path redirect to your new server and use the http-01 verification. There are some nice community-developed tools like letsencrypt-win-simple that work well with IIS in that case.
Unfortunately the new server is not publicly accessible yet. I played with the letsencrypt-win-simple client for a while using the “–test” param, and found another problem: my current ISP doesn’t give direct access to the load-balanced public-facing web servers, instead I have to FTPS my content to their “staging” server which runs a process every five minutes that mirrors the staging to all of the public servers.
I tried to manually upload the created challenge file but of course it changes every time I run the letsencrypt-win-simple process, so I can’t seem to find a way to get that file out to the public server for validation by the simple client.
So I’ve been playing with the ZeroSSL CLI for Windows and it seems to do the same thing the letsencrypt-win-simple client does: in an unstoppable process it creates the cert request and writes it into the .well-known directory and then tries to have the server validate it.
Is there no way to generate a cert and then separately ask a CA to validate it manually?
Not really. The closest X.509 equivalent is the certificate signing request (CSR), a document that indicates what certificate you would like to have. However, every CA will respond to a CSR by issuing a certificate that it constructs itself based on (at least some of) the information in the CSR.
For Let's Encrypt, you can use a CSR, but in any case a precondition for issuance is proving your control over the domain names for which you're requesting the certificate is passing one or more ACME challenges for each name.
It is only "unstoppable" if you use --path option. If you don't, it actually stops and tells you that you need to create a file with a specific name and content. Both are printed out on your screen and the process will continue only when you press Enter. Once you do that, the process will "ask" LE servers to check the challenge file(s). So you can create the file on your other server "manually" as you wanted (if I got what you were saying right).
If you meant "generate a file and then separately ask a CA to validate it manually", that would be what I described above. "Generate a cert" in this context doesn't quite make sense. Just in case you meant CSR in all that, there is also a --generate-only option that stops after keys and CSR are created, without running any further process And finally there is --handle-as dns as @schoen pointed out, which will tell you to create a DNS record for verification and again will be waiting for your input before asking LE to check one.