Let's Encrypt on OctoPi

I could have sworn I'd followed a guide when I set up my last OctoPi system about a year ago, but I just set up another one and couldn't find it. So, not finding one, I decided to write one.

Prerequisites

  • You must own a real, live Internet domain.

As noted in this issue, Let's Encrypt won't issue a cert for a local domain (i.e., something like octopi.local or ender.lan) or for an IP address, so you need a real domain. You can get a domain for free from freenom.com, though they have some annoying renewal requirements and only have certain TLDs available for free. Or you can just pay for a domain; they're generally less than $15/year (and often less than $10/year).

  • You must have a suitable DNS host

This guide is going to use DNS validation to obtain your Let's Encrypt certificate, so nothing on your LAN needs to be exposed to the Internet. For this to work, you'll need to be using a DNS host with an API that's supported by acme.sh. I like, use, and recommend Cloudflare, and will use that in the examples here, but as you can see in the link in the last sentence, acme.sh supports over 50 DNS hosts. Cloudflare provides DNS service for free, so unless you have a particular reason to prefer a different host, I'd recommend using them.

  • Your router, or whatever is serving DNS for your LAN, needs to be configured properly

You're going to be getting a certificate for a specific hostname (I'll use octopi.yourdomain.com in these examples). For this to work without certificate errors, that hostname will need to resolve to your OctoPi instance on your local network (i.e., https://octopi.yourdomain.com will actually point to your OctoPi system).

Installing acme.sh

Many guides for using Let's Encrypt have you use the certbot client. I don't like using that if I can avoid it, though, as it's a tangled mess of dependencies that is far too bloated for most purposes. Instead, this guide uses acme.sh, a lightweight ACME client in a shell script. Installation is simple.

Log in to your OctoPi instance as the default pi user, then become root by running sudo -i. Then, to install acme.sh, run curl https://get.acme.sh | sh. This will download acme.sh, put it in /root/.acme.sh/, and configure a daily cron job to renew your certificates. Log out of this root session by typing exit or Ctrl-D, then run sudo -i again--this will activate the new PATH acme.sh configured.

Issue the certificate

It's now time to issue the certificate. To do this, you'll need to have access to the appropriate API credentials for your DNS host--for Cloudflare, that's the Global API key and the email address on your account. Then set the appropriate environment variables:

export CF_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
export CF_Email="xxxx@sss.com"

If you're using a different DNS host, consult the acme.sh documentation (at the "supported by acme.sh" link above) for the appropriate credentials and how to set them. Once you've done that, issue the certificate. Run the command below, replacing every instance (there are four) of octopi.yourdomain.com with the FQDN you're going to use for your OctoPi system:

acme.sh --issue --dns dns_cf -d octopi.yourdomain.com --renew-hook "cat /root/.acme.sh/octopi.yourdomain.com/fullchain.cer /root/.acme.sh/octopi.yourdomain.com/octopi.yourdomain.com.key >/etc/ssl/snakeoil.pem && systemctl reload haproxy"

If all goes well, this will issue your cert.

The --renew-hook parameter tells acme.sh which command(s) to run to deploy a cert after it's renewed, but they don't run when the cert is first issued. So, after issuing the cert, you'll need to run these manually. As above, you'll need to replace every instance (there are three this time) of octopi.yourdomain.com with the FQDN you're going to use for your OctoPi system:

cat /root/.acme.sh/octopi.yourdomain.com/fullchain.cer /root/.acme.sh/octopi.yourdomain.com/octopi.yourdomain.com.key >/etc/ssl/snakeoil.pem
systemctl reload haproxy

That's it! You have your trusted certificate installed and activated, and it will automatically renew every 60 days or so. And you haven't needed to change any of the default configuration files to do so.

HTTPS redirect

You have your certificate issued and installed, but HTTP requests aren't redirected to HTTPS. You can set this up by adding these two lines to /etc/haproxy/haproxy.cfg:

#redirect to HTTPS if ssl_fc is false / off, unless using the API.
redirect scheme https code 301 if !{ url_beg /api } !{ ssl_fc }

These are added to the frontend section, so it will look like this:

frontend public
        bind :::80 v4v6
        bind :::443 v4v6 ssl crt /etc/ssl/snakeoil.pem
        option forwardfor except 127.0.0.1
        #redirect to HTTPS if ssl_fc is false / off, unless using the API.
        redirect scheme https code 301 if !{ url_beg /api } !{ ssl_fc }
        use_backend webcam if { path_beg /webcam/ }
        default_backend octoprint

Then reload haproxy with systemctl reload haproxy, and the redirect will be in place. To test it, browse to http://octopi.yourdomain.com, and note that you're automatically redirected to HTTPS.

1 Like