How I SSL Secured My Site After (Oops) Exceeding Let’s Encrypt Limit

Binary Belle
9 min readSep 11, 2020

…and before the waiting period was over

Let’s Encrypt is “A nonprofit Certificate Authority providing TLS certificates to 225 million websites.

Unbeknownst to ME until yesterday, Let’s Encrypt has a limit of how many times you can issue a cert for a domain or set of domains per week. I didn’t know this…I didn’t even know to LOOK for this. Guess when I found out about the limit. That’s right; when I exceeded it.

TLDR; If you’ve run into the same issue, try changing the list of domains. For example, if you entered your domains as www.domainname.com and domainname.com, try adding test.domainname.com to that list. (It’s good to have a testing domain anyway!)

After my fix succeeded, it occurred to me that I could have just added one more subdomain to the list, like I’m now suggesting here in my summary, instead of running each domain separately, which is what this post explains how to do. That would have saved me the time figuring out how to modify the Apache files to get the redirect working, and made this post WAY shorter.

First Up

I’m not trying to tell you how to game the system; well, I guess I am, but I hope you’ll only do this once you’ve made the mistake I did, and stumbled onto this post.

They have the limit there for a reason. It’s a non-profit, community funded project, with a large amount of traffic — 225-ish million sites are SSL’d through Let’s Encrypt. I didn’t realize what I was doing when I ran that tool repetitively; and I agree with the limit for free use of the encryption.

What Am I Doing?!

I’m creating a Django website. I’ve created a LOT of websites, but this is my first Django site. It’s my first time hosting through AWS Lightsail, using Bitnami, and my first time using Let’s Encrypt to create an SSL certificate (through Bitnami’s bncert-tool), too. It is NOT, however, the first time I’ve made a hot mess of things.

I decided to automate the whole setup, because I knew I’d have to do this more than once. No way am I going to remember to type all those commands, in the correct order. Let’s just say repetitive work isn’t my strong suit. And although it may exist somewhere, I couldn’t find a way to fully automate what I wanted to automate.

Of course, automating something ALSO means running it a bunch of times, checking the outcome, making tweaks, lather, rinse, repeat. I tell myself it’s a better kind of repetitive, because each time is just a little different. I also learn exactly what I’m doing WAY better than were I to copy and paste instructions from other places into my CLI (command line interface).

In a few days, I got the whole setup automated, up to the Apache config editing and the certificate installation. Yesterday I got the Apache config editing automated. That was pretty easy…and then?

The Bitnami BNCERT-TOOL — UhOh

It took me a few tries to automate the bncert-tool command. Besides getting the script to work, which took a bit, I actually ran the tool five times to be exact, cuz it failed on #6.

First round was running it manually to see what input it needed. Then I used the script to pass those answers into the bncert-tool script.

# What I started withecho “www.$projname.com $projname.com
Y
Y
n
Y
$su_email
Y
\\n
“ | sudo /opt/bitnami/bncert-tool
# figuring out to use \\n cost me some time and possibly a round - I initially had \n. It was supposed to be an Enter, but whatever it sent when I had \n, reported an error.

And then, since AWS Lightsail/Bitnami/whomever, put the last install package together, the bncert-tool changed. So when I ran it, it asked me an extra question — did I want to update the tool? Since I hadn’t passed that answer into my script, the rest of the question answers were out of order. Another round.

I added a Y for updating it, not realizing the implication of the warning “You’ll have to run it manually”. Seeing I was in the script, I just stupidly assumed it would keep going. No. It exited. So now the tool was updated. Maybe there were a different set of questions, right? I’d better check before shoving the script through again. That manual tool run was another round.

I accommodated the tool update exit, by calling the tool twice in my script. First time, it just passed a “Y” to update. The second call passed all the other answers to it.

# This is what I had before the next issue...stay tuned...echo "Y" | sudo /opt/bitnami/bncert-toolecho "www.$projname.com $projname.com
Y
Y
n
Y
$su_email
Y
\\n
" | sudo /opt/bitnami/bncert-tool

It errored, saying it couldn’t find something it needed. I looked, and the necessary file was actually there. I ran it manually, again, with the exact same answers as I’d passed in the code, and it worked fine. Another round.

Hm. I’d just had to write a separate bash function to get the .bash_aliases to source, because it wouldn’t do so directly in my bash script. Well, it did, but it was only sourced while that script was running; which isn’t what I wanted. I wanted the bash_aliases to be available AFTER the script was done running.

Anyway, having just done that, I thought maybe that’s what I needed to do here, too. Another round….or so I thought… because this time, I got kicked out of the processing for issuing too many certs. In hindsight, now that I’ve read a lot more, I understand their reasoning, and I deserved this.

BTW, here’s the automation code that I’m just positive WOULD have worked. Maybe.

# What I ended up with.  This updates the tool, creates a script to run it (because I was having trouble getting it to run directly after the update), and runs it.echo "Y" | sudo /opt/bitnami/bncert-toolcat << EOF >> ~/run_bncert_tool.sh
#!/usr/bin/bash
echo "www.$projname.com $projname.com
Y
Y
n
Y
$su_email
Y
\\n
" | sudo /opt/bitnami/bncert-tool
sudo /opt/bitnami/ctlscript.sh restart
EOF
sudo chown $USER ~/run_bncert_tool.sh
sudo chmod 755 ~/run_bncert_tool.sh
source ~/run_bn_cert_tool.sh

bncert-tool never said anything about the limits until it errored. I googled the error, and THAT’S how I found out the details.

Okay, I thought, I’ll just revoke the previous ones. Nope, doesn’t fix the issue. Plus, it won’t let me revoke, because I’ve already made too many requests (Error 429). Let’s Encrypt DOES provide a staging URL to accommodate a higher number of attempts to test the exact think I was doing…automation.

But the bncert-tool is binary, so I can’t edit it to put that staging URL in it. I’d have to find another script, or figure out how to run it manually with that staging URL. And I don’t know if the experience would have been the same with the staging version. Sigh.

Obsessive Persistence Pays Off

I started to try to accept the outcome of no SSL attempt for 6 more days. It even told me what time I could come back and try again.

But if I’m nothing else, for better or not, I’m obsessively persistent.

The error message said one thing that ended up being the fix-it secret…It said I’d registered that EXACT set of domains too many times. After taking a walk and eating dinner and drinking a glass of wine…I came up with trying to submit them separately. Spoiler alert: It worked…and then I thought of a better way I could have fixed it. LOL. Of course

Anyway, here’s what I did…

Thinking I may only get away with issuing ONE of them at best, I decided to submit the non-www version. The script warned me it wouldn’t setup the www redirection because www wasn’t in the list of domains. Okay. I accepted that.

It SUCCEEDED! What?! I checked the URL in a browser, and it was secure!

Of course I pushed my luck…I ran it again, only this time for just the www domain. Same redirect-isn’t-happening warnings, which I accepted again. Annnnddd SUCCESS again. You can see the two new ones on the top of this list.

Rate limit and certificate information from letsencrypt.org. Powered by crt.sh
Certificates and Rate Limit summary

Fixing The Mess From Fixing My Other Mess

Then I realized; oh, I have two certificates now; different ones. And no redirect. I copied the Redirect code out of another instance I hadn’t deleted, and doing the next few steps is what fixed it.

  1. Update the httpd.conf

I updated the httpd.conf file and changed the domain to zoombeatz.com, instead of www.zoombeatz.com

# httpd.conf removed www from the ServerNameServerName zoombeatz.com:80

2. Add non-www to www redirection to zoombeatz-https-vhosts.conf

zoombeatz-https-vhosts.conf - The bold part is what I added# END: Support domain renewal when using mod_proxy without Location # BEGIN: Enable non-www to www redirection
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} !^localhost
RewriteCond %{HTTP_HOST} !^[0–9]+.[0–9]+.[0–9]+.[0–9]+(:[0–9]+)?$
RewriteCond %{REQUEST_URI} !^/\.well-known
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=permanent,L]
# END: Enable non-www to www redirection

3. Add non-www to www redirection to zoombeatz-vhosts.conf

zoombeatz-vhosts.conf - when I was done with it.  The bold part is what I added.# END: Support domain renewal when using mod_proxy without Location
# BEGIN: Enable HTTP to HTTPS redirection
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} !^localhost
RewriteCond %{HTTP_HOST} !^[0–9]+.[0–9]+.[0–9]+.[0–9]+(:[0–9]+)?$
RewriteCond %{REQUEST_URI} !^/\.well-known
RewriteRule ^/(.*) https://%{SERVER_NAME}/$1 [R,L]
# END: Enable HTTP to HTTPS redirection
# BEGIN: Enable non-www to www redirection
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} !^localhost
RewriteCond %{HTTP_HOST} !^[0–9]+.[0–9]+.[0–9]+.[0–9]+(:[0–9]+)?$
RewriteCond %{REQUEST_URI} !^/\.well-known
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=permanent,L]
# END: Enable non-www to www redirection

4. Restart Apache, hold breath…check browser…It worked! Whew!

Wrap Up

An improvement to the bncert-tool would be to add a warning not to run this tool until you’re READY to issue a certification for REALZ. A staging test tool would be great as well, for people automating setup like I was, although I don’t know if it would have mimicked the same process, including the question about updating.

An improvement to Let’s Encrypt would be to allow someone who f’d up like me, a one time fee of say $25, to get one more shot before they have to wait their 7 days. That would generate revenue for Let’s Encrypt, and it would save people like me a bunch of time either waiting, or figuring a way around it.

The upside of all this is that I learned quite a bit more about SSL certificates and other related topics, than I would have otherwise.

When my week is up, I will be going back to the Let’s Encrypt site, to revoke all those unused certificates. I’ll post about it when I get through that process, too, so if you make the same initial mistake as me, you can clean up after yourself, too. Hopefully I won’t make some new mistakes un-mistaking the first mistakes, but I wouldn’t bet on that.

Also…as I said in the summary at the top, after doing all this, while writing this post…it occurred to me that I could have just submitted three domains at once, instead of the two separately. It would have met their requirement for the list of domains to be “different”, and I wouldn’t have had to do all this monkeying around with the conf files.

Maybe I’ll blow my newly secured instance away, and try that….Just kidding. I think…. :)

UPDATE: I did it…I’ve created another instance since this one…and this time I ran the bncert-tool with four domains instead of two. I didn’t have to update any of the conf files, and now I have four SSL-protected domains — staging, test, www and non-www.

Hope this helps someone!

--

--

Binary Belle

Senior Software Engineer, Inventor, Writer, Zumba Instructor, Storm and Sky Photographer, Drone Pilot, Shar Pei Lover & Owner