[Solved] Caddy permission denied when running as systemd after manual installation

1. The problem I’m having:

I have just manually installed caddy v2.8.4 h1:q3pe0wpBj1OcHFZ3n/1nl4V4bxBrYoSoab7rL9BMYNk=. I picked the caddy_2.8.4_linux_amd64.tar.gz from Github packages and there is simply a caddy executable inside.

I followed the instructions from the manual installation documentation.

I have run

$ sudo setcap cap_net_bind_service=+ep $(which caddy)

In the error messages, there are these specific lines:

Sep 25 19:17:12 localhost.localdomain (caddy)[3169]: caddy.service: Failed to locate executable /usr/bin/caddy: Permission denied
Sep 25 19:17:12 localhost.localdomain (caddy)[3169]: caddy.service: Failed at step EXEC spawning /usr/bin/caddy: Permission denied
Sep 25 19:17:12 localhost.localdomain systemd[1]: caddy.service: Child 3169 belongs to caddy.service.
Sep 25 19:17:12 localhost.localdomain systemd[1]: caddy.service: Main process exited, code=exited, status=203/EXEC
Sep 25 19:17:12 localhost.localdomain systemd[1]: caddy.service: Failed with result 'exit-code'.

However, I have eXecutable right for all users.

$ ls -al /usr/bin/caddy
-rwxr-xr-x. 1 root root 40681624 Jun  2 20:10 /usr/bin/caddy

And I can manually run caddy as the caddy user using

$ sudo -u caddy whoami
caddy

$ sudo -u caddy /usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
2024/09/25 11:26:22.449	INFO	using config from file	{"file": "/etc/caddy/Caddyfile"}
2024/09/25 11:26:22.449	INFO	adapted config to JSON	{"adapter": "caddyfile"}
2024/09/25 11:26:22.450	INFO	admin	admin endpoint started	{"address": "localhost:2019", "enforce_origin": false, "origins": ["//localhost:2019", "//[::1]:2019", "//127.0.0.1:2019"]}
2024/09/25 11:26:22.451	INFO	tls.cache.maintenance	started background certificate maintenance	{"cache": "0xc00035fe80"}
2024/09/25 11:26:22.452	WARN	tls	stapling OCSP	{"error": "no OCSP stapling for [hk]: no OCSP server specified in certificate"}
2024/09/25 11:26:22.452	INFO	http.auto_https	automatic HTTP->HTTPS redirects are disabled	{"server_name": "srv0"}
2024/09/25 11:26:22.452	INFO	http	enabling HTTP/3 listener	{"addr": ":8000"}
2024/09/25 11:26:22.452	INFO	failed to sufficiently increase receive buffer size (was: 208 kiB, wanted: 7168 kiB, got: 416 kiB). See https://github.com/quic-go/quic-go/wiki/UDP-Buffer-Sizes for details.
2024/09/25 11:26:22.452	INFO	http.log	server running	{"name": "srv0", "protocols": ["h1", "h2", "h3"]}
2024/09/25 11:26:22.452	INFO	autosaved config (load with --resume flag)	{"file": "/var/lib/caddy/.config/caddy/autosave.json"}
2024/09/25 11:26:22.452	INFO	serving initial configuration
2024/09/25 11:26:22.453	INFO	tls	storage cleaning happened too recently; skipping for now	{"storage": "FileStorage:/var/lib/caddy/.local/share/caddy", "instance": "89d4c866-0f96-46f2-a41f-8eda924f30a4", "try_again": "2024/09/26 11:26:22.453", "try_again_in": 86399.999999803}
2024/09/25 11:26:22.453	INFO	tls	finished cleaning storage units

$ [user@localhost ~]$ curl -k -D- https://localhost:8000
HTTP/2 200 
alt-svc: h3=":8000"; ma=2592000
content-type: text/html; charset=utf-8
date: Wed, 25 Sep 2024 11:28:53 GMT
etag: W/"c9-tkH+OagGKX3eLy85A53ATPJW+TE"
server: Caddy
x-powered-by: Express
content-length: 201

...

2. Error messages and/or full log output:

$ journalctl -u caddy --no-pager | less +G

Sep 25 19:17:12 localhost.localdomain systemd[1]: caddy.service: Trying to enqueue job caddy.service/restart/replace
Sep 25 19:17:12 localhost.localdomain systemd[1]: caddy.service: Installed new job caddy.service/restart as 779
Sep 25 19:17:12 localhost.localdomain systemd[1]: caddy.service: Enqueued job caddy.service/restart as 779
Sep 25 19:17:12 localhost.localdomain systemd[1]: caddy.service: Job 779 caddy.service/restart finished, result=done
Sep 25 19:17:12 localhost.localdomain systemd[1]: caddy.service: Converting job caddy.service/restart -> caddy.service/start
Sep 25 19:17:12 localhost.localdomain systemd[1]: caddy.service: Passing 0 fds to service
Sep 25 19:17:12 localhost.localdomain systemd[1]: caddy.service: About to execute /usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
Sep 25 19:17:12 localhost.localdomain systemd[1]: caddy.service: Forked /usr/bin/caddy as 3169
Sep 25 19:17:12 localhost.localdomain systemd[1]: caddy.service: Changed failed -> start
Sep 25 19:17:12 localhost.localdomain systemd[1]: Starting Caddy...
Sep 25 19:17:12 localhost.localdomain systemd[1]: caddy.service: User lookup succeeded: uid=982 gid=982
Sep 25 19:17:12 localhost.localdomain (caddy)[3169]: Bind-mounting / on /run/systemd/unit-root (MS_BIND|MS_REC "")...
Sep 25 19:17:12 localhost.localdomain (caddy)[3169]: Applying namespace mount on /run/systemd/unit-root/boot
Sep 25 19:17:12 localhost.localdomain (caddy)[3169]: Applying namespace mount on /run/systemd/unit-root/efi
Sep 25 19:17:12 localhost.localdomain (caddy)[3169]: Applying namespace mount on /run/systemd/unit-root/etc
Sep 25 19:17:12 localhost.localdomain (caddy)[3169]: Bind-mounting /run/systemd/unit-root/etc on /run/systemd/unit-root/etc (MS_BIND|MS_REC "")...
Sep 25 19:17:12 localhost.localdomain (caddy)[3169]: Successfully mounted /run/systemd/unit-root/etc to /run/systemd/unit-root/etc
Sep 25 19:17:12 localhost.localdomain (caddy)[3169]: Applying namespace mount on /run/systemd/unit-root/run/credentials
Sep 25 19:17:12 localhost.localdomain (caddy)[3169]: Bind-mounting /run/systemd/inaccessible/dir on /run/systemd/unit-root/run/credentials (MS_BIND|MS_REC "")...
Sep 25 19:17:12 localhost.localdomain (caddy)[3169]: Successfully mounted /run/systemd/inaccessible/dir to /run/systemd/unit-root/run/credentials
Sep 25 19:17:12 localhost.localdomain (caddy)[3169]: Applying namespace mount on /run/systemd/unit-root/run/systemd/incoming
Sep 25 19:17:12 localhost.localdomain (caddy)[3169]: Followed source symlinks /run/systemd/propagate/caddy.service → /run/systemd/propagate/caddy.service.
Sep 25 19:17:12 localhost.localdomain (caddy)[3169]: Bind-mounting /run/systemd/propagate/caddy.service on /run/systemd/unit-root/run/systemd/incoming (MS_BIND "")...
Sep 25 19:17:12 localhost.localdomain (caddy)[3169]: Successfully mounted /run/systemd/propagate/caddy.service to /run/systemd/unit-root/run/systemd/incoming
Sep 25 19:17:12 localhost.localdomain (caddy)[3169]: Applying namespace mount on /run/systemd/unit-root/tmp
Sep 25 19:17:12 localhost.localdomain (caddy)[3169]: Bind-mounting /tmp/systemd-private-f69532597e214c06939989bffc9584c4-caddy.service-GQU48b/tmp on /run/systemd/unit-root/tmp (MS_BIND|MS_REC "")...
Sep 25 19:17:12 localhost.localdomain (caddy)[3169]: Successfully mounted /tmp/systemd-private-f69532597e214c06939989bffc9584c4-caddy.service-GQU48b/tmp to /run/systemd/unit-root/tmp
Sep 25 19:17:12 localhost.localdomain (caddy)[3169]: Applying namespace mount on /run/systemd/unit-root/usr
Sep 25 19:17:12 localhost.localdomain (caddy)[3169]: Bind-mounting /run/systemd/unit-root/usr on /run/systemd/unit-root/usr (MS_BIND|MS_REC "")...
Sep 25 19:17:12 localhost.localdomain (caddy)[3169]: Successfully mounted /run/systemd/unit-root/usr to /run/systemd/unit-root/usr
Sep 25 19:17:12 localhost.localdomain (caddy)[3169]: Applying namespace mount on /run/systemd/unit-root/var/tmp
Sep 25 19:17:12 localhost.localdomain (caddy)[3169]: Bind-mounting /var/tmp/systemd-private-f69532597e214c06939989bffc9584c4-caddy.service-DIGXdO/tmp on /run/systemd/unit-root/var/tmp (MS_BIND|MS_REC "")...
Sep 25 19:17:12 localhost.localdomain (caddy)[3169]: Successfully mounted /var/tmp/systemd-private-f69532597e214c06939989bffc9584c4-caddy.service-DIGXdO/tmp to /run/systemd/unit-root/var/tmp
Sep 25 19:17:12 localhost.localdomain (caddy)[3169]: Remounted /run/systemd/unit-root/boot/efi.
Sep 25 19:17:12 localhost.localdomain (caddy)[3169]: Remounted /run/systemd/unit-root/boot.
Sep 25 19:17:12 localhost.localdomain (caddy)[3169]: Remounted /run/systemd/unit-root/etc.
Sep 25 19:17:12 localhost.localdomain (caddy)[3169]: Remounted /run/systemd/unit-root/run/credentials.
Sep 25 19:17:12 localhost.localdomain (caddy)[3169]: Remounted /run/systemd/unit-root/run/systemd/incoming.
Sep 25 19:17:12 localhost.localdomain (caddy)[3169]: Remounted /run/systemd/unit-root/usr.
Sep 25 19:17:12 localhost.localdomain (caddy)[3169]: Remounted /run/systemd/unit-root/run/credentials.
Sep 25 19:17:12 localhost.localdomain (caddy)[3169]: caddy.service: Failed to locate executable /usr/bin/caddy: Permission denied
Sep 25 19:17:12 localhost.localdomain (caddy)[3169]: caddy.service: Failed at step EXEC spawning /usr/bin/caddy: Permission denied
Sep 25 19:17:12 localhost.localdomain systemd[1]: caddy.service: Child 3169 belongs to caddy.service.
Sep 25 19:17:12 localhost.localdomain systemd[1]: caddy.service: Main process exited, code=exited, status=203/EXEC
Sep 25 19:17:12 localhost.localdomain systemd[1]: caddy.service: Failed with result 'exit-code'.
Sep 25 19:17:12 localhost.localdomain systemd[1]: caddy.service: Service will not restart (restart setting)
Sep 25 19:17:12 localhost.localdomain systemd[1]: caddy.service: Changed start -> failed
Sep 25 19:17:12 localhost.localdomain systemd[1]: caddy.service: Job 779 caddy.service/start finished, result=failed
Sep 25 19:17:12 localhost.localdomain systemd[1]: Failed to start Caddy.
Sep 25 19:17:12 localhost.localdomain systemd[1]: caddy.service: Unit entered failed state.
Sep 25 19:17:12 localhost.localdomain systemd[1]: caddy.service: Releasing resources...

3. Caddy version:

v2.8.4 h1:q3pe0wpBj1OcHFZ3n/1nl4V4bxBrYoSoab7rL9BMYNk=

4. How I installed and ran Caddy:

Manually installation with reference to the official manual installation documentation and running as a systemd service.

a. System environment:

OS=openEuler 22.03 LTS-SP3 (treat it as CentOS-7 with more up-to-date kernel)
Architecture=amd x86
$ systemctl --version=systemd 249 (v249-80.oe2203sp3)

b. Command:

[user@localhost ~]$ sudo systemctl restart caddy
Job for caddy.service failed because the control process exited with error code.
See "systemctl status caddy.service" and "journalctl -xeu caddy.service" for details.

c. Service/unit/compose file:

# /etc/systemd/system/caddy.service
[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=/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/usr/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:

# /etc/caddy/Caddyfile
{
        auto_https disable_redirects
}

:8000 {
        reverse_proxy localhost:3000

        tls "/etc/caddy/cert/server_cert.crt" "/etc/caddy/cert/server_key.key" {
                key_type rsa4096
        }

        log {
                format console
                output file /var/log/caddy.log {
                        roll_size 100MiB
                        roll_local_time
                        roll_keep 10
                        roll_keep_for 30d
                }
        }
}

5. Links to relevant resources:

This post seems related but it doesn’t help.

OK, I solved it by writing

ExecStart=sh -c "/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile"
ExecReload=sh -c "/usr/bin/caddy reload --config /etc/caddy/Caddyfile --force"

in the caddy.service file. Somehow the sh -c trick works.

That’s really weird. Do you have something like SELinux going on? It might be blocking access to the binary to systemd.

1 Like

Okay! Seems like SELinux is doing its thing.

$ sudo ausearch -m avc -f caddy -i
type=AVC msg=audit(09/25/2024 19:17:12.848:203) : avc:  denied  { execute } for  pid=3169 comm=(caddy) name=caddy dev="dm-0" ino=20064656 scontext=system_u:system_r:init_t:s0 tcontext=unconfined_u:object_r:user_home_t:s0 tclass=file permissive=0 

I will leave it as is for now and use the sh -c method. Thanks.

You might want to consider using systemd overrides instead of editing the existing service file (so that if we push changes to the service file, your changes don’t get overwritten).

3 Likes

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