如何配置 SELinux 以允許特定服務與 Avahi 通信?
我有一個在 Fedora 20 機器上執行的服務,它在啟動時會嘗試向 Avahi 註冊服務。如果我的服務在 SELinux 處於許可模式時啟動,這將非常有效,但在 SELinux 強制執行時該服務不會註冊。
我知道
httpd_dbus_avahi
SELinux 中的布爾值。這完美地允許 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 本身。