Fedora

SELinux 在 systemd 單元中阻塞執行

  • December 30, 2020

我使用 Fedora 31 並嘗試設置 Teamspeak 伺服器。當我查看時,journalctl -u teamspeak我收到以下錯誤:

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'.

我的 systemd 單元如下所示:

[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

我使用以下 ansible playbook 進行設置:

- 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

sealert -l "*"節目:

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

如果我這樣做,我可以毫無問題地執行伺服器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

我不知道如何進一步調試。我該如何解決這個問題?

事實證明,SELinux 認為二進製文件只能從某些位置執行,而我的自定義目錄沒有明確標記為允許。它繼承了var_t/srv/.*我認為)的類型。

要獲取所有目錄的目前規則的廣泛列表,您可以執行semanage fcontext --list.

我使用以下 Ansible 任務添加了一個異常:

- name: set SELinux permissions on ts3server binaries
 sefcontext:
   target: "/srv/teamspeak/versions/[^/]+/ts3server"
   setype: bin_t
- name: reload SELinux policy to ensure that ts3server is executable
 command: restorecon -irv /srv/teamspeak/
 when: tarball.changed

同樣可以通過使用semanage fcontext後跟 的命令來實現restorecon -irv /srv/teamspeak/

引用自:https://serverfault.com/questions/1006417