Using Caddy with Home Assistant

I’m using Caddy with home assistant so I don’t have to forward so many ports on my router to my Raspberry Pi.

My Caddyfile looks like this: {
    header / {
    Strict-Transport-Security "max-age=31536000; includeSubdomains"
    X-XSS-Protection "1; mode=block"
    X-Content-Type-Options "nosniff"
    X-Frame-Options "SAMEORIGIN"
    Referrer-Policy "same-origin"
    proxy / localhost:8123 {
} {
    proxy / localhost:7681 {
} {
    proxy / localhost:3218 {
} {
    proxy / localhost:9541 {

Question 1:

Tried to define a Content-Security-Policy like this:

Content-Security-Policy "default-src 'self' *://**;"

But it just locks me out of Home Assistant.

Second thing is that on my Router I am forwarding port 80 to port 80 on my Rpi running home assistant and I am forwarding port xx443 to port 443 on the Pi as well so I have to specify the port number :xx443 to connect which works fine.

I’m just not sure if this is going to cause and problems renewing my letsencrypt SSL certificate?
I would also like to do the same with port 80 so that post 80 is not exposed… I assume this would definitely break LetsEncrypt certificate renewal? Is there a way to do this? I had a look at some of the issues on Github but it’s not immediately obvious what I can do.

I am assuming it’s not actually a problem not having port 443 forwarded as I think nowdays letsencrypt only does http challenges anyway? I’d like to use the DNS challenge instead but can’t see how I can configure that when I’m using duckdns.

Any advice appreciated…

Can you elaborate on what happens here exactly?

You’ll be fine moving the HTTPS port, since HTTP validation occurs on port 80. TLS-SNI validation used to occur on port 443, but has been disabled.

You’re correct, it would break HTTP validation as the ACME spec specifies port 80 must be used for this purpose. There is no way to signal to LetsEncrypt that it should perform this validation on a different port, you may only opt for a different type of challenge.

You can’t while DuckDNS controls the domain you’re using. You will need to control your own domain for this purpose - you can get a free one at if you like, and point it at Cloudflare for free. Cloudflare is a supported provider for Caddy’s DNS challenges.

You can set the apex record as a CNAME to your DuckDNS domain - Cloudflare will “flatten” it to an A record for requests - and then set the subdomain wildcard as a CNAME to the apex record.

Honestly, I would just put your Raspberry Pi in a DMZ and configure its firewall aggressively. Being able to use default ports (80 and 443) make things so much simpler. The only port I set as non-default nowadays is SSH, and that’s not entirely necessary with a secure configuration anyway (password login disabled, root login disabled, agent forwarding disabled, install fail2ban).

I get a white screen. It’s an iFrame.

The normal duck-dns page is:
If I go to the iFrame tab it should go to in a frame but I get a white page.
Going to the normal http://ip-address works fine.

Thanks for confirming LetsEncrypt only needs port 80 and I can move the https port. :slight_smile: Thanks also for confirming my suspicion about port 80 and also a DNS challenge.

I don’t think it’s worth the bother of playing with a domain on cloudflare… I do have a few domains… I could point the DNS to cloudflare but then I assume I’d need an account with them to host the domain?

I only have ports 80 and xx443 exposed on the Router and they go to the Pi. I have the Hassio configuration password protected and also using a lockout if an incorrect password is entered (5 attempts) So it’s pretty locked down. I think Caddy redirects anything coming in on 80 to https anyway doesn’t it so I believe I’m pretty locked down.

Thanks for your help. I was just concerned that Shodan and are showing port 80 open whereas before even with Lets Encrypt it was closed. Caddy just seems to handle things differently…

Still like to know what’s wrong with the content_security_policy I’m trying to use though (however none of the caddyfiles I see seems to have that in there so maybe I shouldn’t worry about it)

One thought is that *://** wouldn’t actually match because your wildcard specifies four domain elements and the latter only has three.

Public scrapers should show your web ports as open; they need to be so the web server can serve websites. It’s not a security flaw to serve websites on ports 80 and 443, not with a modern web server.

OK I’ll try *:// and see if that works.

I guess I’m just being too paranoid…

well it didn’t make any difference

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.