Fedora

如何配置 SELinux 以允許特定服務與 Avahi 通信?

  • February 27, 2014

我有一個在 Fedora 20 機器上執行的服務,它在啟動時會嘗試向 Avahi 註冊服務。如果我的服務在 SELinux 處於許可模式時啟動,這將非常有效,但在 SELinux 強制執行時該服務不會註冊。

我知道httpd_dbus_avahiSELinux 中的布爾值。這完美地允許 Apache 註冊服務,但我一直無法找到有關如何允許其他特定服務與 Avahi 通信的太多資訊。

更具體地說,我試圖允許 tvheadend 向 Avahi 註冊其 HTSP 服務,但我也很好奇如何允許任何特定服務與 Avahi 通信而不會被 SELinux 停止。我對關閉 SELinux 或允許想要與 Avahi 通信的程序不感興趣。


**編輯:**添加了與 tvheadend 相關的所有 SELinux 和服務單元資訊

—SELinux—

audit.log 消息

執行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=?'

過程

輸出自ps -AZ | grep tvheadend

system_u:system_r:init_t:s0      2599 ?        00:00:06 tvheadend

我注意到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

我僅將此使用者用於執行 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

- -服務 - -

單位文件

[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

單元環境文件

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

執行此服務init_t可能不是一個好主意。

出現此行為的原因可能是tvheadend標記為,並且不存在將此類文件移出上下文的轉換規則。bin_t``init_t

你可以搜尋這個來確定..

$ sesearch -s init_t --type -c process | grep bin_t

此命令不返回任何結果。程序的 init_t 沒有轉換bin_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;

我們還可以檢查策略中被命中的規則是否不會被命中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 ;

為此,只需將您的tvheadend程序重新標記為unconfined_exec_t.

semanage fcontext -a -t unconfined_exec_t -f f /usr/bin/tvheadend

然後恢復。

restorecon /usr/bin/tvheadend

現在,重新執行您的服務應該可以工作了。如果您重新執行ps -AZ | grep tvheadend,您應該會看到您的程序在unconfined_t.

理想情況下,該程序應使用新策略,但如果不存在策略,則最好在unconfined_t域中完全沒有策略的情況下執行它。initrc_t並且init_t並不是真正用於執行服務(儘管有些確實錯誤地進入了那裡),initrc_t最初被設想用於執行 SYSV shell 腳本,並且init_t用於執行 systemd/init 本身。

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