如何配置 SELinux 以允许特定服务与 Avahi 通信?

Lou*_*ato 5 fedora selinux avahi fedora-20

我有一个在 Fedora 20 机器上运行的服务,它在启动时尝试向 Avahi 注册服务。如果我的服务在 SELinux 处于许可模式时启动,这将非常有效,但在 SELinux 强制执行时该服务不会注册。

我知道httpd_dbus_avahiSELinux中的布尔值。这非常适用于允许 Apache 注册服务,但我一直无法找到有关如何允许其他特定服务与 Avahi 通信的大量信息。

更具体地说,我试图允许 tvheadend 向 Avahi 注册其 HTSP 服务,但我也很好奇如何允许任何特定服务与 Avahi 通信而不会被 SELinux 停止。我对关闭 SELinux 或允许想要与 Avahi 通信的进程不感兴趣。


编辑:添加了与 tvheadend 相关的所有 SELinux 和服务单元信息

---SELinux---

审计日志消息

执行semodule -DB并重新启动 tvheadend 服务后。以下是审计日志中出现的所有消息。最后一条消息似乎是问题所在,但我不知道该怎么做...

type=SERVICE_STOP msg=audit(1393282994.012:512): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg=' comm="tvheadend" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'
type=SERVICE_START msg=audit(1393283083.635:513): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg=' comm="tvheadend" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'
type=USER_AVC msg=audit(1393283084.291:514): pid=752 uid=81 auid=4294967295 ses=4294967295 subj=system_u:system_r:system_dbusd_t:s0-s0:c0.c1023 msg='avc:  denied  { send_msg } for msgtype=method_return dest=:1.114 spid=731 tpid=14478 scontext=system_u:system_r:avahi_t:s0 tcontext=system_u:system_r:init_t:s0 tclass=dbus  exe="/usr/bin/dbus-daemon" sauid=81 hostname=? addr=? terminal=?'
Run Code Online (Sandbox Code Playgroud)

过程

输出来自 ps -AZ | grep tvheadend

system_u:system_r:init_t:s0      2599 ?        00:00:06 tvheadend
Run Code Online (Sandbox Code Playgroud)

我注意到init_t进程类型似乎有点奇怪,因为我系统上的所有其他服务都有initrc_t进程类型。我不确定为什么 tvheadend 服务会以这种方式不同。

用户

输出来自 sudo -u hts id

uid=1001(hts) gid=1003(hts) groups=1003(hts),39(video) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
Run Code Online (Sandbox Code Playgroud)

我仅将此用户用于运行 tvheadend 服务。该用户在比系统分区大得多的单独分区上有一个主目录,因为 tvheadend 生成的 DVR 文件可能会变得非常大。

当我创建这个用户时,我没有使用--system带有useradd命令的开关。也许我应该有?

可执行

输出来自 ls -Z /usr/local/bin | grep tvheadend

-rwxr-xr-x. root root system_u:object_r:bin_t:s0       tvheadend
Run Code Online (Sandbox Code Playgroud)

- -服务 - -

单元文件

[Unit]
Description=TVHeadEnd
After=syslog.target network.target avahi-daemon.service sys-devices-pci0000:00-0000:00:1c.0-0000:05:00.0-dvb-dvb0.demux0.device sys-devices-pci0000:00-0000:00:1c.0-0000:05:00.0-dvb-dvb0.dvr0.device sys-devices-pci0000:00-0000:00:1c.0-0000:05:00.0-dvb-dvb0.frontend0.device sys-devices-pci0000:00-0000:00:1c.0-0000:05:00.0-dvb-dvb0.net0.device sys-devices-pci0000:00-0000:00:1c.0-0000:05:00.0-dvb-dvb1.demux0.device sys-devices-pci0000:00-0000:00:1c.0-0000:05:00.0-dvb-dvb1.dvr0.device sys-devices-pci0000:00-0000:00:1c.0-0000:05:00.0-dvb-dvb1.frontend0.device sys-devices-pci0000:00-0000:00:1c.0-0000:05:00.0-dvb-dvb1.net0.device sys-devices-pci0000:00-0000:00:1c.0-0000:05:00.0-video4linux-vbi0.device sys-devices-pci0000:00-0000:00:1c.0-0000:05:00.0-video4linux-vbi1.device sys-devices-pci0000:00-0000:00:1c.0-0000:05:00.0-video4linux-video0.device sys-devices-pci0000:00-0000:00:1c.0-0000:05:00.0-video4linux-video1.device
Wants=sys-devices-pci0000:00-0000:00:1c.0-0000:05:00.0-dvb-dvb0.demux0.device sys-devices-pci0000:00-0000:00:1c.0-0000:05:00.0-dvb-dvb0.dvr0.device sys-devices-pci0000:00-0000:00:1c.0-0000:05:00.0-dvb-dvb0.frontend0.device sys-devices-pci0000:00-0000:00:1c.0-0000:05:00.0-dvb-dvb0.net0.device sys-devices-pci0000:00-0000:00:1c.0-0000:05:00.0-dvb-dvb1.demux0.device sys-devices-pci0000:00-0000:00:1c.0-0000:05:00.0-dvb-dvb1.dvr0.device sys-devices-pci0000:00-0000:00:1c.0-0000:05:00.0-dvb-dvb1.frontend0.device sys-devices-pci0000:00-0000:00:1c.0-0000:05:00.0-dvb-dvb1.net0.device sys-devices-pci0000:00-0000:00:1c.0-0000:05:00.0-video4linux-vbi0.device sys-devices-pci0000:00-0000:00:1c.0-0000:05:00.0-video4linux-vbi1.device sys-devices-pci0000:00-0000:00:1c.0-0000:05:00.0-video4linux-video0.device sys-devices-pci0000:00-0000:00:1c.0-0000:05:00.0-video4linux-video1.device

[Service]
Type=forking
GuessMainPID=no
EnvironmentFile=/etc/sysconfig/tvheadend
ExecStart=/usr/local/bin/tvheadend -f -u $TVH_USER -g $TVH_GROUP -p $TVH_PID -b $TVH_ADDRESS --http_port $TVH_HTTP_PORT --htsp_port $TVH_HTSP_PORT
PIDFile=$TVH_PID
ExecReload=/bin/kill -HUP $MAINPID

[Install]
WantedBy=multi-user.target
Run Code Online (Sandbox Code Playgroud)

单元环境文件

TVH_USER=hts

TVH_GROUP=hts

TVH_PID=/var/run/tvheadend.pid

TVH_ADDRESS=0.0.0.0

TVH_HTTP_PORT=9981

TVH_HTSP_PORT=9982
Run Code Online (Sandbox Code Playgroud)

Mat*_*Ife 8

运行此服务init_t可能不是一个好主意。

出现这种行为的原因tvheadend可能标记为bin_t,并且不存在将这种类型的文件移出init_t上下文的转换规则。

你可以搜索这个来确定..

$ sesearch -s init_t --type -c process | grep bin_t
Run Code Online (Sandbox Code Playgroud)

此命令不返回任何结果。bin_t进程的 init_t 没有转换。

您也应该避免运行这种类型,initrc_t因为它不适合该服务。作为一般事实 -最好的解决方案是为您的服务正确编写一个受限的策略,但这超出了本答案的范围。

相反,您需要将您的流程转换init_t为另一种类型。由于此应用程序不存在策略,因此最好将其移动到unconfined_t,因为确实存在类型转换。

$ sesearch -s init_t --type -c process -t unconfined_exec_t
Found 1 semantic te rules:
   type_transition init_t unconfined_exec_t : process unconfined_t;
Run Code Online (Sandbox Code Playgroud)

我们还可以检查策略中被命中的规则是否不会被命中unconfined_t(它不应该被命中)。

$ sesearch -s avahi_t -p send_msg -c dbus -t unconfined_t --allow
Found 2 semantic av rules:
   allow avahi_t unconfined_t : dbus send_msg ; 
   allow system_bus_type unconfined_t : dbus send_msg ;
Run Code Online (Sandbox Code Playgroud)

为此,只需将您的tvheadend程序重新标记为unconfined_exec_t.

semanage fcontext -a -t unconfined_exec_t -f f /usr/bin/tvheadend
Run Code Online (Sandbox Code Playgroud)

然后还原。

restorecon /usr/bin/tvheadend
Run Code Online (Sandbox Code Playgroud)

现在,重新运行您的服务应该可以了。如果您重新运行,ps -AZ | grep tvheadend您应该看到您的进程在unconfined_t.

理想情况下,该程序应使用新策略,但如果不存在策略,则最好在unconfined_t域中完全没有策略的情况下运行它。initrc_t并且init_t并不真正用于运行服务(尽管有些不正确地进入那里),initrc_t最初被设计用于运行 SYSV shell 脚本并且init_t用于运行 systemd/init 本身。