Вывод команды не перехватывается сценарием оболочки при вызове 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, но я получаю такой же пустой вывод.
Наконец-то мои вопросы
- Почему скрипт bash ведет себя по-разному в этих двух сценариях?
- Вполне вероятно, что проблема, которая существует с 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