[systemd-devel] Running a systemd service in capability-only environment as non-root user

Serge Hallyn serge.hallyn at ubuntu.com
Tue May 27 15:07:34 PDT 2014


Quoting Mantas Mikulėnas (grawity at gmail.com):
> On Tue, May 27, 2014 at 4:31 PM, Michal Witanowski
> <m.witanowski at samsung.com> wrote:
> > Hi,
> >
> > first of all I'd like to mark that I'm not sure if I'm writing in the right
> > place.
> >
> > I have a problem with running a systemd service in "capability-only
> > environment": I want to run a process with some caps (cap_sys_admin
> > cap_dac_override cap_mac_override) as a regular user (UID != 0).
> > My service config file looks something like this:
> >
> > User=test
> > CapabilityBoundingSet=cap_sys_admin cap_dac_override cap_mac_override
> > Capabilities=cap_sys_admin,cap_dac_override,cap_mac_override=eip
> > SecureBits=keep-caps
> >
> > Unfortunately, the process does not gain any permissive capabilities:
> >
> > CapInh: 0000000100200002
> > CapPrm: 0000000000000000
> > CapEff: 0000000000000000
> > CapBnd: 0000000100200002
> >
> > However, when I run the service as root (by removing "User=test") the
> > process does own required caps:
> >
> > CapInh: 0000000100200002
> > CapPrm: 0000000100200002
> > CapEff: 0000000100200002
> > CapBnd: 0000000100200002
> 
> Does the executable file itself have these capabilities set as "=ei"?
> 
> According to the same manual page, each capability must be set as
> inheritable for both the process and the file, to receive them _at
> all_...
> 
> "P'(permitted) = (P(inheritable) & F(inheritable)) | (F(permitted) & cap_bset)"
> 
> ...and as effective on the file, otherwise the new process has to
> manually 'enable' them:
> 
> "P'(effective) = F(effective) ? P'(permitted) : 0"
> 
> ...or at least that seems to be how it works. Damn thing is confusing.

Correct.  keep_caps is about not dropping the capabilities when dropping
all 0 uids, i.e. when systemd does setuid(test).  But systemd is going
to proceed to exec(), causing the capabilities to be re-execed from
there.

So as Mantas wrote, I think what you want is to set
cap_sys_admin,cap_dac_override,cap_mac_override=ie to the file you are
executing.  So long as you don't also set it to 'p', this should be ok
as only processes with cap_sys_admin,cap_dac_override,cap_mac_override=i
will inherit it from the file.

Kinda neat, I especially like the ability to also lock the
service into no-setuid and noroot secbits.

-serge


More information about the systemd-devel mailing list