I use Fedora 31 and tried to set up a Teamspeak server. When I look in journalctl -u teamspeak
I get the following error:
mar 09 22:22:46 melchior systemd[1]: Started Teamspeak server.
mar 09 22:22:46 melchior systemd[20187]: teamspeak.service: Failed to execute command: Permission denied
mar 09 22:22:46 melchior systemd[20187]: teamspeak.service: Failed at step EXEC spawning /srv/teamspeak/3.11.0/ts3server: Permission denied
mar 09 22:22:46 melchior systemd[1]: teamspeak.service: Main process exited, code=exited, status=203/EXEC
mar 09 22:22:46 melchior systemd[1]: teamspeak.service: Failed with result 'exit-code'.
My systemd unit looks like this:
[Unit]
Description=Teamspeak server
After=network-online.target
[Service]
User=teamspeak
Group=teamspeak
WorkingDirectory=/srv/teamspeak/data/
ExecStart=/srv/teamspeak/versions/3.11.0/ts3server dbsqlpath=/srv/teamspeak/versions/3.11.0/sql/ serverquerydocs_path=/srv/teamspeak/versions/3.11.0/serverquerydocs/ license_accepted=1 default_voice_port=9987 filetransfer_port=30033 query_port=10011
Restart=always
[Install]
WantedBy=multi-user.target
I use the following ansible playbook to set it up:
- name: create teamspeak server base folder
file:
path: "/srv/teamspeak"
state: directory
owner: root
group: root
mode: 0755
- name: create teamspeak user
user:
name: teamspeak
comment: "Teamspeak 3 server user"
system: true
create_home: false
shell: /sbin/nologin
# NOTE: SELinux blocks systemd from starting any binary in a user's home
# folder which is why we need versions/ and data/
home: /srv/teamspeak/data
- name: create teamspeak server user folder
file:
path: "/srv/teamspeak/data"
state: directory
owner: teamspeak
group: teamspeak
mode: 0755
- name: create teamspeak server version folder
file:
path: "/srv/teamspeak/versions/{{ teamspeak_version }}"
state: directory
- name: download teamspeak server
get_url:
url: "https://files.teamspeak-services.com/releases/server/{{ teamspeak_version }}/teamspeak3-server_linux_amd64-{{ teamspeak_version }}.tar.bz2"
dest: "/srv/teamspeak/versions/{{ teamspeak_version }}/server.tar.bz2"
checksum: "sha256:18c63ed4a3dc7422e677cbbc335e8cbcbb27acd569e9f2e1ce86e09642c81aa2"
register: tarball
- name: unpack teamspeak3 server files
unarchive:
src: "{{ tarball.dest }}"
dest: "/srv/teamspeak/versions/{{ teamspeak_version }}/"
remote_src: true
extra_opts:
- "--strip-components=1"
# Prevent files from being world writable like some are in the tarball
- "--no-same-permissions"
creates: "/srv/teamspeak/versions/{{ teamspeak_version }}/ts3server"
- name: install service file
template:
src: teamspeak.service
dest: /etc/systemd/system/teamspeak.service
register: service
- name: reload systemd units
when: service.changed
command: systemctl daemon-reload
- name: "enable teamspeak service"
systemd:
name: teamspeak
enabled: true
state: started
Looking in sealert -l "*"
shows:
SELinux is preventing (s3server) from execute access on the file ts3server.
***** Plugin catchall (100. confidence) suggests **************************
If you believe that (s3server) should be allowed execute access on the ts3server file by default.
Then you should report this as a bug.
You can generate a local policy module to allow this access.
Do
allow this access for now by executing:
# ausearch -c '(s3server)' --raw | audit2allow -M my-s3server
# semodule -X 300 -i my-s3server.pp
Additional Information:
Source Context system_u:system_r:init_t:s0
Target Context unconfined_u:object_r:var_t:s0
Target Objects ts3server [ file ]
Source (s3server)
Source Path (s3server)
Port <Unknown>
Host melchior
Source RPM Packages
Target RPM Packages
Policy RPM selinux-policy-3.14.4-45.fc31.noarch
Selinux Enabled True
Policy Type targeted
Enforcing Mode Enforcing
Host Name melchior
Platform Linux melchior 5.4.17-200.fc31.x86_64 #1 SMP Sat
Feb 1 19:00:13 UTC 2020 x86_64 x86_64
Alert Count 65
First Seen 2020-03-09 22:22:45 CET
Last Seen 2020-03-10 20:07:00 CET
Local ID 20f823c0-8e46-46d1-a51c-659040857b34
Raw Audit Messages
type=AVC msg=audit(1583867220.254:4234): 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
Hash: (s3server),init_t,var_t,file,execute
I can run the server without issue if I just do sudo -u teamspeak /srv/teamspeak/versions/3.11.0/ts3server dbsqlpath=/srv/teamspeak/versions/3.11.0/sql/ serverquerydocs_path=/srv/teamspeak/versions/3.11.0/serverquerydocs/ license_accepted=1 default_voice_port=9987 filetransfer_port=30033 query_port=10011
I have no idea how to debug this further. How can I solve this?
Best Answer
It turns out SELinux has an idea that binaries can only be executed from certain locations and my custom directory was not explicitly marked as allowed. It inherited the type
var_t
from/srv/.*
(I think).To get an extensive list of current rules for all directories you can run
semanage fcontext --list
.I added an exception using the following Ansible tasks:
The same can be achieved by using the
semanage fcontext
command followed byrestorecon -irv /srv/teamspeak/
.