Loading certificates fails (unable to traverse into path)

1. The problem I’m having:

I have Caddy running inside an LXC container created using Nix. I previously had it manage Let’s Encrypt certificates . Now I want to use certificates I manage separately, so I switched to:

	tls {
		load /home/caddy/tls
	}

That directory is mounted from the host and owned inside the container by a group that includes the Caddy user, with full read & execute permissions. sudo -u caddy ls /home/caddy/tls is fine inside the container. So is sudo systemd-run --uid $(id -u caddy) --gid $(id -u caddy) -p "SupplementaryGroups=" --service-type exec --wait --collect ls /home/caddy/tls (note the lack of supplementary groups), which shows me the contents of the directory in the system logs. Same for ls on a single file. There’s a symlink in the directory, but the Caddy user is able to resolve that too (and I can cat it via systemd-run).

However, Caddy fails with an error about traversing into the path:

2. Error messages and/or full log output:

Feb 17 02:40:11 margdarshak systemd[1]: Starting Caddy...
Feb 17 02:40:11 margdarshak caddy[729]: {"level":"info","ts":1739740211.6103644,"msg":"using config from file","file":"/etc/caddy/caddy_config"}
Feb 17 02:40:11 margdarshak caddy[729]: {"level":"info","ts":1739740211.613658,"msg":"adapted config to JSON","adapter":"caddyfile"}
Feb 17 02:40:11 margdarshak caddy[729]: {"level":"warn","ts":1739740211.613671,"msg":"Caddyfile input is not formatted; run 'caddy fmt --overwrite' to fix inconsistencies","adapter":"caddyfile","file":"/etc/caddy/caddy_config","line":5}
Feb 17 02:40:11 margdarshak caddy[729]: {"level":"info","ts":1739740211.6162915,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//[::1]:2019","//127.0.0.1:2019","//localhost:2019"]}
Feb 17 02:40:11 margdarshak caddy[729]: {"level":"info","ts":1739740211.6164439,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc0005fa900"}
Feb 17 02:40:11 margdarshak caddy[729]: {"level":"info","ts":1739740211.6164505,"logger":"tls.cache.maintenance","msg":"stopped background certificate maintenance","cache":"0xc0005fa900"}
Feb 17 02:40:11 margdarshak caddy[729]: Error: loading initial config: loading new config: loading http app module: provision http: getting tls app: loading tls app module: provision tls: loading certificates: unable to traverse into path: /home/caddy/tls
Feb 17 02:40:11 margdarshak systemd[1]: caddy.service: Main process exited, code=exited, status=1/FAILURE

3. Caddy version:

2.9.0

4. How I installed and ran Caddy:

Using the NixOS Caddy module:

  services.caddy = {
    enable = true;
    # The config directory will be overlaid at runtime.
    package = pkgs.caddy.withPlugins {
      plugins = [
        "github.com/caddy-dns/porkbun@v0.2.1"
      ];
      hash = "sha256-5rfdWHT2ah5THFKjcSoN+aTLhnjQYbNFQxQTfXB439I=";
    };
    dataDir = "/data/caddy";
    environmentFile = "/home/caddy/secrets/.env";
  };

a. System environment:

NixOS with systemd running inside an unprivileged LXC container managed by Proxmox.

b. Command:

sudo systemctl restart caddy.service

c. Service/unit/compose file:

[Unit]
Description=Caddy
Documentation=https://caddyserver.com/docs/
After=network.target network-online.target
Requires=network-online.target

[Service]
Type=notify
User=caddy
Group=caddy
ExecStart=/nix/store/x19dvl9rn0x7y0jvfgsv50n3a0s234l5-caddy-2.9.0/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/nix/store/x19dvl9rn0x7y0jvfgsv50n3a0s234l5-caddy-2.9.0/bin/caddy reload --config /etc/caddy/Caddyfile --force
TimeoutStopSec=5s
LimitNOFILE=1048576
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target

d. My complete Caddy config:

{
	debug
}


*.{$MAIN_DOMAIN} {
	tls {
		load /home/caddy/tls
	}
	# tls {
	# 	dns porkbun {
	# 		api_key {env.PORKBUN_API_KEY}
	# 		api_secret_key {env.PORKBUN_API_SECRET_KEY}
	# 	}

	# 	propagation_timeout 60m
	# }
	
	@frigate host frigate.{env.MAIN_DOMAIN}
	
	handle @frigate {
		reverse_proxy /* frigate.shani.{env.INTERNAL_DOMAIN}:443 {
			header_up Host {upstream_hostport}

			transport http {
				tls_insecure_skip_verify
			}
		}
	}
	
	import sites/*

	handle {
		abort
	}
}

5. Links to relevant resources:

I remember systemd has nuance around services accessing /home, but I cannot remember the details. Generally I recommend avoiding putting Caddy files in /home. The /var tree is more apt and less problematic.

Thanks, you were right. I changed it and the permissions issue went away.

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