Index | Thread | Search

From:
Stuart Henderson <stu@spacehopper.org>
Subject:
Re: lack of privsep in acme-client(1) - thoughts?
To:
Lloyd <ng2d68@proton.me>
Cc:
tech <tech@openbsd.org>
Date:
Tue, 16 Dec 2025 11:29:43 +0000

Download raw body.

Thread
On 2025/12/16 07:33, Lloyd wrote:
> One of my biggest issues with acme-client(1) - which does string parsing
> of untrusted input from the network - is shown below:
> 
> if (getuid() != 0)
> 	errx(EXIT_FAILURE, "must be run as root");
> 
> AFAIK there is no justified need to run acme-client child processes as
> root, and it could fare better with a dedicated user and some tidying up
> of file locations.
> 
> I think it's one of the few utilities in base that does not do this.

acme-client is one of the few utilities in base that was written to use
pledge from very early on.

the 'portable' version of acme-client (which was archived in 2018 and
I don't think is usable any more) switched uid but the pledges in the
subprocesses are so strong that IIRC this wasn't deemed necessary to
keep.

most subprocs have pledge "stdio" so are extremely restricted (i'm not
100% certain but i think the remaining allowed syscalls are ones which
don't need to check privs anyway)

the others are

chngproc; "stdio cpath wpath" in challenge dir only
dnsproc; r access to files involved in dns resolution
fileproc; "stdio cpath wpath rpath fattr" restricted to certdir only
netproc; r access to /etc/ssl/cert.pem, revoked after connecting

it doesn't seem like dropping root will actually help improve security?

> I'm willing to code up some basic privsep but am unsure of the logistics.
> 
> Ideally the following would need to happen:
> 
> 1. A new UID/GID _acme/_acme are created (how are they checked out)?
> 
> 2. /var/www/acme should be set to 0775 root:_acme
> 
> 3. /etc/acme should be set to 0770 root:_acme
> 
> 4. Certificate storage - needs to be writable - create /etc/ssl/acme
>    and /etc/ssl/acme/private - or leave this up to the user? Needs to
>    be writable by _acme user/group - keys should be protected.

those changes would make it a lot more awkward for some use-cases.

for example, if you have various daemons running as different uids that
need access to keys then you either need to create separate groups for
each of them + _acme, and then _acme will be in many supplemental groups
and you can bump into NGROUPS_MAX fairly easily.