Resolving SELinux Permission Denied Errors When Executing Systemd Units for TeamSpeak Server


2 views

When deploying TeamSpeak server through systemd on Fedora 31, many administrators encounter the frustrating "Permission denied" error during service execution, despite correct file permissions. The root cause often lies in SELinux context misalignment between the target binary and systemd's execution environment.

# Typical error you'll see in journalctl
systemd[20187]: teamspeak.service: Failed at step EXEC spawning /srv/teamspeak/3.11.0/ts3server: Permission denied

The key insight from the sealert output reveals:

Source Context: system_u:system_r:init_t:s0
Target Context: unconfined_u:object_r:var_t:s0

Systemd runs services with init_t context, while your TeamSpeak binary inherited var_t context from being placed under /srv. These security contexts don't align by default in SELinux's targeted policy.

Here are three approaches to resolve this:

1. Correct SELinux Context Permanently

Apply the proper context to your TeamSpeak installation:

# Install required policy tools if missing
sudo dnf install policycoreutils-python-utils

# Apply default context for executables
sudo semanage fcontext -a -t bin_t "/srv/teamspeak/versions/3.11.0/ts3server"
sudo restorecon -v /srv/teamspeak/versions/3.11.0/ts3server

2. Create Custom SELinux Policy Module

When you need specific permission adjustments:

# Generate policy module
sudo ausearch -c '(s3server)' --raw | audit2allow -M my-teamspeak
sudo semodule -i my-teamspeak.pp

# Verify the module loaded
sudo semodule -l | grep teamspeak

3. Alternative Directory Structure

For long-term maintainability, consider restructuring:

sudo mkdir -p /opt/teamspeak/
sudo chown -R teamspeak:teamspeak /opt/teamspeak/
sudo semanage fcontext -a -t usr_t "/opt/teamspeak(/.*)?"
sudo restorecon -Rv /opt/teamspeak

After implementing any solution:

# Check the new context
ls -Z /srv/teamspeak/versions/3.11.0/ts3server

# Test the service
sudo systemctl restart teamspeak
journalctl -u teamspeak -f

Modify your Ansible playbook to include SELinux context handling:

- name: set SELinux context for TeamSpeak binary
  sefcontext:
    target: "/srv/teamspeak/versions/{{ teamspeak_version }}/ts3server"
    setype: bin_t
    state: present

- name: apply SELinux file context
  command: restorecon -v /srv/teamspeak/versions/{{ teamspeak_version }}/ts3server

Remember that these solutions apply generically to similar services facing SELinux execution barriers under systemd.


When setting up a TeamSpeak server through systemd on Fedora 31, you might encounter permission denied errors despite correct file permissions. The key issue stems from SELinux context mismatches between the target binary and the service runtime environment.

# Check current SELinux contexts
ls -Z /srv/teamspeak/versions/3.11.0/ts3server

The critical message in journalctl shows:

avc: denied { execute } for pid=11418 comm="(s3server)" name="ts3server" 
dev="dm-0" ino=1032133 scontext=system_u:system_r:init_t:s0 
tcontext=unconfined_u:object_r:var_t:s0 tclass=file permissive=0

This reveals that systemd (running in init_t context) is being blocked from executing a file labeled with var_t context.

The most robust approach is to create a custom SELinux policy module:

# Generate policy module
ausearch -c '(s3server)' --raw | audit2allow -M my-teamspeak
semodule -i my-teamspeak.pp

# Alternative: Apply proper file context
semanage fcontext -a -t bin_t "/srv/teamspeak/versions/3.11.0/ts3server"
restorecon -v /srv/teamspeak/versions/3.11.0/ts3server

After applying the fixes, verify the contexts match:

# Should now show bin_t or similar executable context
ls -Z /srv/teamspeak/versions/3.11.0/ts3server

# Check for any remaining denials
sealert -a /var/log/audit/audit.log

For temporary solutions or testing, consider:

# 1. Run in permissive mode temporarily
setenforce 0
systemctl start teamspeak
setenforce 1

# 2. Use boolean to allow systemd execution
setsebool -P domain_can_exec_any_file 1

Remember that these alternatives reduce security and should only be temporary measures.

When deploying through Ansible, include SELinux context management:

- name: Set proper SELinux context for TeamSpeak binary
  sefcontext:
    target: '/srv/teamspeak/versions/{{ teamspeak_version }}/ts3server'
    setype: bin_t
    state: present

- name: Apply SELinux file context
  command: restorecon -v /srv/teamspeak/versions/{{ teamspeak_version }}/ts3server