How to configure SELinux to allow specific services to communicate with Avahi?

I have a service, running on a Fedora 20 machine, that when started attempts to register services with Avahi. This works perfectly if my service is started while SELinux is in permissive mode, but the service will not register when SELinux is enforcing.

Я знаю о httpd_dbus_avahi логическое значение в SELinux. Это прекрасно работает, чтобы позволить Apache регистрировать службы, но я не смог найти много информации о том, как разрешить другим конкретным службам взаимодействовать с Avahi.

Точнее говоря, я пытаюсь разрешить tvheadend зарегистрировать свой HTSP-сервис в Avahi, но мне также любопытно, как любой конкретный сервис может связываться с Avahi без остановки SELinux. Я НЕ заинтересован в отключении SELinux или разрешении процесса, который хочет общаться с Avahi.


РЕДАКТИРОВАТЬ: добавлена ​​вся информация SELinux и сервисной единицы, относящаяся к tvheadend

--- ---SELinux

сообщения aud.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. У этого пользователя есть домашний каталог в отдельном разделе, намного превышающем системный раздел, поскольку файлы DVR, сгенерированные tvheadend, могут стать довольно большими.

Когда я создал этого пользователя, я не использовал --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

3 ответа

Решение

Запуск этого сервиса как 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 и init_t предназначен для запуска самого systemd/init.

Manpage для apache_selinux упоминает, что # semanage permissive может использоваться для разрешения запуска определенных процессов в разрешающем режиме.

# semanage permissive -a avahi_t

Я предлагаю найти более подробную информацию о его использовании

Хотя, возможно, было бы разумнее найти лучшее решение, чем просто "разрешить доступ к службе";

особенно когда SELinux предоставляет огромное количество параметров конфигурации, позволяющих заданным разрешениям службы выполнять только то, что вы ожидаете, и ничего более! Однако из-за этого огромного количества вариантов управления администраторы должны узнать, какие существуют варианты, и решить, как / когда / где их эффективно реализовать. Как я уже упоминал, первое место, которое нужно посмотреть, это страницы руководства вашей системы, а также ваш журнал аудита. /var/log/audit/audit.log, Чтобы найти сообщения об avahi, например, в файлах журнала, выполните:

# grep /usr/sbin/avahi /var/log/audit/audit.log

РЕДАКТИРОВАТЬ: отразить обновленный вопрос

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

Взгляните на страницы

Следующие пункты, в частности, должны представлять интерес для вас:

  • system_dbusd_t Тип SELinux:

    $ man system_dbusd_selinux
    
  • avahi_t Тип SELinux:

    $ man avahi_selinux
    
    • взгляните на avahi_exec_t
    • avahi_initrc_exec_t контексты файла
    • avahi_var_run_t
    • avahi_unit_file_t
    • а также список связанных логических значений в нем.

Хорошо, поскольку я не уверен, что вы заметили этот последний бит на avahi_exec_t; и так как я не могу оставлять комментарии: / пока; вот соответствующая информация из самой страницы руководства:

SELinux определяет типы файловых контекстов для avahi. Если вы хотите хранить файлы с этими типами в разных путях, вам нужно выполнить команду semanage, чтобы указать альтернативные метки, а затем использовать restorecon, чтобы поместить метки на диск.

   semanage fcontext -a -t avahi_exec_t '/srv/avahi/content(/.*)?'
   restorecon -R -v /srv/myavahi_content

   Note: SELinux often uses regular expressions to specify labels that match multiple files.

   The following file types are defined for avahi:

   avahi_exec_t

   - Set files with the avahi_exec_t type, if you want to transition an executable to the avahi_t domain.

   Paths:
        /usr/sbin/avahi-daemon, /usr/sbin/avahi-autoipd, /usr/sbin/avahi-dnsconfd

   avahi_initrc_exec_t

   - Set files with the avahi_initrc_exec_t type, if you want to transition an executable to the avahi_initrc_t domain.

   avahi_unit_file_t

   - Set files with the avahi_unit_file_t type, if you want to treat the files as avahi unit content.

SELinux и процессные переходы

Загляните в блог Дэна Уолша для подробного обсуждения / информации о SELinux, в этом посте, в частности, упоминается

Переход процесса говорит, что когда процесс, выполняющийся с меткой a_t, выполняет файл с меткой b_exec_t, он должен выполнять процесс как b_t. Примером этого может быть запуск службы httpd. В этом случае у нас есть undefined_t, который запускает скрипт инициализации с меткой initrc_exec_t, а SELinux запускает процесс как initrc_t.

Кроме того, лучше всего продолжать исследовать tvheadend программа, а также управление SELinux. Вы можете создать собственную политику в соответствии с audit протоколировать сообщения; что-то вроде:

# grep tvheadend /var/log/audit/audit.log | audit2allow -M mypol
# semodule -i mypol.pp

По крайней мере, до тех пор, пока не появятся лучшие решения и / или tvheadend пробивается в репо Fedora. Наконец, взгляните лучше на файл модуля (служебный файл), который вы создали для systemd; проверить на наличие ошибок, потенциальных дополнений и изменений.

Вы можете исправить это с помощью audit2allow для создания пользовательского модуля политики

audit2allow -M custom_avhi <file_containing_AVC-denied messages
******************** IMPORTANT ***********************
To make this policy package active, execute:

semodule -i custom_avhi.pp
Другие вопросы по тегам