![SELinux 阻止 systemd 单元中的执行](https://linux22.com/image/749524/SELinux%20%E9%98%BB%E6%AD%A2%20systemd%20%E5%8D%95%E5%85%83%E4%B8%AD%E7%9A%84%E6%89%A7%E8%A1%8C.png)
我使用 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 剧本进行设置:
- 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
我不知道如何进一步调试。我该如何解决这个问题?
答案1
事实证明,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/
。
答案2
当我们想从 systemd 启动 celery 时,我们遇到了类似的问题。
通过以下步骤解决了该问题:
sudo semanage fcontext -a -t bin_t '/home/\<logged in user\>/.local/bin.*'
sudo chcon -Rv -u system_u -t bin_t '/home/\<logged in user\>/.local/bin'
sudo restorecon -R -v /home/\<logged in user\>/.local/bin
sudo systemctl restart cele123
目录中存在 Celery 可执行文件/home/\<logged in user\>/.local/bin
。systemd 文件夹中的文件中提到了相同的路径cele123.service
。