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.

Boulder

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 acme.sh, 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 https://github.com/letsencrypt/boulder/ $GOPATH/src/github.com/letsencrypt/boulder
cd $GOPATH/src/github.com/letsencrypt/boulder
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 acme.sh. A request for a certificate using acme.sh can look like this:

./acme.sh/acme.sh --issue -d suitecrm.office.nic.cz -w /home/letsencrypt/webroot/ --server boulder.office.nic.cz:4000/directory --force --log --debug 2

In case of success, we will see an output like this one in acme.sh:

[Wed Nov 15 08:50:54 UTC 2017] Single domain='suitecrm.office.nic.cz'
[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='suitecrm.office.nic.cz'
[Wed Nov 15 08:50:55 UTC 2017] Getting new-authz for domain='suitecrm.office.nic.cz'
[Wed Nov 15 08:50:55 UTC 2017] The new-authz request is ok.
[Wed Nov 15 08:50:55 UTC 2017] suitecrm.office.nic.cz is already verified, skip http-01.
[Wed Nov 15 08:50:55 UTC 2017] Verify finished, start to sign.
.acme.sh/acme.sh: line 1819: warning: command substitution: ignored null byte in input
[Wed Nov 15 08:50:55 UTC 2017] Cert success.
-----BEGIN CERTIFICATE-----
MIIElDCCA3ygAwIBAgITAP/EllXr6rPY9+ylrIZbhjKyzzANBgkqhkiG9w0BAQsF
ADAfMR0wGwYDVQQDDBRoMnBweSBoMmNrZXIgZmFrZSBDQTAeFw0xNzExMTUwNzUw
NTVaFw0xODAyMTMwNzUwNTVaMFAxHzAdBgNVBAMTFnN1aXRlY3JtLm9mZmljZS5u
aWMuY3oxLTArBgNVBAUTJGZmYzQ5NjU1ZWJlYWIzZDhmN2VjYTVhYzg2NWI4NjMy
YjJjZjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMtGFyrFlcxWrmuK
BpNz4Q7UztwlOCGpkKLDTSkAVCvxAvuywudk4SJVjWYfQrB0XOaElXy+qjAmZ8Ww
B1zj2icMoBhi8LMQ3Fbu6Yd+dGrVrFVVRBOjiA6Pwm9AxsXniCfD4SSdlt9OierW
apLNRcmtEDfaz7iUHs+G87B5Dv80jTQIJ26rkpXx6HR9KB9KXE8nXUKMiT0C6jhQ
1DD4sz2GihVpXt9WbwDbaSZhU+28TUBmmiR6VCYlwR/SfpdGVqqNz2XBFy+P0/0a
4V1bWmBo57OClNab4DPdE2mdr907nW0chjErhIZn/lUtyqaB3VxxQsbH8y123hzB
/r7sNfcCAwEAAaOCAZYwggGSMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggr
BgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUgkogatL3
06DoEOAq8tyqjhUMPo0wHwYDVR0jBBgwFoAU+3hPEvlgFYMsnxd/NBmzLjbqQYkw
ZAYIKwYBBQUHAQEEWDBWMCIGCCsGAQUFBzABhhZodHRwOi8vMTI3LjAuMC4xOjQw
MDIvMDAGCCsGAQUFBzAChiRodHRwOi8vYm91bGRlcjo0NDMwL2FjbWUvaXNzdWVy
LWNlcnQwIQYDVR0RBBowGIIWc3VpdGVjcm0ub2ZmaWNlLm5pYy5jejAnBgNVHR8E
IDAeMBygGqAYhhZodHRwOi8vZXhhbXBsZS5jb20vY3JsMGEGA1UdIARaMFgwCAYG
Z4EMAQIBMEwGAyoDBDBFMCIGCCsGAQUFBwIBFhZodHRwOi8vZXhhbXBsZS5jb20v
Y3BzMB8GCCsGAQUFBwICMBMMEURvIFdoYXQgVGhvdSBXaWx0MA0GCSqGSIb3DQEB
CwUAA4IBAQCpnzAwWLu+sfl04PrPaSJU5wBAGfEbpyk+qq/MOp425zLeqdOqH+AA
8Wu55oTF1u70EQPqFSZ1dWiyGiE/OrCTXVt41sJuojEWWG4DFeBTCL4cGm6JOFjd
/9LFQMUG6zCZiYNT1K0dps1AEMSyGt5tGS3he5uXjhyxGvaicjo/6rZ5bo/xKfez
jZBEZLYh5ig2gd2Jz3kDmWGwIt89kqjtewQsNk6hOPvMJx5EaWtIYX0SesHiSnF/
YqkDvvxOPiifJP/e7ArHi91H/5yX0mVR90NXp+BWMkck0qQRybx4vHxrfSoSsWAa
6mmrKcaJMhJ7wWuOFoja82oTSQNB1QaX
-----END CERTIFICATE-----
[Wed Nov 15 08:50:55 UTC 2017] Your cert is in /home/letsencrypt/.acme.sh/suitecrm.office.nic.cz/suitecrm.office.nic.cz.cer
[Wed Nov 15 08:50:55 UTC 2017] Your cert key is in /home/letsencrypt/.acme.sh/suitecrm.office.nic.cz/suitecrm.office.nic.cz.key
[Wed Nov 15 08:50:55 UTC 2017] The intermediate CA cert is in /home/letsencrypt/.acme.sh/suitecrm.office.nic.cz/ca.cer
[Wed Nov 15 08:50:55 UTC 2017] And the full chain certs is there: /home/letsencrypt/.acme.sh/suitecrm.office.nic.cz/fullchain.cer

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/github.com/letsencrypt/boulder/test/test-ca2.pem

Conclusion

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 acme.sh 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.

Author:

Leave a comment

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