In the ‘good old days‘ where everyone was a hippy and everyone trusted the other person to do the right thing, encryption was not on the table. We used telnet to login to remote servers, we transferred files from and to FTP servers in the clear, we surfed the nascent WWW using http:// links; there were no pay-walls; and user credentials, well who’d ever heard of those, right.
Now we live in a time where every government spies on you, fake news is the new news, presidents lead their country as if it were a mobster organisation and you’ll go to jail – or worse – if your opinion does not agree with the ruling class or the verbal minority.
So naturally everybody wants – no, needs – to encrypt their communication on the public Internet nowadays.
Lucky for us, Linux is a good platform for the security minded person. All the tools you can wish for are available, for free, with ample documentation and support on how to use them. SSH secure logins, PGP encrypted emails, SSL-encrypted instant messaging, TOR clients for the darkweb, HTTPS connections to remote servers, nothing new. Bob’s your uncle. If you are a consumer.
It’s just that until not too long ago, if you wanted to provide content on a web-server and wanted to make your users’ communications secure with HTTPS, you’d have to pay a lot of money for a SSL certificate that would be accepted by all browsers. Companies like VeriSign, DigiCert, Komodo, Symantec, GeoTrust are Certificate Authorities whose root certificates ended up in all certificate bundles of Operating Systems, browsers and other tools, but these big boys want you to pay them a lot of money for their services.
You can of course use free tools (openssl) to generate SSL vertificates yourself, but these self-signed certificates are difficult to understand and accept for your users if they are primarily non-technical (“hello supportline, my browser tells me that my connection is insecure and your certificate is not trusted“).
SSL certificates for the masses
Since long I have been a supporter of CACert, an organization whose goal is to democratize the use of SSL certificates. Similar to the PGP web-of-trust, the CACert organization has created a group of ‘assurers‘ – these are the people who can create free SSL certificates. These ‘assurers’ are trusted because their identities are being verified face-to-face by showing passports and faces. Getting your assurer status means that your credentials need to be signed by people who agree that you are who you say you are. CACert organizes regular events where you can connect with assurers, and/or become one yourself.
Unfortunately, this grass-roots approach is something the big players (think Google, Mozilla) can not accept, since they do not have control over who becomes an assurer and who is able to issue certificates. Their browsers are therefore still not accepting the CACert root certificate. This is why my web site still needs to display a link to “fix the certificate warning“.
This is not manageable in the long term, even though I still hope the CACert root certificate will ultimately end up being trusted by all browsers.
So I looked at Let’s Encrypt again.
Let’s Encrypt is an organization which has been founded in 2016 by a group of institutions (Electronic Frontier Foundation, Mozilla Foundation, Michigan University, Akamai Technologies and Cisco Systems) who wanted to promote the use of encrypted web traffic by allowing everyone to create the required SSL certificates in an automated way, for free. These institutions have worked with web-browser providers to get them to accept and trust the Let’s Encrypt root certificates. And that was successful.
The result is that nowadays, Let’s Encrypt acts as a free, automated, and open Certificate Authority. You can download and use one of many client programs that are able to create and renew the necessary SSL certificates for your web servers. And all modern browsers accept and trust these certificates.
Let’s Encrypt SSL certificates have a expiration of 3 months after creation, which makes it mandatory to use some mechanism that does regular expiration checks on your server and renews the certificate in time.
I will dedicate the rest of this article to explain how you can use ‘dehydrated‘, a 3rd-party and free Let’s Encrypt client which is fully compatible with the official ‘CertBot’ client of Let’s Encrypt.
Why a 3rd-party tool and not the official client? Well, dehydrated is a simple Bash shell script, easy to read and yet fully functional. On the other hand, please have a look at the list of dependencies you’ll have to install before you can use CertBot on Slackware! That’s 17 other packages! The choice was easily made, and dehydrated is actively developed and supported.
I will show you how to download, install and configure dehydrated, how to configure your Apache web server to use a Let’s Encrypt certificate, and how to automate the renewal of your certificates. After reading the below instructions, you should be able to let people connect to your web-server using HTTPS.
Configure dehydrated
Dehydrated is part of Slackware since the 15.0 release. It ships with a default configuration, a man-page and documentation.
The installed package will also create a cron job “/etc/cron.d/dehydrated” which makes dehydrated run once a day at midnight. I want that file to have some comments about what it does and I do not want to run it at midnight, so I overwrite it with a line that makes it run once a week at 21:00 instead. It will also log its activity to a logfile, “/var/log/dehydrated” in the example below:
cat <<EOT > /etc/cron.d/dehydrated # Check for renewal of Let's Encrypt certificates once per week on Monday: 0 21 * * Mon /usr/bin/dehydrated -c >> /var/log/dehydrated 2>&1 EOT
Dehydrated uses a directory structure below “/etc/dehydrated/”.
The main configuration file you’ll find there is called “config”.
The file “domains.txt” contains the host- and domain names you want to manage SSL certificates for.
The directory “accounts” will contain your Let’s Encrypt user account and private key, once you’ve registered with them.
And a new directory “certs” will be created to store the SSL certificates you are going to create and maintain.
How to deal with these files is going to be addressed in the next paragraphs.
The dehydrated configuration files
config
The main configuration file “/etc/dehydrated/config” is well-commented, so I just show the lines that I used:
DEHYDRATED_USER=alien DEHYDRATED_GROUP=wheel CA="https://acme-staging-v02.api.letsencrypt.org/directory" #CA="https://acme-v02.api.letsencrypt.org/directory" CHALLENGETYPE="http-01" WELLKNOWN="/usr/local/dehydrated" PRIVATE_KEY_RENEW="no" CONTACT_EMAIL=eric.hameleers@gmail.com LOCKFILE="${BASEDIR}/var/lock" HOOK=/etc/dehydrated/hook.sh
Let’s go through these parameters:
- We are starting the ‘dehydrated script as root, via a cron job or at the commandline. The values for DEHYDRATED_USER and DEHYDRATED_GROUP are the user and group the script will switch to at startup. All activities will be done as user ‘alien’ and group ‘wheel’ and not as the user ‘root’. This is a safety measure.
- CA: this contains the Let’s Encrypt URL for dehydrated to connect to. You’ll notice that I actually list two values for “CA” but one is commented out. The idea is that you use the ‘staging’ URL for all your tests and trials, and once you are satisfied with your setup, you switch to the URL for production usage.
Also note that Let’s Encrypt expects clients to use the ACMEv2 protocol. The older ACMEv1 protocol will still work, but you can not register a new account using the old protocol. Its only use nowadays is to assist in migrating old setups to ACMEv2. The “CA” URL contains the protocol version number, and I highlighted that part in red. - CHALLENGETYPE : we will be using HTTP challenge type because that’s easiest to configure. Alternatively if you manage your own DNS domain you could let dehydrate update your DNS zone table to provide the challenge that Let’s Encrypt demands.
What is this challenge? Let’s Encrypt’s ACME-protocol wants to verify that you are in control of your domain and/or hostname. It will try to access a verification file via a HTTP request to your webserver. - WELLKNOWN: this defines the local directory where dehydrated creates the ‘challenge-tokens’ which are then served by your webserver. The Let’s Encrypt ‘ACME server’ will connect to your server as part of the ‘http-01’ challenge and expects to find a specific file there with specific content (created by dehydrated). In the case of a webserver running on our example domain “foo.net”, that URL would be http://foo.net/.well-known/acme-challenge/m4g1C-t0k3n . The dehydrate client must provide that “m4g1c-t0k3n” file which it will create during a certificate creation or renewal. Below I will explain how to create this URL location “.well-known/acme-challenge” and make it readable for an external server like Let’s Encrypt.
If your “domains.txt” file contains more than one hostname or domain, the ACME server will repeat this challenge for every one of them. Usually, multiple hostnames or (sub-)domains means that you have defined multiple VirtualHost in your Apache webserver configuration. For every VirtualHost you need to enable access to this ‘http-01’ challenge location (I will show you how, below).
Note: The first connect from the ACME server will always be over HTTP on port 80, but if your site does a redirect to HTTPS, that will work. - PRIVATE_KEY_RENEW: whether you want the certificate’s private key to be renewed along with the certificate itself. I chose “no” but the default is “yes”.
- CONTACT_EMAIL: the email address which will be associated with your Let’s Encrypt account. This is where warning emails will be sent if your certificate about to expire but has not been renewed.
- LOCK: the directory (which must be writable by our non-root user) where dehydrated will place a lock file during operation.
- HOOK: the path to an optional script that will be invoked at various parts of dehydrate’s activities and which allows you to perform all kinds of related administrative tasks – such as restarting httpd after you have renewed its SSL certificate.
NOTE: do not enable this “HOOK” line – i.e. put a ‘#” comment character in front of the line – until you actually have created a working and executable shell script with that name! You’ll get errors otherwise about the non-existing script.
domains.txt
The file “/etc/dehydrated/domains.txt” contains the list hosts and domain names you want to associate with your SSL certificates. You need to realize that a SSL certificate contains the hostname(s) or the domain name(s) that it is going to be used for. That is why you will sometimes see a “hostname does not match server certificate” warning if you open a URL in your browser, it means that the remote server’s SSL certificate was originally meant to be used with a different hostname.
In our case, the “domains.txt” file contains just one hostname on a single line:
www.foo.net
… but that line can contain any amount of different space-separated hosts under the same domain. For instance the line could be “foo.net www.foo.net” which would tell Let’s Encrypt that the certificate is going to be used on two separate web servers: one with hostname “foo.net” and the other with the hostname “www.foo.net“. Both names will be incorporated into the certificate.
Your “/etc/dehydrated/domains.txt” file can be used to manage the certificates of multiple domains, each domain on its own line (e.g. domain foo.org on one line, and domain foo.net on another line). Each line corresponds to a different SSL certificate – e.g. for different domains. Every line can contain multiple hosts in a single domain (for instance: foo.org www.foo.org ftp.foo.org).
Directory configuration
Two directories are important for dehydrated, and we need to create and/or configure them properly.
/etc/dehydrated
First, the dehydrated configuration directory. We have configured dehydrated to run as user ‘alien’ instead of user ‘root’ so we need to ensure that the directory is writable by this user. Or better (since we installed this as a Slackware package and a package upgrade would undo an ownership change of /etc/dehydrated) let’s manually create the subdirectories “accounts” “certs”, “chains” and “var” where our user actually needs to write, and make ‘alien’ the owner:
# mkdir -p /etc/dehydrated/accounts # chown alien:wheel /etc/dehydrated/accounts # mkdir -p /etc/dehydrated/certs # chown alien:wheel /etc/dehydrated/certs # mkdir -p /etc/dehydrated/chains # chown alien:wheel /etc/dehydrated/chains # mkdir -p /etc/dehydrated/var # chown alien:wheel /etc/dehydrated/var
/usr/local/dehydrated
The directory “/usr/local/dehydrated” is the location where dehydrated to will generate the Let’s Encrypt challenge files. These files provide the proof that we actually own the domain(s) we are requesting a certificate for.
So let’s create that directory and allow our non-root user to write there:
# mkdir -p /usr/local/dehydrated # chown alien:wheel /usr/local/dehydrated
SUDO considerations
We configured the dehydrated script to drop its root privileges at startup and continue as user ‘alien’, group ‘wheel’. Because we also change the group iit is important that the sudo line for root in the file “/etc/sudoers” is changed from the default:
#root ALL=(ALL) ALL
to
root ALL=(ALL:ALL) ALL
Else you’ll get the error “Sorry, user root is not allowed to execute ‘/usr/bin/dehydrated -c’ as alien:wheel on localhost.“.
Apache configuration
I expect that you have already setup your Apache for un-encrypted connections and already have a web site. If you still need to figure out how to setup a web site using Apache, I suggest you look for a good tutorial before you proceed with my article, like https://docs.slackware.com/howtos:network_services:setup_apache .
Before we register an account with Let’s Encrypt and start generating certificates, let’s first update our existing Apache configuration so that it works with dehydrated. We need to make the ‘http-01’ challenge location (http://foo.net/.well-known/acme-challenge/) accessible to external web clients, else the certificate generation will fail.
Note that the above example mentions the “foo.net” hostname. If your “/etc/dehydrated/domains.txt” contains lines with multiple hosts under a domain, you’ll have to make the URL path component “/.well-known/acme-challenge” accessible through every domain host you configured in Apache. The complete certificate generation process will fail in case any of these challenge URLs cannot be validated.
To make life more simple if you run multiple web servers, we created “/usr/local/dehydrated/” to store the challenge file. It’s a single file location. With the help of the Apache “Alias” directive we can use that single file location in all our web servers.
Use this snippet of text in the <VirtualHost></VirtualHost> configuration block for every webserver host:
# We store the dehydrated info under /usr/local and use an Apache 'Alias' # to be able to use it for multiple domains. You'd use this snippet: Alias /.well-known/acme-challenge /usr/local/dehydrated <Directory /usr/local/dehydrated> Options None AllowOverride None Require all granted </Directory>
You can use “lynx” on the command-line to test whether a URL is valid:
$ lynx -dump http://www.foo.net/.well-known/acme-challenge/ Forbidden: You don't have permission to access /.well-known/acme-challenge/ on this server.
Despite that error, this message actually shows that the URL works (otherwise the return message would have been “Not Found: The requested URL /.well-known/acme-challenge was not found on this server.“).
This completes the required Let’s Encrypt modifications to your Apache web server configuration.
Next, and before we restart ‘httpd‘, our Apache server must be enabled to accept SSL connections. This is achieved by un-commenting the following line in “/etc/httpd/httpd.conf”:
# Secure (SSL/TLS) connections Include /etc/httpd/extra/httpd-ssl.conf
You can now restart Apache httpd to activate our modifications (but always test the syntax of your configuration first:
# apachectl configtest # /etc/rc.d/rc.httpd restart
To end the Apache configuration instructions, here are the bits that define the SSL parameters for your host. Note that you should not add them yet! You do not have a SSL certificate yet. Only after you have executed “dehydrated -c” and obtained the certificates, you can add the following lines to every <VirtualHost</VirtualHost> block where where you previously added the ‘Alias’ related stuff above:
SSLEngine on SSLCertificateFile /etc/dehydrated/certs/foo.net/cert.pem SSLCertificateKeyFile /etc/dehydrated/certs/foo.net/privkey.pem SSLCertificateChainFile /etc/dehydrated/certs/foo.net/chain.pem SSLCACertificatePath /etc/ssl/certs SSLCACertificateFile /etc/ssl/certs/ca-certificates.crt
Note the hostname “foo.net” in these SSL lines above? This is an example of course and you need to change that to your own hostname.
What you need to realize is that this name corresponds to the first name of the line in your “/etc/dehydrated/domains.txt” file. Earlier in the article I used an example line for this “domains.txt” file which looks like this: “foo.net www.foo.net“. Even more hosts are possible, they should be space-separated. A single certificate will be generated which is valid for all of these hosts, and the directory where they are stored in is “/etc/dehydrated/certs/” followed by “./foo.net” which the name of that first entry of the line.
Running dehydrated for the first time, using the Let’s Encrypt staging server:
With all the preliminaries taken care of, we can now proceed and run ‘dehydrated’ for the first time. Remember to make it connect to the Let’s Encrypt ‘staging’ server during all your tests, to prevent their production server from getting swamped with bogus test requests!
Examining the manual page (run “man dehydrated“) we find that we need the parameter ‘–cron’, or ‘-c’, to sign/renew non-existent/changed/expiring certificates:
# /usr/bin/dehydrated -c # INFO: Using main config file /etc/dehydrated/config # INFO: Running /usr/bin/dehydrated as alien/wheel # INFO: Using main config file /etc/dehydrated/config To use dehydrated with this certificate authority you have to agree to their terms of service which you can find here: https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf To accept these terms of service run `/usr/bin/dehydrated --register --accept-terms`.
What did we learn here?
In order to use dehydrated, you’ll have to register first. Let’s create your account and generate your private key!
Do not forget to set the “CA” value in /etc/dehydrated/config to a URL supporting ACMEv2. If you use the old staging server URL you’ll see this error: “Account creation on ACMEv1 is disabled. Please upgrade your ACME client to a version that supports ACMEv2 / RFC 8555. See https://community.letsencrypt.org/t/end-of-life-plan-for-acmev1/88430 for details.”
With the proper CA value configured (you’ll have to do this both for the staging and for the production server URL) , you’ll see this if you run “/usr/bin/dehydrated –register –accept-terms”:
# /usr/bin/dehydrated --register --accept-terms # INFO: Using main config file /etc/dehydrated/config # INFO: Running /usr/bin/dehydrated as alien/wheel # INFO: Using main config file /etc/dehydrated/config + Generating account key... + Registering account key with ACME server... + Fetching account ID... + Done!
Generate a test certificate
We’re ready to roll. As said before, it is proper etiquette to run all your tests against the Let’s Encrypt ‘staging’ server and use their production server only for the real certificates you’re going to deploy.
Let’s run the command which is also being used in our weekly cron job, “/usr/bin/dehydrated -c”:
# /usr/bin/dehydrated -c # INFO: Using main config file /etc/dehydrated/config # INFO: Running /usr/bin/dehydrated as alien/wheel # INFO: Using main config file /etc/dehydrated/config + Creating chain cache directory /etc/dehydrated/chains Processing www.foo.net + Creating new directory /etc/dehydrated/certs/www.foo.net ... + Signing domains... + Generating private key... + Generating signing request... + Requesting new certificate order from CA... + Received 1 authorizations URLs from the CA + Handling authorization for www.foo.net + Found valid authorization for www.foo.net + 0 pending challenge(s) + Requesting certificate... + Checking certificate... + Done! + Creating fullchain.pem... + Done!
This works! You can check your web site now if you did not forget to add the SSL lines to your VirtualHost block; your browser will complain that it is getting served an un-trusted SSL certificate issued by “Fake LE Intermediate X1“.
Generate a production certificate
First, change the “CA” variable in “/etc/dehydrated/config” to the production CA URL “https://acme-v02.api.letsencrypt.org/directory”.
Remove the fake certificates that were created in the previous testing step so that we can create real certificates next:
# rm -r /etc/dehydrated/certs/www.foo.net
Now that we’ve cleaned out the fake certificates, we’ll generate real ones:
# /usr/bin/dehydrated -c # INFO: Using main config file /etc/dehydrated/config # INFO: Running /usr/bin/dehydrated as alien/wheel # INFO: Using main config file /etc/dehydrated/config Processing www.foo.net + Creating new directory /etc/dehydrated/certs/www.foo.net ... + Signing domains... + Generating private key... + Generating signing request... + Requesting new certificate order from CA... + Received 1 authorizations URLs from the CA + Handling authorization for www.foo.net + 1 pending challenge(s) + Deploying challenge tokens... + Responding to challenge for www.foo.net authorization... + Challenge is valid! + Cleaning challenge tokens... + Requesting certificate... + Checking certificate... + Done! + Creating fullchain.pem... + Done!
If you reload the Apache server configuration (using the command “apachectl -k graceful”) you’ll now see that your SSL certificate has been signed by “Let’s Encrypt Authority X3” and it is trusted by your browser. We did it!
Automatically reloading Apache config after cert renewal
When your weekly cron job decides that it is time to renew your certificate, we want the dehydrated script (which runs as a non-root account) to reload the Apache configuration. And of course, only root is allowed to do so.
We’ll need a bit of sudo magic to make it possible for the non-root account to run the “apachectl” program. Instead of editing the main file “/etc/sudoers” with the command “visudo” we create a new file “httpd_reload” especially for this occasion, in sub-directory “/etc/sudoers.d/” as follows:
# cat <<EOT > /etc/sudoers.d/httpd_reload alien ALL=NOPASSWD: /usr/sbin/apachectl -k graceful EOT
This sudo configuration allows user ‘alien’ to run the exact command “sudo /usr/sbin/apachectl -k graceful” with root privileges.
Next, we need to instruct the dehydrated script to automatically run “sudo /usr/bin/apachectl -k graceful” after it has renewed any of our certificates. That is where the “HOOK” parameter in “/etc/dehydrated/config” comes to play.
As the hook script, we are going to use dehydrated’s own sample “hook.sh” script that can be downloaded from https://raw.githubusercontent.com/lukas2511/dehydrated/master/docs/examples/hook.sh or (if you used the SlackBuilds.org script to create a package) use “/usr/doc/dehydrated-*/examples/hook.sh”.
# cp -i /usr/doc/dehydrated-*/examples/hook.sh /etc/dehydrated/ # chmod +x /etc/dehydrated/hook.sh
This shell script contains a number of functions, each is relevant and will be called at a certain stage of the certificate renewal process. The dehydrated script will provide several environment variables to allow a high degree of customization, and all of that is properly documented in the sample script, but we do not need any of that. Just at the end of the “deploy_cert()” function we need to add a few lines:
deploy_cert() { # ... # After successfully renewing our Apache certs, the non-root user 'alien' # uses 'sudo' to reload the Apache configuration: sudo /usr/sbin/apachectl -k graceful }
That’s all. Next time dehydrated renews a certificate, the hook script will be called and that will reload the Apache configuration at the appropriate moment, making the new certificate available to visitors of your web site.
Summarizing
I am glad you made it all the way down here! In my usual writing style, the article is quite verbose and gives all kinds of contextual information. Sometimes that makes it difficult for the “don’t bother me with knowledge, just show me the text I should copy/paste ” user but I do not care for that.
I do hope you found this article interesting, and useful. If you spotted any falsehoods,let me know in the comments section below. If some part needs more clarification, just tell me.
Have fun with a secure web!
Eric
And here is a complete VirtualHost block for your amusement. It defines the host http://www.foo.net/ as well as https://www.foo.net/ and it automatically makes every http:// connection switch to https:// so that all your host’s traffic will be secure.
<VirtualHost *:80> ServerName www.foo.net ServerAdmin alien@foo.net DocumentRoot /srv/www/htdocs/ CustomLog /var/log/httpd/www.foo.net_accesslog combined ErrorLog /var/log/httpd/www.foo.net_errorlog Redirect permanent / https://www.foo.net/ </VirtualHost> <VirtualHost *:443> ServerName www.foo.net ServerAdmin alien@foo.net DocumentRoot /srv/www/htdocs/ CustomLog /var/log/httpd/www.foo.net_accesslog combined ErrorLog /var/log/httpd/www.foo.net_errorlog # We store the dehydrated info under /usr/local and use an Apache 'Alias' # to be able to use it for multiple domains. You'd use this snippet: Alias /.well-known/acme-challenge /usr/local/dehydrated <Directory /usr/local/dehydrated> Options None AllowOverride None Require all granted </Directory> SSLEngine on SSLCertificateFile /etc/dehydrated/certs/foo.net/cert.pem SSLCertificateKeyFile /etc/dehydrated/certs/foo.net/privkey.pem SSLCertificateChainFile /etc/dehydrated/certs/foo.net/chain.pem SSLCACertificatePath /etc/ssl/certs SSLCACertificateFile /etc/ssl/certs/ca-certificates.crt </VirtualHost>
Great article Eric! Thanks!
Thanks a lot! As usual, learnt easily some great stuff from your post!
Hello Eric,
glad to see you followed my same line of reasoning when picking dehydrated in place of certbot.
A detail :
SSLCertificateChainFile /etc/dehydrated/certs/foo.net/fullchain.pem
I’d suggest using chain.pem and not fullchain.pem in that . Fullchain.pem includes the cert.pem itself and this makes the certificate offering redundant. Tools like the validator from ssllabs.com will notice that.
Alternatively one would not use SSLCertificateChainFile at all and rather use SSLCertificateFile with fullchain.pem
Hi LoneStar,
Using chain.pem is indeed the better option, and I will update the main article with your suggestion, thanks,
Gnu Privacy Guard is your friend!
Add it to Thunderbird and encrypt your email.
Henry, sure… but that was not really the topic of this article.
thanks very helpful. Can this info be expanded to add dovecot/sasl to update those certs and get publicly verified ssl for imaps, pop3s and smpts? That would be useful, and then there is sftp using vsftp which could also presumably benefit from these certs as well. I don’t know if you can use the same certs for other ssl/tls based protocols as you can for https.
You can use the above to request any number of certificates, they can be used for all kinds of services – imaps, smtps, etc.
The applications that use a certificate just need to be configured to use a certificate path like “/etc/dehydrated/certs/${hostname}/cert.pem”. If you use dovecot or postfix then you know where to configure this.
And similarly to what I showed about the “sudoers.d/httpd_reload” configuration file and the restart command in the “deploy_cert()” function inside the “/etc/dehydrated/hook.sh”script, you can implement this for any other service too.
But I leave that to you, the reader, to work out. All the information you’d need can be found in the article.
Oh my gosh! AlienBob is endorsing and providing a tutorial for LetsEncrypt….
Hath hell frozen over?
Great tutorial. Cheers.
I am not “endorsing” anything here.
Thanks AlienBob,
This worked great, except maybe a note not to enable the HOOK variable in the config until
hook.sh is moved there. Or have it commented out
…or, now you have learned even more, because you experienced that one error and you were able to understand and then fix it.
%>)
Yes
Well, that’s comprehensive and inspiring finally to do it.
I believe, tying in the postfix/dovecot can be w/o difficulties, can’t it?
Thanks, great article as always!
Thank you allienbob
previously I had difficulty making my website trusted by modern browsers.
With the help of the contents in this article that you wrote, then I did it successfully.
regards
Hi!
a note and a question:
– the existence of even zero-length hook.sh with correct permissions is required much earlier in the process – w/o it one can’t even test the config
q: what to do if I already have web-server on https? The challenge is checked against http:// link, not https. (in my case default vhost:80 does not redirect to https, but serves other purposes)
Hi Janis.
The note about the HOOK variable and the required existence of that script was already mentioned a bit higher up in the comments section – and answered. In order to avoid further cases of no fully reading the page and its comments, I have updated the main article with this information now.
Regarding your question: I had the same issue when enabling letsencrypt certificates on existing servers. You will just have to setup a HTTP vhost for this.
In my case, I simply created an Include file that I now use in all my vhosts, with the following content:
# We store the dehydrated info under /usr/local and use
# an Apache 'Alias' to be able to use it for multiple domains.
# You'd use this snippet:
<directory /usr/local/dehydrated>
Options None
AllowOverride None
Require all granted
</directory>
Alias /.well-known/acme-challenge /usr/local/dehydrated
Yes, did not notice about the hook in comments.
Its pity I have to fiddle with simple http – it is not possible in some cases.
Janis, sometimes it is impossible to use the ‘http-01’ challenge type because you cannot configure your webserver as needed.
But if you control the DNS domain for your server, you can add a TXT record to your domain table and use ‘dns-01’ as the challenge type, as explained here: https://letsencrypt.org/docs/challenge-types/
Does that help you?
O, yes, indeed! I was slowly thinking in this direction. For some sites it will definitely help. Thank you!
Actually – bu using Apache module mod_md (http://httpd.apache.org/docs/2.4/mod/mod_md.html), (https://github.com/icing/mod_md/) everything seems being a lot easier. Ia ma using v.2.0.10 with apache 2.4.39 (2.2.x require Apache which does no compile on 14.2 (due to old libs).
At the moment i read in log od my https vhost:
mod_md.c(989): AH10077: SERVER[state=2]: providing certificate
for server SERVER
If everything will be running smooth, I can share the story with you to amend the article if You will find it fit.
It works:
Managed Domains
Name Domains Status Valid Expires Renew Check@ Configuration Renewal
SERVER SERVER ok 2020-01-04 2020-04-03 auto censys.io crt.sh renew-at[33%] ca=[letsencrypt(v2)] contacts=[mailto:ME]
I’ve been having so much trouble getting lets encrypt working on slackware (for years). I had opted for a free service (zerossl.com) which lately began charging for creating lets encrypt wildcard certs ($50 a month… for a free service? oooookkkkk….). I had done searches and came upon your article, and it helped me tremendously. I now have my server getting its own certs from letsencrypt, and I am extremely thankful for this write-up of yours. I have some things I’d like to iron out for my uses but now I’m not completely terrified of failing because I have such a great starting point and now great working certs. Thank you for this, I’m eternally grateful!
Thank you very much Eric! Both your blog and your repo are a great help.
It’s the little things – I generally understand how the stuff works, then I installed certbot (from SBo) and felt lost. Your pointer to dehydrated and the notes which file is which (private key, public key, keychain…) was worth a lot.
Cheers,
Heiko
Hi Eric,
I tried follow your step by step, however I got an error after run /usr/bin/dehydrated -c on production:
SSLCACertificateFile: file ‘/usr/share/curl/ca-bundle.crt’ does not exist or is empty
Please could you help what is the root cause? Since I re-check again your tutorial but I can’t find any mention about the /usr/share/curl directory.
Cheers,
Sukma
My example block for Apache configuration contains the line:
SSLCACertificateFile /usr/share/curl/ca-bundle.crt
This is probably where the error comes from. In Slackware 14.2 this file actually is installed as part of the curl package. But in Slackware-current, this changed on 23 March 2020 and the file was removed in favor of using the CA certificate bundle in /etc/ssl/certs/ .
I do not use letsencrypt on any Slackware-current server but I expect that you would have to change the above line to:
SSLCACertificateFile /etc/ssl/certs/ca-certificates.crt
…which is the new location for the system-wide certificates bundle. This file is (re)created by the “update-ca-certificates” script which runs when you install or upgrade the ca-certificates package.
I just tried this on Slackware 14.2, and this file is not there.
/etc/ssl/certs/ca-certificates.crt , however, is present.
I have updated the main article, the curl version of the CA certificate collection is no longer present in Slackware and the file in /etc/ssl/certs needs to be used.
Dehydrated is now included in Slackware 15 🙂
I’ve been trying this for a couple days now. I seem to be able to get it partly working. I started with the .orig httpd,conf I and have DNS working so I can get the “it works” page from outside I have to leave out the ‘SSLEngine on’ from and the cert paths from your example at this point since I don’t yet have a cert. So when I add the port 80 virtual host pointing to DocumentRoot /srv/www/htdocs/ I get a 403 forbidden like I should. Then running dehydrated it fails with a 403
+ Challenge validation has failed 🙁
ERROR: Challenge is invalid! (returned: invalid) (result: {
“type”: “http-01”,
“status”: “invalid”,
“error”: {
“type”: “urn:ietf:params:acme:error:unauthorized”,
“detail”: “Invalid response from http://www.foo.net/.well-known/acme-challenge/2twGBENyUdhtWYOIP0rNALPauI9KX6SneoYMjcNwoFQ [xx.xxx.xxx.xxx]: \”\u003c!DOCTYPE HTML PUBLIC \\\”-//IETF//DTD HTML 2.0//EN\\\”\u003e\\n\u003chtml\u003e\u003chead\u003e\\n\u003ctitle\u003e403 Forbidden\u003c/title\u003e\\n\u003c/head\u003e\u003cbody\u003e\\n\u003ch1\u003eForbidden\u003c/h1\u003e\\n\u003cp\””,
“status”: 403
},
“url”: “https://acme-v02.api.letsencrypt.org/acme/chall-v3/11741701788/j4WG8Q”,
“token”: “2twGBENyUdhtWYOIP0rNALPauI9KX6SneoYMjcNwoFQ”,
“validationRecord”: [
{
“url”: “http://www.foo.net/.well-known/acme-challenge/2twGBENyUdhtWYOIP0rNALPauI9KX6SneoYMjcNwoFQ”,
“hostname”: “www.foo.net”,
“port”: “80”,
“addressesResolved”: [
“xx.xxx.xxx.xxx”
],
“addressUsed”: “xx.xxx.xxx.xxx”
}
],
“validated”: “2021-03-22T01:45:56Z”
})
I’m stumped here.
Try whether the URL works that letsencrypt is accessing. Put a file “testing” in /usr/local/dehydrated and then try what happens if you access http://www.foo.net/.well-known/acme-challenge/testing in a browser or using lynx on a commandline. You should not get a 403 error then. If you do, you’ll have to re-evaluate your apache setup, If it works, perhaps you should check your letsencrypt account, was it actually created?
OH geez, it was an id10t error. When I went back to the httpd.conf.orig for this last attempt I forgot to remove the default DocumentRoot way down at the bottom so I had two DocumentRoot’s conflicting with each other 🙂
Ok, I see the issue now.
I have a redirect in for foo.net to foo.net/nextcloud
so then I get foo.net/nextcloud/.well-known/acme-challenge 🙂
I’m stuck at the config when editing the lines to use, how can I execute that?
I don’t understand what you are asking.
AH00526: Syntax error on line 324 of /etc/httpd/extra/httpd-ssl.conf:
Invalid command ‘SSLEngine’, perhaps misspelled or defined by a module not included in the server configuration
You need to enable SSL support in your Apache configuration, otherwise it does not make sense to want to work with SSL certificates.
In /etc/http/httpd.conf at least you need to change these defaults and remove the relevant comment characters:
# Dynamic Shared Object (DSO) Support
#LoadModule ssl_module lib64/httpd/modules/mod_ssl.so
# Secure (SSL/TLS) connections
#Include /etc/httpd/extra/httpd-ssl.conf
Okay.. I’m I enable and included SSL and ran into this error…
AH00526: Syntax error on line 325 of /etc/httpd/extra/httpd-ssl.conf:
SSLCertificateFile: file ‘/etc/dehydrated/certs/foo.net/cert.pem’ does not exist or is empty
I don’t understand why it’s saying it’s missing when I checked…
root@fubx:/etc/dehydrated# ls /etc/dehydrated/certs/foo.net/cert-1628197118.
cert-1628197118.csr cert-1628197118.pem
“cert.pem” is not mentioned in that directory listing.
Uncle Bob this is getting really complicated.
root@fubx:/etc/dehydrated# /usr/bin/dehydrated -c
# INFO: Using main config file /etc/dehydrated/config
# INFO: Running /usr/bin/dehydrated as roofy/wheel
# INFO: Using main config file /etc/dehydrated/config
Processing foo.net with alternative names: http://www.foo.net
+ Creating new directory /etc/dehydrated/certs/foo.net …
+ Signing domains…
+ Generating private key…
+ Generating signing request…
+ Requesting new certificate order from CA…
+ Received 2 authorizations URLs from the CA
+ Handling authorization for http://www.foo.net
+ Handling authorization for foo.net
+ 2 pending challenge(s)
+ Deploying challenge tokens…
+ Responding to challenge for http://www.foo.net authorization…
+ Cleaning challenge tokens…
+ Challenge validation has failed 🙁
ERROR: Challenge is invalid! (returned: invalid) (result: {
“type”: “http-01”,
“status”: “invalid”,
“error”: {
“type”: “urn:ietf:params:acme:error:unauthorized”,
“detail”: “Invalid response from https://foo.net/.well-known/acme-challenge/Dr3ENmASayU-XUlx0BiwJB4ek0Y_rihf7EUuyrt0XTI [185.199.111.153]: \”\u003c!DOCTYPE html\u003e\\n\u003chtml\u003e\\n \u003chead\u003e\\n \u003cmeta http-equiv=\\\”Content-type\\\” content=\\\”text/html; charset=utf-8\\\”\u003e\\n \u003cmeta http-equiv=\\\”Co\””,
“status”: 403
},
“url”: “https://acme-staging-v02.api.letsencrypt.org/acme/chall-v3/205750328/nIB23A”,
“token”: “Dr3ENmASayU-XUlx0BiwJB4ek0Y_rihf7EUuyrt0XTI”,
“validationRecord”: [
{
“url”: “http://www.foo.net/.well-known/acme-challenge/Dr3ENmASayU-XUlx0BiwJB4ek0Y_rihf7EUuyrt0XTI”,
“hostname”: “www.foo.net”,
“port”: “80”,
“addressesResolved”: [
“185.199.108.153”,
“185.199.109.153”,
“185.199.111.153”,
“185.199.110.153”
],
“addressUsed”: “185.199.108.153”
},
{
“url”: “https://foo.net/.well-known/acme-challenge/Dr3ENmASayU-XUlx0BiwJB4ek0Y_rihf7EUuyrt0XTI”,
“hostname”: “foo.net”,
“port”: “443”,
“addressesResolved”: [
“185.199.111.153”,
“185.199.109.153”,
“185.199.108.153”,
“185.199.110.153”
],
“addressUsed”: “185.199.111.153”
}
],
“validated”: “2021-08-06T02:32:42Z”
})
Is “foo.net” actually owned by you? Apparently that domain resolves to 4 separate IP addresses, is it load-balanced?
I am not here to debug your infrastructure setup, that part is your responsibility.
The important thing to note is that Let’s Encrypt needs to be able to access the /.well-known/acme-challenge/ subdirectory without errors in order to read what was written there by dehydrated.
I see a status: 403 in your logs which means Let’s Encrypt runs into a “HTTP: Forbidden” URL. You are probably blocking something or your Apache configuration is wonky.
I ran a “httpd -t” it said syntax OK is there anyway i can check if my IP address is blocking anything?
Accessing the URL https://foo.net/.well-known/acme-challenge/ in a browser should give you a HTTP 403 (forbidden), That means the configuration is correct (otherwise you would get a 404 not found).
Now place a file in that directory (I assume you know where /.well-known/acme-challenge/ points to in your filesystem). Suppose the file is called “myfile” then accessing https://foo.net/.well-known/acme-challenge/myfile in a browser should give you that actual file. Not a 403 and not a 404. If you can not get access to ‘myfile’ then your Apache httpd config is too restrictive.
This post is a great guide and transitioning to secure hosting. Unfortunately, I must be doing something wrong in following the instructions. I followed everything that you suggested and got down to getting the test certificates (Running dehydrated for the first time…).The attempt to get the certificates failed with a 400 – Connection refused error. I tried to test my setup by creating a file in /usr/local/dehydrated. That also gives me a connection refused error. My Virtual Hosts entry in /etc/httpd/extra/httpd-vhosts.conf is
ServerAdmin webmaster@otterlywoods.com
DocumentRoot “/var/www/OtterlyWoods.com”
ServerName otterlywoods.com
ServerAlias http://www.otterlywoods.com
ErrorLog “/var/log/httpd/OtterlyWoods.com-error_log”
CustomLog “/var/log/httpd/OtterlyWoods.com-access_log” common
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Require all granted
Allow from all
# We store the dehydrated info under /usr/local and use an Apache ‘Alias’
# to be able to use it for multiple domains. You’d use this snippet:
Alias /.well-known/acme-challenge /usr/local/dehydrated
Options None
AllowOverride None
Require all granted
I could not find anything to help me correct this from the server side and there was nothing in the logs to help. I suspect a permissions problem, but don’t know what to try. Any help or pointers to other documents would be greatly appreciated!
If the apache log does not show you anything then your web request has not even reached the apache server. It could be a firewall blocking port 80.
I went through everything again more carefully and it worked this time. Not sure what was the problem before. Thank you for the help!
Hello,
I am on a subdomain and try to get it working, no success so far
# INFO: Using main config file /etc/dehydrated/config
# INFO: Running /usr/bin/dehydrated as maart/wheel
# INFO: Using main config file /etc/dehydrated/config
Processing xxxxxx.xs4all.nl
+ Signing domains…
+ Generating private key…
+ Generating signing request…
+ Requesting new certificate order from CA…
+ Received 1 authorizations URLs from the CA
+ Handling authorization for xxxxxx.xs4all.nl
+ 1 pending challenge(s)
+ Deploying challenge tokens…
+ Responding to challenge for xxxxxx.xs4all.nl authorization…
+ Cleaning challenge tokens…
+ Challenge validation has failed 🙁
ERROR: Challenge is invalid! (returned: invalid) (result: {
“type”: “http-01”,
“status”: “invalid”,
“error”: {
“type”: “urn:ietf:params:acme:error:caa”,
“detail”: “CAA record for xxxxxx.xs4all.nl prevents issuance”,
“status”: 403
},
“url”: “https://acme-staging-v02.api.letsencrypt.org/acme/chall-v3/522529348/Q4kszw”,
“token”: “5z2_IpvaC9gNjJRSzmqzMyZFrWWns0O6U7j4SDnTKtA”,
“validationRecord”: [
{
“url”: “http://xxxxxx.xs4all.nl/.well-known/acme-challenge/5z2_IpvaC9gNjJRSzmqzMyZFrWWns0O6U7j4SDnTKtA”,
“hostname”: “xxxxxx.xs4all.nl”,
“port”: “80”,
“addressesResolved”: [
“xx.100.158.243”
],
“addressUsed”: “xx.100.158.243”
}
],
“validated”: “2021-09-19T11:42:43Z”
})
What does this mean is my configuration OK but do i have some dns problems?
Strange, the error “CAA record for xxxxxx.xs4all.nl prevents issuance” is explained in https://letsencrypt.org/docs/caa/ but if I look for the CAA records of the xs4all.nl domain, I see:
Which means, xs4all.nl and all its subdomains by default should accept certificates issued by letsencrypt.org. Perhaps your subdomain has its own CAA record which overrules the above generic CAA record?
In any case, you can open a new topic for your problem on https://community.letsencrypt.org/ if you are unable to fix it. Also, XS4all has (or had in the good old days before KPN bought them) a good helpdesk.
Thank you for this! This is awesome!
Hello. Can someone help?
ERROR: Challenge is invalid! (returned: invalid)
(result:
[“type”] “http-01”
[“status”] “invalid”
[“error”,”type”] “urn:ietf:params:acme:error:unauthorized”
[“error”,”detail”] “148.71.136.248: Invalid response from http://data2023.ddns.net/.well-known/acme-challenge/z0KpQnpusKZflyKBrRDl7T1_FlZr0dXi91YwKCw0w3A: 404″
[“error”,”status”] 403
[“error”] {“type”:”urn:ietf:params:acme:error:unauthorized”,”detail”:”148.71.136.248: Invalid response from http://data2023.ddns.net/.well-known/acme-challenge/z0KpQnpusKZflyKBrRDl7T1_FlZr0dXi91YwKCw0w3A: 404″,”status”:403}
[“url”] “https://acme-staging-v02.api.letsencrypt.org/acme/chall-v3/9467610824/8VJB8A”
[“token”] “z0KpQnpusKZflyKBrRDl7T1_FlZr0dXi91YwKCw0w3A”
[“validationRecord”,0,”url”] “http://data2023.ddns.net/.well-known/acme-challenge/z0KpQnpusKZflyKBrRDl7T1_FlZr0dXi91YwKCw0w3A”
[“validationRecord”,0,”hostname”] “data2023.ddns.net”
[“validationRecord”,0,”port”] “80”
[“validationRecord”,0,”addressesResolved”,0] “148.71.136.248”
[“validationRecord”,0,”addressesResolved”] [“148.71.136.248”]
[“validationRecord”,0,”addressUsed”] “148.71.136.248”
[“validationRecord”,0] {“url”:”http://data2023.ddns.net/.well-known/acme-challenge/z0KpQnpusKZflyKBrRDl7T1_FlZr0dXi91YwKCw0w3A”,”hostname”:”data2023.ddns.net”,”port”:”80″,”addressesResolved”:[“148.71.136.248″],”addressUsed”:”148.71.136.248″}
[“validationRecord”] [{“url”:”http://data2023.ddns.net/.well-known/acme-challenge/z0KpQnpusKZflyKBrRDl7T1_FlZr0dXi91YwKCw0w3A”,”hostname”:”data2023.ddns.net”,”port”:”80″,”addressesResolved”:[“148.71.136.248″],”addressUsed”:”148.71.136.248″}]
[“validated”] “2023-11-15T00:27:15Z”)
Not as locky as @Eugene: no duplicated DocumentRoot;
Can access files in /.well-known/acme-challenge/ on the browser;
Check owner, read and wright permissions on server folder;
What else?
do you have python-importlib_metadata and python-zipp installed?. apparently that is a new dep for letsencrypt 2.7.4, which wa only added a few days ago. it might help.
Yes. python-importlib_metadata-5.0.0 and python-zipp-3.8.0
With mod_md.so and mod_vhost_alias.so HTTPD does not start saying: SSLCertificateFile: file ‘/etc/dehydrated/certs/data2023.ddns.net/cert.pem’ does not exist or is empty
ServerAdmin gone@data2023.ddns.net
DocumentRoot “/var/www/htdocs/”
ServerName data2023.ddns.net
ServerAlias data2023.ddns.net
ErrorLog “/var/log/httpd/data2023.ddns.net-error_log”
CustomLog “/var/log/httpd/data2023.ddns.net-access_log” common
# We store the dehydrated info under /usr/local and use an Apache ‘Alias’
# to be able to use it for multiple domains. You’d use this snippet:
Alias /.well-known/acme-challenge /usr/local/dehydrated
Options None
AllowOverride None
Require all granted
SSLEngine on
# SSLCertificateFile /etc/dehydrated/certs/data2023.ddns.net/cert.pem
# SSLCertificateKeyFile /etc/dehydrated/certs/data2023.ddns.net/privkey.pem
# SSLCertificateChainFile /etc/dehydrated/certs/data2023.ddns.net/chain.pem
SSLCACertificatePath /etc/ssl/certs
SSLCACertificateFile /etc/ssl/certs/ca-certificates.crt
Couple of things: either use Apache’s mod_md.so and then also add the required configuration to your Vhost, or use dehydrated. Not both.
Tim thinks you are using the letsencrypt certbot, but you are not, so python-importlib_metadata and python-zipp are irrelevant.
The URL http://data2023.ddns.net/.well-known/acme-challenge/ is perperly accessible now. That means you should no longer be getting the 404 “not found” or 403 “not authorized” error responses anymore.
I guess your issue should be resolved by now?
No, “dehydrated -c” still returns the same “ERROR: Challenge is invalid! (returned: invalid)”.
I am a nub to http and dehydrated so… here goes a silly question: From your response I am thinking httpd-vhosts.conf is the incorrect place to add configurations, so where should I add SSLEngine and so on?
There will be a whole lot more messages after that “ERROR”. All of that text is relevant.
And please do not post the complete error message text here in your posts. For long swabs of text I would prefer if you use a pastebin facility like https://pastebin.com/ or https://zerobin.net/ and then share the resulting URL.
As for your lack of experience with configuring Apache httpd: this blog is not the place to gain that knowledge. As I stated in the article, you should read a couple of good tutorials,
But I can at least give a couple of hints,
Make sure you have an un-encrypted web site up and running, and *then* you can add the bits that Let’s Encrypt needs.
Don’t add configuration for SSL yet! Only after your Let’s Encrypt SSL certificates have been generated using “dehydrated -c” you are ready to add the SSL configuration to the VirtualHost block in your Apache httpd configuration.
Which file to edit? The default configuration for Apache httpd as found in Slackware uses /etc/httpd/extra/httpd-vhosts.conf for plain web sites and /etc/httpd/extra/httpd-ssl.conf for secure web sites. But that is not mandatory. For instance, I run many web sites. I keep the http and https configuration for a web site in one single file, because changes are made a lot easier and faster that way.
This may be important to figure this out: I am using Noip to point to may computer.
Where your hostname is registered should not make a difference.
Got it going with SSL For Free.
Dehydrated -c keeps to the same error (404, 403). Giving up.
Thanks to all for your precious time.
Great tutorial, and to the point. On a clean install of Slackware-current I did have a few trivial issues. Not related to Lets Encrypt and Dehydrated, more of setting up SSL for HTTP
I had to comment out both of these.
SSLCertificateFile “/private/etc/apache2/server.crt”
and
SSLCertificateKeyFile “/private/etc/apache2/server.key”
I wasnt sure if this was related to me using apachectl -t or if I just restarted httpd it would have been ok
In Httpd.conf
I also had to uncomment mod_socache_shmcb.so along with the usual mod_ssl and Include httpd-ssl
But this was all new to me, so assumed this would have been normal for someone that knows what they are doing in regards to setting up httpd
Weirdly loved how I actually had to read all of your documentation, rather than you just giving me everything in one… feel alot more prepared if I had to do this again
Hi Eric.
I spent some time past weekend, trying to set up Let’s Encrypt in a server (Slackware 15 Current) deployed in Linode. My plan is to access xfce remotely from a Browser at work.
Some questions:
1. Does Dehydrated script work only on Slackware 15 Production?.
2. I installed the script setting up config files. Account open and test certificates were generated under /etc/dehydrated/certs/www.mysite.com/, but no cert file is generated by dehydrated script at location: /.well-known/acme-challenge (or alias) /usr/local/dehydrated.
3. I removed /etc/dehydrated/certs/www.mysite.com directory with cert files below it, and repeated “/usr/bin/dehydrated -c” to regenerate them again. I also tried “/usr/bin/dehydrated –force -c” with no success in both cases. There are no warning/Error messages on dehydrated execution.
4. Successive dehydrated scrip executions reports existing and valid certs on my server until abril or may 2024 so no renew process necessary.
I appreciate in advance your advice or guidance to troubleshoot this install.
Thanks again Eric and I hope you are much better regarding your health.
Francisco.
Hi Francisco, I use dehydrated on Slackware 15.0 and -current servers that are connected to the Internet, and there’s nothing I have to do differently to make it work on -current.
But, you may not have the correct understanding how deydrated (or other acme clients) work. The certificates are always created in a subdirectory of “/etc/dehydrated/certs/” . The location “/usr/local/dehydrated” which is exposed on your HTTP host as the path “/.well-known/acme-challenge” will contain the challenges for Let’s Encrypt server to which it will respond with an accept (thereby generating new certs) or a deny (no new cert will be generated). The challenge file is removed after dehydrated completes its interaction with the Let’s Encrypt server.
One thing to note is that with dehydrated 0.7.1 (which also got added to Slackware 15.0 patches) the value of “CA” in etc/dehydrated/config has changed from a URL to a keyword (i.e. simplifying the configuration and abstracting away how Let’s Encrypt handles the requests).
This is how it looks now:
# URL to certificate authority or internal preset
# Presets: letsencrypt, letsencrypt-test, zerossl, buypass, buypass-test
# default: letsencrypt
CA="letsencrypt"
This is how it looked before 0.7.1:
#CA="https://acme-staging-v02.api.letsencrypt.org/directory"
CA="https://acme-v02.api.letsencrypt.org/directory"
It looks like the old URL-style value for “CA” is still accepted for compatibility with configs from older releases.
I was having an issue with the failing on the challenge type http-01. I had the
Options None
AllowOverride None
Require all granted
section and commented out under the *:443 section in the httpd-vhosts.conf file. I moved to the *:80 section and that worked, but…
Now I have this error when trying to retrieve the cert.
bash-5.1# dehydrated -c
# INFO: Using main config file /etc/dehydrated/config
# INFO: Running /usr/bin/dehydrated as will/wheel
# INFO: Using main config file /etc/dehydrated/config
Processing trentholdings.com with alternative names: http://www.trentholdings.com
+ Signing domains…
+ Generating private key…
+ Generating signing request…
+ Requesting new certificate order from CA…
+ Received 2 authorizations URLs from the CA
+ Handling authorization for trentholdings.com
+ Found valid authorization for trentholdings.com
+ Handling authorization for http://www.trentholdings.com
+ Found valid authorization for http://www.trentholdings.com
+ 0 pending challenge(s)
+ Requesting certificate…
curl: option : blank argument where content is expected
curl: try ‘curl –help’ or ‘curl –manual’ for more information
ERROR: Problem connecting to server (post for ; curl returned with 2)
Any ideas?
Currently http://www.trentholdings.com leads to a completely different domain but I assume that originally this was not happening. The redirect will for sure kill a Let’s Encrypt certificate request.
I am puzzled by the “curl: option : blank argument where content is expected” error. In the private email you sent me earlier, this does not occur. What did you change?
Also, I assume that your error is caused by an Apache httpd mis-configuration. The only way to allow people to help troubleshoot that, is by sharing your full Apache httpd configuration. Not just those three lines concerning Options, AllowOverride and Require.
Please do not post your configuration here in a comment. Instead, use a PasteBin service, set an expiration date and then share the resulting link here.