cert-proxy-client: ssl-cert group grants traversal but cannot read private keys ai:claude-opus-5 #48

Open
opened 2026-08-11 09:20:28 +02:00 by heiko · 0 comments
Owner

Splitting this out of #45, where it surfaced. This is not a regression — the behaviour is identical in the pre-gogogo packaging, so it is a pre-existing design question rather than a packaging bug.

Observation

The client package sets up /var/lib/cert-proxy/certs as 0750 root:ssl-cert (previously via a hand-written dpkg-statoverride in postinst, since 5d5ce00 via systemd/cert-proxy-client.tmpfiles). The apparent intent is that members of ssl-cert — nginx, exim, dovecot, ... — can read the downloaded key material.

They cannot. Only the top-level certs/ directory carries the group; everything below it is root:root:

  • the per-domain subdirectories are created at runtime by shared.Mkdir() (internal/shared/mkdir.go), which calls os.Mkdir(dir, 0777) — so with the usual umask they end up 0755 root:root;
  • privkey.pem is written 0600 by writeFile() (cmd/cert-proxy-client/cert/cert.go, private == true), owner root.

So ssl-cert membership buys directory traversal into certs/ and nothing else. Any consumer that needs a private key must run as root, which makes the group ownership on certs/ decorative.

Question

Which of these is the intended design?

  1. Consumers run as root (they read the key at startup before dropping privileges — the common nginx/exim case). Then the ssl-cert group serves no purpose and the sysusers/tmpfiles snippets could drop it, simplifying the package.
  2. Consumers read keys as ssl-cert. Then the client needs to chgrp/chmod what it writes — roughly 0640 root:ssl-cert for privkey.pem and 0750 root:ssl-cert for the domain directories — presumably behind an option such as -certgroup, since cert-proxy-client also runs on hosts with no ssl-cert group at all (and on Windows).

Option 2 is the only one under which the current directory mode makes sense, but it is a behaviour change and needs a decision before implementation.

Not affected

#45 itself (the missing /etc/cert-proxy/hook and /var/lib/cert-proxy/certs) is fixed by 5d5ce00 and is independent of this.

Splitting this out of #45, where it surfaced. **This is not a regression** — the behaviour is identical in the pre-gogogo packaging, so it is a pre-existing design question rather than a packaging bug. ## Observation The client package sets up `/var/lib/cert-proxy/certs` as `0750 root:ssl-cert` (previously via a hand-written `dpkg-statoverride` in `postinst`, since 5d5ce00 via `systemd/cert-proxy-client.tmpfiles`). The apparent intent is that members of `ssl-cert` — nginx, exim, dovecot, ... — can read the downloaded key material. They cannot. Only the top-level `certs/` directory carries the group; everything below it is `root:root`: * the per-domain subdirectories are created at runtime by `shared.Mkdir()` (`internal/shared/mkdir.go`), which calls `os.Mkdir(dir, 0777)` — so with the usual umask they end up `0755 root:root`; * `privkey.pem` is written `0600` by `writeFile()` (`cmd/cert-proxy-client/cert/cert.go`, `private == true`), owner `root`. So `ssl-cert` membership buys directory traversal into `certs/` and nothing else. Any consumer that needs a private key must run as root, which makes the group ownership on `certs/` decorative. ## Question Which of these is the intended design? 1. **Consumers run as root** (they read the key at startup before dropping privileges — the common nginx/exim case). Then the `ssl-cert` group serves no purpose and the sysusers/tmpfiles snippets could drop it, simplifying the package. 2. **Consumers read keys as `ssl-cert`.** Then the client needs to chgrp/chmod what it writes — roughly `0640 root:ssl-cert` for `privkey.pem` and `0750 root:ssl-cert` for the domain directories — presumably behind an option such as `-certgroup`, since cert-proxy-client also runs on hosts with no `ssl-cert` group at all (and on Windows). Option 2 is the only one under which the current directory mode makes sense, but it is a behaviour change and needs a decision before implementation. ## Not affected #45 itself (the missing `/etc/cert-proxy/hook` and `/var/lib/cert-proxy/certs`) is fixed by 5d5ce00 and is independent of this.
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
heiko/cert-proxy#48
No description provided.