_o/ author here! mkcert is definitely my most popular tool, and it's always a delight to see how it makes developers' lives easier and how happy they are about it <3
Something that I wonder about from time to time is how "done" is mkcert. A lot of its value is in simplicity, so I've rejected attempts to make it more of a toolkit to generate all sorts of certificates (although I see the value in being able to edit the expiration and other fields). The only thing on my TODO is splitting the trust stores out into an importable package for other tools to use. Maybe that will act as a release valve for other use cases.
In a sense, mkcert will never be done because its job is also to keep up with browser requirements for you, but that goes in waves, and not much has changed in the last couple years. (Unlike the first years of mkcert, when things were really a moving target.) Similarly, it has to keep up with new trust stores and ways to install into them, and we might be overdue for a pass of that, but these are not really new features, just maintenance.
No matter what I work on and how complex, mkcert is always there for my dev environment. In combination with cert-manager's CA support[0], even TLS for Kubernetes development environments is simple as it gets.
Thanks for this tool! I found it when Apple started enforcing stricter requirements for certificates, and the commands I was using to create certificates at the time had become inadequate. I have since used mkcert to generate dozen of certificates for my local network, which work on any service and device.
The only drawback of mkcert is that it makes you forget the steps needed to make a certificate!
Thanks you for making it and keeping it simple. I agree that the simplicity is what makes it great to use for localhost testing. Big fan of this tool since I found it.
I've used this in the past and it has been very convenient! Thanks Filippo!
Having said that, nowadays I just bring up a local caddy instance and use that. Caddy can set up and use a local CA for development/testing [1]. In my case I'm using caddy on my little public-facing hobby server anyway, so it's convenient to have a similar setup in local dev. If I cared about actually getting at & directly using the certificates myself I'd probably go back to mkcert.
For local (GUI!) tools I find XCA (https://hohnstaedt.de/xca/) excellent. It has a few ready to fo templates out of the box, and you can make your own.
It's pretty good for having your own simple CA, self signed certificates or anything of the sort, as well as having a nicer interface for anything that's not one of the ACME providers (e.g. Let's Encrypt) or when you don't need CLI or automation.
Does anyone know of something that is meant for production use for generating in-house certificate authorities and signing certificates?
I've used scripts I've written myself that run OpenSSL commands. They get the job done, but they're not the kind of thing that fits all use cases, and they're not user-friendly.
I've tried EasyRSA which is not particularly easy either. It requires some unexpected use of environment variables, and I didn't find the documentation very clear either.
Hashicorp Vault is an obvious one. Microsoft Active Directory Certificate Service is another.
If you're looking for a service-oriented offering, maybe think about Keyfactor, Venafi ... do you already have a PKI that you need to integrate with, etc?
Intuitively this seems reasonable, but, as a sense check I want to put the other side: Not necessarily with the goal that you change your mind, but that you didn't end up just doing what was intuitive without weighing the options.
The public CAs are run pretty well, and they have people actually overseeing them to verify that remains so, without you lifting a finger (well, unless you'd like to help oversee them at least). In contrast a local CA is very likely to be poorly run, because it's not really anybody's actual job to do it properly, you can't justify the expense [If you're Google, then, sure, you can justify the expense but also you are not asking about this on HN] to train them, they can't afford the time and effort to do their best work.
The public CAs are almost certainly not going to lose their root private key, if bad guys do steal the root key for a CA, it'll make news and also you almost certainly aren't the target, in contrast the root key for your private CA probably lives on somebody's laptop (which can be left on a train) or a server somewhere.
There's good tooling for the public CAs. Your software might already come ready to use ACME, and if it doesn't you will find instructions pretty easily. In contrast although there are technology stacks for this stuff without the public CA context, they're not as widespread, particularly in Free Software, and you may find if you need certs for five systems that means five separate tools. Or you do it manually which sucks.
Everything already trusts the public CAs. It's not difficult to tell Mac OS, Windows or even a Linux distro to trust some root CA, but it's an extra step to be done and if you forget it may be difficult to figure out why things don't work. For some services that's enough, but if you also want BYO devices to work that's a nightmare, likewise for guest devices.
Names will almost certainly leak anyway. If your goal is to hide the fact secret-project.example.com exists, I strongly recommend instead changing it to some-codename.example.com so that you needn't care much if the name leaks.
None of the above makes mkcert a bad idea - mkcert is for development. But you should weigh this when deciding whether internal-git-server.mycorp.example should just use Let's Encrypt certificates rather than spinning up an internal only CA.
We use this with vite-plugin-mkcert to provide https localdev with just the installation of mkcert from homebrew. Wayyyy simpler than any other method of providing localdev https.
Dumb question alert; can these certs be repurposed to sign windows binaries for running locally?
Depending on the environment, windows can be set to prohibit executing anything that isn't signed....which is annoying on a dev machine building windows executables.
Even if not explicitly set that way, I found that windows security can intermittently end up blocking unsigned stuff, which if anything is even more annoying than a consistent rule. Had this problem when trying to make a python gui executable.
Is this really needed for the "localhost" name? I understand the need for this because a lot of people create multiple local services with specific names other than localhost, so it would be flagged as not being secure?
I really enjoy this tool making it easier, combined with dnsmasq and nginx, to spin things up in whatever custom local tld I want with a secure and trusted development certificate
Have you actually tried doing this? It's an absolute nightmare. I tried creating SSL test certs for my websockets implementation and just gave up because I just couldn't get them working with my libraries SSL stream implementation.
It's not just arcane it's a horrible idea from an infosec perspective. Thinking about all my wonderful developers having local trusted root CAs just sitting on their hard drives is making my blood pressure skyrocket.
I have it boiled into a few shell scripts that generate the cnf files needed. OpenSSL has improved its CLI beyond the old Perl script that had long been used for running a local CA and you get fine grained control over what features you want.
Could you elaborate? Where is it missing support for Python? It just generates TLS certs for local use, and where would Cygwin, npm (a package manager), and Emacs (a text editor) even figure in any of this?
I guess this is mostly for generating localhost certs, that was not what I thought you needed this for. I was listing stuff that is a problem with running your own CA, so mainly if you are unlucky enough to be behind a enterprise proxy. I.e. how to import trusted certs everywhere.
I can not remember how and where you need to install these certs, but it just about finding where different applications store their trust stores. Lots of them have their own solutions.
Npm has an option in the config that allow you to choose your own ca location.
That has little to do with supporting specific languages and environments though, and more to do with those languages not have a good method to do CA installation. I have no idea about Node.js, but Python will just use the regular trust store for the OS, because it's all just OpenSSL under the hood.
Your problem isn't with mkcert and mkcert isn't missing support for anything, but with there not being a good, universal way to manage trust stores. That's an independent issue that mkcert can't fix.
Something that I wonder about from time to time is how "done" is mkcert. A lot of its value is in simplicity, so I've rejected attempts to make it more of a toolkit to generate all sorts of certificates (although I see the value in being able to edit the expiration and other fields). The only thing on my TODO is splitting the trust stores out into an importable package for other tools to use. Maybe that will act as a release valve for other use cases.
In a sense, mkcert will never be done because its job is also to keep up with browser requirements for you, but that goes in waves, and not much has changed in the last couple years. (Unlike the first years of mkcert, when things were really a moving target.) Similarly, it has to keep up with new trust stores and ways to install into them, and we might be overdue for a pass of that, but these are not really new features, just maintenance.
Previously:
Mkcert: Tool for making locally-trusted development certificates — https://news.ycombinator.com/item?id=17748208 — Aug 2018 (39 comments)
Show HN: Mkcert – Valid HTTPS certificates for localhost — https://news.ycombinator.com/item?id=18842218 — Jan 2019 (118 comments)