Вывод команды не перехватывается сценарием оболочки при вызове snmp pass

Эта проблема

SNMPD правильно делегирует запросы на опрос SNMP другой программе, но ответ от этой программы недействителен. Ручной запуск программы с теми же аргументами отвечает правильно.

Деталь

Я установил правильные драйверы LSI raid на сервере и хочу настроить SNMP. Согласно инструкции, я добавил следующее /etc/snmp/snmpd.conf чтобы перенаправить запросы SNMP-опросов с заданным префиксом OID в программу:

pass .1.3.6.1.4.1.3582 /usr/sbin/lsi_mrdsnmpmain

Он не работает правильно для запросов SNMP:

snmpget -v1 -c public localhost .1.3.6.1.4.1.3582.5.1.4.2.1.2.1.32.1

Я получаю следующий ответ:

Error in packet
Reason: (noSuchName) There is no such variable name in this MIB.
Failed object: SNMPv2-SMI::enterprises.3582.5.1.4.2.1.2.1.32.1

Что я пробовал

SNMPD передает два аргумента, -g а также <oid> и ожидает трехстрочный ответ <oid>, <data-type> а также <data-value>,

Если я вручную запустить следующее:

/usr/sbin/lsi_mrdsnmpmain -g .1.3.6.1.4.1.3582.5.1.4.2.1.2.1.32.0

Я правильно получаю правильный трехстрочный ответ:

.1.3.6.1.4.1.3582.5.1.4.2.1.2.1.32.0
integer
30

Это означает, что pass Команда работает правильно и /usr/sbin/lsi_mrdsnmpmain программа работает правильно в этом примере

Я пытался заменить /usr/sbin/lsi_mrdsnmpmain с помощью сценария Bash. Сценарий bash делегирует вызов и регистрирует предоставленные аргументы и выходные данные делегированного вызова:

#!/bin/bash
echo "In: '$@" > /var/log/snmp-pass-test
RETURN=$(/usr/sbin/lsi_mrdsnmpmain $@)
echo "$RETURN"
echo "Out: '$RETURN'" >> /var/log/snmp-pass-test

И модифицировал pass Команда для перенаправления в скрипт bash. Если я запускаю скрипт bash вручную /usr/sbin/snmp-pass-test -g .1.3.6.1.4.1.3582.5.1.4.2.1.2.1.32.0 Я получаю правильный трехстрочный ответ, как и при запуске /usr/sbin/lsi_mrdsnmpmain вручную, и я получаю следующие записи:

In: '-g .1.3.6.1.4.1.3582.5.1.4.2.1.2.1.32.0
Out: '.1.3.6.1.4.1.3582.5.1.4.2.1.2.1.32.0
integer
30'

Когда я перезапущу snmpget тест, я получаю то же самое Error in packet... ошибка и запись в журнале bash-скрипта показывает, что захваченный вывод делегированного вызова пуст:

In: '-g .1.3.6.1.4.1.3582.5.1.4.2.1.2.1.32.0
Out: ''

Если я изменю сценарий bash, чтобы отобразить только пустую строку, я также получу то же самое Error in packet... сообщение.

Я также пытался убедиться, что переменные среды, которые присутствуют, когда я вызываю вручную /usr/sbin/lsi_mrdsnmpmain одинаковы для скрипта bash, но я получаю такой же пустой вывод.

Наконец-то мои вопросы

  1. Почему скрипт bash ведет себя по-разному в этих двух сценариях?
  2. Вполне вероятно, что проблема, которая существует с bash-скриптами, такая же, как изначально замеченная (запускаемая вручную программа имеет другой вывод, чем запускаемая программа SNMPD)?

Обновления

предложения eewanco

Какой пользователь запускает программу в каждом сценарии?

я добавил echo "$(whoami)" > /var/log/snmp-pass-test к сценарию bash и root был добавлен в журналы

Может быть, попробуйте выполнить его в cron

Добавление следующего в crontab root и запись правильного трехстрочного ответа:

* * * * * /usr/sbin/lsi_mrdsnmpmain -g .1.3.6.1.4.1.3582.5.1.4.2.1.2.1.32.1 >> /var/log/snmp-test-cron 2>&1

Предложение Гриши Левита

Попробуйте войти в stderr

Нет зарегистрированных ошибок

Проверка /var/log/messages

Когда я запускаю его через SNMPD, я получаю MegaRAID SNMP AGENT: Error in getting Shared Memory(lsi_mrdsnmpmain) журнал. Когда я запускаю это непосредственно, я не делаю. Я немного погуглил и мне может понадобиться установить lm_sensors; Я попробую это.

Я установил lm_sensors & compat-libstdC++-33.i686 (последний, потому что он сказал, что это было предварительным условием из инструкций, и я его пропустил), удалил и переустановил драйверы LSI и испытываю ту же проблему.

SELinux

Я случайно наткнулся на страницу о расширении snmpd с помощью скриптов, и там написано, что у скрипта есть правильный контекст SELinux. Я побежал grep AVC /var/log/audit/audit.log | grep snmp до и после запуска snmpget и следующая запись добавляется как прямой результат запуска snmpget:

type=AVC msg=audit(1485967641.075:271): avc:  denied  { unix_read unix_write } for  pid=5552 comm="lsi_mrdsnmpmain" key=558265  scontext=system_u:system_r:snmpd_t:s0 tcontext=system_u:system_r:initrc_t:s0 tclass=shm

Теперь я предполагаю, что SELinux вызывает сбой вызова; Я буду копать дальше... см. Ответ для решения.

Strace (предложение Еванко)

Попробуйте использовать strace с и без snmp и посмотрите, сможете ли вы поймать ошибку системного вызова или некоторые дополнительные подсказки

Для полноты картины я хотел посмотреть, не намекал ли strace, что SELinux отрицает это. Мне пришлось удалить пакеты политики с помощью semodule -r <policy-package-name> чтобы снова решить проблему, выполните следующее:

strace snmpget -v1 -c public localhost .1.3.6.1.4.1.3582.5.1.4.2.1.2.1.32.1 >> strace.log 2>&1

Конец strace.log выглядит следующим образом, и если я что-то упустил, он не дает никаких подсказок:

...
sendmsg(3, {msg_name(16)={sa_family=AF_INET, sin_port=htons(161),     sin_addr=inet_addr("127.0.0.1")}, msg_iov(1)=    [{"0;\2\1\0\4\20public\240$\2\4I\264-m\2"..., 61}], msg_controllen=32,     {cmsg_len=28, cmsg_level=SOL_IP, cmsg_type=, ...}, msg_flags=0},     MSG_DONTWAIT|MSG_NOSIGNAL) = 61
select(4, [3], NULL, NULL, {0, 999997}) = 1 (in [3], left {0, 998475})
brk(0xab9000)                           = 0xab9000
recvmsg(3, {msg_name(16)={sa_family=AF_INET, sin_port=htons(161),     sin_addr=inet_addr("127.0.0.1")}, msg_iov(1)=    [{"0;\2\1\0\4\20public\242$\2\4I\264-m\2"..., 65536}],     msg_controllen=0, msg_flags=0}, MSG_DONTWAIT) = 61
write(2, "Error in packet\nReason: (noSuchN"..., 81Error in packet
Reason: (noSuchName) There is no such variable name in this MIB.
) = 81
write(2, "Failed object: ", 15Failed object: )         = 15
write(2, "SNMPv2-SMI::enterprises.3582.5.1"..., 48SNMPv2-        SMI::enterprises.3582.5.1.4.2.1.2.1.32.1
) = 48
write(2, "\n", 1
)                       = 1
brk(0xaa9000)                           = 0xaa9000
close(3)                                = 0
exit_group(2)                           = ?
+++ exited with 2 +++

1 ответ

Решение

Именно SELinux отказывал snmpd в делегированном вызове /usr/sbin/lsi_mrdsnmpmain (и, возможно, за его пределами).

Чтобы определить это, я побежал grep AVC /var/log/audit/audit.log и для каждой записи я запускал следующее:

echo "<grepped-output>" | audit2allow -a -M <filename>

Это создает пакет политики SELinux, который должен разрешить делегированный вызов. Затем пакет загружается с использованием следующего:

semodule -i <filename>.pp

Я должен был сделать это 5 раз, так как были разные причины отказа (unix_read unix_write, associate, read write). Я посмотрю, чтобы объединить модули в один.

Теперь, когда я бегу snmpget Я получаю правильный делегированный вывод:

SNMPv2-SMI::enterprises.3582.5.1.4.2.1.2.1.32.1 = INTEGER: 34
Другие вопросы по тегам