Systemd service does not start (permission denied)

systemdteamspeak

So today I decided to move my ts3 server from my old windows box to a new centos8 server. Everything works fine but now I am trying to create a systemd service file so the server can start automatically on boot. I can run everything nicely when I try to start things as the service user, but I cannot start it as root (using systemctl). A little more info:

The user I want things to run with

[root@lnxsrv01 opt]# id teamspeak
uid=1000(teamspeak) gid=1000(teamspeak) groups=1000(teamspeak)

My folder structure (notice permissions and exec flags)

[root@lnxsrv01 teamspeak]# ll
total 16380
drwxr-xr-x. 9 teamspeak teamspeak     4096 Nov  2 17:28 .
drwxr-xr-x. 3 root      root            23 Nov  2 16:11 ..
-rw-------. 1 teamspeak teamspeak      629 Nov  2 17:30 .bash_history
-rw-rw-rw-. 1 teamspeak teamspeak    66724 Jul  2 11:21 CHANGELOG
drwxr-xr-x. 3 teamspeak teamspeak      192 Jun 17 18:27 doc
drwx------. 4 teamspeak teamspeak       45 Nov  2 16:59 files
-rwxr-xr-x. 1 teamspeak teamspeak   947368 Jul  2 15:24 libts3db_mariadb.so
-rwxr-xr-x. 1 teamspeak teamspeak  2174344 Jul  2 15:24 libts3db_sqlite3.so
-rwxr-xr-x. 1 teamspeak teamspeak  1096144 Jul  2 15:24 libts3_ssh.so
-rw-r--r--. 1 teamspeak teamspeak    68141 Jun 17 18:27 LICENSE
drwx------. 2 teamspeak teamspeak      270 Nov  2 17:10 logs
-rw-rw-rw-. 1 teamspeak teamspeak        0 Nov  2 16:59 query_ip_blacklist.txt
-rw-rw-rw-. 1 teamspeak teamspeak       14 Nov  2 16:59 query_ip_whitelist.txt
drwxr-xr-x. 2 teamspeak teamspeak       29 Jul  2 15:24 redist
drwxrwxrwx. 2 teamspeak teamspeak     8192 Jun 24 11:28 serverquerydocs
drwxrwxrwx. 5 teamspeak teamspeak     8192 Jun 17 18:26 sql
-rw-rw-rw-. 1 teamspeak teamspeak     3243 Nov  2 16:59 ssh_host_rsa_key
-rwxr-xr-x. 1 teamspeak teamspeak 12033888 Jul  2 15:24 ts3server
-rw-rw-r--. 1 teamspeak teamspeak        0 Nov  2 16:59 .ts3server_license_accepted
-rwxrwxrwx. 1 teamspeak teamspeak      117 Jun 17 18:26 ts3server_minimal_runscript.sh
-rw-rw-r--. 1 teamspeak teamspeak        6 Nov  2 17:10 ts3server.pid
-rw-r--r--. 1 teamspeak teamspeak   282624 Nov  2 16:58 ts3server.sqlitedb
-rw-r--r--. 1 teamspeak teamspeak    32768 Nov  2 17:22 ts3server.sqlitedb-shm
-rw-r--r--. 1 teamspeak teamspeak     6320 Nov  2 17:21 ts3server.sqlitedb-wal
-rwxrwxrwx. 1 teamspeak teamspeak     2654 Jun 18 11:51 ts3server_startscript.sh
drwxr-xr-x. 2 teamspeak teamspeak       85 Jul  2 15:24 tsdns
[root@lnxsrv01 teamspeak]# pwd
/opt/teamspeak

My systemd service file

[root@lnxsrv01 teamspeak]# cat /lib/systemd/system/teamspeak3.service
[Unit]
Description=TeamSpeak Server Service
After=network.target

[Service]
Type=forking
WorkingDirectory=/opt/teamspeak/
ExecStart=/opt/teamspeak/ts3server_startscript.sh start
ExecStop=/opt/teamspeak/ts3server_startscript.sh stop
User=teamspeak
Group=teamspeak
PIDFile=/opt/teamspeak/ts3server.pid
Restart=always
RestartSec=9
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=teamspeak3

[Install]
WantedBy=multi-user.target

Relevant syslog entries

Nov  2 17:26:36 lnxsrv01 systemd[17585]: teamspeak3.service: Failed to execute command: Permission denied
Nov  2 17:26:36 lnxsrv01 systemd[17585]: teamspeak3.service: Failed at step EXEC spawning /opt/teamspeak/ts3server_startscript.sh: Permission denied
Nov  2 17:26:36 lnxsrv01 systemd[1]: teamspeak3.service: Control process exited, code=exited status=203
Nov  2 17:26:36 lnxsrv01 systemd[1]: teamspeak3.service: Failed with result 'exit-code'.
Nov  2 17:26:36 lnxsrv01 systemd[1]: Failed to start TeamSpeak Server Service.
Nov  2 17:26:43 lnxsrv01 systemd[1]: Stopped TeamSpeak Server Service.

When I su to the 'teamspeak' user and run the startscript from there, everything works fine. But I can't seem to get things working with systemd.

Any ideas what I am missing here?

Best Answer

If a problem can be solved by turning off SELinux, it pays to dig deeper and find out why.

(You would not turn off your firewall to open port 80, would you?)

In this particular case, in order for a binary or script to be called through a systemd unit file, it needs to be of SELinux type bin_t (as files in /usr/bin and /usr/sbin usually are).

To find out which type a file has, use ls's -Z flag. Then set the type accordingly:

chcon -t bin_t /opt/teamspeak/ts3server_startscript.sh

To find out which actions were blocked by SELinux (and why), take a look at the audit log in /var/log/audit/audit.log.

More often than not, however, changing a file's SELinux type is not enough:

  • Sometimes you'll need to use the semanage fcontext … (manpage here) command to make permanent security context changes (so that new files in a directory inherit the proper context).

  • Sometimes a boolean exists for the exact thing you're trying to accomplish.

  • In your worst case, you'll need to compile a SELinux policy package (I wrote an article about that some time ago).

Related Question