If you did not know yet, I’m a huge fan of Let’s Encrypt, however, we need to give them some slack, they only publicly announced 1 year, 2 months, 26 days, 18 hours and 13 minutes ago. In that time they created the entire backbone, code and structure to start giving out validated certificates, for free. They currently have a beta sticker on still, and I do agree, there github account is still very active with over 150 contributors pitching in. The official client however has many dependencies, that many in fact that Centos 6 has only recently been supported. But what about Centos 5 ? or older Ubuntu LTS ? or any other Linux Distro ? What about when my apps are using a not supported python ? Well that is where the Linux community shines most, someone thinks I can do this different and so Lukas Schauer (personal website) created a super tiny (821 lines) low-requirement shell script called dehydrated. I still have little experience when it comes to certificates and https in general, but getting you’re visitors a encrypted line to visit is now easier then ever !
Requirements
Most Linux distro’s will have this already installed, so this should not make a problem. I’m using a Centos 32bit VPS for this example, but this should be doable for pretty much any Linux distro.
yum install nano wget curl sed grep mktemp git
That’s it, for me only nano and wget had to be installed on a Centos minimal! (note : nano or …)
Installation
Its a bash script! Either download and chmod or download the entire package using git.
cd /opt git clone https://github.com/lukas2511/dehydrated.git cd dehydrated/
Configuration
You could run everything from console, but for automation it might be a good idea to configure it in a script itself. For that purpose it uses a file named config.sh. There is also a file domains.txt for the domain names. I copied the example :
cp docs/examples/config config.sh ln -s config.sh config
In config.sh remove the # (hashtag) from all value’s, the defaults should work well. The only exceptions are :
WELLKNOWN="/var/www/dehydrated"
and (change the e-mail address in to a working one!)
CONTACT_EMAIL="my.working@email.tld"
Now we need to create a file /opt/dehydrated/domains.txt there you need to add domain names you wanne get a certificate for. I tested it with one subdomain :
test.svennd.be
and that worked, however if you want multiple use :
svennd.be test.svennd.be alfa.svennd.be
Would validate svennd.be, test.svennd.be and alfa.svennd.be in one certificate, (as alternatives) You can also read up on the github,
That’s it for configuration!
Setting up the environment
For this server I am using Apache, you will have to find how to get this working with others webservers.
First make the directory (WELLKNOWN) we have used in the configuration :
mkdir /var/www/dehydrated/
warning : using /home as WELLKNOWN might give problems on a default Apache installation. (you would need mod_userdir)
On a clean install this was the config I used, most likely parts will already be there: (read comments)
# allow multiple hosts on 1 IP NameVirtualHost *:80 <VirtualHost *:80> # documentroot DocumentRoot /var/www/html # servername ServerName test.svennd.be # vital : Alias /.well-known/acme-challenge /var/www/dehydrated/ # this might not be needed <Directory "/var/www/dehydrated/"> Header add Content-Type text/plain </Directory> </VirtualHost>
Restart apache with service httpd restart
, and then go ahead and create you’re certificate!
Creating a certificate
Now getting to the easy part, getting the certificate :
./dehydrated -c
This should result in something as :

Let’s Encrypt the web, this is where my https story began!
This will generate :
├── certs │ └── domain.tld │ ├── cert.csr │ ├── cert.pem │ ├── fullchain.pem │ └── privkey.pem ├── config.sh ├── domains.txt ├── dehydrated ├── LICENSE ├── private_key.pem └── README.md
From there you could just use this tutorial for adding it to apache.
Troubleshooting
During the testing I made some errors, you might encounter them as well.
Challenge invalid
ERROR: Challenge is invalid! (returned: invalid) (result: {"type":"http-01","status":"invalid","error":{"type":"urn:acme:error:unauthorized","detail":"Invalid response from http://domain.tld/.well-known/acme-challenge/[]: 500"},"uri":"https://acme-v01.api.letsencrypt.org/acme/challenge/","token":"","keyAuthorization":".-","validationRecord":[{"url":"http://domain.tld/.well-known/acme-challenge/","hostname":"domain.tld","port":"80","addressesResolved":[""],"addressUsed":""}]})
This happened for me when the directory was not accessible. Settings where wrong, be sure to test it with creating test files (touch /my/.well-known/test.html) and then hitting them on the webserver.
No registration exists matching provided key
./dehydrated --cron # INFO: Using main config file /opt/dehydrated/config.sh Processing domain.tld + Signing domains... + Creating new directory /opt/dehydrated/certs/domain.tld ... + Generating private key... + Generating signing request... + Requesting challenge for domain.tld... + ERROR: An error occurred while sending post-request to https://acme-v01.api.letsencrypt.org/acme/new-authz (Status 403) Details: {"type":"urn:acme:error:unauthorized","detail":"No registration exists matching provided key","status":403}
This weird one happened when 1) I did not enter a valid e-mail address and 2) an e-mail adres that was used by another domain.
Conclusion
While the official method surely should be default, due to the way ACME is setup, Let’s Encrypt allows for other clients, one of these is a very simple shell script, and that works in even the most variable environments. A big thanks to lukas2511 and Let’s Encrypt for making this possible! Happy Encrypting !
Changes :
- Letsencrypt.sh has been renamed to dehydrated for legal reasons.
- Slightly adapted the guide to reflect where config.sh comes from, also renamed some old letsencrypt.sh references to dehydrated. (13/03/2017)
[…] Note : There are alternatives ways of getting lets encrypt to work in non-default environments, one is described in my new article : Let’s Encrypt on … any Linux distro […]
Awesome ! Thanks for this. I was struggling with official repository and my CentOS 6.7 x86_64. They are not compatible because the packaged Python is 2.6 (2.7 is required by CentOS).
In your example, note that letsencrypt.sh does work with /opt/letsencrypt.sh/domains.txt if $BASEDIR is not set in config.sh
As I wanted my certs to be stored in a dedicated directory (modding config.sh’ $BASEDIR), I had to put domains.txt into this same dedicated directory.
Ah, interesting ! I also got it working on Centos 6 with the official repo : https://www.svennd.be/lets-encrypt-with-centos-6/
Glad you joined the encrypted part of the web !
In config.sh remove the # (hashtag) from all value’s
i can’t find the config.sh
someone to help
Under examples there is an example “config” file, I linked it as “config.sh” see : https://github.com/lukas2511/dehydrated/blob/master/docs/examples/config
what about mkdir /var/www/letsencrypt/
what after creating this
sorry im beginner
You need to adapt the Apache configuration, to allow WELLKNOWN directory to be used. I slightly adapted the article so its a bit more clear, although letsencrypt has been renamed dehydrated.
Also this guide is pretty dated, right now certbot (the official Let’s Encrypt tool) works pretty nicely, maybe you can try that ? https://certbot.eff.org
btw, we are all beginners, no need to point out, this guide was unclear you should say so 🙂
good luck
im trying to install passbolt in centos6 can you help on this
how to installit or somthing like that or can share with me some steps to complet it
I installed Passbolt on Centos 7 recently https://www.svennd.be/installing-passbolt-on-centos-7/ the steps should be similar in Centos 6.
[…] my own guide with dehydrated and Cloudflare, in case you don’t use Cloudflare, you could use this guide or one of the other installation methods I have written in the past. Whatever method you chose, […]