Let's Encrypt On Raspberry Pi


(Peter) #1

I’m moving my Caddy installation from Windows to a Raspberry Pi. I’ve hit another stumbling block getting Let’s Encrypt working.

This is my Caddy file:

web.mydomain.com:8181 localhost:8181 192.168.1.77:8181 {
root /home/pi/caddywww
tls {
dns cloudflare
}
gzip
fastcgi / /var/run/php/php7.0-fpm.sock {
ext .php
split .php
index index.php
}
}

For privacy reasons, I changed the domain name to mydomain.com to post here on the forum. This is what happens when I attempt to start Caddy:

pi@raspberrypi:~ $ sudo caddy -conf /etc/caddy/Caddyfile &
[1] 1650
pi@raspberrypi:~ $ Activating privacy features…
Your sites will be served over HTTPS automatically using Let’s Encrypt.
By continuing, you agree to the Let’s Encrypt Subscriber Agreement at:
https://acme-v01.api.letsencrypt.org/terms
Please enter your email address so you can recover your account if needed.
You can leave it blank, but you’ll lose the ability to recover your account.
Email address: peter@mydomain.com
-bash: peter@mydomain.com: command not found

[1]+ Stopped sudo caddy -conf /etc/caddy/Caddyfile

As soon as I enter my email address, I get an error.

I’m using the Cloudflare DNS challenge (which I have working on Windows). I set the two environmental variables in /etc/profile. Running “printenv CLOUDFLARE_API_KEY” and “printenv CLOUDFLARE_EMAIL” returns the correct values for those variables. I installed Caddy with the Cloudflare plugin using: curl https://getcaddy.com | bash -s personal tls.dns.cloudflare

Any ideas what I am doing wrong? Is there a log where I can see what error is occurring?


(Matthew Fay) #2

TL;DR: There’s nothing wrong with Caddy here - you’re running it in the background. Bring it back with fg (or don’t use & in the first place), put your email in, then send it away again with Ctrl + Z (pauses it) and then bg (tells it to keep running in the background).

Or, use the -email flag to set your email address at launch.


This is actually due to the job control functionality of bash.

pi@raspberrypi:~ $ sudo caddy -conf /etc/caddy/Caddyfile &
[1] 1650

Here you finish your command with &, telling the shell to fork the new process (Caddy) into the background. You haven’t redirected its output though, so it’s still sending that to your current shell’s stdout. This is what happens when, after the next prompt, you see:

Activating privacy features…
Your sites will be served over HTTPS automatically using Let’s Encrypt.
By continuing, you agree to the Let’s Encrypt Subscriber Agreement at:
https://acme-v01.api.letsencrypt.org/terms
Please enter your email address so you can recover your account if needed.
You can leave it blank, but you’ll lose the ability to recover your account.
Email address

This is normally pretty straightforward - Caddy needs your email, and prompts you to put it in. But Caddy isn’t actually interactive on your current shell - it’s running in the background. So when you type your email address:

Email address: peter@mydomain.com
-bash: peter@mydomain.com: command not found

It’s not going to Caddy, it’s going to the previous pi@raspberrypi:~ $, a bash prompt. Bash has no idea how to interpret this as a command, because there are no builtins or programs in path that match. Meanwhile, Caddy keeps running as job 1, PID 1650, sitting in the background and waiting for input until terminated.


(Peter) #4

Thanks, that solved that problem. I successfully received a certificate for web.mydomain.com

However, when I try to start Caddy I get this error:

caddy -conf /etc/caddy/Caddyfile
Activating privacy features… done.
2018/02/08 02:09:59 listen tcp :80: bind: address already in use

As you can see from my Caddyfile in the first post, I don’t have Caddy set to run anything on port 80 (that’s already being using by something else on the Raspberry Pi), so I want to use port 8181 instead. Why is Caddy trying to use port 80?


(Matthew Fay) #5

Good question indeed. What’s the output of cat /etc/caddy/Caddyfile, exactly?


(Peter) #6

I think I found the answer here: https://caddy.community/t/ssl-only-dont-bind-to-port-80/2133/5

I ran Caddy with “-http-port 9080” and that seems to keep Caddy away from port 80. Looks like it has to do with automatic HTTPS. The default challenge for Let’s Encrypt uses port 80 (which my ISP blocks), so Caddy tries to bind that port automatically.

I’m using the DNS challenge, which doesn’t require port 80. So I don’t think this will cause any unforeseen problems.

Thanks for all of the help with my questions. I really appreciate the help.


(Matthew Fay) #7

Ahh, yeah. I always forget that it doesn’t disable Automatic HTTPS unless you specify a HTTP scheme or port…

Let us know if it all works!


(Peter) #8

Looks like I have it all working! I did run into one other problem. Setting the environmental variables for the Cloudflare DNS challenge in /etc/profile prevented them from being read when launching Caddy on boot in rc.local (I’m guessing /etc/profile is read after rc.local executes, so it can’t see the variables)

Instead, I defined the variables in the rc.local file. Which now has these lines:

export CLOUDFLARE_API_KEY="my api key"
export CLOUDFLARE_EMAIL=“my email address”

caddy -conf /etc/caddy/Caddyfile -http-port 9080 -log /home/pi/log.txt &

Everything seems to be working quite well.

Do you know if using “sudo killall caddy” is bad practice? I’m needing a way to stop/restart Caddy after changing my Caddyfile, and that’s the best way I’ve found so far without actually rebooting the Raspberry Pi.


(Matthew Fay) #9

Apart from the possibility of accidentally killing other Caddy instance if you run more than one, no, it’s not really “bad” practice.

“Best” practice would probably be to use -pidfile /path/to/pidfile and kill $(cat /path/to/pidfile, but that’s probably overkill.

As for changing your Caddyfile - you can signal Caddy to reload without actually stopping the process. It will check the new Caddyfile and load it, and if there are problems, it should keep on serving according to the last good configuration.

The signal you want is USR1 - my goto command is pkill -SIGUSR1 caddy.

https://caddyserver.com/docs/cli#signals