CentOS + SNMP + SELinux

SELinux для большинства является слишком сложной штукой, поэтому они первым делом выключают его. Но данный механизм даёт дополнительный уровень защиты, что делает данный метод не очень интересным.

Например, имеется простенький скрипт, следящий за числом клиентов по NFS для диагностики данного демона. Но включенный SELinux не даёт запускать этот скрипт, чтоб предоставить эту информацию по SNMP.

Скрипт /opt/scripts/s2mon.sh:

#!/bin/bash
exit $(netstat -an | grep 10.0.0.1:2049 | wc -l)

В связи с тем, что используется не лучшая система мониторинга, графики она может строить только если ответом было число, а не строка. Этого можно добиться используя только exit

Настройки SNMP /etc/snmp/snmpd.conf:

rocommunity mon
extend mon /opt/scripts/s2mon.sh

Не забываем, что демона надо перезапустить.

# service snmpd restart

Смотрим состояния SELinux:

# sestatus
SELinux status: enabled
SELinuxfs mount: /selinux
Current mode: enforcing
Mode from config file: enforcing
Policy version: 24
Policy from config file: targeted

Отключаем SELinux:

# setenforce 0

Теперь с другого компа опрашиваем состояние сторонних мониторов:

$ snmpwalk -O n -v 2c -c mon 10.0.1.1 1.3.6.1.4.1.8072.1.3 | grep 5.115
.1.3.6.1.4.1.8072.1.3.2.2.1.2.5.115.50.109.111.110 = STRING: /opt/scripts/s2mon.sh
.1.3.6.1.4.1.8072.1.3.2.2.1.3.5.115.50.109.111.110 = STRING:
.1.3.6.1.4.1.8072.1.3.2.2.1.4.5.115.50.109.111.110 = STRING:
.1.3.6.1.4.1.8072.1.3.2.2.1.5.5.115.50.109.111.110 = INTEGER: 5
.1.3.6.1.4.1.8072.1.3.2.2.1.6.5.115.50.109.111.110 = INTEGER: exec(1)
.1.3.6.1.4.1.8072.1.3.2.2.1.7.5.115.50.109.111.110 = INTEGER: run-on-read(1)
.1.3.6.1.4.1.8072.1.3.2.2.1.20.5.115.50.109.111.110 = INTEGER: permanent(4)
.1.3.6.1.4.1.8072.1.3.2.2.1.21.5.115.50.109.111.110 = INTEGER: active(1)
.1.3.6.1.4.1.8072.1.3.2.3.1.1.5.115.50.109.111.110 = STRING:
.1.3.6.1.4.1.8072.1.3.2.3.1.2.5.115.50.109.111.110 = STRING:
.1.3.6.1.4.1.8072.1.3.2.3.1.3.5.115.50.109.111.110 = INTEGER: 1
.1.3.6.1.4.1.8072.1.3.2.3.1.4.5.115.50.109.111.110 = INTEGER: 3
.1.3.6.1.4.1.8072.1.3.2.4.1.2.5.115.50.109.111.110.1 = STRING:

Интересующая нас строка:

.1.3.6.1.4.1.8072.1.3.2.3.1.4.5.115.50.109.111.110 = INTEGER: 3

А теперь продолжим играться на подопытном. Данные записались в файлик аудита, поэтому запустим на него следующую команду:

# grep snmp /var/log/audit/audit.log | grep denied | audit2allow -M snmpraidlocal
******************** IMPORTANT ***********************
To make this policy package active, execute:
semodule -i snmpraidlocal.pp
# cat snmpraidlocal.te
module snmpraidlocal 1.0;
require {
type admin_home_t;
type snmpd_t;
type tmp_t;
type proc_mdstat_t;
type usr_t;
class dir { write remove_name add_name };
class file { execute read create getattr execute_no_trans write ioctl unlink open };
}
#============= snmpd_t ==============
#!!!! This avc is allowed in the current policy
allow snmpd_t admin_home_t:file { ioctl execute read open getattr execute_no_trans };
#!!!! This avc is allowed in the current policy
allow snmpd_t proc_mdstat_t:file { read getattr open };
#!!!! This avc is allowed in the current policy
allow snmpd_t tmp_t:dir { write remove_name add_name };
#!!!! This avc is allowed in the current policy
allow snmpd_t tmp_t:file { write create unlink open };
#!!!! This avc is allowed in the current policy
allow snmpd_t usr_t:file { execute execute_no_trans };

Выглядит нормально, поэтому применяем данный модуль и включаем SELinux:

# semodule -i snmpraidlocal.pp
# setenforce 1

Перепроверяем показания с другого компа:

$ snmpwalk -O n -v 2c -c mon 10.0.1.1 1.3.6.1.4.1.8072.1.3 | grep 5.115

Радуемся, что всё работает.

Полезные материалы: