Linux create service user

How to run systemd service as specific user and group in Linux

Table of Contents

By default most of the systemd services are configured to run by root user but there is also an option to create a custom systemd service unit file and run it as a speciic user or group or both. So in this article we will check and verify the steps to run systemd service as specific user and group using CentOS/RHEL 7/8 Linux environment.

I have installed Oracle VirtualBox on a Linux server, where I will use a Virtual Machine with RHEL/CentOS 7/8 to verify the steps from this article.

Some more articles on similar topic:

Step 1: Overview on systemd

I hope you are already familiar with below topics

Step 2: Create user and Group

Now this is an optional steps assuming you already have your user and group ready for next steps. But if you do not then you can follow this article to create a new user and assign a custom group (primary or secondary) to the respective user.

Here I have already created a user deepak who is part of deepak and admin group

To verify the groups of any user

So we wish to create a systemd service unit file and run systemd service as specific user and group which for us will be deepak user part of admin group

Step 3: Create Sample Script

We will use our startup script from old articles with some tweaks to check and run systemd service as specific user and group in Linux

So in this script we have added an explicit check for user, so unless the user executing the script is » deepak «, the script will fail to execute. If successful the script will continue to write in /tmp/file for 3 minutes with 1 minute interval. This will also help us make sure that the script does not exits before completing it’s defined task

Change the ownership of the script file to deepak

Provide executable permission to the script

We will execute the script manually to make sure it works as expected

Step 4: Create unit file to run systemd service as specific user and group

Now as highlighted under step 1, I have already written another article with the steps to create a new systemd unit file. Here we will name our systemd unit file as run-as-user.service under /etc/systemd/system . Below is the content of run-as-user.service

Here we have defined User=deepak and Group=admin to make sure the script will be executed only as user deepak which is part of admin group.
You can also use many other directives if required in your environment such as WorkingDirectory , EnvironmentFile etc. For more information check man page of systemd.exec

Refresh the systemd configuration files

Next enable the service (if required) to start automatically at boot

Step 5: Verify the systemd unit file configuration

Now since we are done with the setting up of systemd. Let us verify our configuration. Before starting I have cleared the content of /tmp/file which is where our script /tmp/startup_script.sh will place dummy content every minutes for 3 minutes.

We will only start the run-as-user.service runtime as a reboot is not required to validate the configuration here:

Next check the status of the service

Well looks like everything was good as we were able to run systemd service as specific user and group, you can check the ps status to make sure our script is running using below command:

Now you can monitor the content of /tmp/file for couple of minutes as configured in the script

Lastly I hope the steps from the article to run systemd service as specific user and group in CentOS/RHEL 7/8 Linux was helpful. So, let me know your suggestions and feedback using the comment section.

Related Searches: run service as user linux. systemd allow user to start service. systemd start service as user on boot. linux systemd service run as root. Restarting systemd service only as a specific user? systemd services fail with User= in service file. Start process as a specific user. how to run a service a non-root user completely?

Didn’t find what you were looking for? Perform a quick search across GoLinuxCloud

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

For any other feedbacks or questions you can either use the comments section or contact me form.

Thank You for your support!!

19 thoughts on “How to run systemd service as specific user and group in Linux”

what is the “admin” group? I have a “root” group, but not an admin group.

admin group used here is an example

Shouldn’t systemd’s “–user” feature be used to allow non-root accounts run their own services — without bothering the root-wielding admin every time they want to change something?

I’d love an actual example of that…

Any application level service is executed by normal user such as apache

Man you really helped me thanks a lot dude!

Loved! Very well explained!

This is really helpful, thank you. It is also rather timely as I’m trying to get a service to work with a little twist and maybe you have some insight to this.

I’m running VirtualBox with a Ubuntu 20.04 guest and a Windows 10 host. The VM is defined with a shared folder on the host.
I need to run the service as my user and it has to create some files and directories in the shared folder.
There are some really weird things happening.
– I am unable to write anything to the shared folder when I run the script as a service. I always get “Permission Denied” errors.
No problem if I run the service as “sudo service xxx start”, only when it is started on system init. I specifically have an
“After=.mount” in the Init section.

Читайте также:  Как форматировать загрузочную флешку с линуксом

– If I run using “+” before the script name on ExecStart, it runs as root and creates files, but then they just disappear. Actually,
they show up only in the script (e.g. if I issue an “ls” command) but by the time I get to log in, they are gone.

Anyway, I’m tearing what little hair I have out on this and can’t get anywhere. Any insight would be greatly appreciated.

Sorry, I didn’t realize I couldn’t use angle brackets. My “After=.mount” should have been “After=shared-folder-dir.mount”, copied from the systemctl list-units list.

Hi Alan,
If there is a requirement for a certain file system then instead of After= you should use RequiresMountsFor=/path/to/fs .
Few questions:
If you just run the script as the user, is the script able to perform write operations in the shared folder? – I assume yes?
Because if this works, there is no reason it will fail as systemctl service.
Or do you see problems writing at reboot stage?
If I have more information, I may try to replicate the behaviour in my environment.

I see there are lot of comments. Can you please consolidate and send me a mail

Thanks for the response and for taking a look at this, to answer your questions:

– Just running the service after I log in, everything works, I can write to the shared folder with the service.
– the really weird thing is that I have echo statements showing that when I run as root:
– I can write to the shared folder
– the script sees the files and directories via ls right after creation
– they go away at some point. there is no delete for these files anywhere, but some of them are accessed
by a java program that the script is calling. some are not. but they all disappear by the time I can log in
and look.

Thanks for sharing the additional information, I will not approve the script as that may be confidential.
Give me time till tomorrow, let me try to replicate this and come back. I am also little occupied with my office work.
I assume you are using samba for file sharing.
We can further communicate using your mail address. You can send mail to admin@golinuxcloud.com

First, Thanks a lot for this nice tutorial. This is what i am looking for.

But I faced a problem. In my one test VM, it works fine and then I have tried to do the same procedure in another machine (important vm) but the service has not started. I have tried to start the application manually it works fine (owner of statsup.sh is non-root user).

Then I commented out the User and Group in a Unit file under systemd and it works again. So I guess the problem is with the systemd service file. Kindly give me some idea what to do?

Thank you for your feedback.
Does if work if you try to start the application using the systemd service manually?
Did you checked “journalctl -b” logs for any hint?

One hint from Journalctl >> catalina.sh said permission denied (as my application call catalina.sh)
In my VM no tomcat service and owner of catalina.sh is root
but in my target machine (where i have problem) there is a tomcat service and its stopped and owner of catalina.sh is tomcat
And What does it mean to start the application using the systemd service manually? (i am a newbie)
Can you please give me any idea what to do?

I am not sure if I understand the scenario completely. On your target VM if your service is supposed to be started as root then you can remove the User and Group argument in the systemd unit file. The idea is to understand the requirement first, you mentioned that systemd service fails to start the service automatically so does that mean the service ends up being ‘dead’ or the service is not started at all.

Can the service use a domain user instead of the local user when running.
E.g We have a domain user that will have access to the MSSQL DB on some server
Our client machine is redhat linux on which tomcat is running as a service.
Our client machine is already added to the same domain as the MSSQL DB
The servlet in our tomcat needs to access the MSSQL DB
Instead of SQL Authentication, we want to use windows authentication for this purpose
Now how can we run the tomcat as the same domain user that has access to the MSSQL DB ?

You can just place the username in the User=USERNAME field without any domain details. For ex if your mysqldb user is dbadmin then just place User=dbadmin and it should work. Unless you also have a local user names dbadmin in which case there can be conflict so you will have to delete the local user.

How can I check whether we have systemd privileges or not ?

By default non root users don’t have privilege to use systemd to restart/start/stop services but they should have permission to check the status. You may try to restart any service such as sshd and if you don’t have privilege then the same should fail

Источник

systemd/User

systemd offers users the ability to manage services under the user’s control with a per-user systemd instance, enabling users to start, stop, enable, and disable their own user units. This is convenient for daemons and other services that are commonly run for a single user, such as mpd, or to perform automated tasks like fetching mail.

Contents

How it works

As per default configuration in /etc/pam.d/system-login , the pam_systemd module automatically launches a systemd —user instance when the user logs in for the first time. This process will survive as long as there is some session for that user, and will be killed as soon as the last session for the user is closed. When #Automatic start-up of systemd user instances is enabled, the instance is started on boot and will not be killed. The systemd user instance is responsible for managing user services, which can be used to run daemons or automated tasks, with all the benefits of systemd, such as socket activation, timers, dependency system or strict process control via cgroups.

Читайте также:  Шаблон имени файла windows

Similarly to system units, user units are located in the following directories (ordered by ascending precedence):

    /usr/lib/systemd/user/ where units provided by installed packages belong.

/.local/share/systemd/user/ where units of packages that have been installed in the home directory belong.
/etc/systemd/user/ where system-wide user units are placed by the system administrator.

/.config/systemd/user/ where the user puts their own units.

When a systemd user instance starts, it brings up the per user target default.target . Other units can be controlled manually with systemctl —user . See systemd.special(7) § UNITS MANAGED BY THE USER SERVICE MANAGER .

Basic setup

All the user units will be placed in

/.config/systemd/user/ . If you want to start units on first login, execute systemctl —user enable unit for any unit you want to be autostarted.

Environment variables

The user instance of systemd does not inherit any of the environment variables set in places like .bashrc etc. There are several ways to set environment variables for the systemd user instance:

    For users with a $HOME directory, create a .conf file in the

/.config/environment.d/ directory with lines of the form NAME=VAL . Affects only that user’s user unit. See environment.d(5) for more information.

  • Use the DefaultEnvironment option in /etc/systemd/user.conf file. Affects all user units.
  • Add a drop-in config file in /etc/systemd/system/user@.service.d/ . Affects all user units; see #Service example
  • At any time, use systemctl —user set-environment or systemctl —user import-environment . Affects all user units started after setting the environment variables, but not the units that were already running.
  • Using the dbus-update-activation-environment —systemd —all command provided by dbus. Has the same effect as systemctl —user import-environment , but also affects the D-Bus session. You can add this to the end of your shell initialization file.
  • For «global» environment variables for the user environment you can use the environment.d directories which are parsed by some generators. See environment.d(5) and systemd.generator(7) for more information.
  • You can also write a systemd.environment-generator(7) script which can produce environment variables that vary from user to user, this is probably the best way if you need per-user environments (this is the case for XDG_RUNTIME_DIR , DBUS_SESSION_BUS_ADDRESS , etc).
  • One variable you may want to set is PATH .

    After configuration, the command systemctl —user show-environment can be used to verify that the values are correct.

    Service example

    Create the drop-in directory /etc/systemd/system/user@.service.d/ and inside create a file that has the extension .conf (e.g. local.conf ):

    DISPLAY and XAUTHORITY

    DISPLAY is used by any X application to know which display to use and XAUTHORITY to provide a path to the user’s .Xauthority file and thus the cookie needed to access the X server. If you plan on launching X applications from systemd units, these variables need to be set. Systemd provides a script in /etc/X11/xinit/xinitrc.d/50-systemd-user.sh to import those variables into the systemd user session on X launch. [3] So unless you start X in a nonstandard way, user services should be aware of the DISPLAY and XAUTHORITY .

    If you customize your PATH and plan on launching applications that make use of it from systemd units, you should make sure the modified PATH is set on the systemd environment. Assuming you set your PATH in .bash_profile , the best way to make systemd aware of your modified PATH is by adding the following to .bash_profile after the PATH variable is set:

    Note that this will not affect systemd services started before PATH is imported.

    pam_environment

    Environment variables can be made available through use of the pam_env.so module. See Environment variables#Using pam_env for configuration details.

    Automatic start-up of systemd user instances

    The systemd user instance is started after the first login of a user and killed after the last session of the user is closed. Sometimes it may be useful to start it right after boot, and keep the systemd user instance running after the last session closes, for instance to have some user process running without any open session. Lingering is used to that effect. Use the following command to enable lingering for specific user:

    Writing user units

    See systemd#Writing unit files for general information about writing systemd unit files.

    Example

    The following is an example of a user version of the mpd service:

    Example with variables

    The following is an example of a user version of sickbeard.service , which takes into account variable home directories where SickBeard can find certain files:

    As detailed in systemd.unit(5) , the %h variable is replaced by the home directory of the user running the service. There are other variables that can be taken into account in the systemd manpages.

    Reading the journal

    The journal for the user can be read using the analogous command:

    To specify a unit, one can use

    Note that journald will not write user journals for users with UIDs below 1000, instead directing everything to the system journal.

    Temporary files

    systemd-tmpfiles allows users to manage custom volatile and temporary files and directories just like in the system-wide way (see systemd#systemd-tmpfiles — temporary files). User-specific configuration files are read from

    /.local/share/user-tmpfiles.d/ , in that order. For this functionality to be used, it is needed to enable the necessary systemd user units for your user:

    The syntax of the configuration files is the same than those used system-wide. See the systemd-tmpfiles(8) and tmpfiles.d(5) man pages for details.

    Xorg and systemd

    This article or section needs expansion.

    There are several ways to run xorg within systemd units. Below there are two options, either by starting a new user session with an xorg process, or by launching xorg from a systemd user service.

    Automatic login into Xorg without display manager

    The factual accuracy of this article or section is disputed.

    This option will launch a system unit that will start a user session with an xorg server and then run the usual

    /.xinitrc to launch the window manager, etc. You need to have xlogin-git AUR installed. Set up your xinitrc as specified in the Xinit#xinitrc section.

    Читайте также:  Как включить службу поиска windows

    The session will use its own dbus daemon, but various systemd utilities will automatically connect to the dbus.service instance. Finally, enable the xlogin@username service for automatic login at boot. The user session lives entirely inside a systemd scope and everything in the user session should work just fine.

    Xorg as a systemd user service

    Alternatively, xorg can be run from within a systemd user service. This is nice since other X-related units can be made to depend on xorg, etc, but on the other hand, it has some drawbacks explained below.

    xorg-server provides integration with systemd in two ways:

    • Can be run unprivileged, delegating device management to logind (see Hans de Goede commits around this commit).
    • Can be made into a socket activated service (see this commit). This removes the need for systemd-xorg-launch-helper-gitAUR .

    Unfortunately, to be able to run xorg in unprivileged mode, it needs to run inside a session. So, right now the handicap of running xorg as user service is that it must be run with root privileges (like before 1.16), and cannot take advantage of the unprivileged mode introduced in 1.16.

    This is how to launch xorg from a user service:

    1. Make xorg run with root privileges for any user, by editing /etc/X11/Xwrapper.config

    2. Add the following units to

    where $ is the virtual terminal where xorg will be launched, either hard-coded in the service unit, or set in the systemd environment with

    3. Make sure to configure the DISPLAY environment variable as explained above.

    4. Then, to enable socket activation for xorg on display 0 and tty 2 one would do:

    Now running any X application will launch xorg on virtual terminal 2 automatically.

    The environment variable XDG_VTNR can be set in the systemd environment from .bash_profile , and then one could start any X application, including a window manager, as a systemd unit that depends on xorg@0.socket .

    X clients as a user service

    This section is being considered for removal.

    With an adapted version of sx , one can easily have all the X clients running as a user service while leaving Xorg, the server, running in a session unprivileged.

    First, put a copy of /usr/bin/sx under /usr/local/bin/ . The copy can be named e.g. sdsx so that the original sx can remain accessible.

    The caveat of this approach is that, if for some reason not a single X client succeeded in reaching the server, the server will need to be killed from another tty manually. Also, if e.g. xrdb needs to be run in sxrc , it will now need to be run with the option -retain . See Xserver(1) and xrdb(1) for details.

    One of the use cases and/or advantages of this approach is that the X clients will now be running under the user manager ( user@$uid.service ) and snippet (i.e. systemctl edit ) applied to it (e.g. NetworkNamespacePath= ) will also be applied to the programs running in the graphical environment (including but not limited to the command-line shells running in an terminal emulator).

    Some use cases

    Persistent terminal multiplexer

    This article or section is out of date.

    You may wish your user session to default to running a terminal multiplexer, such as GNU Screen or Tmux, in the background rather than logging you into a window manager session. Separating login from X login is most likely only useful for those who boot to a TTY instead of to a display manager (in which case you can simply bundle everything you start in with myStuff.target).

    To create this type of user session, procede as above, but instead of creating wm.target, create multiplexer.target:

    cruft.target , like mystuff.target above, should start anything you think should run before tmux or screen starts (or which you want started at boot regardless of timing), such as a GnuPG daemon session.

    You then need to create a service for your multiplexer session. Here is a sample service, using tmux as an example and sourcing a gpg-agent session which wrote its information to /tmp/gpg-agent-info . This sample session, when you start X, will also be able to run X programs, since DISPLAY is set.

    Once this is done, systemctl —user enable tmux.service , multiplexer.target and any services you created to be run by cruft.target and you should be set to go! Activated user-session@.service as described above, but be sure to remove the Conflicts=getty@tty1.service from user-session@.service , since your user session will not be taking over a TTY. Congratulations! You have a running terminal multiplexer and some other useful programs ready to start at boot!

    Window manager

    To run a window manager as a systemd service, you first need to run #Xorg as a systemd user service. In the following we will use awesome as an example:

    /.config/systemd/user/wm.target.wants/window_manager.service , allowing it to be started at login. Is recommended to enable this service, not to link it manually.

    Kill user processes on logout

    Arch Linux builds the systemd package with —without-kill-user-processes , setting KillUserProcesses to no by default. This setting causes user processes not to be killed when the user logs out. To change this behavior in order to have all user processes killed on the user’s logout, set KillUserProcesses=yes in /etc/systemd/logind.conf .

    Note that changing this setting breaks terminal multiplexers such as tmux and GNU Screen. If you change this setting, you can still use a terminal multiplexer by using systemd-run as follows:

    For example, to run screen you would do:

    Using systemd-run will keep the process running after logout only while the user is logged in at least once somewhere else in the system and user@.service is still running.

    After the user logs out of all sessions, user@.service will be terminated too, by default, unless the user has «lingering» enabled [8]. To effectively allow users to run long-term tasks even if they are completely logged out, lingering must be enabled for them. See #Automatic start-up of systemd user instances and loginctl(1) for details.

    Troubleshooting

    Runtime directory ‘/run/user/1000’ is not owned by UID 1000, as it should

    If you see errors such as this and your login session is broken, it is possible that another system (non-user) service on your system is creating this folder. This can happen for example if you use a docker container that has a bind mount to /run/user/1000 . To fix this, you can either fix the container by removing the mount, or disable/delay the docker service.

    Источник

    Оцените статью