118

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?

Josip Rodin
  • 1,138
  • I haven't touched a sudo configuration in a while, but couldn't you just do something like cms051=systemctl * httpd.service ? – John WH Smith Mar 26 '15 at 17:29
  • 1
    This would allow you to restart any service then. I should have included that tidbit in the question. Sorry. – Belmin Fernandez Mar 26 '15 at 17:30
  • 3
    None of the answers here even touches upon PolicyKit, as described in answers to https://unix.stackexchange.com/q/496982/5132 , even though the question states that the mechanism does not have to be sudo. – JdeBP May 01 '20 at 05:19

6 Answers6

77

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 
Pro Backup
  • 4,924
jofel
  • 26,758
75

@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
16

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.

don_crissti
  • 82,805
Rich
  • 161
  • How add chance to execute stop/start/restart whithout enter password? – Nikolay Baranenko Oct 18 '18 at 10:58
  • Best answer IMO. Everyone should add a command alias and work with this. – DASKAjA Feb 22 '19 at 14:25
  • Managed to lock myself out of my system by doing this, since one doesn't have the automatic safety check of visudo and sudo does not aut roll back to a working version. Calling this "good practice" seems questionable to me. – goldfishalpha Aug 15 '22 at 19:51
8

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.

Jander
  • 16,682
8

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

Greenonline
  • 1,851
  • 7
  • 17
  • 23
  • This should be the accepted answer. - Here's another in depth look at the approach: https://computingforgeeks.com/how-to-run-systemd-service-without-root-sudo/ – asimovwasright Nov 07 '22 at 09:51
  • 1
    This answer describes how to run a service as a non root user. What this question is about is a non root user controlling a standard systemd service, the other way around. – Graham Leggett Sep 13 '23 at 14:06
1

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.

tanius
  • 874