For my first hackweek, I joined forces with Klaas to work on a LetsEncrypt integration for openSUSE. So we went to create yast-acme. Too many acronyms already? Alright, let’s start with…
The Elevator Pitch
“Imagine setting up encrypted websites and services was as simple as setting up your web server. Our aim is to provide that simplicity in openSUSE.”
This will take some dry background, please bear with me: Until recently, encrypting websites, mail traffic, etc through TLS certificates was a pretty painful process: You either had to purchase a certificate from a Certificate Authority such as Comodo, GoDaddy, Symantec, and others. Their job is to verify that you are in posession of the hostname (e.g. www.mydomain.com), and only issue a certificate if that is the case. In return, they are demanding a (sometimes pretty hefty) fee. That’s because they underwent procedural and technical audits to be accepted in the major browsers, but also e.g. Java. Members of this exclusive club can issue different kinds of Certificates, we only care about Domain Validated (DV) ones. Other forms include Extended Validation (EV), where CAs actually check Company Records and take more effort. This is however not important for most website owners.
On top of being expensive, some CAs have shown that even though they are making good money, recently incidents have shown that the reputation of a “Notary” is not warranted. We have seen everything: bugs in the validation process, gross technical incompetence and even deception. The latter has caused all major browser vendors to distrust the Root Certificates of WoSign and StartCom, both of which have been issuing free Certificates (although at least StartCom charged a fee for identity validation). And every year or two, certificates need to be swapped for new ones, which means spending more money and effort just to get your communication channels secured.
Whoever refused to go that way either had to create a custom CA, and publish the Certificates to all their users/employees, or ship a so called self-signed certificate. Both can (rightfully) lead to pretty scary browser warnings.
The web has been idling in this state until Edward Snowdens’ relevations made is clear that the unencrypted web is dead. However, it was clear that if ubiquitous encryption was to succeed, a new approach would be required. So Mozilla and the EFF, along with several commercial Sponsors created the non-profit Internet Security Research Group (ISRG). IRSG in turn runs LetsEncrypt, a new CA that provides proof-based certificates through the ACME protocol. Contrary to previous approaches, ACME requires a proof of (administrative) ownership of the actual host (more specifically: Port 80), which is a much stronger proof than just ownership of any email address associated with a domain name (e.g. retrieved through whois records). At the same time, this process is repeatable, allowing for automatic renewal.
Finally, the beauty of ISRGs efforts is that both client and server implementations are open source, so anyone could start an ACME-based CA (of course, they would still need to get their root certs accepted by the browser vendors).
Acquiring a Certificate through ACME
In essence, ACME clients first create an account, i.e. registers with LetsEncrypt. Optionally, it’s possible to provide an email address. It will be used by the CA to warn about expiring CAs in case the automatic renewal has failed. For both initial issuance and every renewal, a challenge-response protocol is performed via HTTP on port 80. The LetsEncrypt CA will verify that an agreed-upon token is available in .well-known/acme-challenge. If this succeeds, it will issue the certificate for the requested domain names.
Implementing the ACME protocol ourselves was out of scope for this project. Mostly because there already are quite some client implementations. So the first task was to pick an implementation that was concise, suitable and simple to package. Certbot, the official client currently developed by EFF is a dependency hell. Remember, we want encryption to become ubiquitous. Then there is acmetool, which has quite some nice features. Unfortunately, it is written in Go, which is notoriously hard to package. So we went with dehydrated (formerly “letsencrypt.sh”), which only depends on bash, openssl, curl and diff.
Even before hackweek 15 started, I had started to package up dehydrated for openSUSE (and SLES, and other RPM based distros). Thanks go to Roman Drahtmüller and Darix for improvements.. This includes providing default location handling for .well-known/acme-challenge for Apache (and nginx/lighttpd with limitations).
Through the course of the hackweek, we added a JSON-based status output, which might go upstream after some cleanup.
Next was a Yast-Interface for requesting and managing certificates. The real challenge was that neither Klaas nor I had done Yast hacking before, so we knew nothing about YCP widgets, the ecosystem, etc. Also, my Ruby knowledge was really rusty, and Klaas had never done any Ruby before. But nothing can stop a fearless Perl-Veteran! Also, the Yast module tutorial proved truly useful to get started.
Can be found in this OBS repository. It contains a patched dehydrated, along with the yast(2)-acme module. The module can be used to request certificates.
The Work Ahead
The Yast ecosystem turned out to be a bit more complex than anticipated. Since we had to start from square one in a few places, there is much to be done to make this a really smooth experience:
- Account Setup
- Integration with e.g. the yast-http-server and yast-mail modules
- Certificate revocation
- Auto tests
- Provide a stub responder on Port 80 in case no web server should be installed
However, with the initial success we plan to pursue this project after hackweek. I hope you will join us. Please get in touch with either me or Klaas.
The FAQ: Why not call It Yast-LetsEncrypt?
After Comodo tried to register a trademark for LetsEncrypt, ISRG had to start protecting its trademark. Hence they cannot allow any non-official project to use the name “LetsEncrypt”. This is why we resorted to “ACME”, the name of the protocol.
Just a note to the “Provide a stub responder on Port 80 in case no web server should be installed” item: Ruby contains a bundled web server, if you need just to serve static files than it can be done with a trivial “ruby -run -e httpd . -p80” command.
Hi, thanks for this post, which helps make things clear about the Let’s Encrypt ecosystem, and how its approval process works. It also makes me want to give a look to OpenSuse again 🙂