Ранее я уже
начинал рассматривать данную тему. Но сегодня мне бы хотелось продолжить повествование об изыскании в этом направлении.
Если вы помните, в указанной выше статье, для получения информации об установленных пакетах на целевой машине использовалось копирование архива, содержащего в себе копию директории
/var/lib/rpm на сетевой диск сервера. Далее сервер использовал данный архив для поиска обновлений используемых пакетов.
В этой статье я хочу рассмотреть данный шаг с другой стороны, а именно получение информации об используемых пакетов через службу
SNMP.
Почему я решил попробовать SNMP для данной задачи? Наверно потому, что я еще не разбирался с SNMP в области предоставления данных. Это мой первый опыт, поэтому данная статья скорее всего будет содержать в себе не эффективные методы и способы сбора и предоставления информации. Приступим к рассмотрению.
Вводные данные.
- Первым делом для использования на целевой машине агента snmp, необходимо установить сам snmp: urpmi net-snmp.
- После установки данной службы необходимо её настроить. Минимальные настройки, достаточные для запуска службы
cat /etc/snmp/snmpd.conf
syslocation "BDag host"
syscontact “BDag <bdag@localhost>”
rocommunity public 127.0.0.1
- Так же необходимо наличие установленных пакетов, скорее всего они уже установлены, perl, perl-NetSNMP
Реализация идеи.
После прочтения документации по созданию SNMP агентов и просмотра неодного примера реализации, был модифицирован perl скрипт из примеров, для интеграции его в snmp как агента.
use NetSNMP::OID (':all');
use NetSNMP::agent (':all');
use NetSNMP::ASN (':all');
use URPM;
$program = "BDAG_test_mod";
print STDERR "BDAG test SNMP module v.0.1\nDebug mode is on.\n" if ($debugging);
sub help {
my ($message) = @_;
print STDERR '
ERROR: ' . $program . ':' . $message .
'
Here is some help ...
This program should be started from snmpd.conf.
An example for allowing one to walk /etc/passwd would be when this program is /etc/snmp/snmpagent.pl:
perl print STDERR \'Perl extentsions:\' . \n\"
perl $debugging = \'1\';
perl {$regat = '.1.3.6.1.4.1.8072.999'; $extension='1'; do '/etc/snmp/snmpagent.pl'; }
Use snmpd -f to see what is going on.
The result of a snmpwalk would be:
NET-SNMP-MIB::netSnmp.999.1.1.1 = STRING: "value1"
NET-SNMP-MIB::netSnmp.999.1.1.2 = STRING: "value2"
NET-SNMP-MIB::netSnmp.999.1.1.1 = STRING: "value3"
NET-SNMP-MIB::netSnmp.999.1.1.1 = STRING: "value4"
NB: snmptable requires a MIB to work.
Owen Brotherwood, DK 2007, modifed BDag
GNU General Public License V3
';
die($message);
}
if (!defined($regat)) {
help('No $regat defined');
}
#
# Handler routine to deal with SNMP requests
#
open(PRODID,'/etc/product.id');
my $productid = <PRODID>;
close(PRODID);
chomp($productid);
my @elm=split(',',$productid);
my %product={};
foreach (@elm) {
my @param = split('=',$_);
$product{$param[0]}=$param[1];
}
sub myhandler {
my ($handler, $registration_info, $request_info, $requests) = @_;
my $request;
my %my_oid = ();
my $ASN_OCTET_STR = 4;
my $delimT = '';
my $delimV = ':';
my $db = URPM::DB::open();
undef(@mibdata);
push(@mibdata,lc($product{'vendor'}).':'.lc($product{'branch'}).':'.lc($product{'version'}).':'.lc($product{'arch'}));
$db->traverse(sub {
my ($package) = @_; # this is a URPM::Package object
$pkg=$package->name.":".$package->version.":".$package->release;
push(@mibdata,$pkg);
}
);
$base_oid = new NetSNMP::OID($regat . '.' . $extension);
undef($prev_oid);
$jndex = 1;
foreach $line (@mibdata) {
chomp $line;
if ($delimT != ''){
($index_name, $index_type, $index_values) = split(/$delimT/, $line);
}else{
$index_values = $line;
$index_name = 'Unknown';
$index_type = $ASN_OCTET_STR;
}
my @value = split(/$delimV/, $index_values);
my $index = 1;
foreach $mibit (@value) {
$this_oid = new NetSNMP::OID($base_oid . '.' . $jndex . '.' . $index);
$oid_type{$this_oid} = $index_type;
$oid_value{$this_oid} = $mibit;
$oid_index{$this_oid} = $index;
$oid_jndex{$this_oid} = $jndex;
if (defined($prev_oid)){
$oid_next{$prev_oid} = $this_oid;
}
$prev_oid = $this_oid;
print STDERR "Loading $this_oid $oid_type{$this_oid}::$oid_value{$this_oid} \n" if ($debugging);
$index++;
}
$jndex++;
}
$mjndex = $jndex;
$mindex = $index;
for ($jndex = 1; $jndex < $mjndex; $jndex++) {
$this_oid = new NetSNMP::OID($base_oid . '.' . $jndex);
$next_oid = new NetSNMP::OID($this_oid . '.1');
$oid_next{$this_oid} = $next_oid;
}
for ($request = $requests; $request; $request = $request->next()) {
#
# Work through the list of varbinds
#
my $oid = $request->getOID();
print STDERR "$program @ $oid \n" if ($debugging);
if ($request_info->getMode() == MODE_GET) {
print STDERR "GET" if ($debugging);
if (exists $oid_value{$oid}) {
print STDERR "->$oid_value{$oid}\n" if ($debugging);
$request->setValue($oid_type{$oid}, $oid_value{$oid});
}else{
print STDERR " No value ...\n";
}
}elsif ($request_info->getMode() == MODE_GETNEXT) {
# long way to walk
print STDERR " GETNEXT " if($debugging);
if (defined($oid_next{$oid})) {
$next_oid = $oid_next{$oid};
$type_oid = $oid_type{$next_oid};
$value_oid = $oid_value{$next_oid};
$request->setOID($next_oid);
$request->setValue($type_oid, $value_oid);
}elsif ($oid <= $base_oid) {
$next_oid = new NetSNMP::OID($base_oid . '.1.1');
$type_oid = $oid_type{$next_oid};
$value_oid = $oid_value{$next_oid};
$request->setOID($next_oid);
$request->setValue($type_oid, $value_oid);
}else{
print STDERR "Hit by a truck whilst walking ...\n" if ($debugging);
}
}
}
}
{
if (!$agent) {
help('No $agent defined');
}
print STDERR "$program @ $regat \n";
my $regoid = new NetSNMP::OID($regat);
$agent->register($program, $regoid, \&myhandler);
print STDERR $program . " Agent is started.\n";
}
Данный скрипт сохраняем в директорию /etc/snmp, ну или по вашему желанию. А затем подключаем его в конфигурационном файле /etc/snmp/snmpd.conf
perl $debugging='0';
perl {$regat = '.1.3.6.1.4.1.8072.999'; $extension='1'; do '/etc/snmp/snmpagent.pl'; }
Для того чтобы проверить, все ли работает, достаточно запустить службу:
snmpd -f
и в другой консоли обратимся с запросом к агенту:
snmpwalk -v 2c -c public 127.0.0.1 .1.3.6.1.4.1.8072.999
Результат выполнения данной команды должен быть список:
NET-SNMP-MIB::netSnmp.999.1.1.1 = STRING: «mandriva»
NET-SNMP-MIB::netSnmp.999.1.1.2 = STRING: «devel»
NET-SNMP-MIB::netSnmp.999.1.1.3 = STRING: «2011.0»
NET-SNMP-MIB::netSnmp.999.1.1.4 = STRING: «x86_64»
NET-SNMP-MIB::netSnmp.999.1.2.1 = STRING: «lib64kopeteidentity1»
NET-SNMP-MIB::netSnmp.999.1.2.2 = STRING: «4.5.80»
NET-SNMP-MIB::netSnmp.999.1.2.3 = STRING: «1mdv2011.0»
NET-SNMP-MIB::netSnmp.999.1.3.1 = STRING: «lib64nepomuktasks0»
…
Используемая литература:
- Extending snmpd using perl
- man:URPM
PS: Информацию передает довольно медленно, при этом наблюдается сильная нагрузка на процессор. В связи с этим, если кто знает как данную проблему решить прошу сообщить.
С передачей данных через SNMP работаю впервые, поэтому алгоритмы могут быть не эффективны, приветствуются любые дополнения и комментарии по данной теме.
Комментарии (0)
rss свернуть / развернуть