Linux Manage system services as non root user - chaitanyavangalapudi/devops-scripts GitHub Wiki
systemd does not allow non root users to start or stop system services. But sometimes we require non-root users also to manage system services for continuous integration and deployment purposes. We can use sudo to configure command-sudo rules allowing users and/or groups to trigger specific set of systemctl commands that require sudo access to a particular user/group. You may associate sudo with providing access equivalent to root, but it can be also be used to allow a specific user root access for a specific, limited set of commands.
In our case, let us assume that we want to run nginx process as non-root user (deployment) and below are our target commmands. You may need to install sudo package to have sudo available on your system.
/usr/bin/journalctl
/usr/bin/systemctl start nginx
/usr/bin/systemctl restart nginx
/usr/bin/systemctl stop nginx
nginx -t
Note: /usr/bin/systemctl status nginx (/usr/bin/systemctl status *) doesn't require sudo access. It can be run by any user, hence doesn't require sudo access.
Sudo access can be given to a user either by editing the /etc/sudoers file or placing separate file under /etc/sudoers.d/ for a specific user.
Method #1 Editing /etc/sudoers
Follow the steps below to configure sudo rules for non-root user (in our case deployment) to run a specific systemctl command.
Step #1 Use the command “visudo” to configure the sudo rules to allow deployment user to run commands specified above for nginx process
Edit your /etc/sudoers file with visudo (or vi /etc/sudoers) to add a Cmd_alias for the commands you want the unprivileged user to be able to use. Then add a line to allow the user to use the commands defined with the alias like below:
visudo
## Manage specific systemd services
Cmnd_Alias SYSTEMD_NGINX = /usr/bin/journalctl, /usr/bin/systemctl start nginx, /usr/bin/systemctl restart nginx, /usr/bin/systemctl stop nginx, nginx -t
deployment ALL = SYSTEMD_NGINX
Step #2 Run the command Without sudo
$ systemctl restart nginx
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===
Authentication is required to manage system services or units.
Authenticating as: root
Password:
Step #3 Run the command with sudo
$ sudo systemctl restart nginx
$ echo $?
0
Step #4 Running a command not specified in sudoers file
[deployment@localhost ~]$ sudo systemctl restart dockerd
We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:
#1) Respect the privacy of others.
#2) Think before you type.
#3) With great power comes great responsibility.
[sudo] password for deployment:
Step #5 Running a command for process specified in sudoers file but adding .service string
[deployment@localhost ~]$ sudo systemctl restart nginx.service
We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:
#1) Respect the privacy of others.
#2) Think before you type.
#3) With great power comes great responsibility.
[sudo] password for deployment:
NOTE: sudoers requires exact syntax specified in the file, so care needs to be taken to ensure the commands specified match with the expected commands to be run.
As seen in the example below “nginx.service” and “nginx” are actually the same when we use them with systemctl but for the sudoers file they are 2 different commands and will throw an error as shown below:
NOTE: If you want sudo command for a user without password add line like below for that particular user with NOPASSWD
## Same thing without a password
deployment ALL= NOPASSWD: /usr/bin/systemctl start jenkins
deployment ALL= NOPASSWD: /usr/bin/systemctl stop jenkins
deployment ALL= NOPASSWD: /usr/bin/systemctl restart jenkins
deployment ALL= /usr/bin/systemctl restart crond
Method #2 Adding separate file under /etc/sudoers.d for each user
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 sudoers.d/filename in the sudoers, which most new distros do anyway. Placing these 2 lines in your sudoers file 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 as it is.
Add below lines to a new file /etc/sudoers.d/deployment
deployment ALL= NOPASSWD: /usr/bin/systemctl start jenkins
deployment ALL= NOPASSWD: /usr/bin/systemctl stop jenkins
deployment ALL= NOPASSWD: /usr/bin/systemctl restart jenkins
deployment ALL= /usr/bin/systemctl restart crond
Other Configurations
Suppose you want to give access to a group of users (let us say group name is deployment), then you can use configuration like below to give them sudo access (/etc/sudoers.d/deployment
)
## Allows people in group deployment to run all commands
%deployment ALL=(ALL) ALL
## Same thing without a password
# %deployment ALL=(ALL) NOPASSWD: ALL
## Allows members of the users group to mount and unmount the
## cdrom as root
# %users ALL=/sbin/mount /mnt/cdrom, /sbin/umount /mnt/cdrom
%deployment ALL=/usr/bin/systemctl restart httpd.service
%deployment ALL=/usr/bin/systemctl stop httpd.service
%deployment ALL=NOPASSWD: /usr/bin/systemctl start httpd.service
Cmnd_Alias SYSTEMD_NGINX = /usr/bin/journalctl, /usr/bin/systemctl start nginx, /usr/bin/systemctl restart nginx, /usr/bin/systemctl stop nginx, nginx -t
%deployment ALL=NOPASSWD: SYSTEMD_NGINX
References: