Using PolicyKit to allow non-root users to start and stop a service
Asked Answered
M

3

6

I have a requirement to allow non-root users to start and stop a service. It was recommended to me to use PolicyKit rather than sudoers.d, which I am familiar with.

As I have no experience with PolicyKit, I thought I would experiment and create a rule to allow non-root users to start and stop the Docker service. I have created a file, /etc/polkit-1/rules.d/10-docker.rules containing:

polkit.addRule(function(action, subject) {
    if (action.id == "org.freedesktop.systemd1.manage-units" &&
        action.lookup("unit") == "docker.service")
    {
        return polkit.Result.YES;
    }
})

However, whenever I execute systemctl start|stop|restart docker.service, I keep getting prompted for a password. What am I missing?

Also, I would like to limit non-root users to control this service who are in a specific group e.g. blah. How do I incorporate this into my rule?

My target OS is RHEL 7.7.

Masteratarms answered 28/4, 2020 at 13:6 Comment(1)
I don"t use RHEL 7.7, so not sure. It seems that RHEL 7.7 use old polkit with pkla files and new polkit with rules files! I think you must defined a action in /etc/polkit-1/action for docker.service.Grout
E
2

As pointed out by Simão, the unit information is not supplied to polkit by systemd on RHEL 7. One way around the problem is to use pkexec to wrap the call to systemctl. You would need a wrapper script for your specific service, then have the rules apply to pkexec. The users would execute the command

pkexec /path/to/script

and the polkit rule would look something like this:

  polkit.addRule( 
  function(action,subject)
  {
    if ( (action.id == "org.freedesktop.policykit.exec") &&
         (action.lookup("user") == "root") &&
         (action.lookup("program") == "/path/to/script") &&
         (subject.isInGroup("someGroup") ) )
      return polkit.Result.YES;

    return polkit.Result.NOT_HANDLED;
  }
);

In a practical sense, this just re-creates sudo and scripts using the polkit framework. Whether this is "better" than using sudo is a value judgement I'll leave to others.

Ectomere answered 19/3, 2022 at 2:17 Comment(0)
S
1

On CentOS7, action does not have access to the unit information. This was introduced on a later systemd version, v226.

https://github.com/systemd/systemd/commit/88ced61bf9673407f4b15bf51b1b408fd78c149d

I was also hit by this. You will need to allow the user to manage all units or go back to the stone age of having shell scripts on sudoers.

Also, I would like to limit non-root users to control this service who are in a specific group e.g. blah. How do I incorporate this into my rule?

Use subject.isInGroup("group").

See:

Sublime answered 18/6, 2020 at 12:56 Comment(0)
C
0

/etc/polkit-1/rules.d/10-docker.rules

polkit.addRule(function(action, subject) {
  if (action.id == "org.freedesktop.systemd1.manage-units" &&
    action.lookup("unit") == "docker.service")  &&
    subject.isInGroup("mygroup"))
    {
      return polkit.Result.YES;
    }
})

Also you need to run visudo and add these lines

%mygroup ALL= NOPASSWD: /usr/bin/systemctl restart docker.service
%mygroup ALL= NOPASSWD: /usr/bin/systemctl stop docker.service
%mygroup ALL= NOPASSWD: /usr/bin/systemctl start docker.service
%mygroup ALL= NOPASSWD: /usr/bin/systemctl status docker.servicee

Tutorial: https://keshavarzreza.ir/create-linux-systemd-service-runable-for-non-root-users/

Corded answered 3/9, 2020 at 18:27 Comment(1)
there's no reason to use both sudo and polkit.Dorsoventral

© 2022 - 2024 — McMap. All rights reserved.