0

First things first, OS: Debian 10

I've created a systemd service that runs at startup. It needs to be able to read from a file that needs to be protected. Correct me if I'm wrong, but it seems like a bad practice to just have it run as sudo, so I figured that this is a great chance to use sudoers. Using visudo I added a group, and gave it access to the file, adding a system user to the group. (I also made a system group with the same name, just in lowercase, and added the user.)

_using visudo_
...
User_Alias            _MY-FANCY-GROUP-NAME_=_system-user-name_
MY-FANCY-GROUP-NAME   ALL=NOPASSWD:/path/to/file

I then edited the service to run as that system user.

...
[Service]
...
User=_system-user-name_
Group=_my-fancy-group-name_
...

It fails on startup, though, with code=exited, status=1/FAILURE). I can't figure out why. ls -l shows the service is owned by root:

-rw-r--r-- 1 root root ...

But ps seems to say it's be executed by my user (not the system user I created).

I suppose there are two questions here:

1) It seems pretty clear to me that I did something wrong, but I don't know what. What did I do wrong here?

2) What is the best way for me to give the service access to the file?

Thanks!

7
  • Where is the systemd service file located exactly? Nov 12, 2019 at 13:31
  • @grawity /etc/systemd/system/my-service.service Nov 12, 2019 at 13:31
  • Well that's not a standard systemd unit path. Can you double-check it? Do you start it with systemctl --user or systemctl --system? Nov 12, 2019 at 13:32
  • @grawity typo in the path - I fixed it (whoops) Nov 12, 2019 at 13:34
  • The service is enabled, starts on boot (just fails). I can access it with systemctl. Traditionally, I've used sudo systemctl start when I'm manually launching. Nov 12, 2019 at 13:34

1 Answer 1

1

it seems like a bad practice to just have it run as sudo, so I figured that this is a great chance to use sudoers. Using visudo I added a group, and gave it access to the file.

First, sudo and sudoers are practically the same thing. Second, that's not how sudoers works.

Sudo is just a tool to switch user accounts. This means that there's no such thing as "running as sudo". – if you use e.g. sudo myprogram to start a program as root, then it's just running as root.

It also means /etc/sudoers does not actually give access to files. The sudoers entries are not applied by the kernel, nor by anything else except the 'sudo' command itself. And the aliases listed within sudoers do not become system groups – they only act as macros within the same configuration file.

The only thing done by entries in /etc/sudoers is to allow the specified user account to run sudo this or sudo that – to run a whole program under some different user account (usually root but not necessarily).

Notice how most configuration examples do not list arbitrary files, they list paths to executables. For example, if your sudoers file has e.g. ALL = NOPASSWD: cat /path/to/file, then the user account will be able to run sudo cat /path/to/file and read its stdout... but it still won't be able to read the file directly.

ls -l shows the service is owned by root:

-rw-r--r-- 1 root root ...

It doesn't matter who owns the .service files, they just hold configuration for systemd. It also doesn't matter who owns the actual executables (unless the latter have the 'setuid' bit set, like rws – but in your case they do not).

For system services (those in '/etc/systemd/system'), the service manager always just uses the account specified in [Service] User=, and if it's not specified it'll use root.

But ps seems to say it's be executed by my user (not the system user I created).

It's possible that systemd is still using the previous configuration because it refused to load the new one – it couldn't verify that the my-fancy-group-name group actually exists. You only mention adding the group to /etc/sudoers, but that's the wrong location – system groups are only created via groupadd, or by adding them to /etc/group.

Note that systemd does not reload changes automatically. If your previous version of the .service file had User=my-user, this will stick until you run sudo systemctl daemon-reload followed by restarting the actual service – or until you reboot the system.

2) What is the best way for me to give the service access to the file?

Files have a group assigned to them using chgrp or chown. After you've actually created the group using 'groupadd', you can then chgrp the file to that group and give it read permissions:

groupadd my-fancy-group-name
chown :my-fancy-group-name /etc/ponies.conf
chmod g+w /etc/ponies.conf

The service's user account doesn't need to be a member of this group, since you already explicitly specified it in the service's Group= setting. However, if you actually want to add it as a permanent member, use gpasswd -a for that (which again edits /etc/group).

In case the file already has another group assigned and you don't want to change that, you can also use file ACLs. They work mostly the same way except there can be more than one user, and more than one group:

setfacl -m u:system-user-name:r <file>
-or-
setfacl -m g:my-fancy-group-name:r <file>

(Small side note that while ACLs are present, traditional "group" permissions get a different meaning, and to change the traditional permission bits you would need setfacl -m g::rx instead of chmod g=rx for example.)

1
  • Thanks for the answer! It turns out that I had used groupadd to create the group (I hadn't been very specific in the question when I mentioned that I had made a group), but you are spot on that I had misunderstood how sudoers works. Thanks! Nov 13, 2019 at 9:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .