Your Own Certification Authority in a Letsencrypt Style

Have you ever thought of automating the certificate issuing in your organization’s internal certification authority? How about using the same procedure as in Let’s Encrypt and the ACME protocol, while enjoying all the benefits ACME has to offer? The possible solution is to use Boulder. I will now try to break down for you the Boulder’s installation process and the pitfalls that I encountered during the setup.


What is Boulder? I think the annotation on github is very concise, so I will quote it here:

“This is an implementation of an ACME-based CA. The ACME protocol allows the CA to automatically verify that an applicant for a certificate actually controls an identifier, and allows domain holders to issue and revoke certificates for their domains.”

Now let’s try and see ACME differently. If we look deeper into the configuration file of some of the ACME clients, for example, we will probably see a variable linking to a remote Let’s Encrypt server. It is very likely to be this server. If you were impatient and clicked on the link, by now you’re probably aware that Boulder is a special API that firstly makes sure that you are an administrator of the machine or domain, and secondly, allows you to issue certificates signed by the authority running within the Boulder server.

Boulder’s internal structure revolves around four types of objects: registration, authorization, challenge, and certificates. The components in the Boulder model are named in the same way as in the ACME protocol.

Boulder is written in the Go language and is pre-configured to be launched with Docker. The launch is not complicated, all you need is enough space, installed Docker, and the git and docker-compose packages. According to the manual, you need to set the variables, clone the repository, set the FAKE_DNS variable, and then run the docker-compose that will build Boulder.

mkdir ~/gopath
export GOPATH=~/gopath
git clone $GOPATH/src/
cd $GOPATH/src/
docker-compose build
docker-compose up

If everything is set correctly, the docker-compose will report in triumph:

boulder_1 | All servers running. Hit ^C to kill.

On the server with Boulder running, Boulder web interface should be listening on port 4000.

Issue of certificates

Certificates can be issued in a similar way as with Let’s Encrypt. If we are going to authenticate the server using HTTP instead of DNS, a correctly set up proxy for the .well-known challenge will come in handy. To issue the certificate, we will need one of the Acme clients, e.g. acme-tiny or A request for a certificate using can look like this:

./ --issue -d -w /home/letsencrypt/webroot/ --server --force --log --debug 2

In case of success, we will see an output like this one in

[Wed Nov 15 08:50:54 UTC 2017] Single domain=''
[Wed Nov 15 08:50:55 UTC 2017] Getting domain auth token for each domain
[Wed Nov 15 08:50:55 UTC 2017] Getting webroot for domain=''
[Wed Nov 15 08:50:55 UTC 2017] Getting new-authz for domain=''
[Wed Nov 15 08:50:55 UTC 2017] The new-authz request is ok.
[Wed Nov 15 08:50:55 UTC 2017] is already verified, skip http-01.
[Wed Nov 15 08:50:55 UTC 2017] Verify finished, start to sign. line 1819: warning: command substitution: ignored null byte in input
[Wed Nov 15 08:50:55 UTC 2017] Cert success.
[Wed Nov 15 08:50:55 UTC 2017] Your cert is in /home/letsencrypt/
[Wed Nov 15 08:50:55 UTC 2017] Your cert key is in /home/letsencrypt/
[Wed Nov 15 08:50:55 UTC 2017] The intermediate CA cert is in /home/letsencrypt/
[Wed Nov 15 08:50:55 UTC 2017] And the full chain certs is there: /home/letsencrypt/

In the issued certificate we can see that the certificate issuer is a testing authority named:

CN=h2ppy h2cker fake CA

In the sources of Boulder itself, you can find this authority in this path:

openssl x509 --text -in ~/gopath/src/


I think Boulder is an interesting software that will surely find its way across the Linux community, and be appreciated by many people, even though it is a relatively new project.

However, what it is missing, in my opinion, is the necessary documentation, without which the necessary further actions — typically, replacing of the testing internal authority with another one — are left to improvisation or communication with developers. However, as far as communication is concerned, my experience with the developers is utterly positive. For example, the author of the script corrected my bug in the matter of hours and a Boulder developer responded to my comments in the bug-tracker. It is evident that the authors themselves want to know how their software is used, and they are not indifferent to its fate.

In addition to the documentation, a “best practice” would be useful, such as whether Boulder can be internally secured to ensure that the certificates cannot be issued by everyone, or how to handle with intermediate certificates.


Leave a comment

All fields are required. Email won't be shown.