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