Home Assistant Add-on: Caddy 2

I just launched Caddy2 a few hours ago and have hit this error also…

INFO: Run Caddy...
{"level":"info","ts":1680053243.2530215,"msg":"using provided configuration","config_file":"/share/caddy/Caddyfile","config_adapter":""}
Error: adapting config using caddyfile: parsing caddyfile tokens for 'tls': /share/caddy/Caddyfile:20 - Error during parsing: getting module named 'dns.providers.cloudflare': module not registered: dns.providers.cloudflare
INFO: Service caddy exited with code 1 (by signal 0)
                tls {
                        dns cloudflare {env.CLOUDFLARE_AUTH_TOKEN}
                }

                reverse_proxy localhost:<port>

Probably need to make a custom caddy binary with that module built in. Go to caddy website https://caddyserver.com/download select the computer architecture you are running, add the cloudfare dns, save the file as /share/caddy/caddy and the addon should use that binary instead next time you restart.

1 Like

Thak you! That worked!

image

I figured this out a while after my post. What I can’t figure out is no matter what I do to add the cloudflare IPs to my trusted_proxies section when I proxy via cloudflare, the sites will not load. They work just fine if I set the site to DNS Only in cloudflare.

EDIT: My problem is the non-standard port that I am using. It isn’t compatible with Cloudflare’s list of cached ports. I either need to use one of theirs or just disable the caching for that subdomain.

I’m using Cloudflared tunnels and I can’t get HA to work via them and Caddy 2, only Vaultwarden is working. With NPM, the reverse was true: HA worked fine but not Vaultwarden.

Just got it all working…

HA configuration.yaml:

homeassistant:
  auth_providers:
    - type: homeassistant
    - type: trusted_networks
      trusted_networks:
        - 192.168.1.0/24
        - fd12:3456:7890:1::fc
      trusted_users:
        192.168.1.100: 7c824b771254da39c719cddefae9008
        192.168.1.130: 30fd5dd9c3878e0a3c4fb48016b6197
      allow_bypass_login: true

http:
  ip_ban_enabled: true
  login_attempts_threshold: 3
  use_x_forwarded_for: true
  trusted_proxies:
    - ::1              # IPv6 localhost
    - 127.0.0.1        # IPv4 localhost - Caddy 2 reverse proxy
    - 172.30.32.0/23   # Docker subnets - Cloudflared tunnel(s)

Cloudflared:

external_hostname: ""
additional_hosts:
  - hostname: <ha>.<my_domain.com>
    service: http://192.168.1.104:8123
    disableChunkedEncoding: true
  - hostname: <vaultwarden>.<my_domain.com>
    service: https://192.168.1.104:<custom_port>
    disableChunkedEncoding: true
nginx_proxy_manager: false

Caddy 2:

args: []
env_vars:
  - name: CLOUDFLARE_AUTH_TOKEN
    value: <my_api_token>
log_level: info
non_caddyfile_config:
  destination: localhost
  domain: <ha>.<my_domain.com>
  email: <my_email@my_domain.com>
  port: 8123

Caddyfile:

{
        email <my_email@my_domain.com>
}

(common) {
        tls {
                dns cloudflare {env.CLOUDFLARE_AUTH_TOKEN}
        }

        header / {
                Strict-Transport-Security "max-age=31536000; includeSubdomains"
                X-XSS-Protection "1; mode=block"
                X-Content-Type-Options "nosniff"
                Referrer-Policy "same-origin"
                Permissions-Policy "geolocation=(self), microphone=()"
                Content-Security-Policy "frame-ancestors <my_domain.com>:XXXXX *.my_domain.com:XXXXX>
                -Server
        }
}

<ha>.<my_domain.com> {
        import common
        reverse_proxy localhost:8123 {
        }
}
<vaultwarden>.<my_domain.com> {
        import common
        reverse_proxy localhost:<my_custom_port> {
        }
}

I should add that I also utilized Cloudflare’s SSL/TLS encryption in Flexible mode as well as created an API Token in Cloudflare, My Profile, API Tokens with Zone.Zone:Read & Zone.DNS:Write permissions for Caddy 2’s use

1 Like

does it work behind a CGNAT?

We do a reverse proxy on Caddy 2 for a Unify controller:

unifi.my.domain {
  reverse_proxy https://192.168.7.4 {
    transport http {
      tls_insecure_skip_verify
    }
    header_up -Authorization
    header_up Host {host}
  }
}

1 Like

Just came across this and got it working. I found it very confusing so leaving a couple of notes for anyone else who wants to try this.

I have the ssl certificate and key files stored in a folder so the tls line is different to above:

tls /path_to_sslcertificate.pem /path_to_sslkey.pem

I have also changed the Content-Security-Policy to allow http to serve https iframes:

Content-Security-Policy "frame-ancestors default-src 'self' https://mydomain.org:port  *mydomain.org:port http://localhomeassistantname:port http://homeassistantIPaddress:port"

It still gets the A+ rating from https://securityheaders.com/.

The whole file is:

(common) {
   tls /path_to_sslcertificate.pem /path_to_sslkey.pem
   header {
       Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"
       X-XSS-Protection "1; mode=block"
       X-Content-Type-Options "nosniff"
       Referrer-Policy "same-origin"
       -Server
       Content-Security-Policy "frame-ancestors default-src 'self' https://mydomain.org:port  *mydomain.org:port http://localhomeassistantname:port http://homeassistantIPaddress:port"
       Permissions-Policy "geolocation=(self mydomain.org *.mydomain.org), microphone=()"
    }
}

mydomain.org:port {
      import common
      reverse_proxy homeassistantIPaddress:port
}

Did anyone insert robots.txt in root? I want to host some services in public and wants to know how.

Hello everyone, im trying to configure Caddy2 in order to provide https for Vaultwarden (port 7277) instance (only LAN, no internet) but im stuck with these errors:

a. System environment:

HassOs:

  • Core 2024.1.0
  • Supervisor 2023.12.0
  • Operating System 11.2
  • Frontend 20240103.3
    Vaultwarden Add-on:
    “Vaultwarden (Bitwarden) Current version: 0.20.1”
    DuckDNS Integration:1.15.0
    Integration with domain linked to my Public IP. Domain: smartzucchero.duckdns.org

All components are on the same machine (192.168.0.2)

VW Config:

ssl: true
certfile: fullchain.pem
keyfile: privkey.pem
log_level: debug

3. Caddy version:

Caddy 2, Current version: 1.5.4e.

I used the custom binary for arm54 platform with the duckdns module built-in (retrieved from the official caddy website) and made it executable through chmod but still receiving error:

s6-rc: info: service s6rc-oneshot-runner: starting
s6-rc: info: service s6rc-oneshot-runner successfully started
s6-rc: info: service base-addon-banner: starting

-----------------------------------------------------------
 Add-on: Caddy 2
 Open source web and proxy server with automatic HTTPS
-----------------------------------------------------------
 Add-on version: 1.5.4
 You are running the latest version of this add-on.
 System: Home Assistant OS 11.2  (aarch64 / raspberrypi4-64)
 Home Assistant Core: 2024.1.0
 Home Assistant Supervisor: 2023.12.0
-----------------------------------------------------------
 Please, share the above information when looking for help
 or support in, e.g., GitHub, forums or the Discord chat.
-----------------------------------------------------------
s6-rc: info: service base-addon-banner successfully started
s6-rc: info: service fix-attrs: starting
s6-rc: info: service base-addon-log-level: starting
s6-rc: info: service fix-attrs successfully started
Log level is set to DEBUG
s6-rc: info: service base-addon-log-level successfully started
s6-rc: info: service legacy-cont-init: starting
s6-rc: info: service legacy-cont-init successfully started
s6-rc: info: service caddy: starting
s6-rc: info: service caddy successfully started
s6-rc: info: service legacy-services: starting
s6-rc: info: service legacy-services successfully started
INFO: Prepare Caddy...
INFO: Found custom Caddy at /share/caddy/caddy
v2.7.6 h1:w0NymbG2m9PcvKWsrXO6EEkY9Ru4FJK8uQbYcev1p3A=
INFO: Prepare Caddyfile...
INFO: Caddyfile found at /share/caddy/Caddyfile
INFO: Run Caddy...
DEBUG: '/share/caddy/caddy' run --config '/share/caddy/Caddyfile' ''
{"level":"info","ts":1704471555.2387967,"msg":"using provided configuration","config_file":"/share/caddy/Caddyfile","config_adapter":""}
{"level":"info","ts":1704471555.2464736,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//localhost:2019","//[::1]:2019","//127.0.0.1:2019"]}
{"level":"info","ts":1704471555.2471159,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0x40002d2b00"}
{"level":"info","ts":1704471555.2474158,"logger":"http.auto_https","msg":"server is listening only on the HTTPS port but has no TLS connection policies; adding one to enable TLS","server_name":"srv0","https_port":443}
{"level":"info","ts":1704471555.2474706,"logger":"http.auto_https","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
{"level":"info","ts":1704471555.248698,"logger":"tls.cache.maintenance","msg":"stopped background certificate maintenance","cache":"0x40002d2b00"}
Error: loading initial config: loading new config: http app module: start: listening on :443: listen tcp :443: bind: address already in use
INFO: Service caddy exited with code 1 (by signal 0)
s6-rc: info: service legacy-services: stopping
s6-rc: info: service legacy-services successfully stopped
s6-rc: info: service caddy: stopping
s6-rc: info: service caddy successfully stopped
s6-rc: info: service legacy-cont-init: stopping
s6-rc: info: service legacy-cont-init successfully stopped
s6-rc: info: service fix-attrs: stopping
s6-rc: info: service base-addon-log-level: stopping
s6-rc: info: service fix-attrs successfully stopped
s6-rc: info: service base-addon-log-level successfully stopped
s6-rc: info: service base-addon-banner: stopping
s6-rc: info: service base-addon-banner successfully stopped
s6-rc: info: service s6rc-oneshot-runner: stopping
s6-rc: info: service s6rc-oneshot-runner successfully stopped

This is the accutally Caddyfile config:

{
	email [email protected]
}

smartzucchero.duckdns.org {
	tls {
		dns duckdns TOKEN
	}
	reverse_proxy https://localhost:7277
}

This is my “http” Configuration.yaml file:

http:
    server_port: 8123
    ssl_certificate: /ssl/fullchain.pem
    ssl_key: /ssl/privkey.pem
    base_url: https://smartzucchero.duckdns.org
    use_x_forwarded_for: true
    trusted_proxies:
        - 172.18.0.0/24
        - 192.168.50.2

Im also trying to investigate what could be running on 443 but i cant figure it out:
Cattura

@berichta i believe in you <3

you can also ask on the caddy forum. This is generic to caddy not specific to the addon…

Hi @alebald1,
It looks like you are trying to use the same URL for different routes.
smartzucchero.duckdns.org → localhost:8123
smartzucchero.duckdns.org → localhost:7277

The first one is bound by home assistant, the second one by caddy.
Both together can not work. That is also what caddy states:

Error: loading initial config: loading new config: http app module: start: listening on :443: listen tcp :443: bind: address already in use

My suggestion would be to create another domain, using it purely for vaultwarden.

For example you could create a new domain like smartzucchero2.duckdns.org, then changing your caddyfile:


smartzucchero2.duckdns.org {
	tls {
		dns duckdns TOKEN
	}
	reverse_proxy https://localhost:7277
}

I made a very poorly written Home Assistant addon that builds a custom caddy binary for use with berichta’s addon. Available from my repo: https://github.com/jdeath/homeassistant-addons/

With google domains going away and the replacement not supporting dynamic dns, I switched to cloudfare. The caddy download page kept hanging to include cloudfare plugin, so I made this addon so I could run xcaddy. It is not the greatest interface. You have to edit a script to include your desired xcaddy command. Hopefully it will help someone in a bind.

ps. Did you know that caddy will also update your dynamic dns IP addresses? This saves me from running inadyn. The default build on my addon includes all the plugins to make this happen (plus others I use). There is no log output when it updates them, but it does do it!