How could we allow non-root users to control a systemd service?

With sysvinit, a sudoers entry like this would suffice:

%webteam cms051=/sbin/service httpd *

This would allow for commands such as:

  • sudo service httpd status
  • sudo service httpd restart

Now, with systemd, the service name is the final argument. I.e., the service restart would be done with:

systemctl restart httpd.service

Naturally, I thought defining the command as systemctl * httpd.service would work but that would allow something like systemctl restart puppet.service httpd.service which is not the desired effect.

With that being considered, what would be the best way allow non-root users to control a systemd service then? This doesn’t need to be sudoers; perhaps a file permission change may be sufficient?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Just add all needed commands to sudoers separately:

%webteam cms051=/usr/bin/systemctl restart httpd.service
%webteam cms051=/usr/bin/systemctl stop httpd.service
%webteam cms051=/usr/bin/systemctl start httpd.service 
%webteam cms051=/usr/bin/systemctl status httpd.service

Method 2

@jofel’s answer was exactly what I needed to get a working setup. POsting this for anyone else stumbling on this question. I needed a way to have capistrano restart my Ruby application after deploying from my local machine. That means I needed passwordless access to restarting systemd services. THIS is what I have and it works wonderfully!

Note: my user and group is called deployer
Put code in a custom file here: /etc/sudoers.d/deployer
Code:

%deployer ALL= NOPASSWD: /bin/systemctl start my_app
%deployer ALL= NOPASSWD: /bin/systemctl stop my_app
%deployer ALL= NOPASSWD: /bin/systemctl restart my_app

Method 3

Create a command alias with the commands you want them to have access to. Then assign the group to that command alias:

Cmnd_Alias APACHE-SVC = /usr/bin/systemctl stop httpd, /usr/bin/systemctl start httpd, /usr/bin/systemctl restart httpd

%webteam ALL=APACHE-SVC

It is also good practice to place any edits in your /etc/sudoers.d/filename rather than directly editing the sudoers file. Make sure to point to your .d/filename in the sudoers, which most new distros do anyway. Placing these 2 lines in your sudoers should do the trick:

## Read drop-in files from /etc/sudoers.d (the # here does not mean a comment)
#includedir /etc/sudoers.d

Note: That # in front of the includedir is not a comment. It must remain.

Method 4

It’s safest to itemize them as jofel suggests.

If I wanted to allow someone to use a limited subset of a command’s abilities, I would not trust wildcards in a sudoers line to do it. Even if the language was more expressive than shell globs, there are just too many corner cases to keep track of.

The “service httpd *” line is relatively safe because (verify this:) service only has one useful flag (--status-all) which doesn’t do anything particularly sensitive, and (verify this too:) /etc/init.d/httpd will only accept the command lines you want to allow.

If there are so many combinations that listing them out becomes awkward, you should probably question what you are doing. But you could give them access to a carefully written helper script that runs the command for them (much like /etc/init.d/http). Even in this case you should be as precise and explicit as possible to list out exactly what commands and options are allowed, and don’t pass any user input directly to the target command.

Method 5

Since many (most?) Unixes and Linuxes that use the systemd init system also provide the service command as a high-level interface to it (source), often could simply keep the same configuration you’re used to from the sysvinit init system.

So, in a a file /etc/sudoers.d/webteam you would write:

%webteam cms051=/sbin/service httpd *

which then enables users in group webteam to use all actions on service httpd when calling with sudo, such as sudo service httpd restart.

Method 6

In RHEL8:

An alternate option is to have an httpd.service file under webteam home directory ~/.config/systemd/user and they can start/stop/enable etc themselves:

systemctl --user enable httpd.service
systemctl --user start httpd.service

Validated that the above works as long as the user has permission to start the service. This seems useful on dev systems allowing the developers to also do timers and pipelines effectively with all the configs available to them as supposed to in devops/ops hands.

Also seems like it would be beneficial for moving it to prod with the whole startup sequence tested in an actual server environment using the operations built httpd, and not have the devs say “but it worked on my laptop and broke when I pushed to dev”. But I am just thinking and writing here.

Best online ref, as the systemd user documentation is not copious:

https://wiki.archlinux.org/title/systemd/User


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x