Automatically certify local development servers along with remote production servers

@david7364 let’s rewind everything.

What do you actually need?

Installing WinFsp and SSHFS-Win for this feature uses roughly 7 MB of disk space; it is way overkill just to download two files and still requires all the tens of thousands of developers to write or find their own script manually.

I will ask the following question to heed your advice to move in the direction of a fully-specified idea:

How about Let's Encrypt or Certbot supplying everyone with an optional script to download the cert files (for each kind of OS), and Acme and/or Certbot sends the development website a renewal time notice (by calling--doing a POST or GET--to a PHP or other URL in the dev website from the Certbot process)? Then all the developer has to do during setup is download the script. The Acme process would then indirectly cause the local script to download the cert files. This requires no direct secure connection from the Certbot process to the development server, and only the work of writing the script for every OS added (optionally) to every Acme provider, in addition to supporting the renewal notifications.

The certificate isn't enough for a development server to serve a website. You also need the private key, and you have two options: always reuse the same (don't) or move it across servers (unadvisable, so forget about the script being part of a mainstream distribution).

From what I can tell your issue is immediately solved by installing an acme client that uses dns-01 challenges on your development server. This way, your production server gets a certificate for example.com only, and your development server gets a certificate for local.example.com only.

I'm surprised that my OP doesn't make this clear; I tried so hard.

It is bad software practice to develop or debug production websites because it can give a bad visitor experience and can reveal secrets. Thus, the Web necessarily includes development servers (which may or may not be connected to the Internet through a WAN connection).

I need for the Let's Encrypt initiative (which I helped shape in its earliest days) to optionally download the private key and certificate files to an associated development server initially and at certificate renewal time, so that the development server will track the certificate renewals on the production server automatically. This would allow developers to test the wide range of security features locally, using their development servers, before releasing new or updated websites.

This suggestion fits perfectly into the Let's Encrypt mission to make the entire Web secure. The "entire Web" includes most development servers, so they should be specifically included.

Ok, and why is that different from using another Let’s Encrypt certificate with the same characteristics on the development server? (same issuing date, same alg, same keylength, only CN and SAN different.)

I see two problems with this: first, having a separate certificate for a dev server means that security (TLS) internals will be different from the security at the prod server, which may make certain advanced security debugging difficult, and second, this requires the dev server to have an authoritative zone in a DNS and be connected directly to the Internet. This is a big setup burden on some small developers, and requires an active Internet connection which may not be desired for security or other reasons.

I believe that Certbot already can send email when a renewal occurs, and I believe that management tools like cPanel can pass this on, so if nothing else works, at least Acme can include a requirement that a script for every OS be created to download the private key and certificate files when run manually by the developer.

I’m trying to make this as easy as possible, so security descends into development servers as it should.

I don't have the knowledge to answer that question. Someone who knows what kinds of security testing need to be done in a dev environment needs to answer that.

But I am pretty sure that installing Certbot locally on a dev server is a lot more work for the developer, and requires that the dev server have an Internet connection at renewal time. It may also require a DNS authoritative zone for the dev websites, not sure of this.

This is infeasible. There's no way that an RFC can (and should) mandate that someone make a script for every single OS in the world, especially for something as complex as this where configurations can vary wildly.

Also, most ACME clients already have deploy and post deploy hooks to move certificates around wherever you need them.

Nonsense. Acme itself gives a specification that must be implemented on every single OS if Let's Encrypt is to fully meet its mission. If Certbot, for example, runs on most OSes, then why can't it provide a separate script to update cert files on dev servers? It can't be that hard to write for an expert.

Many production websites use management tools like cPanel that are not likely to support the use of Acme client hooks.

We can go back and forth on this, but the end is, this won’t ever happen. Tools already exist that allow you to do what you want to do with minimal, albeit some effort.

If that were true, then most dev websites that mirror prod websites would have already implemented automatic certificate update upon Let's Encrypt renewal for the prod website (even when cPanel is used), and I highly doubt that this is true. I have not been able to create such software for my dev server, and I have years of experience doing Web programming (which does not make me an expert!).

I challenge you to prove what you claim: to specify in detail this supposed minimal effort way to do what I have described. It should run automatically, take only a few minutes for the average developer to create or configure, and not install any software of significant size on dev servers. If I could have done that myself, I would have, and used what I created as an example of how Acme should be extended.

That's because ACME is a protocol for an API and validation methods for certificate issuance. The actual implementation of said API and other stuff like validation methods is all up to the developer, which can be any OS. Also, how anyone actually uses that certificate, is all up to the user/developer of an ACME client.
Also, Let's Encrypt cannot and will not issue hostnames for which there is no validation. So even if you'd say: "Couldn't an ACME server just issue an extra hostname with an added local sub(sub)domain for every certificate issued?" then the answer is NO, not without actually validating that hostname. That's just the rules of the CA/B Forum baseline requirements.

Because every dev setup is different? How can one client know where to put that extra certificate? Perhaps, to humor me, could you explain how your local dev setup is? And how your production setup (where your certificate is now) is?

That's basically what I said.

The developer knows! So the developer can configure this new script where to put the dev server copy of the prod server cert files.

Sure. My local dev setup is a standard Windows Apache server. It is configured with the usual "VirtualHost" directive representing each website that has a corresponding remote prod website.

As part of a virtual host configuration, Apache is given several directives, including "SSLEngine on", "SSLCertificateFile pathname/local.example.com.crt", and "SSLCertificateFile pathname/local.example.com.key". These paths never change, but their file contents must change with every Let's Encrypt renewal of the corresponding remote prod website certificate.

I forgot to answer the last part of your question. All my prod websites are hosted commercially using an Apache server which is managed by cPanel running under Centos (Linux), all on a VPS. cPanel includes support for Let’s Encrypt certificates, I think through a plugin.

So now you've got a Linux production with a Windows local development setup? And you're worried about tiny security differences caused by two separate certificates (which can be nearly identical by the way..)?

Also, it would mean your CentOS dev system needs to have an "entry point" in your Windows system. Your Windows system would need to be able to "accept" the dev-certificate issued by the prod system. How would the prod system do that? Upload the file through a FTP server you run on the Windows server? Use a special designed SMB share? Can Windows run a SSH daemon, so you could use SCP? There are soooooooooooo many possibilities which cannot be included in "a single configurable script" in my opinion.

In any case I think this is not something the certbot team would have very high (if at all.....) on their priority list. But you're always welcome to script it yourself! Certbot is Open Source Software after all..

2 Likes

I'm not following you. My Windows system has for years accepted the Centos cPanel certificate files that I manually downloaded. Certificate files have a standard format (fortunately), so my "local.example.com" trick described above works perfectly. What I'm suggesting is that updating these files should be done automatically, without each of the tens of thousands of developers spending weeks each figuring out how to do it.

I agree. That is why I suggested by this posting that a requirement be added to Acme. I think ALL of the Web should be secure, not just prod servers, especially for those dev servers that connect to the Internet.

This thread has run its course; posts have elaborated on the feature request, and there’s no more to discuss about the details without things getting more contentious. Thanks for your participation!

2 Likes

Hi,

I’m late to this thread, but I will take the moderator’s privilege and have the last word because I think I have some good answers.

The problem of trusted certificates for local development is a real one, and it’s a pain. I’ve written about it at https://letsencrypt.org/docs/certificates-for-localhost/. Since then, Filippo Valsorda wrote an excellent tool called mkcert. It autogenerates a self-signed certificate and takes care of the hassle of setting up your local operating system to trust it just like a CA-signed certificate. That’s my current recommendation for solving this problem.

There were a couple of themes that came up in this thread: Let’s Encrypt and other publicly trusted CAs can’t issue for the name localhost, but that’s not a problem with @david7364’s approach. Separately, it’s possible for a subscriber to create a hostname that resolves to 127.0.0.1, and get a certificate for that, as @david7364 does here. That doesn’t violate the BRs, and if it works for you, great.

One important caveat is that some companies have taken that approach (domain name that resolves to 127.0.0.1) and used it to issue a certificate for a private key that they ship in client software: example1, example2, example3. That’s a problem because the private key then becomes compromised and the certificate will be revoked. However, that doesn’t seem to be at issue here.

I do consider improving the situation for certificates on localhost to be part of Let’s Encrypt’s mission, broadly considered. Easy and accurate local development of HTTPS sites is important for the deployability of HTTPS generally. I appreciate the suggestion here to improve scripting components, but we don’t plan to go that direction. The best path for improving the situation is broader use of tools like mkcert, and ideally building them into packaging for software like Apache and Nginx. If our engineers have time we may reach out to the relevant packagers - but I would also encourage folks from this community to do so if you are so inclined.

By the way, you mentioned Caddy, so you’ll be interested to know: Caddy automatically issues and serves a locally-trusted, self-signed certificate for localhost. It sounds like it may be a great fit for your use case!

Thanks,
Jacob

4 Likes